#include "stdafx.h" #include "ttd.h" #include "command.h" #include "player.h" #include "gfx.h" #include "window.h" #include "saveload.h" #include "economy.h" /* p1 = player p2 = face */ int32 CmdSetPlayerFace(int x, int y, uint32 flags, uint32 p1, uint32 p2) { if (flags & DC_EXEC) { DEREF_PLAYER(p1)->face = p2; MarkWholeScreenDirty(); } return 0; } /* p1 = player * p2 = color */ int32 CmdSetPlayerColor(int x, int y, uint32 flags, uint32 p1, uint32 p2) { Player *p,*pp; // /* can only set color for itself */ // if ( (byte)p1 != _current_player) // return CMD_ERROR; p = DEREF_PLAYER(p1); /* ensure no dups */ FOR_ALL_PLAYERS(pp) { if (pp->is_active && pp != p && pp->player_color == (byte)p2) return CMD_ERROR; } if (flags & DC_EXEC) { _player_colors[p1] = (byte)p2; p->player_color = (byte)p2; MarkWholeScreenDirty(); } return 0; } int32 CmdIncreaseLoan(int x, int y, uint32 flags, uint32 p1, uint32 p2) { Player *p; int32 size; if ( (byte)p1 != _current_player) return CMD_ERROR; p = DEREF_PLAYER(p1); if (p->current_loan >= _economy.max_loan) { SET_DPARAM32(0, _economy.max_loan); return_cmd_error(STR_702B_MAXIMUM_PERMITTED_LOAN); } if (flags & DC_EXEC) { if (p2) size = _economy.max_loan - p->current_loan; else size = IS_HUMAN_PLAYER((byte)p1) ? 10000 : 50000; p->money64 += size; p->current_loan += size; UpdatePlayerMoney32(p); InvalidatePlayerWindows(p); } return 0; } int32 CmdDecreaseLoan(int x, int y, uint32 flags, uint32 p1, uint32 p2) { Player *p; int32 size; if ( (byte)p1 != _current_player) return CMD_ERROR; p = DEREF_PLAYER(p1); if (p->current_loan == 0) return_cmd_error(STR_702D_LOAN_ALREADY_REPAYED); size = p->current_loan; // p2 is true while CTRL is pressed (repay all possible loan, or max money you have) if (!p2) { if (_patches.ainew_active) size = min(size, 10000); else size = min(size, IS_HUMAN_PLAYER((byte)p1) ? 10000 : 50000); } else { // only repay in chunks of 10K size = min(size, p->player_money); size = max(size, 10000); size -= size % 10000; } if (p->player_money < size) { SET_DPARAM32(0, size); return_cmd_error(STR_702E_REQUIRED); } if (flags & DC_EXEC) { p->money64 -= size; p->current_loan -= size; UpdatePlayerMoney32(p); InvalidatePlayerWindows(p); } return 0; } int32 CmdChangeCompanyName(int x, int y, uint32 flags, uint32 p1, uint32 p2) { StringID str,old_str; Player *p; str = AllocateName((byte*)_decode_parameters, 4); if (str == 0) return CMD_ERROR; if (flags & DC_EXEC) { p = DEREF_PLAYER(p1); old_str = p->name_1; p->name_1 = str; DeleteName(old_str); MarkWholeScreenDirty(); } else { DeleteName(str); } return 0; } int32 CmdChangePresidentName(int x, int y, uint32 flags, uint32 p1, uint32 p2) { StringID str,old_str; Player *p; str = AllocateName((byte*)_decode_parameters, 4); if (str == 0) return CMD_ERROR; if (flags & DC_EXEC) { p = DEREF_PLAYER(p1); old_str = p->president_name_1; p->president_name_1 = str; DeleteName(old_str); if (p->name_1 == STR_SV_UNNAMED) { byte *s = " Transport"; byte *d = (byte*)_decode_parameters, b; d--; do d++; while (*d); do *d++ = b = *s++; while(d != (byte*)endof(_decode_parameters) && b != 0); DoCommandByTile(0, p1, 0, DC_EXEC, CMD_CHANGE_COMPANY_NAME); } MarkWholeScreenDirty(); } else { DeleteName(str); } return 0; } static void UpdateSignVirtCoords(SignStruct *ss) { Point pt = RemapCoords(ss->x, ss->y, ss->z); SET_DPARAM16(0, ss->str); UpdateViewportSignPos(&ss->sign, pt.x, pt.y - 6, STR_2806); } void UpdateAllSignVirtCoords() { SignStruct *ss; for(ss=_sign_list; ss != endof(_sign_list); ss++) if (ss->str != 0) UpdateSignVirtCoords(ss); } static void MarkSignDirty(SignStruct *ss) { MarkAllViewportsDirty( ss->sign.left-6, ss->sign.top-3, ss->sign.left+ss->sign.width_1*4+12, ss->sign.top + 45 ); } int32 CmdPlaceSign(int x, int y, uint32 flags, uint32 p1, uint32 p2) { SignStruct *ss; for(ss=_sign_list; ss != endof(_sign_list); ss++) { if (ss->str == 0) { if (flags & DC_EXEC) { ss->str = STR_280A_SIGN; ss->x = x; ss->y = y; ss->z = GetSlopeZ(x,y); UpdateSignVirtCoords(ss); MarkSignDirty(ss); _new_sign_struct = ss; } return 0; } } return_cmd_error(STR_2808_TOO_MANY_SIGNS); } // p1 = sign index // p2: 1 -> remove sign int32 CmdRenameSign(int x, int y, uint32 flags, uint32 p1, uint32 p2) { StringID str,old_str; SignStruct *ss; if (_decode_parameters[0] != 0 && !p2) { str = AllocateName((byte*)_decode_parameters, 0); if (str == 0) return CMD_ERROR; if (flags & DC_EXEC) { ss = &_sign_list[p1]; MarkSignDirty(ss); DeleteName(ss->str); ss->str = str; UpdateSignVirtCoords(ss); MarkSignDirty(ss); } else { DeleteName(str); } } else { if (flags & DC_EXEC) { ss = &_sign_list[p1]; old_str = ss->str; ss->str = 0; DeleteName(old_str); MarkSignDirty(ss); } } return 0; } // p1 = 0 decrease pause counter // p1 = 1 increase pause counter int32 CmdPause(int x, int y, uint32 flags, uint32 p1, uint32 p2) { if (flags & DC_EXEC) { _pause += p1?1:-1; if(_pause==(byte)-1) _pause = 0; InvalidateWindow(WC_STATUS_BAR, 0); InvalidateWindow(WC_MAIN_TOOLBAR, 0); } return 0; } int32 CmdResume(int x, int y, uint32 flags, uint32 p1, uint32 p2) { return 0; } int32 CmdMoneyCheat(int x, int y, uint32 flags, uint32 p1, uint32 p2) { SET_EXPENSES_TYPE(EXPENSES_OTHER); return (int32)p1; } int32 CmdChangeDifficultyLevel(int x, int y, uint32 flags, uint32 p1, uint32 p2) { if (flags & DC_EXEC) { if (p1 != (uint32)-1L) { ((int*)&_opt_mod_ptr->diff)[p1] = p2; _opt_mod_ptr->diff_level = 3; } else { _opt_mod_ptr->diff_level = p2; } InvalidateWindow(WC_GAME_OPTIONS, 0); } return 0; } static const byte _sign_desc[] = { SLE_VAR(SignStruct,str, SLE_UINT16), SLE_VAR(SignStruct,x, SLE_INT16), SLE_VAR(SignStruct,y, SLE_INT16), SLE_VAR(SignStruct,z, SLE_UINT8), SLE_END() }; static void Save_SIGN() { SignStruct *s; int i; for(i=0,s=_sign_list; i!=lengthof(_sign_list); i++,s++) { if (s->str != 0) { SlSetArrayIndex(i); SlObject(s, _sign_desc); } } } static void Load_SIGN() { int index; while ((index = SlIterateArray()) != -1) { SlObject(&_sign_list[index], _sign_desc); } } const ChunkHandler _sign_chunk_handlers[] = { { 'SIGN', Save_SIGN, Load_SIGN, CH_ARRAY | CH_LAST}, };