This commit is contained in:
Ted John 2024-05-09 06:28:02 -03:00 committed by GitHub
commit b46a75affb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 233 additions and 0 deletions

View File

@ -34,6 +34,7 @@
0.4.10 (2024-04-02)
------------------------------------------------------------------------
- Feature: [#18171] Add port of the RCT1 Stand-Up Roller Coaster.
- Feature: [#20263] Ability to increase the size of the map in the (0, 0) direction.
- Feature: [#21590] [Plugin] Plugins can now read and write banner properties of tile elements.
- Feature: [#21636] Add shortcut key for sorting tile elements.
- Feature: [objects#294] Add scenery versions of wooden truss supports.

View File

@ -939,6 +939,8 @@ declare global {
interface MapChangeSizeArgs extends GameActionArgs {
targetSizeX: number;
targetSizeY: number;
shiftX: number;
shiftY: number;
}
interface MazePlaceTrackArgs extends GameActionArgs {

View File

@ -18,7 +18,13 @@
#include "../world/Park.h"
MapChangeSizeAction::MapChangeSizeAction(const TileCoordsXY& targetSize)
: MapChangeSizeAction(targetSize, TileCoordsXY())
{
}
MapChangeSizeAction::MapChangeSizeAction(const TileCoordsXY& targetSize, const TileCoordsXY& shift)
: _targetSize(targetSize)
, _shift(shift)
{
}
@ -31,6 +37,7 @@ void MapChangeSizeAction::Serialise(DataSerialiser& stream)
{
GameAction::Serialise(stream);
stream << DS_TAG(_targetSize);
stream << DS_TAG(_shift);
}
GameActions::Result MapChangeSizeAction::Query() const
@ -63,6 +70,9 @@ GameActions::Result MapChangeSizeAction::Execute() const
MapExtendBoundarySurfaceY();
}
// Shift the map (allows increasing the map at the 0,0 position
ShiftMap(_shift);
// Shrink map
if (_targetSize.x < gameState.MapSize.x || _targetSize.y < gameState.MapSize.y)
{
@ -84,4 +94,6 @@ void MapChangeSizeAction::AcceptParameters(GameActionParameterVisitor& visitor)
{
visitor.Visit("targetSizeX", _targetSize.x);
visitor.Visit("targetSizeY", _targetSize.y);
visitor.Visit("shiftX", _shift.x);
visitor.Visit("shiftY", _shift.y);
}

View File

@ -17,6 +17,7 @@ class MapChangeSizeAction final : public GameActionBase<GameCommand::ChangeMapSi
public:
MapChangeSizeAction() = default;
MapChangeSizeAction(const TileCoordsXY& targetSize);
MapChangeSizeAction(const TileCoordsXY& targetSize, const TileCoordsXY& shift);
void AcceptParameters(GameActionParameterVisitor& visitor) override;
uint16_t GetActionFlags() const override;
@ -27,4 +28,5 @@ public:
private:
TileCoordsXY _targetSize;
TileCoordsXY _shift;
};

View File

@ -21,6 +21,11 @@
#include "../actions/WallRemoveAction.h"
#include "../audio/audio.h"
#include "../core/Guard.hpp"
#include "../entity/Duck.h"
#include "../entity/EntityTweener.h"
#include "../entity/Fountain.h"
#include "../entity/PatrolArea.h"
#include "../entity/Staff.h"
#include "../interface/Cursors.h"
#include "../interface/Viewport.h"
#include "../interface/Window.h"
@ -44,6 +49,7 @@
#include "../world/TilePointerIndex.hpp"
#include "Banner.h"
#include "Climate.h"
#include "Entrance.h"
#include "Footpath.h"
#include "MapAnimation.h"
#include "Park.h"
@ -2230,3 +2236,200 @@ MapRange ClampRangeWithinMap(const MapRange& range)
MapRange validRange = MapRange{ aX, aY, bX, bY };
return validRange;
}
static inline void shiftIfNotNull(TileCoordsXY& coords, const TileCoordsXY& amount)
{
if (!coords.IsNull())
coords += amount;
}
static inline void shiftIfNotNull(CoordsXY& coords, const CoordsXY& amount)
{
if (!coords.IsNull())
coords += amount;
}
void ShiftMap(const TileCoordsXY& amount)
{
if (amount.x == 0 && amount.y == 0)
return;
auto amountToMove = amount.ToCoordsXY();
auto& gameState = GetGameState();
// Tile elements
auto newElements = std::vector<TileElement>();
for (int32_t y = 0; y < kMaximumMapSizeTechnical; y++)
{
for (int32_t x = 0; x < kMaximumMapSizeTechnical; x++)
{
auto srcX = x - amount.x;
auto srcY = y - amount.y;
if (x > 0 && y > 0 && x < gameState.MapSize.x - 1 && y < gameState.MapSize.y - 1 && srcX > 0 && srcY > 0
&& srcX < gameState.MapSize.x - 1 && srcY < gameState.MapSize.y - 1)
{
auto srcTile = _tileIndex.GetFirstElementAt(TileCoordsXY(srcX, srcY));
do
{
newElements.push_back(*srcTile);
} while (!(srcTile++)->IsLastForTile());
}
else if (x == 0 || y == 0 || x == gameState.MapSize.x - 1 || y == gameState.MapSize.y - 1)
{
auto surface = GetDefaultSurfaceElement();
surface.SetBaseZ(kMinimumLandZ);
surface.SetClearanceZ(kMinimumLandZ);
surface.AsSurface()->SetSlope(0);
surface.AsSurface()->SetWaterHeight(0);
newElements.push_back(surface);
}
else
{
auto copyX = std::clamp(srcX, 1, gameState.MapSize.x - 2);
auto copyY = std::clamp(srcY, 1, gameState.MapSize.y - 2);
auto srcTile = MapGetSurfaceElementAt(TileCoordsXY(copyX, copyY));
if (srcTile != nullptr)
{
auto tileEl = *srcTile;
tileEl.SetOwner(OWNERSHIP_UNOWNED);
tileEl.SetParkFences(0);
tileEl.SetLastForTile(true);
newElements.push_back(*reinterpret_cast<TileElement*>(&tileEl));
}
else
{
newElements.push_back(GetDefaultSurfaceElement());
}
}
}
}
SetTileElements(std::move(newElements));
MapRemoveOutOfRangeElements();
for (auto& spawn : gameState.PeepSpawns)
spawn += amountToMove;
for (auto& entrance : gameState.Park.Entrances)
entrance += amountToMove;
// Entities
auto& entityTweener = EntityTweener::Get();
for (auto i = 0; i < EnumValue(EntityType::Count); i++)
{
auto entityType = static_cast<EntityType>(i);
auto& list = GetEntityList(entityType);
for (const auto& entityId : list)
{
auto entity = GetEntity(entityId);
// Do not tween the entity
entityTweener.RemoveEntity(entity);
auto location = entity->GetLocation();
location += amountToMove;
entity->MoveTo(location);
switch (entityType)
{
case EntityType::Guest:
case EntityType::Staff:
{
auto peep = entity->As<Peep>();
if (peep != nullptr)
{
peep->NextLoc += amountToMove;
peep->DestinationX += amountToMove.x;
peep->DestinationY += amountToMove.y;
peep->PathfindGoal += amount;
for (auto& h : peep->PathfindHistory)
h += amount;
}
break;
}
case EntityType::Vehicle:
{
auto vehicle = entity->As<Vehicle>();
if (vehicle != nullptr)
{
vehicle->TrackLocation += amountToMove;
vehicle->BoatLocation += amountToMove;
}
break;
}
case EntityType::Duck:
{
auto duck = entity->As<Duck>();
if (duck != nullptr)
{
duck->target_x += amountToMove.x;
duck->target_y += amountToMove.y;
}
break;
}
case EntityType::JumpingFountain:
{
auto fountain = entity->As<JumpingFountain>();
if (fountain != nullptr)
{
fountain->TargetX += amountToMove.x;
fountain->TargetY += amountToMove.y;
}
}
default:
break;
}
if (entityType == EntityType::Staff)
{
auto staff = entity->As<Staff>();
if (staff != nullptr)
{
auto patrol = staff->PatrolInfo;
if (patrol != nullptr)
{
auto positions = patrol->ToVector();
for (auto& p : positions)
p += amount;
patrol->Clear();
patrol->Union(positions);
}
}
}
}
}
// Rides
for (auto& ride : GetRideManager())
{
auto& stations = ride.GetStations();
for (auto& station : stations)
{
shiftIfNotNull(station.Start, amountToMove);
shiftIfNotNull(station.Entrance, amount);
shiftIfNotNull(station.Exit, amount);
}
shiftIfNotNull(ride.overall_view, amountToMove);
shiftIfNotNull(ride.boat_hire_return_position, amount);
shiftIfNotNull(ride.CurTestTrackLocation, amount);
shiftIfNotNull(ride.ChairliftBullwheelLocation[0], amount);
shiftIfNotNull(ride.ChairliftBullwheelLocation[1], amount);
shiftIfNotNull(ride.CableLiftLoc, amountToMove);
}
// Banners
auto numBanners = GetNumBanners();
auto id = BannerIndex::FromUnderlying(0);
size_t count = 0;
while (count < numBanners)
{
auto* banner = GetBanner(id);
if (banner != nullptr)
{
banner->position += amount;
count++;
}
id = BannerIndex::FromUnderlying(id.ToUnderlying() + 1);
}
ShiftAllMapAnimations(amountToMove);
}

View File

@ -256,3 +256,4 @@ void FixLandOwnershipTiles(std::initializer_list<TileCoordsXY> tiles);
void FixLandOwnershipTilesWithOwnership(
std::initializer_list<TileCoordsXY> tiles, uint8_t ownership, bool doNotDowngrade = false);
MapRange ClampRangeWithinMap(const MapRange& range);
void ShiftMap(const TileCoordsXY& amount);

View File

@ -709,3 +709,14 @@ void MapAnimationAutoCreateAtTileElement(TileCoordsXY coords, TileElement* el)
break;
}
}
void ShiftAllMapAnimations(CoordsXY amount)
{
if (amount.x == 0 && amount.y == 0)
return;
for (auto& a : _mapAnimations)
{
a.location += amount;
}
}

View File

@ -46,3 +46,4 @@ void MapAnimationInvalidateAll();
const std::vector<MapAnimation>& GetMapAnimations();
void MapAnimationAutoCreate();
void MapAnimationAutoCreateAtTileElement(TileCoordsXY coords, TileElement* el);
void ShiftAllMapAnimations(CoordsXY amount);