Add support for money cheat in multiplayer

Add a setting for whether this is permitted by multiplayer clients
pull/145/head
Jonathan G Rennison 4 years ago
parent b209b37db9
commit ab99c16601

@ -54,7 +54,7 @@ static int32 _money_cheat_amount = 10000000;
*/ */
static int32 ClickMoneyCheat(int32 p1, int32 p2) static int32 ClickMoneyCheat(int32 p1, int32 p2)
{ {
DoCommandP(0, (uint32)(p2 * _money_cheat_amount), 0, CMD_MONEY_CHEAT); DoCommandP(0, (uint32)(p2 * _money_cheat_amount), 0, _network_server || _network_settings_access ? CMD_MONEY_CHEAT_ADMIN : CMD_MONEY_CHEAT);
return _money_cheat_amount; return _money_cheat_amount;
} }
@ -158,6 +158,7 @@ typedef int32 CheckButtonClick(int32 p1, int32 p2);
enum CheatNetworkMode { enum CheatNetworkMode {
CNM_ALL, CNM_ALL,
CNM_LOCAL_ONLY, CNM_LOCAL_ONLY,
CNM_MONEY,
}; };
/** Information of a cheat. */ /** Information of a cheat. */
@ -175,7 +176,7 @@ struct CheatEntry {
* Order matches with the values of #CheatNumbers * Order matches with the values of #CheatNumbers
*/ */
static const CheatEntry _cheats_ui[] = { static const CheatEntry _cheats_ui[] = {
{CNM_LOCAL_ONLY, SLE_INT32, STR_CHEAT_MONEY, &_money_cheat_amount, &_cheats.money.been_used, &ClickMoneyCheat }, {CNM_MONEY, SLE_INT32, STR_CHEAT_MONEY, &_money_cheat_amount, &_cheats.money.been_used, &ClickMoneyCheat },
{CNM_LOCAL_ONLY, SLE_UINT8, STR_CHEAT_CHANGE_COMPANY, &_local_company, &_cheats.switch_company.been_used, &ClickChangeCompanyCheat }, {CNM_LOCAL_ONLY, SLE_UINT8, STR_CHEAT_CHANGE_COMPANY, &_local_company, &_cheats.switch_company.been_used, &ClickChangeCompanyCheat },
{CNM_ALL, SLE_BOOL, STR_CHEAT_EXTRA_DYNAMITE, &_cheats.magic_bulldozer.value, &_cheats.magic_bulldozer.been_used, nullptr }, {CNM_ALL, SLE_BOOL, STR_CHEAT_EXTRA_DYNAMITE, &_cheats.magic_bulldozer.value, &_cheats.magic_bulldozer.been_used, nullptr },
{CNM_ALL, SLE_BOOL, STR_CHEAT_CROSSINGTUNNELS, &_cheats.crossing_tunnels.value, &_cheats.crossing_tunnels.been_used, nullptr }, {CNM_ALL, SLE_BOOL, STR_CHEAT_CROSSINGTUNNELS, &_cheats.crossing_tunnels.value, &_cheats.crossing_tunnels.been_used, nullptr },
@ -185,6 +186,21 @@ static const CheatEntry _cheats_ui[] = {
{CNM_LOCAL_ONLY, SLE_INT32, STR_CHEAT_CHANGE_DATE, &_cur_year, &_cheats.change_date.been_used, &ClickChangeDateCheat }, {CNM_LOCAL_ONLY, SLE_INT32, STR_CHEAT_CHANGE_DATE, &_cur_year, &_cheats.change_date.been_used, &ClickChangeDateCheat },
}; };
static bool IsCheatAllowed(CheatNetworkMode mode)
{
switch (mode) {
case CNM_ALL:
return !_networking || _network_server || _network_settings_access;
case CNM_LOCAL_ONLY:
return !_networking;
case CNM_MONEY:
return !_networking || _network_server || _network_settings_access || _settings_game.difficulty.money_cheat_in_multiplayer;
}
return false;
}
assert_compile(CHT_NUM_CHEATS == lengthof(_cheats_ui)); assert_compile(CHT_NUM_CHEATS == lengthof(_cheats_ui));
/** Widget definitions of the cheat GUI. */ /** Widget definitions of the cheat GUI. */
@ -230,7 +246,7 @@ struct CheatWindow : Window {
for (int i = 0; i != lengthof(_cheats_ui); i++) { for (int i = 0; i != lengthof(_cheats_ui); i++) {
const CheatEntry *ce = &_cheats_ui[i]; const CheatEntry *ce = &_cheats_ui[i];
if (_networking && ce->mode == CNM_LOCAL_ONLY) continue; if (!IsCheatAllowed(ce->mode)) continue;
DrawSprite((*ce->been_used) ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, PAL_NONE, box_left, y + icon_y_offset + 2); DrawSprite((*ce->been_used) ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, PAL_NONE, box_left, y + icon_y_offset + 2);
@ -283,7 +299,7 @@ struct CheatWindow : Window {
uint lines = 0; uint lines = 0;
for (int i = 0; i != lengthof(_cheats_ui); i++) { for (int i = 0; i != lengthof(_cheats_ui); i++) {
const CheatEntry *ce = &_cheats_ui[i]; const CheatEntry *ce = &_cheats_ui[i];
if (_networking && ce->mode == CNM_LOCAL_ONLY) continue; if (!IsCheatAllowed(ce->mode)) continue;
lines++; lines++;
switch (ce->type) { switch (ce->type) {
case SLE_BOOL: case SLE_BOOL:
@ -335,7 +351,7 @@ struct CheatWindow : Window {
for (uint i = 0; i != lengthof(_cheats_ui) && i <= btn; i++) { for (uint i = 0; i != lengthof(_cheats_ui) && i <= btn; i++) {
const CheatEntry *ce = &_cheats_ui[i]; const CheatEntry *ce = &_cheats_ui[i];
if (_networking && ce->mode == CNM_LOCAL_ONLY) btn++; if (!IsCheatAllowed(ce->mode)) btn++;
} }
if (btn >= lengthof(_cheats_ui)) return; if (btn >= lengthof(_cheats_ui)) return;
@ -379,7 +395,7 @@ struct CheatWindow : Window {
if (value != oldvalue) { if (value != oldvalue) {
if (_networking) { if (_networking) {
DoCommandP(0, (uint32)btn, (uint32)value, CMD_CHEAT_SETTING); if (btn != CHT_MONEY) DoCommandP(0, (uint32)btn, (uint32)value, CMD_CHEAT_SETTING);
} else { } else {
WriteValue(ce->variable, ce->type, (int64)value); WriteValue(ce->variable, ce->type, (int64)value);
} }
@ -426,5 +442,7 @@ static WindowDesc _cheats_desc(
void ShowCheatWindow() void ShowCheatWindow()
{ {
DeleteWindowById(WC_CHEATS, 0); DeleteWindowById(WC_CHEATS, 0);
new CheatWindow(&_cheats_desc); if (!_networking || _network_server || _network_settings_access || _settings_game.difficulty.money_cheat_in_multiplayer) {
new CheatWindow(&_cheats_desc);
}
} }

@ -159,6 +159,7 @@ CommandProc CmdClearArea;
CommandProc CmdGiveMoney; CommandProc CmdGiveMoney;
CommandProc CmdMoneyCheat; CommandProc CmdMoneyCheat;
CommandProc CmdMoneyCheatAdmin;
CommandProc CmdChangeBankBalance; CommandProc CmdChangeBankBalance;
CommandProc CmdCheatSetting; CommandProc CmdCheatSetting;
CommandProc CmdBuildCanal; CommandProc CmdBuildCanal;
@ -379,7 +380,8 @@ static const Command _command_proc_table[] = {
DEF_CMD(CmdClearArea, CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_CLEAR_AREA; destroying multi-tile houses makes town rating differ between test and execution DEF_CMD(CmdClearArea, CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_CLEAR_AREA; destroying multi-tile houses makes town rating differ between test and execution
DEF_CMD(CmdMoneyCheat, CMD_OFFLINE, CMDT_CHEAT ), // CMD_MONEY_CHEAT DEF_CMD(CmdMoneyCheat, 0, CMDT_CHEAT ), // CMD_MONEY_CHEAT
DEF_CMD(CmdMoneyCheatAdmin, CMD_SERVER_NS, CMDT_CHEAT ), // CMD_MONEY_CHEAT_ADMIN
DEF_CMD(CmdChangeBankBalance, CMD_DEITY, CMDT_MONEY_MANAGEMENT ), // CMD_CHANGE_BANK_BALANCE DEF_CMD(CmdChangeBankBalance, CMD_DEITY, CMDT_MONEY_MANAGEMENT ), // CMD_CHANGE_BANK_BALANCE
DEF_CMD(CmdCheatSetting, CMD_SERVER, CMDT_CHEAT ), // CMD_CHEAT_SETTING DEF_CMD(CmdCheatSetting, CMD_SERVER, CMDT_CHEAT ), // CMD_CHEAT_SETTING
DEF_CMD(CmdBuildCanal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_CANAL DEF_CMD(CmdBuildCanal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_CANAL

@ -317,6 +317,7 @@ enum Commands {
CMD_CLEAR_AREA, ///< clear an area CMD_CLEAR_AREA, ///< clear an area
CMD_MONEY_CHEAT, ///< do the money cheat CMD_MONEY_CHEAT, ///< do the money cheat
CMD_MONEY_CHEAT_ADMIN, ///< do the money cheat (admin mode)
CMD_CHANGE_BANK_BALANCE, ///< change bank balance to charge costs or give money from a GS CMD_CHANGE_BANK_BALANCE, ///< change bank balance to charge costs or give money from a GS
CMD_CHEAT_SETTING, ///< change a cheat setting CMD_CHEAT_SETTING, ///< change a cheat setting
CMD_BUILD_CANAL, ///< build a canal CMD_BUILD_CANAL, ///< build a canal

@ -1188,6 +1188,8 @@ STR_CONFIG_SETTING_DISASTERS :Disasters: {STR
STR_CONFIG_SETTING_DISASTERS_HELPTEXT :Toggle disasters which may occasionally block or destroy vehicles or infrastructure STR_CONFIG_SETTING_DISASTERS_HELPTEXT :Toggle disasters which may occasionally block or destroy vehicles or infrastructure
STR_CONFIG_SETTING_CITY_APPROVAL :Town council's attitude towards area restructuring: {STRING2} STR_CONFIG_SETTING_CITY_APPROVAL :Town council's attitude towards area restructuring: {STRING2}
STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Choose how much noise and environmental damage by companies affect their town rating and further construction actions in their area STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Choose how much noise and environmental damage by companies affect their town rating and further construction actions in their area
STR_MONEY_CHEAT_MULTIPLAYER :Allow multiplayer clients to use the money cheat: {STRING2}
STR_MONEY_CHEAT_MULTIPLAYER_HELPTEXT :If enabled, non-admin multiplayer clients can use the money cheat. The money cheat is always available in single-player mode, and to the multiplayer server admin.
STR_CONFIG_SETTING_MAX_HEIGHTLEVEL :Maximum map height: {STRING2} STR_CONFIG_SETTING_MAX_HEIGHTLEVEL :Maximum map height: {STRING2}
STR_CONFIG_SETTING_MAX_HEIGHTLEVEL_HELPTEXT :Set the maximum allowed height for mountains on the map STR_CONFIG_SETTING_MAX_HEIGHTLEVEL_HELPTEXT :Set the maximum allowed height for mountains on the map

@ -339,8 +339,12 @@ struct MainWindow : Window
break; break;
case GHK_MONEY: // Gimme money case GHK_MONEY: // Gimme money
/* You can only cheat for money in single player. */ /* You can only cheat for money in single player or when otherwise suitably authorised. */
if (!_networking) DoCommandP(0, 10000000, 0, CMD_MONEY_CHEAT); if (!_networking || _settings_game.difficulty.money_cheat_in_multiplayer) {
DoCommandP(0, 10000000, 0, CMD_MONEY_CHEAT);
} else if (_network_server || _network_settings_access) {
DoCommandP(0, 10000000, 0, CMD_MONEY_CHEAT_ADMIN);
}
break; break;
case GHK_UPDATE_COORDS: // Update the coordinates of all station signs case GHK_UPDATE_COORDS: // Update the coordinates of all station signs

@ -198,6 +198,29 @@ CommandCost CmdPause(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2,
*/ */
CommandCost CmdMoneyCheat(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) CommandCost CmdMoneyCheat(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{ {
if (_networking && !_settings_game.difficulty.money_cheat_in_multiplayer) return CMD_ERROR;
if (flags & DC_EXEC) {
_cheats.money.been_used = true;
SetWindowDirty(WC_CHEATS, 0);
}
return CommandCost(EXPENSES_OTHER, -(int32)p1);
}
/**
* Change the financial flow of your company (admin).
* @param tile unused
* @param flags operation to perform
* @param p1 the amount of money to receive (if positive), or spend (if negative)
* @param p2 unused
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdMoneyCheatAdmin(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
if (flags & DC_EXEC) {
_cheats.money.been_used = true;
SetWindowDirty(WC_CHEATS, 0);
}
return CommandCost(EXPENSES_OTHER, -(int32)p1); return CommandCost(EXPENSES_OTHER, -(int32)p1);
} }

@ -1273,6 +1273,12 @@ static bool DifficultyNoiseChange(int32 i)
return true; return true;
} }
static bool DifficultyMoneyCheatMultiplayerChange(int32 i)
{
DeleteWindowById(WC_CHEATS, 0);
return true;
}
static bool MaxNoAIsChange(int32 i) static bool MaxNoAIsChange(int32 i)
{ {
if (GetGameSettings().difficulty.max_no_competitors != 0 && if (GetGameSettings().difficulty.max_no_competitors != 0 &&

@ -1983,6 +1983,7 @@ static SettingsContainer &GetSettingsTree()
ai->Add(new SettingEntry("economy.give_money")); ai->Add(new SettingEntry("economy.give_money"));
ai->Add(new SettingEntry("economy.allow_shares")); ai->Add(new SettingEntry("economy.allow_shares"));
ai->Add(new SettingEntry("economy.min_years_for_shares")); ai->Add(new SettingEntry("economy.min_years_for_shares"));
ai->Add(new SettingEntry("difficulty.money_cheat_in_multiplayer"));
} }
main->Init(); main->Init();

@ -67,6 +67,7 @@ struct DifficultySettings {
bool line_reverse_mode; ///< reversing at stations or not bool line_reverse_mode; ///< reversing at stations or not
bool disasters; ///< are disasters enabled bool disasters; ///< are disasters enabled
byte town_council_tolerance; ///< minimum required town ratings to be allowed to demolish stuff byte town_council_tolerance; ///< minimum required town ratings to be allowed to demolish stuff
bool money_cheat_in_multiplayer; ///< is the money cheat permitted for non-admin multiplayer clients
}; };
/** Settings relating to viewport/smallmap scrolling. */ /** Settings relating to viewport/smallmap scrolling. */

@ -26,6 +26,7 @@ static bool ProgrammableSignalsShownChanged(int32);
static bool VehListCargoFilterShownChanged(int32); static bool VehListCargoFilterShownChanged(int32);
static bool TownFoundingChanged(int32 p1); static bool TownFoundingChanged(int32 p1);
static bool DifficultyNoiseChange(int32 i); static bool DifficultyNoiseChange(int32 i);
static bool DifficultyMoneyCheatMultiplayerChange(int32 i);
static bool MaxNoAIsChange(int32 i); static bool MaxNoAIsChange(int32 i);
static bool CheckRoadSide(int p1); static bool CheckRoadSide(int p1);
static bool ChangeMaxHeightLevel(int32 p1); static bool ChangeMaxHeightLevel(int32 p1);
@ -378,6 +379,16 @@ strhelp = STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT
strval = STR_CITY_APPROVAL_PERMISSIVE strval = STR_CITY_APPROVAL_PERMISSIVE
proc = DifficultyNoiseChange proc = DifficultyNoiseChange
[SDT_BOOL]
base = GameSettings
var = difficulty.money_cheat_in_multiplayer
def = false
str = STR_MONEY_CHEAT_MULTIPLAYER
strhelp = STR_MONEY_CHEAT_MULTIPLAYER_HELPTEXT
proc = DifficultyMoneyCheatMultiplayerChange
cat = SC_EXPERT
patxname = ""cheat.difficulty.money_cheat_in_multiplayer""
[SDTG_VAR] [SDTG_VAR]
name = ""diff_level"" name = ""diff_level""
var = _old_diff_level var = _old_diff_level

@ -2154,7 +2154,7 @@ struct MainToolbarWindow : Window {
case MTHK_ZOOMEDIN_SCREENSHOT: MenuClickScreenshot(SC_ZOOMEDIN); break; case MTHK_ZOOMEDIN_SCREENSHOT: MenuClickScreenshot(SC_ZOOMEDIN); break;
case MTHK_DEFAULTZOOM_SCREENSHOT: MenuClickScreenshot(SC_DEFAULTZOOM); break; case MTHK_DEFAULTZOOM_SCREENSHOT: MenuClickScreenshot(SC_DEFAULTZOOM); break;
case MTHK_GIANT_SCREENSHOT: MenuClickScreenshot(SC_WORLD); break; case MTHK_GIANT_SCREENSHOT: MenuClickScreenshot(SC_WORLD); break;
case MTHK_CHEATS: if (!_networking || _network_server || _network_settings_access) ShowCheatWindow(); break; case MTHK_CHEATS: ShowCheatWindow(); break;
case MTHK_TERRAFORM: ShowTerraformToolbar(); break; case MTHK_TERRAFORM: ShowTerraformToolbar(); break;
case MTHK_EXTRA_VIEWPORT: ShowExtraViewPortWindowForTileUnderCursor(); break; case MTHK_EXTRA_VIEWPORT: ShowExtraViewPortWindowForTileUnderCursor(); break;
case MTHK_CLIENT_LIST: if (_networking) ShowClientList(); break; case MTHK_CLIENT_LIST: if (_networking) ShowClientList(); break;

Loading…
Cancel
Save