mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-18 20:43:04 +01:00
Implement large scenery ternary colours
This commit is contained in:
@@ -571,6 +571,8 @@ public:
|
||||
widgets[WIDX_SCENERY_PRIMARY_COLOUR_BUTTON].type = WindowWidgetType::ColourBtn;
|
||||
if (sceneryEntry->flags & LARGE_SCENERY_FLAG_HAS_SECONDARY_COLOUR)
|
||||
widgets[WIDX_SCENERY_SECONDARY_COLOUR_BUTTON].type = WindowWidgetType::ColourBtn;
|
||||
if (sceneryEntry->flags & LARGE_SCENERY_FLAG_HAS_TERTIARY_COLOUR)
|
||||
widgets[WIDX_SCENERY_TERTIARY_COLOUR_BUTTON].type = WindowWidgetType::ColourBtn;
|
||||
}
|
||||
else if (tabSelectedScenery.SceneryType == SCENERY_TYPE_WALL)
|
||||
{
|
||||
@@ -1200,8 +1202,13 @@ private:
|
||||
else if (scenerySelection.SceneryType == SCENERY_TYPE_LARGE)
|
||||
{
|
||||
auto sceneryEntry = get_large_scenery_entry(scenerySelection.EntryIndex);
|
||||
auto imageId = ImageId(
|
||||
sceneryEntry->image + gWindowSceneryRotation, gWindowSceneryPrimaryColour, gWindowScenerySecondaryColour);
|
||||
auto imageId = ImageId(sceneryEntry->image + gWindowSceneryRotation);
|
||||
if (sceneryEntry->flags & LARGE_SCENERY_FLAG_HAS_PRIMARY_COLOUR)
|
||||
imageId = imageId.WithPrimary(gWindowSceneryPrimaryColour);
|
||||
if (sceneryEntry->flags & LARGE_SCENERY_FLAG_HAS_SECONDARY_COLOUR)
|
||||
imageId = imageId.WithSecondary(gWindowScenerySecondaryColour);
|
||||
if (sceneryEntry->flags & LARGE_SCENERY_FLAG_HAS_TERTIARY_COLOUR)
|
||||
imageId = imageId.WithTertiary(gWindowSceneryTertiaryColour);
|
||||
gfx_draw_sprite(&dpi, imageId, { 33, 0 });
|
||||
}
|
||||
else if (scenerySelection.SceneryType == SCENERY_TYPE_WALL)
|
||||
|
||||
@@ -1066,7 +1066,8 @@ static void RepaintSceneryToolDown(const ScreenCoordsXY& windowPos, rct_widgetin
|
||||
|
||||
auto repaintScenery = LargeScenerySetColourAction(
|
||||
{ info.Loc, info.Element->GetBaseZ(), info.Element->GetDirection() },
|
||||
info.Element->AsLargeScenery()->GetSequenceIndex(), gWindowSceneryPrimaryColour, gWindowScenerySecondaryColour);
|
||||
info.Element->AsLargeScenery()->GetSequenceIndex(), gWindowSceneryPrimaryColour, gWindowScenerySecondaryColour,
|
||||
gWindowSceneryTertiaryColour);
|
||||
|
||||
GameActions::Execute(&repaintScenery);
|
||||
break;
|
||||
@@ -1947,7 +1948,8 @@ static void WindowTopToolbarSceneryToolDown(const ScreenCoordsXY& windowPos, rct
|
||||
CoordsXYZD loc = { gridPos, gSceneryPlaceZ, direction };
|
||||
|
||||
auto sceneryPlaceAction = LargeSceneryPlaceAction(
|
||||
loc, selectedScenery, gWindowSceneryPrimaryColour, gWindowScenerySecondaryColour);
|
||||
loc, selectedScenery, gWindowSceneryPrimaryColour, gWindowScenerySecondaryColour,
|
||||
gWindowSceneryTertiaryColour);
|
||||
|
||||
auto res = GameActions::Query(&sceneryPlaceAction);
|
||||
if (res.Error == GameActions::Status::Ok)
|
||||
@@ -1972,7 +1974,7 @@ static void WindowTopToolbarSceneryToolDown(const ScreenCoordsXY& windowPos, rct
|
||||
CoordsXYZD loc = { gridPos, gSceneryPlaceZ, direction };
|
||||
|
||||
auto sceneryPlaceAction = LargeSceneryPlaceAction(
|
||||
loc, selectedScenery, gWindowSceneryPrimaryColour, gWindowScenerySecondaryColour);
|
||||
loc, selectedScenery, gWindowSceneryPrimaryColour, gWindowScenerySecondaryColour, gWindowSceneryTertiaryColour);
|
||||
sceneryPlaceAction.SetCallback([=](const GameAction* ga, const GameActions::Result* result) {
|
||||
if (result->Error == GameActions::Status::Ok)
|
||||
{
|
||||
@@ -2553,12 +2555,12 @@ static money64 TryPlaceGhostWall(
|
||||
}
|
||||
|
||||
static money64 TryPlaceGhostLargeScenery(
|
||||
CoordsXYZD loc, ObjectEntryIndex entryIndex, colour_t primaryColour, colour_t secondaryColour)
|
||||
CoordsXYZD loc, ObjectEntryIndex entryIndex, colour_t primaryColour, colour_t secondaryColour, colour_t tertiaryColour)
|
||||
{
|
||||
scenery_remove_ghost_tool_placement();
|
||||
|
||||
// 6e25a7
|
||||
auto sceneryPlaceAction = LargeSceneryPlaceAction(loc, entryIndex, primaryColour, secondaryColour);
|
||||
auto sceneryPlaceAction = LargeSceneryPlaceAction(loc, entryIndex, primaryColour, secondaryColour, tertiaryColour);
|
||||
sceneryPlaceAction.SetFlags(GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND);
|
||||
auto res = GameActions::Execute(&sceneryPlaceAction);
|
||||
if (res.Error != GameActions::Status::Ok)
|
||||
@@ -2866,7 +2868,7 @@ static void TopToolbarToolUpdateScenery(const ScreenCoordsXY& screenPos)
|
||||
{
|
||||
cost = TryPlaceGhostLargeScenery(
|
||||
{ mapTile, gSceneryPlaceZ, direction }, selection.EntryIndex, gWindowSceneryPrimaryColour,
|
||||
gWindowScenerySecondaryColour);
|
||||
gWindowScenerySecondaryColour, gWindowSceneryTertiaryColour);
|
||||
|
||||
if (cost != MONEY64_UNDEFINED)
|
||||
break;
|
||||
|
||||
@@ -20,11 +20,12 @@
|
||||
#include "../world/Surface.h"
|
||||
|
||||
LargeSceneryPlaceAction::LargeSceneryPlaceAction(
|
||||
const CoordsXYZD& loc, ObjectEntryIndex sceneryType, uint8_t primaryColour, uint8_t secondaryColour)
|
||||
const CoordsXYZD& loc, ObjectEntryIndex sceneryType, uint8_t primaryColour, uint8_t secondaryColour, uint8_t tertiaryColour)
|
||||
: _loc(loc)
|
||||
, _sceneryType(sceneryType)
|
||||
, _primaryColour(primaryColour)
|
||||
, _secondaryColour(secondaryColour)
|
||||
, _tertiaryColour(tertiaryColour)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -34,6 +35,7 @@ void LargeSceneryPlaceAction::AcceptParameters(GameActionParameterVisitor& visit
|
||||
visitor.Visit("object", _sceneryType);
|
||||
visitor.Visit("primaryColour", _primaryColour);
|
||||
visitor.Visit("secondaryColour", _secondaryColour);
|
||||
visitor.Visit("tertiaryColour", _tertiaryColour);
|
||||
}
|
||||
|
||||
uint16_t LargeSceneryPlaceAction::GetActionFlags() const
|
||||
@@ -45,7 +47,8 @@ void LargeSceneryPlaceAction::Serialise(DataSerialiser& stream)
|
||||
{
|
||||
GameAction::Serialise(stream);
|
||||
|
||||
stream << DS_TAG(_loc) << DS_TAG(_sceneryType) << DS_TAG(_primaryColour) << DS_TAG(_secondaryColour);
|
||||
stream << DS_TAG(_loc) << DS_TAG(_sceneryType) << DS_TAG(_primaryColour) << DS_TAG(_secondaryColour)
|
||||
<< DS_TAG(_tertiaryColour);
|
||||
}
|
||||
|
||||
GameActions::Result LargeSceneryPlaceAction::Query() const
|
||||
@@ -62,7 +65,7 @@ GameActions::Result LargeSceneryPlaceAction::Query() const
|
||||
|
||||
money32 supportsCost = 0;
|
||||
|
||||
if (_primaryColour > TILE_ELEMENT_COLOUR_MASK || _secondaryColour > TILE_ELEMENT_COLOUR_MASK)
|
||||
if (_primaryColour >= COLOUR_COUNT || _secondaryColour >= COLOUR_COUNT || _tertiaryColour >= COLOUR_COUNT)
|
||||
{
|
||||
log_error(
|
||||
"Invalid game command for scenery placement, primaryColour = %u, secondaryColour = %u", _primaryColour,
|
||||
@@ -381,6 +384,7 @@ void LargeSceneryPlaceAction::SetNewLargeSceneryElement(LargeSceneryElement& sce
|
||||
sceneryElement.SetSequenceIndex(tileNum);
|
||||
sceneryElement.SetPrimaryColour(_primaryColour);
|
||||
sceneryElement.SetSecondaryColour(_secondaryColour);
|
||||
sceneryElement.SetTertiaryColour(_tertiaryColour);
|
||||
|
||||
if (GetFlags() & GAME_COMMAND_FLAG_GHOST)
|
||||
{
|
||||
|
||||
@@ -27,12 +27,14 @@ private:
|
||||
ObjectEntryIndex _sceneryType{ OBJECT_ENTRY_INDEX_NULL };
|
||||
uint8_t _primaryColour{};
|
||||
uint8_t _secondaryColour{};
|
||||
uint8_t _tertiaryColour{};
|
||||
|
||||
public:
|
||||
LargeSceneryPlaceAction() = default;
|
||||
|
||||
LargeSceneryPlaceAction(
|
||||
const CoordsXYZD& loc, ObjectEntryIndex sceneryType, uint8_t primaryColour, uint8_t secondaryColour);
|
||||
const CoordsXYZD& loc, ObjectEntryIndex sceneryType, uint8_t primaryColour, uint8_t secondaryColour,
|
||||
uint8_t tertiaryColour);
|
||||
|
||||
void AcceptParameters(GameActionParameterVisitor& visitor) override;
|
||||
|
||||
|
||||
@@ -14,11 +14,12 @@
|
||||
#include "../world/Scenery.h"
|
||||
|
||||
LargeScenerySetColourAction::LargeScenerySetColourAction(
|
||||
const CoordsXYZD& loc, uint8_t tileIndex, uint8_t primaryColour, uint8_t secondaryColour)
|
||||
const CoordsXYZD& loc, uint8_t tileIndex, uint8_t primaryColour, uint8_t secondaryColour, uint8_t tertiaryColour)
|
||||
: _loc(loc)
|
||||
, _tileIndex(tileIndex)
|
||||
, _primaryColour(primaryColour)
|
||||
, _secondaryColour(secondaryColour)
|
||||
, _tertiaryColour(tertiaryColour)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -31,7 +32,8 @@ void LargeScenerySetColourAction::Serialise(DataSerialiser& stream)
|
||||
{
|
||||
GameAction::Serialise(stream);
|
||||
|
||||
stream << DS_TAG(_loc) << DS_TAG(_tileIndex) << DS_TAG(_primaryColour) << DS_TAG(_secondaryColour);
|
||||
stream << DS_TAG(_loc) << DS_TAG(_tileIndex) << DS_TAG(_primaryColour) << DS_TAG(_secondaryColour)
|
||||
<< DS_TAG(_tertiaryColour);
|
||||
}
|
||||
|
||||
GameActions::Result LargeScenerySetColourAction::Query() const
|
||||
@@ -60,15 +62,21 @@ GameActions::Result LargeScenerySetColourAction::QueryExecute(bool isExecuting)
|
||||
return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_REPAINT_THIS, STR_NONE);
|
||||
}
|
||||
|
||||
if (_primaryColour > 31)
|
||||
if (_primaryColour >= COLOUR_COUNT)
|
||||
{
|
||||
log_error("Invalid primary colour: colour = %u", _primaryColour);
|
||||
return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_REPAINT_THIS, STR_NONE);
|
||||
}
|
||||
|
||||
if (_secondaryColour > 31)
|
||||
if (_secondaryColour >= COLOUR_COUNT)
|
||||
{
|
||||
log_error("Invalid primary colour: colour = %u", _secondaryColour);
|
||||
log_error("Invalid secondary colour: colour = %u", _secondaryColour);
|
||||
return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_REPAINT_THIS, STR_NONE);
|
||||
}
|
||||
|
||||
if (_tertiaryColour >= COLOUR_COUNT)
|
||||
{
|
||||
log_error("Invalid tertiary colour: colour = %u", _tertiaryColour);
|
||||
return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_REPAINT_THIS, STR_NONE);
|
||||
}
|
||||
|
||||
@@ -135,6 +143,7 @@ GameActions::Result LargeScenerySetColourAction::QueryExecute(bool isExecuting)
|
||||
{
|
||||
tileElement->SetPrimaryColour(_primaryColour);
|
||||
tileElement->SetSecondaryColour(_secondaryColour);
|
||||
tileElement->SetTertiaryColour(_tertiaryColour);
|
||||
|
||||
map_invalidate_tile_full(currentTile);
|
||||
}
|
||||
|
||||
@@ -18,10 +18,12 @@ private:
|
||||
uint8_t _tileIndex{};
|
||||
uint8_t _primaryColour{};
|
||||
uint8_t _secondaryColour{};
|
||||
uint8_t _tertiaryColour{};
|
||||
|
||||
public:
|
||||
LargeScenerySetColourAction() = default;
|
||||
LargeScenerySetColourAction(const CoordsXYZD& loc, uint8_t tileIndex, uint8_t primaryColour, uint8_t secondaryColour);
|
||||
LargeScenerySetColourAction(
|
||||
const CoordsXYZD& loc, uint8_t tileIndex, uint8_t primaryColour, uint8_t secondaryColour, uint8_t tertiaryColour);
|
||||
|
||||
uint16_t GetActionFlags() const override;
|
||||
|
||||
|
||||
@@ -106,7 +106,14 @@ void LargeSceneryObject::DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int3
|
||||
{
|
||||
auto screenCoords = ScreenCoordsXY{ width / 2, (height / 2) - 39 };
|
||||
|
||||
const auto image = ImageId(_legacyType.image, COLOUR_BORDEAUX_RED, COLOUR_YELLOW);
|
||||
auto image = ImageId(_legacyType.image);
|
||||
if (_legacyType.flags & LARGE_SCENERY_FLAG_HAS_PRIMARY_COLOUR)
|
||||
image = image.WithPrimary(COLOUR_BORDEAUX_RED);
|
||||
if (_legacyType.flags & LARGE_SCENERY_FLAG_HAS_SECONDARY_COLOUR)
|
||||
image = image.WithSecondary(COLOUR_YELLOW);
|
||||
if (_legacyType.flags & LARGE_SCENERY_FLAG_HAS_TERTIARY_COLOUR)
|
||||
image = image.WithTertiary(COLOUR_DARK_BROWN);
|
||||
|
||||
gfx_draw_sprite(dpi, image, screenCoords);
|
||||
}
|
||||
|
||||
@@ -143,6 +150,7 @@ void LargeSceneryObject::ReadJson(IReadObjectContext* context, json_t& root)
|
||||
{
|
||||
{ "hasPrimaryColour", LARGE_SCENERY_FLAG_HAS_PRIMARY_COLOUR },
|
||||
{ "hasSecondaryColour", LARGE_SCENERY_FLAG_HAS_SECONDARY_COLOUR },
|
||||
{ "hasTertiaryColour", LARGE_SCENERY_FLAG_HAS_TERTIARY_COLOUR },
|
||||
{ "isAnimated", LARGE_SCENERY_FLAG_ANIMATED },
|
||||
{ "isPhotogenic", LARGE_SCENERY_FLAG_PHOTOGENIC },
|
||||
{ "isTree", LARGE_SCENERY_FLAG_IS_TREE },
|
||||
|
||||
@@ -374,7 +374,18 @@ void PaintLargeScenery(paint_session& session, uint8_t direction, uint16_t heigh
|
||||
}
|
||||
else
|
||||
{
|
||||
imageTemplate = ImageId(0, tileElement.GetPrimaryColour(), tileElement.GetSecondaryColour());
|
||||
if (sceneryEntry->flags & LARGE_SCENERY_FLAG_HAS_PRIMARY_COLOUR)
|
||||
{
|
||||
imageTemplate = imageTemplate.WithPrimary(tileElement.GetPrimaryColour());
|
||||
}
|
||||
if (sceneryEntry->flags & LARGE_SCENERY_FLAG_HAS_SECONDARY_COLOUR)
|
||||
{
|
||||
imageTemplate = imageTemplate.WithSecondary(tileElement.GetSecondaryColour());
|
||||
}
|
||||
if (sceneryEntry->flags & LARGE_SCENERY_FLAG_HAS_TERTIARY_COLOUR)
|
||||
{
|
||||
imageTemplate = imageTemplate.WithTertiary(tileElement.GetTertiaryColour());
|
||||
}
|
||||
}
|
||||
|
||||
auto boxlengthZ = std::min<uint8_t>(tile->z_clearance, 128) - 3;
|
||||
|
||||
@@ -1127,7 +1127,8 @@ static GameActions::Result TrackDesignPlaceSceneryElement(
|
||||
flags |= GAME_COMMAND_FLAG_REPLAY;
|
||||
}
|
||||
auto sceneryPlaceAction = LargeSceneryPlaceAction(
|
||||
{ mapCoord.x, mapCoord.y, z, rotation }, entryInfo->Index, scenery.primary_colour, scenery.secondary_colour);
|
||||
{ mapCoord.x, mapCoord.y, z, rotation }, entryInfo->Index, scenery.primary_colour, scenery.secondary_colour,
|
||||
COLOUR_DARK_BROWN);
|
||||
sceneryPlaceAction.SetFlags(flags);
|
||||
auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&sceneryPlaceAction)
|
||||
: GameActions::QueryNested(&sceneryPlaceAction);
|
||||
|
||||
@@ -26,6 +26,11 @@ colour_t LargeSceneryElement::GetSecondaryColour() const
|
||||
return Colour[1];
|
||||
}
|
||||
|
||||
colour_t LargeSceneryElement::GetTertiaryColour() const
|
||||
{
|
||||
return Colour[2];
|
||||
}
|
||||
|
||||
void LargeSceneryElement::SetPrimaryColour(colour_t newColour)
|
||||
{
|
||||
assert(newColour <= 31);
|
||||
@@ -38,6 +43,12 @@ void LargeSceneryElement::SetSecondaryColour(colour_t newColour)
|
||||
Colour[1] = newColour;
|
||||
}
|
||||
|
||||
void LargeSceneryElement::SetTertiaryColour(colour_t newColour)
|
||||
{
|
||||
assert(newColour <= 31);
|
||||
Colour[2] = newColour;
|
||||
}
|
||||
|
||||
Banner* LargeSceneryElement::GetBanner() const
|
||||
{
|
||||
return ::GetBanner(GetBannerIndex());
|
||||
|
||||
@@ -97,6 +97,7 @@ enum LARGE_SCENERY_FLAGS
|
||||
LARGE_SCENERY_FLAG_ANIMATED = (1 << 3), // 0x8
|
||||
LARGE_SCENERY_FLAG_PHOTOGENIC = (1 << 4), // 0x10
|
||||
LARGE_SCENERY_FLAG_IS_TREE = (1 << 5), // 0x20
|
||||
LARGE_SCENERY_FLAG_HAS_TERTIARY_COLOUR = (1 << 6), // 0x40
|
||||
};
|
||||
|
||||
enum WALL_SCENERY_FLAGS
|
||||
|
||||
@@ -483,6 +483,8 @@ public:
|
||||
void SetPrimaryColour(colour_t colour);
|
||||
colour_t GetSecondaryColour() const;
|
||||
void SetSecondaryColour(colour_t colour);
|
||||
colour_t GetTertiaryColour() const;
|
||||
void SetTertiaryColour(colour_t colour);
|
||||
|
||||
Banner* GetBanner() const;
|
||||
::BannerIndex GetBannerIndex() const;
|
||||
|
||||
Reference in New Issue
Block a user