mirror of https://github.com/OpenRCT2/OpenRCT2.git
Implement S4 restricted scenery
This commit is contained in:
parent
37725ae566
commit
5c8512f51c
|
@ -187,7 +187,7 @@ static void init_scenery_entry(
|
|||
{
|
||||
Guard::ArgumentInRange<int32_t>(selection.EntryIndex, 0, OBJECT_ENTRY_INDEX_NULL);
|
||||
|
||||
if (gCheatsIgnoreResearchStatus || scenery_is_invented(selection))
|
||||
if (IsSceneryAvailableToBuild(selection))
|
||||
{
|
||||
// Check if in any other groups
|
||||
for (const auto& otherTab : _tabEntries)
|
||||
|
@ -296,7 +296,7 @@ static void window_scenery_init(rct_window* w)
|
|||
for (size_t i = 0; i < sceneryGroupEntry->entry_count; i++)
|
||||
{
|
||||
auto sceneryEntry = sceneryGroupEntry->scenery_entries[i];
|
||||
if (scenery_is_invented(sceneryEntry) || gCheatsIgnoreResearchStatus)
|
||||
if (IsSceneryAvailableToBuild(sceneryEntry))
|
||||
{
|
||||
tabInfo.Entries.push_back(sceneryEntry);
|
||||
}
|
||||
|
|
|
@ -78,6 +78,9 @@ void GameState::InitAll(int32_t mapSize)
|
|||
context_broadcast_intent(&intent);
|
||||
|
||||
load_palette();
|
||||
|
||||
CheatsReset();
|
||||
ClearRestrictedScenery();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -84,6 +84,7 @@ namespace OpenRCT2
|
|||
constexpr uint32_t BANNERS = 0x33;
|
||||
// constexpr uint32_t STAFF = 0x35;
|
||||
constexpr uint32_t CHEATS = 0x36;
|
||||
constexpr uint32_t RESTRICTED_OBJECTS = 0x37;
|
||||
constexpr uint32_t PACKED_OBJECTS = 0x80;
|
||||
// clang-format on
|
||||
}; // namespace ParkFileChunkType
|
||||
|
@ -128,6 +129,7 @@ namespace OpenRCT2
|
|||
ReadWriteNotificationsChunk(os);
|
||||
ReadWriteInterfaceChunk(os);
|
||||
ReadWriteCheatsChunk(os);
|
||||
ReadWriteRestrictedObjectsChunk(os);
|
||||
|
||||
// Initial cash will eventually be removed
|
||||
gInitialCash = gCash;
|
||||
|
@ -156,6 +158,7 @@ namespace OpenRCT2
|
|||
ReadWriteNotificationsChunk(os);
|
||||
ReadWriteInterfaceChunk(os);
|
||||
ReadWriteCheatsChunk(os);
|
||||
ReadWriteRestrictedObjectsChunk(os);
|
||||
ReadWritePackedObjectsChunk(os);
|
||||
}
|
||||
|
||||
|
@ -438,6 +441,28 @@ namespace OpenRCT2
|
|||
});
|
||||
}
|
||||
|
||||
void ReadWriteRestrictedObjectsChunk(OrcaStream& os)
|
||||
{
|
||||
os.ReadWriteChunk(ParkFileChunkType::RESTRICTED_OBJECTS, [](OrcaStream::ChunkStream& cs) {
|
||||
auto& restrictedScenery = GetRestrictedScenery();
|
||||
|
||||
// We are want to support all object types in the future, so convert scenery type
|
||||
// to object type when we write the list
|
||||
cs.ReadWriteVector(restrictedScenery, [&cs](ScenerySelection& item) {
|
||||
if (cs.GetMode() == OrcaStream::Mode::READING)
|
||||
{
|
||||
item.SceneryType = GetSceneryTypeFromObjectType(static_cast<ObjectType>(cs.Read<uint16_t>()));
|
||||
item.EntryIndex = cs.Read<ObjectEntryIndex>();
|
||||
}
|
||||
else
|
||||
{
|
||||
cs.Write(static_cast<uint16_t>(GetObjectTypeFromSceneryType(item.SceneryType)));
|
||||
cs.Write(item.EntryIndex);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ReadWritePackedObjectsChunk(OrcaStream& os)
|
||||
{
|
||||
static constexpr uint8_t DESCRIPTOR_DAT = 0;
|
||||
|
|
|
@ -219,6 +219,8 @@ public:
|
|||
research_determine_first_of_type();
|
||||
|
||||
CheatsReset();
|
||||
ClearRestrictedScenery();
|
||||
RestrictAllMiscScenery();
|
||||
}
|
||||
|
||||
bool GetDetails(scenario_index_entry* dst) override
|
||||
|
|
|
@ -480,6 +480,7 @@ public:
|
|||
research_determine_first_of_type();
|
||||
|
||||
CheatsReset();
|
||||
ClearRestrictedScenery();
|
||||
}
|
||||
|
||||
void ImportRides()
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "Climate.h"
|
||||
#include "Footpath.h"
|
||||
#include "Fountain.h"
|
||||
#include "LargeScenery.h"
|
||||
#include "Map.h"
|
||||
#include "Park.h"
|
||||
#include "SmallScenery.h"
|
||||
|
@ -52,6 +53,8 @@ int16_t gSceneryCtrlPressZ;
|
|||
|
||||
money32 gClearSceneryCost;
|
||||
|
||||
static std::vector<ScenerySelection> _restrictedScenery;
|
||||
|
||||
// rct2: 0x009A3E74
|
||||
const CoordsXY SceneryQuadrantOffsets[] = { { 7, 7 }, { 7, 23 }, { 23, 23 }, { 23, 7 } };
|
||||
|
||||
|
@ -281,3 +284,149 @@ int32_t wall_entry_get_door_sound(const rct_scenery_entry* wallEntry)
|
|||
{
|
||||
return (wallEntry->wall.flags2 & WALL_SCENERY_2_DOOR_SOUND_MASK) >> WALL_SCENERY_2_DOOR_SOUND_SHIFT;
|
||||
}
|
||||
|
||||
bool IsSceneryAvailableToBuild(ScenerySelection item)
|
||||
{
|
||||
if (!gCheatsIgnoreResearchStatus)
|
||||
{
|
||||
if (!scenery_is_invented(item))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gCheatsSandboxMode)
|
||||
{
|
||||
if (IsSceneryItemRestricted(item))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static ObjectEntryIndex GetMaxObjectsForSceneryType(uint8_t sceneryType)
|
||||
{
|
||||
switch (sceneryType)
|
||||
{
|
||||
case SCENERY_TYPE_SMALL:
|
||||
return MAX_SMALL_SCENERY_OBJECTS;
|
||||
case SCENERY_TYPE_PATH_ITEM:
|
||||
return MAX_PATH_ADDITION_OBJECTS;
|
||||
case SCENERY_TYPE_WALL:
|
||||
return MAX_WALL_SCENERY_OBJECTS;
|
||||
case SCENERY_TYPE_LARGE:
|
||||
return MAX_LARGE_SCENERY_OBJECTS;
|
||||
case SCENERY_TYPE_BANNER:
|
||||
return MAX_BANNER_OBJECTS;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static rct_scenery_entry* GetSceneryEntry(ScenerySelection item)
|
||||
{
|
||||
switch (item.SceneryType)
|
||||
{
|
||||
case SCENERY_TYPE_SMALL:
|
||||
return get_small_scenery_entry(item.EntryIndex);
|
||||
case SCENERY_TYPE_PATH_ITEM:
|
||||
return get_footpath_item_entry(item.EntryIndex);
|
||||
case SCENERY_TYPE_WALL:
|
||||
return get_wall_entry(item.EntryIndex);
|
||||
case SCENERY_TYPE_LARGE:
|
||||
return get_large_scenery_entry(item.EntryIndex);
|
||||
case SCENERY_TYPE_BANNER:
|
||||
return get_banner_entry(item.EntryIndex);
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsSceneryItemRestricted(ScenerySelection item)
|
||||
{
|
||||
auto it = std::find(_restrictedScenery.begin(), _restrictedScenery.end(), item);
|
||||
return it != _restrictedScenery.end();
|
||||
}
|
||||
|
||||
void ClearRestrictedScenery()
|
||||
{
|
||||
_restrictedScenery.clear();
|
||||
}
|
||||
|
||||
std::vector<ScenerySelection>& GetRestrictedScenery()
|
||||
{
|
||||
return _restrictedScenery;
|
||||
}
|
||||
|
||||
void RestrictAllMiscScenery()
|
||||
{
|
||||
std::vector<ScenerySelection> nonMiscScenery;
|
||||
for (ObjectEntryIndex i = 0; i < MAX_SCENERY_GROUP_OBJECTS; i++)
|
||||
{
|
||||
auto sgEntry = get_scenery_group_entry(i);
|
||||
if (sgEntry != nullptr)
|
||||
{
|
||||
for (size_t j = 0; j < sgEntry->entry_count; j++)
|
||||
{
|
||||
nonMiscScenery.push_back(sgEntry->scenery_entries[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (uint8_t sceneryType = SCENERY_TYPE_SMALL; sceneryType < SCENERY_TYPE_COUNT; sceneryType++)
|
||||
{
|
||||
auto maxObjects = GetMaxObjectsForSceneryType(sceneryType);
|
||||
for (ObjectEntryIndex i = 0; i < maxObjects; i++)
|
||||
{
|
||||
ScenerySelection sceneryItem = { sceneryType, i };
|
||||
auto sceneryEntry = GetSceneryEntry(sceneryItem);
|
||||
if (sceneryEntry != nullptr)
|
||||
{
|
||||
auto it = std::find(nonMiscScenery.begin(), nonMiscScenery.end(), sceneryItem);
|
||||
if (it == nonMiscScenery.end())
|
||||
{
|
||||
_restrictedScenery.push_back(sceneryItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ObjectType GetObjectTypeFromSceneryType(uint8_t type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case SCENERY_TYPE_SMALL:
|
||||
return ObjectType::SmallScenery;
|
||||
case SCENERY_TYPE_PATH_ITEM:
|
||||
return ObjectType::PathBits;
|
||||
case SCENERY_TYPE_WALL:
|
||||
return ObjectType::Walls;
|
||||
case SCENERY_TYPE_LARGE:
|
||||
return ObjectType::LargeScenery;
|
||||
case SCENERY_TYPE_BANNER:
|
||||
return ObjectType::Banners;
|
||||
default:
|
||||
throw std::runtime_error("Invalid scenery type");
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t GetSceneryTypeFromObjectType(ObjectType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ObjectType::SmallScenery:
|
||||
return SCENERY_TYPE_SMALL;
|
||||
case ObjectType::PathBits:
|
||||
return SCENERY_TYPE_PATH_ITEM;
|
||||
case ObjectType::Walls:
|
||||
return SCENERY_TYPE_WALL;
|
||||
case ObjectType::LargeScenery:
|
||||
return SCENERY_TYPE_LARGE;
|
||||
case ObjectType::Banners:
|
||||
return SCENERY_TYPE_BANNER;
|
||||
default:
|
||||
throw std::runtime_error("Invalid object type");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -264,4 +264,14 @@ rct_scenery_group_entry* get_scenery_group_entry(ObjectEntryIndex entryIndex);
|
|||
|
||||
int32_t wall_entry_get_door_sound(const rct_scenery_entry* wallEntry);
|
||||
|
||||
bool IsSceneryAvailableToBuild(ScenerySelection item);
|
||||
|
||||
bool IsSceneryItemRestricted(ScenerySelection item);
|
||||
void ClearRestrictedScenery();
|
||||
void RestrictAllMiscScenery();
|
||||
std::vector<ScenerySelection>& GetRestrictedScenery();
|
||||
|
||||
ObjectType GetObjectTypeFromSceneryType(uint8_t type);
|
||||
uint8_t GetSceneryTypeFromObjectType(ObjectType type);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue