Vehicle Tool Down (#1084)

* Implement air tool down

* Implement pickup tool down water

* Implement pickup tool down land

* Fix broken land placement
This commit is contained in:
Duncan 2021-08-06 09:24:52 +01:00 committed by GitHub
parent a57af0e1f1
commit 43b670507d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 139 additions and 6 deletions

View File

@ -147,6 +147,7 @@ namespace OpenLoco::GameCommands
, trackAndDirection(regs.bp)
, trackProgress(regs.ebx >> 16)
, head(regs.di)
, convertGhost((regs.ebx >> 16) == 0xFFFF)
{
}
@ -154,6 +155,7 @@ namespace OpenLoco::GameCommands
uint16_t trackAndDirection;
uint16_t trackProgress;
EntityId_t head;
bool convertGhost = false;
explicit operator registers() const
{
@ -163,7 +165,7 @@ namespace OpenLoco::GameCommands
regs.ax = pos.x;
regs.cx = pos.y;
regs.dx = pos.z / 4;
regs.ebx = (regs.ebx & 0xFFFF) | (trackProgress << 16);
regs.ebx = convertGhost ? 0xFFFF0000 : (trackProgress << 16);
return regs;
}
};
@ -954,12 +956,14 @@ namespace OpenLoco::GameCommands
: stationId(regs.bp)
, airportNode(regs.dl)
, head(regs.di)
, convertGhost((regs.ebx >> 16) == 0xFFFF)
{
}
StationId_t stationId;
uint8_t airportNode;
EntityId_t head;
bool convertGhost = false;
explicit operator registers() const
{
@ -967,6 +971,7 @@ namespace OpenLoco::GameCommands
regs.bp = stationId;
regs.di = head;
regs.dl = airportNode;
regs.ebx = convertGhost ? 0xFFFF0000 : 0;
return regs;
}
};
@ -1019,11 +1024,13 @@ namespace OpenLoco::GameCommands
explicit VehicleWaterPlacementArgs(const registers regs)
: pos(regs.ax, regs.cx, regs.dx)
, head(regs.di)
, convertGhost((regs.ebx >> 16) == 0xFFFF)
{
}
Map::Pos3 pos;
EntityId_t head;
bool convertGhost = false;
explicit operator registers() const
{
@ -1032,6 +1039,7 @@ namespace OpenLoco::GameCommands
regs.cx = pos.y;
regs.dx = pos.z;
regs.di = head;
regs.ebx = convertGhost ? 0xFFFF0000 : 0;
return regs;
}
};

View File

@ -762,6 +762,7 @@ namespace OpenLoco::StringIds
constexpr string_id vehicle_has_broken_down = 1159;
constexpr string_id vehicle_is_stuck = 1160;
constexpr string_id cant_place_string_id_here = 1163;
constexpr string_id cant_remove_string_id = 1164;
constexpr string_id cant_pass_signal_at_danger = 1165;

View File

@ -3872,14 +3872,138 @@ namespace OpenLoco::Ui::Windows::Vehicle
}
}
// 0x004B2D8A
static void pickupToolError(const Vehicles::VehicleHead& head)
{
auto args = FormatArguments::common();
args.skip(6);
args.push(head.name);
args.push(head.ordinalNumber);
Error::open(StringIds::cant_place_string_id_here, StringIds::null);
}
// 0x004B2E18
static void pickupToolDownAir(Window& self, const Vehicles::VehicleHead& head, const int16_t x, const int16_t y)
{
auto placementArgs = getVehicleAirPlacementArgsFromCursor(head, x, y);
if (!placementArgs)
{
pickupToolError(head);
return;
}
if (*_ghostAirportStationId == placementArgs->stationId && *_ghostAirportNode == placementArgs->airportNode)
{
if (head.tile_x != -1 && (head.var_38 & Vehicles::Flags38::isGhost))
{
// Will convert inplace vehicle into non ghost
placementArgs->convertGhost = true;
}
}
if (!placementArgs->convertGhost)
{
removeAirplaneGhost(head);
}
auto args = FormatArguments::common();
args.skip(6);
args.push(head.name);
args.push(head.ordinalNumber);
GameCommands::setErrorTitle(StringIds::cant_place_string_id_here);
if (GameCommands::do_58(GameCommands::Flags::apply, *placementArgs))
{
Input::toolCancel();
self.callOnMouseUp(Common::widx::tabMain);
}
}
// 0x004B2F1C
static void pickupToolDownWater(Window& self, const Vehicles::VehicleHead& head, const int16_t x, const int16_t y)
{
auto placementArgs = getVehicleWaterPlacementArgsFromCursor(head, x, y);
if (!placementArgs)
{
pickupToolError(head);
return;
}
if (_1136264 == 0 && *_ghostVehiclePos == placementArgs->pos)
{
if (head.tile_x != -1 && (head.var_38 & Vehicles::Flags38::isGhost))
{
// Will convert inplace vehicle into non ghost
placementArgs->convertGhost = true;
}
}
if (!placementArgs->convertGhost)
{
removeBoatGhost(head);
}
auto args = FormatArguments::common();
args.skip(6);
args.push(head.name);
args.push(head.ordinalNumber);
GameCommands::setErrorTitle(StringIds::cant_place_string_id_here);
if (GameCommands::do_62(GameCommands::Flags::apply, *placementArgs))
{
Input::toolCancel();
self.callOnMouseUp(Common::widx::tabMain);
}
}
// 0x004B2C95
template<typename GetPlacementArgsFunc>
static void pickupToolDownLand(Window& self, const Vehicles::VehicleHead& head, const int16_t x, const int16_t y, GetPlacementArgsFunc&& getPlacementArgs)
{
auto placementArgs = getPlacementArgs(head, x, y);
if (!placementArgs)
{
pickupToolError(head);
return;
}
if (*_ghostLandTrackAndDirection == placementArgs->trackAndDirection && *_ghostVehiclePos == placementArgs->pos && *_1136264 == placementArgs->trackProgress)
{
if (head.tile_x != -1 && (head.var_38 & Vehicles::Flags38::isGhost))
{
// Will convert inplace vehicle into non ghost
placementArgs->convertGhost = true;
}
}
if (!placementArgs->convertGhost)
{
removeLandGhost(head);
}
auto args = FormatArguments::common();
args.skip(6);
args.push(head.name);
args.push(head.ordinalNumber);
GameCommands::setErrorTitle(StringIds::cant_place_string_id_here);
if (GameCommands::do_1(GameCommands::Flags::apply, *placementArgs))
{
Input::toolCancel();
self.callOnMouseUp(Common::widx::tabMain);
}
}
// 0x004B2C74
static void pickupToolDown(Window& self, const int16_t x, const int16_t y)
{
registers regs;
regs.esi = X86Pointer(&self);
regs.ax = x;
regs.bx = y;
call(0x004B2C74, regs);
auto* head = getVehicle(&self);
switch (head->mode)
{
case TransportMode::rail:
pickupToolDownLand(self, *head, x, y, getVehicleRailPlacementArgsFromCursor);
break;
case TransportMode::road:
pickupToolDownLand(self, *head, x, y, getVehicleRoadPlacementArgsFromCursor);
break;
case TransportMode::air:
pickupToolDownAir(self, *head, x, y);
break;
case TransportMode::water:
pickupToolDownWater(self, *head, x, y);
break;
}
}
// 0x004B3035