Station rename command (#984)
This re-introduces the possibility of resetting/regenerating station names automatically by using an empty station name. Previously, our re-implementation (C++ code) inadvertently removed this option.
This commit is contained in:
parent
d10b16e404
commit
fbc145a5bf
|
@ -2,6 +2,7 @@
|
|||
------------------------------------------------------------------------
|
||||
- Feature: [#856] Allow filtering the vehicle list by station or cargo type.
|
||||
- Fix: [#982] Incorrect rating calculation for cargo causing penalty for fast vehicles.
|
||||
- Fix: [#984] Unable to reset/regenerate station names by using an empty name.
|
||||
- Fix: [#1008] Inability to decrease max altitude for trees in landscape editor.
|
||||
- Fix: [#1016] Incorrect detection of station causing incorrect smoke sounds.
|
||||
- Technical: [#986] Stack misalignment in GCC builds caused unexplained crashes on Linux and Mac during interop hooks with loco.exe.
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace OpenLoco::GameCommands
|
|||
{ GameCommand::gc_unk_8, nullptr, 0x0049C7F2, true },
|
||||
{ GameCommand::changeLoan, nullptr, 0x0046DE88, false },
|
||||
{ GameCommand::vehicleRename, Vehicles::rename, 0x004B6572, false },
|
||||
{ GameCommand::changeStationName, nullptr, 0x00490756, false },
|
||||
{ GameCommand::changeStationName, renameStation, 0x00490756, false },
|
||||
{ GameCommand::vehicleLocalExpress, nullptr, 0x004B694B, true },
|
||||
{ GameCommand::gc_unk_13, nullptr, 0x00488BDB, true },
|
||||
{ GameCommand::gc_unk_14, nullptr, 0x004891E4, true },
|
||||
|
|
|
@ -675,6 +675,9 @@ namespace OpenLoco::GameCommands
|
|||
// Defined in GameCommands/RenameIndustry.cpp
|
||||
void renameIndustry(registers& regs);
|
||||
|
||||
// Defined in GameCommands/RenameStation.cpp
|
||||
void renameStation(registers& regs);
|
||||
|
||||
// Defined in GameCommands/RenameTown.cpp
|
||||
void renameTown(registers& regs);
|
||||
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
#include "../Economy/Expenditures.h"
|
||||
#include "../Industry.h"
|
||||
#include "../Interop/Interop.hpp"
|
||||
#include "../Localisation/FormatArguments.hpp"
|
||||
#include "../Localisation/StringIds.h"
|
||||
#include "../Localisation/StringManager.h"
|
||||
#include "../StationManager.h"
|
||||
#include "../TownManager.h"
|
||||
#include "../Types.hpp"
|
||||
#include "GameCommands.h"
|
||||
|
||||
using namespace OpenLoco::Interop;
|
||||
|
||||
namespace OpenLoco::GameCommands
|
||||
{
|
||||
/**
|
||||
* 0x00490756
|
||||
* Renames a particular station.
|
||||
*
|
||||
* This command is called 3 times before the buffer is applied. Each time, 12 chars of the 36 char buffer are provided.
|
||||
* The resulting station name has a maximum length of 31 chars; the last bytes are not used.
|
||||
*
|
||||
* @param flags @<bl> - game command flags
|
||||
* @param stationId @<cx> - station id
|
||||
* @param index @<ax> - update index (in order of: 1, 2, 0)
|
||||
* @param buffer0 @<edx> - First part (4 chars) of the 12 update buffer
|
||||
* @param buffer1 @<dx> - Second part (4 chars) of the 12 update buffer
|
||||
* @param buffer2 @<bp> - Third part (4 chars) of the 12 update buffer
|
||||
* @return @<ebx> - returns 0 if rename is successful; otherwise GameCommands::FAILURE
|
||||
*/
|
||||
static uint32_t renameStation(const uint8_t flags, StationId_t stationId, int16_t index, uint32_t buffer0, uint32_t buffer1, uint32_t buffer2)
|
||||
{
|
||||
GameCommands::setExpenditureType(ExpenditureType::Miscellaneous);
|
||||
|
||||
// Keep track of the station id over several calls.
|
||||
static StationId_t _stationId{};
|
||||
if (index == 1)
|
||||
_stationId = stationId;
|
||||
|
||||
static uint32_t renameBuffer[9];
|
||||
|
||||
// Fill buffer over calls into the renameBuffer
|
||||
if ((flags & GameCommands::Flags::apply) != 0)
|
||||
{
|
||||
static const std::array<int, 3> transformTable = { 2, 0, 1 };
|
||||
int arrayIndex = transformTable.at(index);
|
||||
renameBuffer[arrayIndex * 3] = buffer0;
|
||||
renameBuffer[arrayIndex * 3 + 1] = buffer1;
|
||||
renameBuffer[arrayIndex * 3 + 2] = buffer2;
|
||||
}
|
||||
|
||||
// Applying the buffer?
|
||||
if (index != 0)
|
||||
return 0;
|
||||
|
||||
char renameStringBuffer[37] = "";
|
||||
memcpy(renameStringBuffer, renameBuffer, sizeof(renameBuffer));
|
||||
renameStringBuffer[36] = '\0';
|
||||
|
||||
// Figure out the current name for this station.
|
||||
char currentStationName[256] = "";
|
||||
auto station = StationManager::get(_stationId);
|
||||
auto args = FormatArguments::common(station->town);
|
||||
StringManager::formatString(currentStationName, station->name, &args);
|
||||
|
||||
// Verify the new name actually differs from the old one.
|
||||
if (strcmp(currentStationName, renameStringBuffer) == 0)
|
||||
return 0;
|
||||
|
||||
string_id oldStringId = station->name;
|
||||
|
||||
// If an empty string is given, generate one instead.
|
||||
if (strlen(renameStringBuffer) == 0)
|
||||
{
|
||||
// Are we bailing out early?
|
||||
if ((flags & GameCommands::Flags::apply) == 0)
|
||||
return 0;
|
||||
|
||||
station->name = StationManager::generateNewStationName(_stationId, station->town, Map::Pos3(station->x, station->y, station->z), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Allocate a string id for the new name.
|
||||
string_id allocatedStringId = StringManager::userStringAllocate(renameStringBuffer, 0);
|
||||
if (allocatedStringId == StringIds::empty)
|
||||
return GameCommands::FAILURE;
|
||||
|
||||
// Are we bailing out early?
|
||||
if ((flags & GameCommands::Flags::apply) == 0)
|
||||
{
|
||||
StringManager::emptyUserString(allocatedStringId);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Apply the new name to the station.
|
||||
station->name = allocatedStringId;
|
||||
}
|
||||
|
||||
StringManager::emptyUserString(oldStringId);
|
||||
station->updateLabel();
|
||||
Gfx::invalidateScreen();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void renameStation(registers& regs)
|
||||
{
|
||||
regs.ebx = renameStation(regs.bl, regs.cx, regs.ax, regs.edx, regs.ebp, regs.edi);
|
||||
}
|
||||
}
|
|
@ -249,6 +249,7 @@ namespace OpenLoco::StringIds
|
|||
constexpr string_id tooltip_signal_single_direction = 277;
|
||||
constexpr string_id tooltip_bridge_stats = 278;
|
||||
constexpr string_id tooltip_select_station_type = 279;
|
||||
constexpr string_id station_name_ordinal = 280;
|
||||
|
||||
constexpr string_id vehicle_details_weight = 328;
|
||||
constexpr string_id vehicle_details_total_power_and_weight = 329;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "StationManager.h"
|
||||
#include "CompanyManager.h"
|
||||
#include "Interop/Interop.hpp"
|
||||
#include "Localisation/FormatArguments.hpp"
|
||||
#include "OpenLoco.h"
|
||||
#include "TownManager.h"
|
||||
#include "Ui/WindowManager.h"
|
||||
|
@ -120,6 +121,27 @@ namespace OpenLoco::StationManager
|
|||
}
|
||||
}
|
||||
|
||||
// 0x048F988
|
||||
string_id generateNewStationName(StationId_t stationId, TownId_t townId, Map::Pos3 position, uint8_t mode)
|
||||
{
|
||||
auto* station = get(stationId);
|
||||
if (station == nullptr)
|
||||
return StringIds::null;
|
||||
|
||||
station->name = StringIds::null;
|
||||
|
||||
registers regs;
|
||||
regs.esi = reinterpret_cast<int32_t>(station);
|
||||
regs.ebx = townId;
|
||||
regs.dh = static_cast<uint8_t>(position.z / 4);
|
||||
regs.dl = mode;
|
||||
regs.ax = position.x & 0xFFE0;
|
||||
regs.cx = position.y & 0xFFE0;
|
||||
|
||||
call(0x048F988, regs);
|
||||
return regs.bx;
|
||||
}
|
||||
|
||||
// 0x0049088B
|
||||
void zeroUnused()
|
||||
{
|
||||
|
|
|
@ -15,5 +15,6 @@ namespace OpenLoco::StationManager
|
|||
void update();
|
||||
void updateLabels();
|
||||
void updateDaily();
|
||||
string_id generateNewStationName(StationId_t stationId, TownId_t townId, Map::Pos3 position, uint8_t mode);
|
||||
void zeroUnused();
|
||||
}
|
||||
|
|
|
@ -846,9 +846,6 @@ namespace OpenLoco::Ui::Windows::Station
|
|||
if (callingWidget != Common::widx::caption)
|
||||
return;
|
||||
|
||||
if (strlen(input) == 0)
|
||||
return;
|
||||
|
||||
GameCommands::setErrorTitle(StringIds::error_cant_rename_station);
|
||||
|
||||
uint32_t* buffer = (uint32_t*)input;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
<ClCompile Include="GameCommands\GameCommands.cpp" />
|
||||
<ClCompile Include="GameCommands\LoadSaveQuit.cpp" />
|
||||
<ClCompile Include="GameCommands\RenameIndustry.cpp" />
|
||||
<ClCompile Include="GameCommands\RenameStation.cpp" />
|
||||
<ClCompile Include="GameCommands\RenameTown.cpp" />
|
||||
<ClCompile Include="GameCommands\TogglePause.cpp" />
|
||||
<ClCompile Include="GameCommands\VehiclePickup.cpp" />
|
||||
|
|
Loading…
Reference in New Issue