1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-20 05:23:04 +01:00

Implement ScenarioPatcher with FixLandOwnership capabilities

This commit is contained in:
Tulio Leao
2024-01-12 19:15:55 -03:00
parent 6278732f12
commit e7ee0ba63a
5 changed files with 189 additions and 40 deletions

View File

@@ -39,26 +39,27 @@ static constexpr const char* DirectoryNamesRCT2[] = {
};
static constexpr u8string_view DirectoryNamesOpenRCT2[] = {
u8"data", // DATA
u8"landscape", // LANDSCAPE
u8"language", // LANGUAGE
u8"chatlogs", // LOG_CHAT
u8"serverlogs", // LOG_SERVER
u8"keys", // NETWORK_KEY
u8"object", // OBJECT
u8"plugin", // PLUGIN
u8"save", // SAVE
u8"scenario", // SCENARIO
u8"screenshot", // SCREENSHOT
u8"sequence", // SEQUENCE
u8"shaders", // SHADER
u8"themes", // THEME
u8"track", // TRACK
u8"heightmap", // HEIGHTMAP
u8"replay", // REPLAY
u8"desyncs", // DESYNCS
u8"crash", // CRASH
u8"assetpack", // ASSET_PACK
u8"data", // DATA
u8"landscape", // LANDSCAPE
u8"language", // LANGUAGE
u8"chatlogs", // LOG_CHAT
u8"serverlogs", // LOG_SERVER
u8"keys", // NETWORK_KEY
u8"object", // OBJECT
u8"plugin", // PLUGIN
u8"save", // SAVE
u8"scenario", // SCENARIO
u8"screenshot", // SCREENSHOT
u8"sequence", // SEQUENCE
u8"shaders", // SHADER
u8"themes", // THEME
u8"track", // TRACK
u8"heightmap", // HEIGHTMAP
u8"replay", // REPLAY
u8"desyncs", // DESYNCS
u8"crash", // CRASH
u8"assetpack", // ASSET_PACK
u8"scenario_patches", // SCENARIO_PATCHES
};
static constexpr u8string_view FileNames[] = {

View File

@@ -32,26 +32,27 @@ namespace OpenRCT2
enum class DIRID
{
DATA, // Contains g1.dat, music etc.
LANDSCAPE, // Contains scenario editor landscapes (SC6).
LANGUAGE, // Contains language packs.
LOG_CHAT, // Contains chat logs.
LOG_SERVER, // Contains server logs.
NETWORK_KEY, // Contains the user's public and private keys.
OBJECT, // Contains objects.
PLUGIN, // Contains plugins (.js).
SAVE, // Contains saved games (SV6).
SCENARIO, // Contains scenarios (SC6).
SCREENSHOT, // Contains screenshots.
SEQUENCE, // Contains title sequences.
SHADER, // Contains OpenGL shaders.
THEME, // Contains interface themes.
TRACK, // Contains track designs.
HEIGHTMAP, // Contains heightmap data.
REPLAY, // Contains recorded replays.
LOG_DESYNCS, // Contains desync reports.
CRASH, // Contains crash dumps.
ASSET_PACK, // Contains asset packs.
DATA, // Contains g1.dat, music etc.
LANDSCAPE, // Contains scenario editor landscapes (SC6).
LANGUAGE, // Contains language packs.
LOG_CHAT, // Contains chat logs.
LOG_SERVER, // Contains server logs.
NETWORK_KEY, // Contains the user's public and private keys.
OBJECT, // Contains objects.
PLUGIN, // Contains plugins (.js).
SAVE, // Contains saved games (SV6).
SCENARIO, // Contains scenarios (SC6).
SCREENSHOT, // Contains screenshots.
SEQUENCE, // Contains title sequences.
SHADER, // Contains OpenGL shaders.
THEME, // Contains interface themes.
TRACK, // Contains track designs.
HEIGHTMAP, // Contains heightmap data.
REPLAY, // Contains recorded replays.
LOG_DESYNCS, // Contains desync reports.
CRASH, // Contains crash dumps.
ASSET_PACK, // Contains asset packs.
SCENARIO_PATCHES, // Contains scenario patches.
};
enum class PATHID

View File

@@ -995,6 +995,7 @@
<ClCompile Include="profiling\Profiling.cpp" />
<ClCompile Include="rct12\CSStringConverter.cpp" />
<ClCompile Include="rct12\RCT12.cpp" />
<ClCompile Include="rct12\ScenarioPatcher.cpp" />
<ClCompile Include="rct12\SawyerChunk.cpp" />
<ClCompile Include="rct12\SawyerChunkReader.cpp" />
<ClCompile Include="rct12\SawyerChunkWriter.cpp" />

View File

@@ -0,0 +1,129 @@
/*****************************************************************************
* Copyright (c) 2014-2024 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#include "ScenarioPatcher.h"
#include "../Context.h"
#include "../PlatformEnvironment.h"
#include "../core/File.h"
#include "../core/Guard.hpp"
#include "../core/Json.hpp"
#include "../core/Path.hpp"
#include "../world/Location.hpp"
#include "../world/Map.h"
#include "../world/Surface.h"
#include <iostream>
static u8string ToOwnershipJsonKey(int ownershipType)
{
switch (ownershipType)
{
case OWNERSHIP_UNOWNED:
return "unowned";
case OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED:
return "construction_rights_owned";
case OWNERSHIP_OWNED:
return "owned";
case OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE:
return "construction_rights_available";
case OWNERSHIP_AVAILABLE:
return "available";
}
Guard::Assert(0, "Unrecognized ownership type flag");
return {};
}
static void ApplyLandOwnershipFixes(const json_t& landOwnershipFixes, int ownershipType)
{
auto ownershipTypeKey = ToOwnershipJsonKey(ownershipType);
if (!landOwnershipFixes.contains(ownershipTypeKey))
{
return;
}
auto ownershipParameters = landOwnershipFixes[ownershipTypeKey];
constexpr u8string_view coordinatesKey = "coordinates";
if (!ownershipParameters.contains(coordinatesKey))
{
Guard::Assert(0, "Cannot have ownership fix without coordinates array");
return;
}
else if (!ownershipParameters[coordinatesKey].is_array())
{
Guard::Assert(0, "Ownership fix coordinates should be an array");
return;
}
auto ownershipCoords = Json::AsArray(ownershipParameters[coordinatesKey]);
if (ownershipCoords.empty())
{
Guard::Assert(0, "Ownership fix coordinates array should not be empty");
return;
}
const bool cannotDowngrade = ownershipParameters.contains("cannot_downgrade")
? Json::GetBoolean(ownershipParameters["cannot_downgrade"], false)
: false;
std::initializer_list<TileCoordsXY> tiles;
for (size_t i = 0; i < ownershipCoords.size(); ++i)
{
if (!ownershipCoords[i].is_array())
{
Guard::Assert(0, "Ownership fix coordinates should contain only arrays");
return;
}
auto coordinatesPair = Json::AsArray(ownershipCoords[i]);
if (coordinatesPair.size() != 2)
{
Guard::Assert(0, "Ownership fix coordinates sub array should have 2 elements");
return;
}
FixLandOwnershipTilesWithOwnership(
{ { Json::GetNumber<int32_t>(coordinatesPair[0]), Json::GetNumber<int32_t>(coordinatesPair[1]) } }, ownershipType,
cannotDowngrade);
}
}
static void ApplyLandOwnershipFixes(const json_t& scenarioPatch)
{
constexpr u8string_view landOwnershipKey = "land_ownership";
if (!scenarioPatch.contains(landOwnershipKey))
{
return;
}
auto landOwnershipFixes = scenarioPatch[landOwnershipKey];
for (const auto& ownershipType : { OWNERSHIP_UNOWNED, OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED, OWNERSHIP_OWNED,
OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE, OWNERSHIP_AVAILABLE })
{
ApplyLandOwnershipFixes(landOwnershipFixes, ownershipType);
}
}
static u8string GetPatchFileName(u8string_view scenarioName)
{
auto env = OpenRCT2::GetContext()->GetPlatformEnvironment();
auto scenarioPatches = env->GetDirectoryPath(OpenRCT2::DIRBASE::OPENRCT2, OpenRCT2::DIRID::SCENARIO_PATCHES);
auto scenarioPatchFile = Path::WithExtension(Path::GetFileNameWithoutExtension(scenarioName), ".json");
return Path::Combine(scenarioPatches, scenarioPatchFile);
}
void RCT12::FetchAndApplyScenarioPatch(u8string_view scenarioName)
{
auto patchPath = GetPatchFileName(scenarioName);
std::cout << "Path is: " << patchPath << std::endl;
// TODO: Check if case sensitive, some scenario names have all lowercase variations
if (File::Exists(patchPath))
{
auto scenarioPatch = Json::ReadFromFile(patchPath);
ApplyLandOwnershipFixes(scenarioPatch);
}
}

View File

@@ -0,0 +1,17 @@
/*****************************************************************************
* Copyright (c) 2014-2024 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#pragma once
#include "../core/String.hpp"
namespace RCT12
{
void FetchAndApplyScenarioPatch(u8string_view scenarioName);
}