1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-18 12:33:17 +01:00
Files
OpenRCT2/src/openrct2/object/WallObject.cpp
Michael Steenbeek 6808b8b734 Fix JSON object walls with only remap colours 2 and 3 (#11821)
This fixes the hack, allowing JSON files laid out in the described manner to actually work properly.
The objects themselves will also need to be updated, but that can be done separately.
2020-05-28 22:03:50 +02:00

161 lines
5.9 KiB
C++

/*****************************************************************************
* Copyright (c) 2014-2020 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 "WallObject.h"
#include "../core/IStream.hpp"
#include "../core/String.hpp"
#include "../drawing/Drawing.h"
#include "../interface/Cursors.h"
#include "../localisation/Language.h"
#include "../world/Banner.h"
#include "ObjectJsonHelpers.h"
void WallObject::ReadLegacy(IReadObjectContext* context, IStream* stream)
{
stream->Seek(6, STREAM_SEEK_CURRENT);
_legacyType.wall.tool_id = stream->ReadValue<uint8_t>();
_legacyType.wall.flags = stream->ReadValue<uint8_t>();
_legacyType.wall.height = stream->ReadValue<uint8_t>();
_legacyType.wall.flags2 = stream->ReadValue<uint8_t>();
_legacyType.wall.price = stream->ReadValue<uint16_t>();
_legacyType.wall.scenery_tab_id = OBJECT_ENTRY_INDEX_NULL;
stream->Seek(1, STREAM_SEEK_CURRENT);
_legacyType.wall.scrolling_mode = stream->ReadValue<uint8_t>();
GetStringTable().Read(context, stream, OBJ_STRING_ID_NAME);
rct_object_entry sgEntry = stream->ReadValue<rct_object_entry>();
SetPrimarySceneryGroup(&sgEntry);
GetImageTable().Read(context, stream);
// Validate properties
if (_legacyType.wall.price <= 0)
{
context->LogError(OBJECT_ERROR_INVALID_PROPERTY, "Price can not be free or negative.");
}
// Autofix this object (will be turned into an official object later).
auto identifier = GetLegacyIdentifier();
if (identifier == "XXWLBR03")
{
_legacyType.wall.flags2 &= ~WALL_SCENERY_2_DOOR_SOUND_MASK;
_legacyType.wall.flags2 |= (1u << WALL_SCENERY_2_DOOR_SOUND_SHIFT) & WALL_SCENERY_2_DOOR_SOUND_MASK;
}
}
void WallObject::Load()
{
GetStringTable().Sort();
_legacyType.name = language_allocate_object_string(GetName());
_legacyType.image = gfx_object_allocate_images(GetImageTable().GetImages(), GetImageTable().GetCount());
}
void WallObject::Unload()
{
language_free_object_string(_legacyType.name);
gfx_object_free_images(_legacyType.image, GetImageTable().GetCount());
_legacyType.name = 0;
_legacyType.image = 0;
}
void WallObject::DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t height) const
{
int32_t x = width / 2;
int32_t y = height / 2;
x += 14;
y += (_legacyType.wall.height * 2) + 16;
uint32_t imageId = 0x20D00000 | _legacyType.image;
if (_legacyType.wall.flags & WALL_SCENERY_HAS_SECONDARY_COLOUR)
{
imageId |= 0x92000000;
}
gfx_draw_sprite(dpi, imageId, x, y, 0);
if (_legacyType.wall.flags & WALL_SCENERY_HAS_GLASS)
{
imageId = _legacyType.image + 0x44500006;
gfx_draw_sprite(dpi, imageId, x, y, 0);
}
else if (_legacyType.wall.flags & WALL_SCENERY_IS_DOOR)
{
imageId++;
gfx_draw_sprite(dpi, imageId, x, y, 0);
}
}
void WallObject::ReadJson(IReadObjectContext* context, const json_t* root)
{
auto properties = json_object_get(root, "properties");
_legacyType.wall.tool_id = ObjectJsonHelpers::ParseCursor(
ObjectJsonHelpers::GetString(properties, "cursor"), CURSOR_FENCE_DOWN);
_legacyType.wall.height = json_integer_value(json_object_get(properties, "height"));
_legacyType.wall.price = json_integer_value(json_object_get(properties, "price"));
auto jScrollingMode = json_object_get(properties, "scrollingMode");
_legacyType.wall.scrolling_mode = jScrollingMode != nullptr ? json_integer_value(jScrollingMode) : SCROLLING_MODE_NONE;
SetPrimarySceneryGroup(ObjectJsonHelpers::GetString(json_object_get(properties, "sceneryGroup")));
// Flags
_legacyType.wall.flags = ObjectJsonHelpers::GetFlags<uint8_t>(
properties,
{
{ "hasPrimaryColour", WALL_SCENERY_HAS_PRIMARY_COLOUR },
{ "hasSecondaryColour", WALL_SCENERY_HAS_SECONDARY_COLOUR },
{ "hasTernaryColour", WALL_SCENERY_HAS_TERNARY_COLOUR },
{ "hasGlass", WALL_SCENERY_HAS_GLASS },
{ "isBanner", WALL_SCENERY_IS_BANNER },
{ "isDoor", WALL_SCENERY_IS_DOOR },
{ "isLongDoorAnimation", WALL_SCENERY_LONG_DOOR_ANIMATION },
});
_legacyType.wall.flags2 = ObjectJsonHelpers::GetFlags<uint8_t>(
properties,
{
{ "isOpaque", WALL_SCENERY_2_IS_OPAQUE },
{ "isAnimated", WALL_SCENERY_2_ANIMATED },
});
// HACK To avoid 'negated' properties in JSON, handle this separately until
// flag is inverted in this code base.
if (!ObjectJsonHelpers::GetBoolean(properties, "isAllowedOnSlope", false))
{
_legacyType.wall.flags |= WALL_SCENERY_CANT_BUILD_ON_SLOPE;
}
// HACK WALL_SCENERY_HAS_PRIMARY_COLOUR actually means, has any colour but we simplify the
// JSON and handle this on load. We should change code base in future to reflect the JSON.
if (!(_legacyType.wall.flags & WALL_SCENERY_HAS_PRIMARY_COLOUR))
{
if ((_legacyType.wall.flags & WALL_SCENERY_HAS_SECONDARY_COLOUR)
|| (_legacyType.wall.flags & WALL_SCENERY_HAS_TERNARY_COLOUR))
{
_legacyType.wall.flags |= WALL_SCENERY_HAS_PRIMARY_COLOUR;
_legacyType.wall.flags2 |= WALL_SCENERY_2_NO_SELECT_PRIMARY_COLOUR;
}
}
// Door sound
auto jDoorSound = json_object_get(properties, "doorSound");
if (jDoorSound != nullptr)
{
auto doorSound = json_integer_value(jDoorSound);
_legacyType.wall.flags2 |= (doorSound << WALL_SCENERY_2_DOOR_SOUND_SHIFT) & WALL_SCENERY_2_DOOR_SOUND_MASK;
}
ObjectJsonHelpers::LoadStrings(root, GetStringTable());
ObjectJsonHelpers::LoadImages(context, root, GetImageTable());
}