Add more identified fields and improve tile engine (#91)

This commit is contained in:
Ted John 2018-02-02 19:12:14 +00:00 committed by GitHub
parent 0fa0aa545e
commit 2ac01fde26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 190 additions and 24 deletions

View File

@ -26,13 +26,13 @@ namespace openloco
return name == string_ids::null;
}
static bool find_20(surface_element* surface)
static bool find_5(surface_element* surface)
{
auto element = surface;
while (!element->is_last())
{
element++;
if (element->type() == element_type::unk_20)
if (element->type() == element_type::unk_8)
{
return true;
}
@ -60,7 +60,7 @@ namespace openloco
if (bl == 0 || bl != obj->var_EA)
{
var_DB++;
if ((!(obj->var_E4 & 0x10000000) && (surface->data()[4] & 0xE0) == 0) || find_20(surface))
if ((!(obj->var_E4 & 0x10000000) && (surface->data()[4] & 0xE0) == 0) || find_5(surface))
{
var_DD++;
}

View File

@ -1,21 +1,34 @@
#include "tile.h"
#include "../industrymgr.h"
#include "../objects/objectmgr.h"
#include <cassert>
using namespace openloco;
using namespace openloco::map;
const uint8_t* tile_element::data() const
const uint8_t* tile_element_base::data() const
{
return (uint8_t*)this;
}
element_type tile_element::type() const
element_type tile_element_base::type() const
{
return (element_type)(_type & 0x3C);
return (element_type)((_type & 0x3C) >> 2);
}
bool tile_element::is_last() const
bool tile_element_base::is_last() const
{
return (_flags & 0x80) != 0;
return (_flags & element_flags::last) != 0;
}
building_object* building_element::object() const
{
return objectmgr::get<building_object>(object_id());
}
industry* industry_element::industry() const
{
return industrymgr::get(industry_id());
}
tile::tile(tile_coord_t x, tile_coord_t y, tile_element* data)
@ -68,7 +81,7 @@ tile_element* tile::operator[](size_t i)
return &_data[i];
}
size_t tile::index_of(const tile_element* element) const
size_t tile::index_of(const tile_element_base* element) const
{
size_t i = 0;
for (const auto& tile : *this)

View File

@ -4,12 +4,19 @@
#include <cstdint>
#include <limits>
namespace openloco
{
struct building_object;
struct industry;
}
namespace openloco::map
{
using coord_t = int16_t;
using tile_coord_t = uint16_t;
constexpr coord_t tile_size = 32;
constexpr coord_t map_rows = 384;
constexpr coord_t map_columns = 384;
constexpr coord_t map_size = map_columns * tile_size;
@ -23,7 +30,15 @@ namespace openloco::map
{
coord_t x = 0;
coord_t y = 0;
map_pos() {}
map_pos(coord_t x, coord_t y)
: x(x)
, y(y)
{
}
};
#pragma pack(pop)
constexpr bool operator==(const map_pos& lhs, const map_pos& rhs)
{
return lhs.x == rhs.x && lhs.y == rhs.y;
@ -32,41 +47,82 @@ namespace openloco::map
{
return !(lhs == rhs);
}
#pragma pack(push, 1)
struct map_pos3
{
coord_t x = 0;
coord_t y = 0;
coord_t z = 0;
operator map_pos() const
{
return map_pos(x, y);
}
};
#pragma pack(pop)
enum class element_type
{
surface,
unk_20 = 20,
surface, // 0x00
station = 2, // 0x08
building = 4, // 0x10
industry = 5, // 0x14
unk_8 = 8, // 0x20
};
struct surface_element;
struct tile_element
namespace element_flags
{
private:
constexpr uint8_t flag_4 = 1 << 4;
constexpr uint8_t last = 1 << 7;
}
struct surface_element;
struct station_element;
struct building_element;
struct industry_element;
#pragma pack(push, 1)
struct tile_element_base
{
protected:
uint8_t _type;
uint8_t _flags;
uint8_t _base_z;
uint8_t _clear_z;
public:
// Temporary, use this to get fields easily before they are defined
const uint8_t* data() const;
element_type type() const;
uint8_t flags() const { return _flags; }
uint8_t base_z() const { return _base_z; }
uint8_t clear_z() const { return _clear_z; }
bool is_flag_4() const { return _flags & element_flags::flag_4; }
bool is_last() const;
};
struct tile_element : public tile_element_base
{
private:
uint8_t pad[4];
template<typename TType, element_type TClass>
TType* as() const
{
return type() == TClass ? (TType*)this : nullptr;
}
public:
// Temporary, use this to get fields easily before they are defined
const uint8_t* data() const;
element_type type() const;
bool is_last() const;
public:
surface_element* as_surface() const { return as<surface_element, element_type::surface>(); }
station_element* as_station() const { return as<station_element, element_type::station>(); }
building_element* as_building() const { return as<building_element, element_type::building>(); }
industry_element* as_industry() const { return as<industry_element, element_type::industry>(); }
};
static_assert(sizeof(tile_element) == 8);
struct surface_element : public tile_element
struct surface_element : public tile_element_base
{
private:
uint8_t _slope;
@ -81,6 +137,49 @@ namespace openloco::map
uint8_t industry_id() const { return _industry; }
};
struct station_element : public tile_element_base
{
private:
uint8_t _4;
uint8_t _5;
uint8_t _6;
uint8_t _7;
public:
uint8_t object_id() const { return _5 & 0x1F; }
uint8_t unk_5b() const { return _5 >> 5; }
};
struct building_element : public tile_element_base
{
private:
uint8_t _4;
uint8_t _5;
uint8_t _6;
uint8_t _7;
public:
bool has_40() const { return (_type & 0x40) != 0; }
bool has_80() const { return (_type & 0x80) != 0; }
uint8_t object_id() const { return _4; }
building_object* object() const;
uint8_t var_5b() const { return _5 & 3; }
};
struct industry_element : public tile_element_base
{
private:
uint8_t _4;
uint8_t _5;
uint8_t _6;
uint8_t _7;
public:
uint8_t industry_id() const { return _4; }
openloco::industry* industry() const;
};
#pragma pack(pop)
struct tile
{
private:
@ -101,7 +200,7 @@ namespace openloco::map
size_t size();
tile_element* operator[](size_t i);
size_t index_of(const tile_element* element) const;
size_t index_of(const tile_element_base* element) const;
surface_element* surface();
};
}

View File

@ -0,0 +1,19 @@
#pragma once
#include "../localisation/stringmgr.h"
namespace openloco
{
struct building_object
{
string_id name;
uint8_t pad_02[0x98 - 0x02];
uint8_t var_98;
uint8_t pad_99[0xA0 - 0x99];
uint8_t var_A0[2];
uint8_t var_A2[2];
uint8_t var_A4[2];
uint8_t var_A6[2];
uint8_t var_A8[2];
};
}

View File

@ -7,7 +7,9 @@ namespace openloco
struct industry_object
{
string_id name;
uint8_t pad_02[0xE4 - 0x02];
uint8_t pad_02[0xDE - 0x02];
uint8_t var_DE[2];
uint8_t var_E0[3];
uint32_t var_E4;
uint8_t pad_E8[0xEA - 0xE8];
uint8_t var_EA;

View File

@ -65,12 +65,24 @@ namespace openloco::objectmgr
return _cargoObjects[id];
}
template<>
road_station_object* get(size_t id)
{
return _roadStationObjects[id];
}
template<>
vehicle_object* get(size_t id)
{
return _vehicleObjects[id];
}
template<>
building_object* get(size_t id)
{
return _buildingObjects[id];
}
template<>
industry_object* get(size_t id)
{

View File

@ -103,7 +103,11 @@ namespace openloco::objectmgr
template<>
cargo_object* get(size_t id);
template<>
road_station_object* get(size_t id);
template<>
vehicle_object* get(size_t id);
template<>
building_object* get(size_t id);
template<>
industry_object* get(size_t id);
}

View File

@ -0,0 +1,15 @@
#pragma once
#include "../localisation/stringmgr.h"
namespace openloco
{
struct road_station_object
{
string_id name;
uint8_t pad_02[0x0B - 0x02];
uint8_t var_0B;
uint8_t pad_0C[0x2C - 0x0C];
uint8_t var_2C;
};
}

View File

@ -79,9 +79,11 @@
<ClInclude Include="map\tile_loop.hpp" />
<ClInclude Include="map\tilemgr.h" />
<ClInclude Include="messagemgr.h" />
<ClInclude Include="objects\building_object.h" />
<ClInclude Include="objects\cargo_object.h" />
<ClInclude Include="objects\industry_object.h" />
<ClInclude Include="objects\objectmgr.h" />
<ClInclude Include="objects\road_station_object.h" />
<ClInclude Include="platform\platform.h" />
<ClInclude Include="objects\vehicle_object.h" />
<ClInclude Include="utility\prng.hpp" />