Cheats: Enable setting magic bulldozer, tunnels and jet crashes in multiplayer

pull/145/head
Jonathan G Rennison 4 years ago
parent bdf3af72ec
commit 86b6e9727f

@ -27,6 +27,7 @@
#include "tile_map.h"
#include "newgrf.h"
#include "error.h"
#include "network/network.h"
#include "widgets/cheat_widget.h"
@ -147,20 +148,6 @@ static int32 ClickChangeMaxHlCheat(int32 p1, int32 p2)
return _settings_game.construction.max_heightlevel;
}
/** Available cheats. */
enum CheatNumbers {
CHT_MONEY, ///< Change amount of money.
CHT_CHANGE_COMPANY, ///< Switch company.
CHT_EXTRA_DYNAMITE, ///< Dynamite anything.
CHT_CROSSINGTUNNELS, ///< Allow tunnels to cross each other.
CHT_NO_JETCRASH, ///< Disable jet-airplane crashes.
CHT_SETUP_PROD, ///< Allow manually editing of industry production.
CHT_EDIT_MAX_HL, ///< Edit maximum allowed heightlevel
CHT_CHANGE_DATE, ///< Do time traveling.
CHT_NUM_CHEATS, ///< Number of cheats.
};
/**
* Signature of handler function when user clicks at a cheat.
* @param p1 The new value.
@ -168,8 +155,14 @@ enum CheatNumbers {
*/
typedef int32 CheckButtonClick(int32 p1, int32 p2);
enum CheatNetworkMode {
CNM_ALL,
CNM_LOCAL_ONLY,
};
/** Information of a cheat. */
struct CheatEntry {
CheatNetworkMode mode; ///< network/local mode
VarType type; ///< type of selector
StringID str; ///< string with descriptive text
void *variable; ///< pointer to the variable
@ -182,14 +175,14 @@ struct CheatEntry {
* Order matches with the values of #CheatNumbers
*/
static const CheatEntry _cheats_ui[] = {
{SLE_INT32, STR_CHEAT_MONEY, &_money_cheat_amount, &_cheats.money.been_used, &ClickMoneyCheat },
{SLE_UINT8, STR_CHEAT_CHANGE_COMPANY, &_local_company, &_cheats.switch_company.been_used, &ClickChangeCompanyCheat },
{SLE_BOOL, STR_CHEAT_EXTRA_DYNAMITE, &_cheats.magic_bulldozer.value, &_cheats.magic_bulldozer.been_used, nullptr },
{SLE_BOOL, STR_CHEAT_CROSSINGTUNNELS, &_cheats.crossing_tunnels.value, &_cheats.crossing_tunnels.been_used, nullptr },
{SLE_BOOL, STR_CHEAT_NO_JETCRASH, &_cheats.no_jetcrash.value, &_cheats.no_jetcrash.been_used, nullptr },
{SLE_BOOL, STR_CHEAT_SETUP_PROD, &_cheats.setup_prod.value, &_cheats.setup_prod.been_used, &ClickSetProdCheat },
{SLE_UINT8, STR_CHEAT_EDIT_MAX_HL, &_settings_game.construction.max_heightlevel, &_cheats.edit_max_hl.been_used, &ClickChangeMaxHlCheat },
{SLE_INT32, STR_CHEAT_CHANGE_DATE, &_cur_year, &_cheats.change_date.been_used, &ClickChangeDateCheat },
{CNM_LOCAL_ONLY, 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_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_NO_JETCRASH, &_cheats.no_jetcrash.value, &_cheats.no_jetcrash.been_used, nullptr },
{CNM_LOCAL_ONLY, SLE_BOOL, STR_CHEAT_SETUP_PROD, &_cheats.setup_prod.value, &_cheats.setup_prod.been_used, &ClickSetProdCheat },
{CNM_LOCAL_ONLY, SLE_UINT8, STR_CHEAT_EDIT_MAX_HL, &_settings_game.construction.max_heightlevel, &_cheats.edit_max_hl.been_used, &ClickChangeMaxHlCheat },
{CNM_LOCAL_ONLY, SLE_INT32, STR_CHEAT_CHANGE_DATE, &_cur_year, &_cheats.change_date.been_used, &ClickChangeDateCheat },
};
assert_compile(CHT_NUM_CHEATS == lengthof(_cheats_ui));
@ -237,6 +230,7 @@ struct CheatWindow : Window {
for (int i = 0; i != lengthof(_cheats_ui); i++) {
const CheatEntry *ce = &_cheats_ui[i];
if (_networking && ce->mode == CNM_LOCAL_ONLY) continue;
DrawSprite((*ce->been_used) ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, PAL_NONE, box_left, y + icon_y_offset + 2);
@ -286,8 +280,11 @@ struct CheatWindow : Window {
if (widget != WID_C_PANEL) return;
uint width = 0;
uint lines = 0;
for (int i = 0; i != lengthof(_cheats_ui); i++) {
const CheatEntry *ce = &_cheats_ui[i];
if (_networking && ce->mode == CNM_LOCAL_ONLY) continue;
lines++;
switch (ce->type) {
case SLE_BOOL:
SetDParam(0, STR_CONFIG_SETTING_ON);
@ -325,7 +322,7 @@ struct CheatWindow : Window {
size->width = width + 20 + this->box_width + SETTING_BUTTON_WIDTH /* stuff on the left */ + 10 /* extra spacing on right */;
this->header_height = GetStringHeight(STR_CHEATS_WARNING, size->width - WD_FRAMERECT_LEFT - WD_FRAMERECT_RIGHT) + WD_PAR_VSEP_WIDE;
size->height = this->header_height + WD_FRAMERECT_TOP + WD_PAR_VSEP_NORMAL + WD_FRAMERECT_BOTTOM + this->line_height * lengthof(_cheats_ui);
size->height = this->header_height + WD_FRAMERECT_TOP + WD_PAR_VSEP_NORMAL + WD_FRAMERECT_BOTTOM + this->line_height * lines;
}
void OnClick(Point pt, int widget, int click_count) override
@ -336,6 +333,11 @@ struct CheatWindow : Window {
bool rtl = _current_text_dir == TD_RTL;
if (rtl) x = wid->current_x - x;
for (uint i = 0; i != lengthof(_cheats_ui) && i <= btn; i++) {
const CheatEntry *ce = &_cheats_ui[i];
if (_networking && ce->mode == CNM_LOCAL_ONLY) btn++;
}
if (btn >= lengthof(_cheats_ui)) return;
const CheatEntry *ce = &_cheats_ui[btn];
@ -358,12 +360,12 @@ struct CheatWindow : Window {
/* Not clicking a button? */
if (!IsInsideMM(x, 10 + this->box_width, 10 + this->box_width + SETTING_BUTTON_WIDTH)) return;
*ce->been_used = true;
if (!_networking) *ce->been_used = true;
switch (ce->type) {
case SLE_BOOL:
value ^= 1;
if (ce->proc != nullptr) ce->proc(value, 0);
if (ce->proc != nullptr && !_networking) ce->proc(value, 0);
break;
default:
@ -375,7 +377,13 @@ struct CheatWindow : Window {
break;
}
if (value != oldvalue) WriteValue(ce->variable, ce->type, (int64)value);
if (value != oldvalue) {
if (_networking) {
DoCommandP(0, (uint32)btn, (uint32)value, CMD_CHEAT_SETTING);
} else {
WriteValue(ce->variable, ce->type, (int64)value);
}
}
this->SetTimeout();
@ -390,6 +398,8 @@ struct CheatWindow : Window {
void OnQueryTextFinished(char *str) override
{
if (_networking) return;
/* Was 'cancel' pressed or nothing entered? */
if (str == nullptr || StrEmpty(str)) return;

@ -37,6 +37,20 @@ struct Cheats {
Cheat edit_max_hl; ///< edit the maximum heightlevel; this is a cheat because of the fact that it needs to reset NewGRF game state and doing so as a simple configuration breaks the expectation of many
};
/** Available cheats. */
enum CheatNumbers {
CHT_MONEY, ///< Change amount of money.
CHT_CHANGE_COMPANY, ///< Switch company.
CHT_EXTRA_DYNAMITE, ///< Dynamite anything.
CHT_CROSSINGTUNNELS, ///< Allow tunnels to cross each other.
CHT_NO_JETCRASH, ///< Disable jet-airplane crashes.
CHT_SETUP_PROD, ///< Allow manually editing of industry production.
CHT_EDIT_MAX_HL, ///< Edit maximum allowed heightlevel
CHT_CHANGE_DATE, ///< Do time traveling.
CHT_NUM_CHEATS, ///< Number of cheats.
};
extern Cheats _cheats;
#endif /* CHEAT_TYPE_H */

@ -160,6 +160,7 @@ CommandProc CmdClearArea;
CommandProc CmdGiveMoney;
CommandProc CmdMoneyCheat;
CommandProc CmdChangeBankBalance;
CommandProc CmdCheatSetting;
CommandProc CmdBuildCanal;
CommandProc CmdBuildLock;
@ -380,6 +381,7 @@ static const Command _command_proc_table[] = {
DEF_CMD(CmdMoneyCheat, CMD_OFFLINE, CMDT_CHEAT ), // CMD_MONEY_CHEAT
DEF_CMD(CmdChangeBankBalance, CMD_DEITY, CMDT_MONEY_MANAGEMENT ), // CMD_CHANGE_BANK_BALANCE
DEF_CMD(CmdCheatSetting, CMD_SERVER, CMDT_CHEAT ), // CMD_CHEAT_SETTING
DEF_CMD(CmdBuildCanal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_CANAL
DEF_CMD(CmdCreateSubsidy, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_CREATE_SUBSIDY
DEF_CMD(CmdCompanyCtrl, CMD_SPECTATOR | CMD_CLIENT_ID | CMD_NO_EST, CMDT_SERVER_SETTING ), // CMD_COMPANY_CTRL

@ -318,6 +318,7 @@ enum Commands {
CMD_MONEY_CHEAT, ///< do the money cheat
CMD_CHANGE_BANK_BALANCE, ///< change bank balance to charge costs or give money from a GS
CMD_CHEAT_SETTING, ///< change a cheat setting
CMD_BUILD_CANAL, ///< build a canal
CMD_CREATE_SUBSIDY, ///< create a new subsidy

@ -20,6 +20,7 @@
#include "company_gui.h"
#include "company_base.h"
#include "core/backup_type.hpp"
#include "cheat_type.h"
#include "table/strings.h"
@ -200,6 +201,42 @@ CommandCost CmdMoneyCheat(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
return CommandCost(EXPENSES_OTHER, -(int32)p1);
}
/**
* Change the value of a cheat setting.
* @param tile unused
* @param flags operation to perform
* @param p1 the cheat number
* @param p2 the cheat value
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdCheatSetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
Cheat *cht = nullptr;
switch ((CheatNumbers) p1) {
case CHT_EXTRA_DYNAMITE:
cht = &_cheats.magic_bulldozer;
break;
case CHT_CROSSINGTUNNELS:
cht = &_cheats.crossing_tunnels;
break;
case CHT_NO_JETCRASH:
cht = &_cheats.no_jetcrash;
break;
default:
return CMD_ERROR;
}
if (flags & DC_EXEC) {
cht->value = p2;
cht->been_used = true;
SetWindowDirty(WC_CHEATS, 0);
}
return CommandCost();
}
/**
* Change the bank bank balance of a company by inserting or removing money without affecting the loan.
* @param tile unused

@ -1286,6 +1286,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_SETTINGS_ACCESS
_network_settings_access = p->Recv_bool();
DeleteWindowById(WC_CHEATS, 0);
ReInitAllWindows();
return NETWORK_RECV_STATUS_OKAY;

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

Loading…
Cancel
Save