Remove track Construction Window (#1110)
* Implement track removal * Add road equivalent connections * Implement removeRoad
This commit is contained in:
parent
ef420ec6e6
commit
6e74345b08
|
@ -54,7 +54,7 @@ namespace OpenLoco::GameCommands
|
|||
{ GameCommand::vehicleCreate, Vehicles::create, 0x004AE5E4, true },
|
||||
{ GameCommand::vehicleSell, nullptr, 0x004AED34, true },
|
||||
{ GameCommand::createTrack, nullptr, 0x0049BB98, true },
|
||||
{ GameCommand::gc_unk_8, nullptr, 0x0049C7F2, true },
|
||||
{ GameCommand::removeTrack, nullptr, 0x0049C7F2, true },
|
||||
{ GameCommand::changeLoan, nullptr, 0x0046DE88, false },
|
||||
{ GameCommand::vehicleRename, Vehicles::rename, 0x004B6572, false },
|
||||
{ GameCommand::changeStationName, renameStation, 0x00490756, false },
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace OpenLoco::GameCommands
|
|||
vehicleCreate = 5,
|
||||
vehicleSell = 6,
|
||||
createTrack = 7,
|
||||
gc_unk_8 = 8,
|
||||
removeTrack = 8,
|
||||
changeLoan = 9,
|
||||
vehicleRename = 10,
|
||||
changeStationName = 11,
|
||||
|
@ -276,6 +276,40 @@ namespace OpenLoco::GameCommands
|
|||
}
|
||||
};
|
||||
|
||||
struct TrackRemovalArgs
|
||||
{
|
||||
static constexpr auto command = GameCommand::removeTrack;
|
||||
|
||||
TrackRemovalArgs() = default;
|
||||
explicit TrackRemovalArgs(const registers& regs)
|
||||
: pos(regs.ax, regs.cx, regs.di)
|
||||
, rotation(regs.bh & 0x3)
|
||||
, trackId(regs.dl & 0x3F)
|
||||
, index(regs.dh)
|
||||
, trackObjectId(regs.ebp)
|
||||
{
|
||||
}
|
||||
|
||||
Map::Pos3 pos;
|
||||
uint8_t rotation;
|
||||
uint8_t trackId;
|
||||
uint8_t index;
|
||||
uint8_t trackObjectId;
|
||||
|
||||
explicit operator registers() const
|
||||
{
|
||||
registers regs;
|
||||
regs.eax = pos.x;
|
||||
regs.cx = pos.y;
|
||||
regs.di = pos.z;
|
||||
regs.bh = rotation;
|
||||
regs.dl = trackId;
|
||||
regs.dh = index;
|
||||
regs.ebp = trackObjectId;
|
||||
return regs;
|
||||
}
|
||||
};
|
||||
|
||||
// Change loan
|
||||
inline void do_9(currency32_t newLoan)
|
||||
{
|
||||
|
|
|
@ -82,6 +82,7 @@ namespace OpenLoco::Map
|
|||
|
||||
bool isGhost() const { return _flags & ElementFlags::ghost; }
|
||||
bool isFlag5() const { return _flags & ElementFlags::flag_5; }
|
||||
bool isFlag6() const { return _flags & ElementFlags::flag_6; }
|
||||
void setFlag6(bool state)
|
||||
{
|
||||
_flags &= ~ElementFlags::flag_6;
|
||||
|
@ -273,11 +274,12 @@ namespace OpenLoco::Map
|
|||
bool hasSignal() const { return (_type & 0x40) != 0; }
|
||||
uint8_t unkDirection() const { return _type & 0x03; }
|
||||
uint8_t trackId() const { return _4 & 0x3F; } // _4
|
||||
bool has_4_80() const { return (_4 & 0x80) != 0; }
|
||||
bool hasBridge() const { return (_4 & 0x80) != 0; }
|
||||
uint8_t trackObjectId() const { return _5 >> 4; } // _5u
|
||||
uint8_t sequenceIndex() const { return _5 & 0xF; } // _5l
|
||||
uint8_t bridge() const { return _6 >> 5; } // _6u
|
||||
uint8_t owner() const { return _7 & 0xF; } // _7l
|
||||
bool has_6_10() const { return (_6 & 0x10) != 0; }
|
||||
uint8_t bridge() const { return _6 >> 5; } // _6u
|
||||
uint8_t owner() const { return _7 & 0xF; } // _7l
|
||||
void setOwner(uint8_t newOwner) { _7 = (_7 & 0xF0) | (newOwner & 0xF); }
|
||||
bool hasMod(uint8_t mod) const { return _7 & (1 << (4 + mod)); } // _7u
|
||||
uint8_t mods() const { return _7 >> 4; } // _7u
|
||||
|
@ -309,7 +311,7 @@ namespace OpenLoco::Map
|
|||
public:
|
||||
uint8_t unkDirection() const { return _type & 0x03; }
|
||||
uint8_t roadId() const { return _4 & 0xF; } // _4l
|
||||
bool has_4_80() const { return (_4 & 0x80) != 0; }
|
||||
bool hasBridge() const { return (_4 & 0x80) != 0; }
|
||||
uint8_t roadObjectId() const { return _5 >> 4; } // _5u
|
||||
uint8_t sequenceIndex() const { return _5 & 0x3; } // _5l
|
||||
uint8_t bridge() const { return _6 >> 5; } // _6u
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace OpenLoco
|
|||
namespace Flags12
|
||||
{
|
||||
constexpr uint8_t unk_01 = 1 << 1;
|
||||
constexpr uint8_t unk_02 = 1 << 2;
|
||||
constexpr uint8_t unk_03 = 1 << 3;
|
||||
constexpr uint8_t isRoad = 1 << 6; // If not set this is tram track
|
||||
}
|
||||
|
|
|
@ -278,7 +278,7 @@ namespace OpenLoco::Ui::Windows::Construction
|
|||
|
||||
_lastSelectedBridge = lastBridge;
|
||||
|
||||
if (copyElement->has_4_80())
|
||||
if (copyElement->hasBridge())
|
||||
{
|
||||
_lastSelectedBridge = copyElement->bridge();
|
||||
}
|
||||
|
@ -360,7 +360,7 @@ namespace OpenLoco::Ui::Windows::Construction
|
|||
lastBridge = _bridgeList[0];
|
||||
|
||||
_lastSelectedBridge = lastBridge;
|
||||
if (copyElement->has_4_80())
|
||||
if (copyElement->hasBridge())
|
||||
{
|
||||
_lastSelectedBridge = copyElement->bridge();
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "../../Objects/ObjectManager.h"
|
||||
#include "../../Objects/RoadObject.h"
|
||||
#include "../../Objects/TrackObject.h"
|
||||
#include "../../Station.h"
|
||||
#include "../../TrackData.h"
|
||||
#include "../../Ui/Dropdown.h"
|
||||
#include "../../Widget.h"
|
||||
|
@ -304,13 +305,500 @@ namespace OpenLoco::Ui::Windows::Construction::Construction
|
|||
activateSelectedConstructionWidgets();
|
||||
}
|
||||
|
||||
static loco_global<Map::Pos2[16], 0x00503C6C> _503C6C;
|
||||
struct TrackConnections
|
||||
{
|
||||
uint32_t size;
|
||||
uint16_t data[16];
|
||||
void push_back(uint16_t value)
|
||||
{
|
||||
if (size < (sizeof(data) / sizeof(*data)) - 1)
|
||||
{
|
||||
data[size++] = value;
|
||||
data[size] = 0xFFFF;
|
||||
}
|
||||
}
|
||||
uint16_t pop_back()
|
||||
{
|
||||
return data[--size];
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(TrackConnections) == 0x24);
|
||||
static loco_global<TrackConnections, 0x0113609C> _113609C;
|
||||
static loco_global<uint8_t, 0x0113607D> _113607D;
|
||||
static loco_global<uint8_t, 0x0112C2EE> _112C2EE;
|
||||
static loco_global<uint8_t, 0x0112C2EE> _112C2ED;
|
||||
static loco_global<uint32_t, 0x00525FC0> _525FC0;
|
||||
static loco_global<StationId_t, 0x01135FAE> _1135FAE;
|
||||
static loco_global<StationId_t, 0x01136087> _1136087;
|
||||
static loco_global<uint8_t[2], 0x0113601A> _113601A;
|
||||
|
||||
// 0x00478895
|
||||
static void getRoadConnections(const Map::Pos3& pos, TrackConnections& data, const CompanyId_t company, const uint8_t roadObjectId, const uint16_t trackAndDirection)
|
||||
{
|
||||
const auto nextTrackPos = pos + TrackData::getUnkTrack(trackAndDirection).pos;
|
||||
_1135FAE = StationId::null; // stationId
|
||||
|
||||
uint8_t baseZ = nextTrackPos.z / 4;
|
||||
uint8_t nextRotation = TrackData::getUnkTrack(trackAndDirection).rotationEnd;
|
||||
_112C2EE = nextRotation;
|
||||
|
||||
const auto tile = Map::TileManager::get(nextTrackPos);
|
||||
for (const auto& el : tile)
|
||||
{
|
||||
auto* elRoad = el.asRoad();
|
||||
if (elRoad == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(_525FC0 & (1 << elRoad->roadObjectId())))
|
||||
{
|
||||
if (elRoad->owner() != company)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (elRoad->roadObjectId() != roadObjectId)
|
||||
{
|
||||
if (roadObjectId != 0xFF)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!(_525FC0 & (1 << roadObjectId)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ((elRoad->mods() & _113601A[0]) != _113601A[0])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (elRoad->isGhost() || elRoad->isFlag5())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (elRoad->sequenceIndex() == 0)
|
||||
{
|
||||
auto trackAndDirection2 = (elRoad->roadId() << 3) | elRoad->unkDirection();
|
||||
if (nextRotation == TrackData::getUnkRoad(trackAndDirection2).rotationBegin)
|
||||
{
|
||||
const auto& roadPiece = TrackData::getRoadPiece(elRoad->roadId());
|
||||
if (baseZ == (elRoad->baseZ() - roadPiece[0].z / 4))
|
||||
{
|
||||
if (elRoad->hasBridge())
|
||||
{
|
||||
trackAndDirection2 |= elRoad->bridge() << 9;
|
||||
trackAndDirection2 |= (1 << 12);
|
||||
}
|
||||
|
||||
if (_113601A[1] != elRoad->mods())
|
||||
{
|
||||
trackAndDirection2 |= (1 << 13);
|
||||
}
|
||||
|
||||
if (elRoad->hasStationElement())
|
||||
{
|
||||
auto* elStation = tile.roadStation(elRoad->roadId(), elRoad->unkDirection(), elRoad->baseZ());
|
||||
if (elStation == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!elStation->isFlag5() && !elStation->isGhost())
|
||||
{
|
||||
_1135FAE = elStation->stationId();
|
||||
_1136087 = elStation->objectId();
|
||||
}
|
||||
}
|
||||
|
||||
_112C2ED = elRoad->roadObjectId();
|
||||
data.push_back(trackAndDirection2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!elRoad->isFlag6())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto trackAndDirection2 = (elRoad->roadId() << 3) | (1 << 2) | elRoad->unkDirection();
|
||||
if (nextRotation != TrackData::getUnkRoad(trackAndDirection2).rotationBegin)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const auto& roadPiece = TrackData::getRoadPiece(elRoad->roadId());
|
||||
if (baseZ != (elRoad->baseZ() - (TrackData::getUnkRoad(trackAndDirection2).pos.z + roadPiece[elRoad->sequenceIndex()].z) / 4))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (elRoad->hasBridge())
|
||||
{
|
||||
trackAndDirection2 |= elRoad->bridge() << 9;
|
||||
trackAndDirection2 |= (1 << 12);
|
||||
}
|
||||
|
||||
if (_113601A[1] != elRoad->mods())
|
||||
{
|
||||
trackAndDirection2 |= (1 << 13);
|
||||
}
|
||||
|
||||
if (elRoad->hasStationElement())
|
||||
{
|
||||
auto* elStation = tile.roadStation(elRoad->roadId(), elRoad->unkDirection(), elRoad->baseZ());
|
||||
if (elStation == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!elStation->isFlag5() && !elStation->isGhost())
|
||||
{
|
||||
_1135FAE = elStation->stationId();
|
||||
_1136087 = elStation->objectId();
|
||||
}
|
||||
}
|
||||
data.push_back(trackAndDirection2);
|
||||
}
|
||||
}
|
||||
|
||||
// 0x004A2604
|
||||
static void getTrackConnections(const Map::Pos3& pos, TrackConnections& data, const CompanyId_t company, const uint8_t trackObjectId, const uint16_t trackAndDirection)
|
||||
{
|
||||
const auto nextTrackPos = pos + TrackData::getUnkTrack(trackAndDirection).pos;
|
||||
_1135FAE = StationId::null; // stationId
|
||||
_113607D = 0;
|
||||
|
||||
uint8_t baseZ = nextTrackPos.z / 4;
|
||||
uint8_t nextRotation = TrackData::getUnkTrack(trackAndDirection).rotationEnd;
|
||||
|
||||
const auto tile = Map::TileManager::get(nextTrackPos);
|
||||
for (const auto& el : tile)
|
||||
{
|
||||
auto* elTrack = el.asTrack();
|
||||
if (elTrack == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (elTrack->owner() != company)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (elTrack->trackObjectId() != trackObjectId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((elTrack->mods() & _113601A[0]) != _113601A[0])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (elTrack->isGhost() || elTrack->isFlag5())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (elTrack->sequenceIndex() == 0)
|
||||
{
|
||||
auto trackAndDirection2 = (elTrack->trackId() << 3) | elTrack->unkDirection();
|
||||
if (nextRotation == TrackData::getUnkTrack(trackAndDirection2).rotationBegin)
|
||||
{
|
||||
const auto& trackPiece = TrackData::getTrackPiece(elTrack->trackId());
|
||||
if (baseZ == (elTrack->baseZ() - trackPiece[0].z / 4))
|
||||
{
|
||||
if (elTrack->hasBridge())
|
||||
{
|
||||
trackAndDirection2 |= elTrack->bridge() << 9;
|
||||
trackAndDirection2 |= (1 << 12);
|
||||
}
|
||||
|
||||
if (_113601A[1] != elTrack->mods())
|
||||
{
|
||||
trackAndDirection2 |= (1 << 13);
|
||||
}
|
||||
|
||||
if (elTrack->hasStationElement())
|
||||
{
|
||||
auto* elStation = (reinterpret_cast<TileElement*>(elTrack) + 1)->asStation();
|
||||
if (elStation == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!elStation->isFlag5() && !elStation->isGhost())
|
||||
{
|
||||
_1135FAE = elStation->stationId();
|
||||
}
|
||||
}
|
||||
|
||||
if (elTrack->has_6_10())
|
||||
{
|
||||
_113607D = 1;
|
||||
}
|
||||
|
||||
if (elTrack->hasSignal())
|
||||
{
|
||||
auto* elSignal = (reinterpret_cast<TileElement*>(elTrack) + 1)->asSignal();
|
||||
if (elSignal == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!elSignal->isFlag5() && !elSignal->isGhost())
|
||||
{
|
||||
trackAndDirection2 |= (1 << 15);
|
||||
}
|
||||
}
|
||||
data.push_back(trackAndDirection2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!elTrack->isFlag6())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto trackAndDirection2 = (elTrack->trackId() << 3) | (1 << 2) | elTrack->unkDirection();
|
||||
if (nextRotation != TrackData::getUnkTrack(trackAndDirection2).rotationBegin)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto previousBaseZ = elTrack->baseZ() - (TrackData::getTrackPiece(elTrack->trackId())[elTrack->sequenceIndex()].z + TrackData::getUnkTrack(trackAndDirection2).pos.z) / 4;
|
||||
if (previousBaseZ != baseZ)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (elTrack->hasBridge())
|
||||
{
|
||||
trackAndDirection2 |= elTrack->bridge() << 9;
|
||||
trackAndDirection2 |= (1 << 12);
|
||||
}
|
||||
|
||||
if (_113601A[1] != elTrack->mods())
|
||||
{
|
||||
trackAndDirection2 |= (1 << 13);
|
||||
}
|
||||
|
||||
if (elTrack->hasStationElement())
|
||||
{
|
||||
auto* elStation = (reinterpret_cast<TileElement*>(elTrack) + 1)->asStation();
|
||||
if (elStation == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!elStation->isFlag5() && !elStation->isGhost())
|
||||
{
|
||||
_1135FAE = elStation->stationId();
|
||||
}
|
||||
}
|
||||
|
||||
if (elTrack->has_6_10())
|
||||
{
|
||||
_113607D = 1;
|
||||
}
|
||||
|
||||
if (elTrack->hasSignal())
|
||||
{
|
||||
auto* elSignal = (reinterpret_cast<TileElement*>(elTrack) + 1)->asSignal();
|
||||
if (elSignal == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!elSignal->isFlag5() && !elSignal->isGhost())
|
||||
{
|
||||
trackAndDirection2 |= (1 << 15);
|
||||
}
|
||||
}
|
||||
data.push_back(trackAndDirection2);
|
||||
}
|
||||
}
|
||||
|
||||
// 0x004A012E
|
||||
static void removeTrack()
|
||||
{
|
||||
_trackCost = 0x80000000;
|
||||
_byte_1136076 = 0;
|
||||
removeConstructionGhosts();
|
||||
if (_constructionHover != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Map::Pos3 loc(_x, _y, _constructionZ);
|
||||
uint32_t trackAndDirection = 0;
|
||||
|
||||
if (_constructionRotation < 4)
|
||||
{
|
||||
trackAndDirection = 0;
|
||||
}
|
||||
else if (_constructionRotation < 8)
|
||||
{
|
||||
trackAndDirection = 26 << 3;
|
||||
}
|
||||
else if (_constructionRotation < 12)
|
||||
{
|
||||
trackAndDirection = 27 << 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
trackAndDirection = 1 << 3;
|
||||
loc += _503C6C[_constructionRotation];
|
||||
}
|
||||
trackAndDirection |= (1 << 2) | (_constructionRotation & 0x3);
|
||||
_113601A[0] = 0;
|
||||
_113601A[1] = 0;
|
||||
_113609C->size = 0;
|
||||
getTrackConnections(loc, _113609C, CompanyManager::getControllingId(), _trackType, trackAndDirection);
|
||||
|
||||
if (_113609C->size == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto trackAndDirection2 = (_113609C->data[_113609C->size - 1] & 0x1FF) ^ (1 << 2);
|
||||
Map::Pos3 loc2(_x, _y, _constructionZ);
|
||||
loc2 -= TrackData::getUnkTrack(trackAndDirection2).pos;
|
||||
if (trackAndDirection2 & (1 << 2))
|
||||
{
|
||||
loc2.z += TrackData::getUnkTrack(trackAndDirection2).pos.z;
|
||||
}
|
||||
|
||||
const auto& trackPiece = TrackData::getTrackPiece(trackAndDirection2 >> 3);
|
||||
const auto i = (trackAndDirection2 & (1 << 2)) ? trackPiece.size() - 1 : 0;
|
||||
loc2.z += trackPiece[i].z;
|
||||
|
||||
GameCommands::TrackRemovalArgs args;
|
||||
args.pos = loc2;
|
||||
args.index = trackPiece[i].index;
|
||||
args.rotation = trackAndDirection2 & 0x3;
|
||||
args.trackId = trackAndDirection2 >> 3;
|
||||
args.trackObjectId = _trackType;
|
||||
|
||||
auto* trackObj = ObjectManager::get<TrackObject>(_trackType);
|
||||
auto formatArgs = FormatArguments::common();
|
||||
formatArgs.skip(3 * sizeof(string_id));
|
||||
formatArgs.push(trackObj->name);
|
||||
GameCommands::setErrorTitle(StringIds::cant_build_pop3_string);
|
||||
|
||||
if (GameCommands::doCommand(args, GameCommands::Flags::apply) != GameCommands::FAILURE)
|
||||
{
|
||||
Map::Pos3 newConstructLoc = Map::Pos3(_x, _y, _constructionZ) - TrackData::getUnkTrack(trackAndDirection2).pos;
|
||||
_x = newConstructLoc.x;
|
||||
_y = newConstructLoc.y;
|
||||
_constructionZ = newConstructLoc.z;
|
||||
_constructionRotation = TrackData::getUnkTrack(trackAndDirection2).rotationBegin;
|
||||
_lastSelectedTrackPiece = 0;
|
||||
_lastSelectedTrackGradient = 0;
|
||||
activateSelectedConstructionWidgets();
|
||||
}
|
||||
}
|
||||
|
||||
// 0x004A02F2
|
||||
static void removeRoad()
|
||||
{
|
||||
_trackCost = 0x80000000;
|
||||
_byte_1136076 = 0;
|
||||
removeConstructionGhosts();
|
||||
if (_constructionHover != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Map::Pos3 loc(_x, _y, _constructionZ);
|
||||
uint32_t trackAndDirection = (1 << 2) | (_constructionRotation & 0x3);
|
||||
_113601A[0] = 0;
|
||||
_113601A[1] = 0;
|
||||
_113609C->size = 0;
|
||||
getRoadConnections(loc, _113609C, CompanyManager::getControllingId(), _trackType & ~(1 << 7), trackAndDirection);
|
||||
|
||||
if (_113609C->size == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < _113609C->size; ++i)
|
||||
{
|
||||
// If trackId is zero
|
||||
if ((_113609C->data[i] & 0x1F8) == 0)
|
||||
{
|
||||
std::swap(_113609C->data[0], _113609C->data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
auto* roadObj = ObjectManager::get<RoadObject>(_trackType & ~(1 << 7));
|
||||
if (!(roadObj->flags & Flags12::unk_02))
|
||||
{
|
||||
_113609C->size = 1;
|
||||
_113609C->data[1] = 0xFFFF;
|
||||
}
|
||||
|
||||
uint16_t trackAndDirection2 = 0;
|
||||
while (_113609C->size != 0)
|
||||
{
|
||||
trackAndDirection2 = (_113609C->pop_back() & 0x1FF) ^ (1 << 2);
|
||||
Map::Pos3 loc2(_x, _y, _constructionZ);
|
||||
loc2 -= TrackData::getUnkRoad(trackAndDirection2).pos;
|
||||
if (trackAndDirection2 & (1 << 2))
|
||||
{
|
||||
loc2.z += TrackData::getUnkRoad(trackAndDirection2).pos.z;
|
||||
}
|
||||
|
||||
const auto& roadPiece = TrackData::getRoadPiece(trackAndDirection2 >> 3);
|
||||
const auto i = (trackAndDirection2 & (1 << 2)) ? roadPiece.size() - 1 : 0;
|
||||
loc2.z += roadPiece[i].z;
|
||||
|
||||
GameCommands::RoadRemovalArgs args;
|
||||
args.pos = loc2;
|
||||
args.sequenceIndex = roadPiece[i].index;
|
||||
args.unkDirection = trackAndDirection2 & 0x3;
|
||||
args.roadId = trackAndDirection2 >> 3;
|
||||
args.objectId = _trackType & ~(1 << 7);
|
||||
|
||||
auto* trackObj = ObjectManager::get<RoadObject>(_trackType & ~(1 << 7));
|
||||
auto formatArgs = FormatArguments::common();
|
||||
formatArgs.skip(3 * sizeof(string_id));
|
||||
formatArgs.push(trackObj->name);
|
||||
GameCommands::setErrorTitle(StringIds::cant_build_pop3_string);
|
||||
|
||||
if (GameCommands::doCommand(args, GameCommands::Flags::apply) == GameCommands::FAILURE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Map::Pos3 newConstructLoc = Map::Pos3(_x, _y, _constructionZ) - TrackData::getUnkRoad(trackAndDirection2).pos;
|
||||
_x = newConstructLoc.x;
|
||||
_y = newConstructLoc.y;
|
||||
_constructionZ = newConstructLoc.z;
|
||||
_constructionRotation = TrackData::getUnkRoad(trackAndDirection2).rotationBegin;
|
||||
_lastSelectedTrackPiece = 0;
|
||||
_lastSelectedTrackGradient = 0;
|
||||
activateSelectedConstructionWidgets();
|
||||
}
|
||||
|
||||
// 0x004A0121
|
||||
static void removeTrack(Window* self, WidgetIndex_t widgetIndex)
|
||||
{
|
||||
registers regs;
|
||||
regs.edx = widgetIndex;
|
||||
regs.esi = X86Pointer(self);
|
||||
call(0x004A0121, regs);
|
||||
if (_trackType & (1 << 7))
|
||||
{
|
||||
removeRoad();
|
||||
}
|
||||
else
|
||||
{
|
||||
removeTrack();
|
||||
}
|
||||
}
|
||||
|
||||
// 0x0049D3F6
|
||||
|
|
Loading…
Reference in New Issue