diff --git a/command.c b/command.c index bd88aafd2b..b50d524f96 100644 --- a/command.c +++ b/command.c @@ -77,6 +77,7 @@ DEF_COMMAND(CmdBuildIndustry); //DEF_COMMAND(CmdDestroyIndustry); DEF_COMMAND(CmdBuildCompanyHQ); +DEF_COMMAND(CmdDestroyCompanyHQ); DEF_COMMAND(CmdSetPlayerFace); DEF_COMMAND(CmdSetPlayerColor); @@ -149,6 +150,7 @@ DEF_COMMAND(CmdClearArea); DEF_COMMAND(CmdMoneyCheat); DEF_COMMAND(CmdBuildCanal); +DEF_COMMAND(CmdBuildLock); DEF_COMMAND(CmdPlayerCtrl); @@ -156,149 +158,148 @@ DEF_COMMAND(CmdLevelLand); DEF_COMMAND(CmdRefitRailVehicle); -DEF_COMMAND(CmdBuildLock); - DEF_COMMAND(CmdStartScenario); DEF_COMMAND(CmdBuildManySignals); /* The master command table */ static CommandProc * const _command_proc_table[] = { - CmdBuildRailroadTrack, /* 0 */ - CmdRemoveRailroadTrack, /* 1 */ - CmdBuildSingleRail, /* 2 */ - CmdRemoveSingleRail, /* 3 */ - CmdLandscapeClear, /* 4 */ - CmdBuildBridge, /* 5 */ - CmdBuildRailroadStation, /* 6 */ - CmdBuildTrainDepot, /* 7 */ - CmdBuildSignals, /* 8 */ - CmdRemoveSignals, /* 9 */ - CmdTerraformLand, /* 10 */ - CmdPurchaseLandArea, /* 11 */ - CmdSellLandArea, /* 12 */ - CmdBuildTunnel, /* 13 */ + CmdBuildRailroadTrack, /* 0 */ + CmdRemoveRailroadTrack, /* 1 */ + CmdBuildSingleRail, /* 2 */ + CmdRemoveSingleRail, /* 3 */ + CmdLandscapeClear, /* 4 */ + CmdBuildBridge, /* 5 */ + CmdBuildRailroadStation, /* 6 */ + CmdBuildTrainDepot, /* 7 */ + CmdBuildSignals, /* 8 */ + CmdRemoveSignals, /* 9 */ + CmdTerraformLand, /* 10 */ + CmdPurchaseLandArea, /* 11 */ + CmdSellLandArea, /* 12 */ + CmdBuildTunnel, /* 13 */ CmdRemoveFromRailroadStation, /* 14 */ - CmdConvertRail, /* 15 */ - CmdBuildTrainCheckpoint, /* 16 */ - CmdRenameCheckpoint, /* 17 */ - CmdRemoveTrainCheckpoint, /* 18 */ - CmdBuildTruckStation, /* 19 */ - NULL, /* 20 */ - CmdBuildBusStation, /* 21 */ - NULL, /* 22 */ - CmdBuildLongRoad, /* 23 */ - CmdRemoveLongRoad, /* 24 */ - CmdBuildRoad, /* 25 */ - CmdRemoveRoad, /* 26 */ - CmdBuildRoadDepot, /* 27 */ - NULL, /* 28 */ - CmdBuildAirport, /* 29 */ - CmdBuildDock, /* 30 */ - CmdBuildShipDepot, /* 31 */ - CmdBuildBuoy, /* 32 */ - CmdPlantTree, /* 33 */ - CmdBuildRailVehicle, /* 34 */ - CmdMoveRailVehicle, /* 35 */ - CmdStartStopTrain, /* 36 */ - NULL, /* 37 */ - CmdSellRailWagon, /* 38 */ - CmdTrainGotoDepot, /* 39 */ - CmdForceTrainProceed, /* 40 */ - CmdReverseTrainDirection, /* 41 */ + CmdConvertRail, /* 15 */ + CmdBuildTrainCheckpoint, /* 16 */ + CmdRenameCheckpoint, /* 17 */ + CmdRemoveTrainCheckpoint, /* 18 */ + CmdBuildTruckStation, /* 19 */ + NULL, /* 20 */ + CmdBuildBusStation, /* 21 */ + NULL, /* 22 */ + CmdBuildLongRoad, /* 23 */ + CmdRemoveLongRoad, /* 24 */ + CmdBuildRoad, /* 25 */ + CmdRemoveRoad, /* 26 */ + CmdBuildRoadDepot, /* 27 */ + NULL, /* 28 */ + CmdBuildAirport, /* 29 */ + CmdBuildDock, /* 30 */ + CmdBuildShipDepot, /* 31 */ + CmdBuildBuoy, /* 32 */ + CmdPlantTree, /* 33 */ + CmdBuildRailVehicle, /* 34 */ + CmdMoveRailVehicle, /* 35 */ + CmdStartStopTrain, /* 36 */ + NULL, /* 37 */ + CmdSellRailWagon, /* 38 */ + CmdTrainGotoDepot, /* 39 */ + CmdForceTrainProceed, /* 40 */ + CmdReverseTrainDirection, /* 41 */ - CmdModifyOrder, /* 42 */ - CmdSkipOrder, /* 43 */ - CmdDeleteOrder, /* 44 */ - CmdInsertOrder, /* 45 */ + CmdModifyOrder, /* 42 */ + CmdSkipOrder, /* 43 */ + CmdDeleteOrder, /* 44 */ + CmdInsertOrder, /* 45 */ - CmdChangeTrainServiceInt, /* 46 */ + CmdChangeTrainServiceInt, /* 46 */ - CmdBuildIndustry, /* 47 */ - CmdBuildCompanyHQ, /* 48 */ - CmdSetPlayerFace, /* 49 */ - CmdSetPlayerColor, /* 50 */ + CmdBuildIndustry, /* 47 */ + CmdBuildCompanyHQ, /* 48 */ + CmdSetPlayerFace, /* 49 */ + CmdSetPlayerColor, /* 50 */ - CmdIncreaseLoan, /* 51 */ - CmdDecreaseLoan, /* 52 */ + CmdIncreaseLoan, /* 51 */ + CmdDecreaseLoan, /* 52 */ - CmdWantEnginePreview, /* 53 */ + CmdWantEnginePreview, /* 53 */ - CmdNameVehicle, /* 54 */ - CmdRenameEngine, /* 55 */ + CmdNameVehicle, /* 54 */ + CmdRenameEngine, /* 55 */ - CmdChangeCompanyName, /* 56 */ - CmdChangePresidentName, /* 57 */ + CmdChangeCompanyName, /* 56 */ + CmdChangePresidentName, /* 57 */ - CmdRenameStation, /* 58 */ + CmdRenameStation, /* 58 */ - CmdSellAircraft, /* 59 */ - CmdStartStopAircraft, /* 60 */ - CmdBuildAircraft, /* 61 */ - CmdSendAircraftToHangar, /* 62 */ + CmdSellAircraft, /* 59 */ + CmdStartStopAircraft, /* 60 */ + CmdBuildAircraft, /* 61 */ + CmdSendAircraftToHangar, /* 62 */ CmdChangeAircraftServiceInt, /* 63 */ - CmdRefitAircraft, /* 64 */ + CmdRefitAircraft, /* 64 */ - CmdPlaceSign, /* 65 */ - CmdRenameSign, /* 66 */ + CmdPlaceSign, /* 65 */ + CmdRenameSign, /* 66 */ - CmdBuildRoadVeh, /* 67 */ - CmdStartStopRoadVeh, /* 68 */ - CmdSellRoadVeh, /* 69 */ - CmdSendRoadVehToDepot, /* 70 */ - CmdTurnRoadVeh, /* 71 */ + CmdBuildRoadVeh, /* 67 */ + CmdStartStopRoadVeh, /* 68 */ + CmdSellRoadVeh, /* 69 */ + CmdSendRoadVehToDepot, /* 70 */ + CmdTurnRoadVeh, /* 71 */ CmdChangeRoadVehServiceInt, /* 72 */ - CmdPause, /* 73 */ + CmdPause, /* 73 */ - CmdBuyShareInCompany, /* 74 */ - CmdSellShareInCompany, /* 75 */ - CmdBuyCompany, /* 76 */ + CmdBuyShareInCompany, /* 74 */ + CmdSellShareInCompany, /* 75 */ + CmdBuyCompany, /* 76 */ - CmdBuildTown, /* 77 */ - NULL, /* 78 */ - NULL, /* 79 */ - CmdRenameTown, /* 80 */ - CmdDoTownAction, /* 81 */ + CmdBuildTown, /* 77 */ + NULL, /* 78 */ + NULL, /* 79 */ + CmdRenameTown, /* 80 */ + CmdDoTownAction, /* 81 */ - CmdSetRoadDriveSide, /* 82 */ - CmdSetTownNameType, /* 83 */ - NULL, /* 84 */ - CmdChangeDifficultyLevel, /* 85 */ + CmdSetRoadDriveSide, /* 82 */ + CmdSetTownNameType, /* 83 */ + NULL, /* 84 */ + CmdChangeDifficultyLevel, /* 85 */ - CmdStartStopShip, /* 86 */ - CmdSellShip, /* 87 */ - CmdBuildShip, /* 88 */ - CmdSendShipToDepot, /* 89 */ - CmdChangeShipServiceInt, /* 90 */ - CmdRefitShip, /* 91 */ + CmdStartStopShip, /* 86 */ + CmdSellShip, /* 87 */ + CmdBuildShip, /* 88 */ + CmdSendShipToDepot, /* 89 */ + CmdChangeShipServiceInt, /* 90 */ + CmdRefitShip, /* 91 */ - CmdStartNewGame, /* 92 */ - CmdLoadGame, /* 93 */ - CmdCreateScenario, /* 94 */ - CmdSetSinglePlayer, /* 95 */ - NULL, /* 96 */ - CmdSetNewLandscapeType, /* 97 */ + CmdStartNewGame, /* 92 */ + CmdLoadGame, /* 93 */ + CmdCreateScenario, /* 94 */ + CmdSetSinglePlayer, /* 95 */ + NULL, /* 96 */ + CmdSetNewLandscapeType, /* 97 */ - CmdGenRandomNewGame, /* 98 */ + CmdGenRandomNewGame, /* 98 */ - CmdCloneOrder, /* 99 */ + CmdCloneOrder, /* 99 */ - CmdClearArea, /* 100 */ - CmdResume, /* 101 */ + CmdClearArea, /* 100 */ + CmdResume, /* 101 */ - CmdMoneyCheat, /* 102 */ - CmdBuildCanal, /* 103 */ - CmdPlayerCtrl, /* 104 */ + CmdMoneyCheat, /* 102 */ + CmdBuildCanal, /* 103 */ + CmdPlayerCtrl, /* 104 */ - CmdLevelLand, /* 105 */ + CmdLevelLand, /* 105 */ - CmdRefitRailVehicle, /* 106 */ - CmdRestoreOrderIndex, /* 107 */ - CmdBuildLock, /* 108 */ - CmdStartScenario, /* 109 */ - CmdBuildManySignals, /* 110 */ - //CmdDestroyIndustry, /* 109 */ + CmdRefitRailVehicle, /* 106 */ + CmdRestoreOrderIndex, /* 107 */ + CmdBuildLock, /* 108 */ + CmdStartScenario, /* 109 */ + CmdBuildManySignals, /* 110 */ + //CmdDestroyIndustry, /* 109 */ + CmdDestroyCompanyHQ, /* 111 */ }; int32 DoCommandByTile(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc) @@ -366,7 +367,7 @@ error: int32 GetAvailableMoneyForCommand() { uint pid = _current_player; - if (pid >= 8) return 0x7FFFFFFF; // max int + if (pid >= MAX_PLAYERS) return 0x7FFFFFFF; // max int return DEREF_PLAYER(pid)->player_money; } @@ -389,7 +390,7 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback, _additional_cash_required = 0; // spectator has no rights. - if (_current_player == 0xff) { + if (_current_player == OWNER_SPECTATOR) { ShowErrorMessage(_error_message, _error_message_2, x, y); return false; } diff --git a/command.h b/command.h index 49ba78ebf8..af610a3831 100644 --- a/command.h +++ b/command.h @@ -145,6 +145,7 @@ enum { CMD_BUILD_MANY_SIGNALS = 110, //CMD_DESTROY_INDUSTRY = 109, + CMD_DESTROY_COMPANY_HQ = 111, }; enum { diff --git a/economy.c b/economy.c index eef997e671..5504f0fab5 100644 --- a/economy.c +++ b/economy.c @@ -12,7 +12,7 @@ #include "industry.h" #include "town.h" -static void UpdatePlayerHouse(Player *p, uint score) +void UpdatePlayerHouse(Player *p, uint score) { byte val; uint tile = p->location_of_house; @@ -82,7 +82,7 @@ uint32 CalculateCompanyValue(Player *p) { // if update is set to true, the economy is updated with this score // (also the house is updated, should only be true in the on-tick event) -void UpdateCompanyRatingAndValue(Player *p, bool update) +int UpdateCompanyRatingAndValue(Player *p, bool update) { byte owner = p->index; int score = 0; @@ -225,6 +225,7 @@ void UpdateCompanyRatingAndValue(Player *p, bool update) } InvalidateWindow(WC_PERFORMANCE_DETAIL, 0); + return score; } // use 255 as new_player to delete the player. @@ -385,7 +386,7 @@ year_4: p->bankrupt_timeout = 0x456; } else { p->money64 = p->player_money = 100000000; - ChangeOwnershipOfPlayerItems(owner, 0xFF); + ChangeOwnershipOfPlayerItems(owner, 0xFF); // 255 is no owner p->is_active = false; } } diff --git a/economy.h b/economy.h index cee60e3141..89f694f0e9 100644 --- a/economy.h +++ b/economy.h @@ -62,7 +62,8 @@ static const ScoreInfo score_info[] = { int _score_part[MAX_PLAYERS][NUM_SCORE]; -void UpdateCompanyRatingAndValue(Player *p, bool update); +int UpdateCompanyRatingAndValue(Player *p, bool update); +void UpdatePlayerHouse(Player *p, uint score); VARDEF Subsidy _subsidies[MAX_PLAYERS]; diff --git a/lang/english.txt b/lang/english.txt index 15d7ec4dd2..b22586cb2d 100644 --- a/lang/english.txt +++ b/lang/english.txt @@ -1900,8 +1900,10 @@ STR_706D_PRESIDENT :President STR_706E_TYCOON :Tycoon STR_706F_BUILD_HQ :{BLACK}Build HQ STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Build company headquarters / view company headquarters +STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Rebuild company headquarters elsewhere for 1% cost of company value STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS:{WHITE}Can't build company headquarters... STR_7072_VIEW_HQ :{BLACK}View HQ +STR_RELOCATE_HQ :{BLACK}Relocate HQ STR_7073_WORLD_RECESSION_FINANCIAL :{BIGFONT}{BLACK}World Recession!{}{}Financial experts fear worst as economy slumps! STR_7074_RECESSION_OVER_UPTURN_IN :{BIGFONT}{BLACK}Recession Over!{}{}Upturn in trade gives confidence to industries as economy strengthens! STR_7075_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Toggle large/small window size diff --git a/misc_gui.c b/misc_gui.c index bfdc81ae7c..c79c6aa3e3 100644 --- a/misc_gui.c +++ b/misc_gui.c @@ -159,6 +159,7 @@ static void Place_LandInfo(uint tile) #if defined(_DEBUG) DEBUG(misc, 0) ("TILE: %#x (%i,%i)", tile, GET_TILE_X(tile), GET_TILE_Y(tile)); + DEBUG(misc, 0) ("TILE: %d ", tile); DEBUG(misc, 0) ("_map_type_and_height=%#x", _map_type_and_height[tile]); DEBUG(misc, 0) ("_map2=%#x", _map2[tile]); DEBUG(misc, 0) ("_map3_lo=%#x", _map3_lo[tile]); diff --git a/player.h b/player.h index c2cfbed4d7..0d46e0627a 100644 --- a/player.h +++ b/player.h @@ -7,7 +7,7 @@ typedef struct PlayerEconomyEntry { int32 income; int32 expenses; int32 delivered_cargo; - int32 performance_history; + int32 performance_history; // player score (scale 0-1000) int32 company_value; } PlayerEconomyEntry; diff --git a/player_gui.c b/player_gui.c index 38821d5ade..823c6619d5 100644 --- a/player_gui.c +++ b/player_gui.c @@ -364,6 +364,7 @@ static const Widget _other_player_company_widgets[] = { { WWT_EMPTY, 0, 0, 0, 0, 0, 0x0, 0}, { WWT_EMPTY, 0, 0, 0, 0, 0, 0x0, 0}, { WWT_PUSHTXTBTN, 14, 266, 355, 18, 29, STR_7072_VIEW_HQ, STR_7070_BUILD_COMPANY_HEADQUARTERS}, +{ WWT_EMPTY, 0, 0, 0, 0, 0, 0x0, 0}, { WWT_PUSHTXTBTN, 14, 0, 179, 158, 169, STR_7077_BUY_25_SHARE_IN_COMPANY, STR_7079_BUY_25_SHARE_IN_THIS_COMPANY}, { WWT_PUSHTXTBTN, 14, 180, 359, 158, 169, STR_7078_SELL_25_SHARE_IN_COMPANY, STR_707A_SELL_25_SHARE_IN_THIS_COMPANY}, { WWT_LAST}, @@ -378,6 +379,7 @@ static const Widget _my_player_company_bh_widgets[] = { { WWT_PUSHTXTBTN, 14, 180, 269, 158, 169, STR_7009_PRESIDENT_NAME, STR_7032_CHANGE_THE_PRESIDENT_S}, { WWT_PUSHTXTBTN, 14, 270, 359, 158, 169, STR_7008_COMPANY_NAME, STR_7033_CHANGE_THE_COMPANY_NAME}, { WWT_PUSHTXTBTN, 14, 266, 355, 18, 29, STR_7072_VIEW_HQ, STR_7070_BUILD_COMPANY_HEADQUARTERS}, +{ WWT_PUSHTXTBTN, 14, 266, 355, 32, 43, STR_RELOCATE_HQ, STR_RELOCATE_COMPANY_HEADQUARTERS}, { WWT_LAST}, }; @@ -474,9 +476,8 @@ static void PlayerCompanyWndProc(Window *w, WindowEvent *e) Player *p = DEREF_PLAYER(w->window_number); uint32 dis; - if (w->widget == _my_player_company_widgets && - p->location_of_house != 0) - w->widget = _my_player_company_bh_widgets; + if (w->widget != _other_player_company_widgets) + w->widget = (p->location_of_house != 0) ? _my_player_company_bh_widgets : _my_player_company_widgets; SET_DPARAM16(0, p->name_1); SET_DPARAM32(1, p->name_2); @@ -554,11 +555,15 @@ static void PlayerCompanyWndProc(Window *w, WindowEvent *e) } } break; - case 8: /* buy 25% */ + case 8: /* relocate HQ */ + SetObjectToPlaceWnd(0x2D0, 1, w); + SetTileSelectSize(2, 2); + break; + case 9: /* buy 25% */ DoCommandP(0, w->window_number, 0, NULL, CMD_BUY_SHARE_IN_COMPANY | CMD_MSG(STR_707B_CAN_T_BUY_25_SHARE_IN_THIS)); break; - case 9: /* sell 25% */ + case 10: /* sell 25% */ DoCommandP(0, w->window_number, 0, NULL, CMD_SELL_SHARE_IN_COMPANY | CMD_MSG(STR_707C_CAN_T_SELL_25_SHARE_IN)); break; } @@ -570,10 +575,14 @@ static void PlayerCompanyWndProc(Window *w, WindowEvent *e) SetWindowDirty(w); break; - case WE_PLACE_OBJ: - if (DoCommandP(e->place.tile, 0, 0, NULL, CMD_BUILD_COMPANY_HQ | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS))) + case WE_PLACE_OBJ: { + // you cannot destroy a HQ, only relocate it. So build_HQ is called, just with different flags + TileIndex tile = DEREF_PLAYER(w->window_number)->location_of_house; + if (DoCommandP(e->place.tile, (tile == 0) ? 0 : (1 << 16) | w->window_number, 0, NULL, CMD_BUILD_COMPANY_HQ | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS))) ResetObjectToPlace(); break; + } + case WE_DESTROY: DeleteWindowById(WC_PLAYER_COLOR, w->window_number); diff --git a/unmovable_cmd.c b/unmovable_cmd.c index 85afec5f1d..1c6d26f5b6 100644 --- a/unmovable_cmd.c +++ b/unmovable_cmd.c @@ -116,8 +116,11 @@ static int32 ClearTile_Unmovable(uint tile, byte flags) byte m5 = _map5[tile]; //Town *t; - if (m5 & 0x80) + if (m5 & 0x80) { + if (_current_player == OWNER_WATER) + return DoCommandByTile(tile, OWNER_WATER, 0, flags, CMD_DESTROY_COMPANY_HQ); return_cmd_error(STR_5804_COMPANY_HEADQUARTERS_IN); + } if (m5 == 3) // company owned land return DoCommandByTile(tile, 0, 0, flags, CMD_SELL_LAND_AREA); @@ -331,15 +334,26 @@ restart: extern int32 CheckFlatLandBelow(uint tile, uint w, uint h, uint flags, uint invalid_dirs, int *); +/* p1 = relocate HQ + p1&0xFF = player whose HQ is up for relocation +*/ int32 CmdBuildCompanyHQ(int x, int y, uint32 flags, uint32 p1, uint32 p2) { uint tile = TILE_FROM_XY(x,y); - + Player *p = DEREF_PLAYER(_current_player); + int score; + int32 cost = 0; + if (CheckFlatLandBelow(tile, 2, 2, flags, 0, NULL) == CMD_ERROR) return CMD_ERROR; + if (p1) + cost = DoCommand(GET_TILE_X(p->location_of_house)*16, GET_TILE_Y(p->location_of_house)*16, p1&0xFF, 0, flags, CMD_DESTROY_COMPANY_HQ); + if (flags & DC_EXEC) { - DEREF_PLAYER(_current_player)->location_of_house = tile; + score = UpdateCompanyRatingAndValue(p, false); + + p->location_of_house = tile; ModifyTile(tile + TILE_XY(0,0), MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5, @@ -360,11 +374,47 @@ int32 CmdBuildCompanyHQ(int x, int y, uint32 flags, uint32 p1, uint32 p2) MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5, 0x83 ); + UpdatePlayerHouse(p, score); + InvalidateWindow(WC_COMPANY, (int)p->index); } - return 0; + return cost; } +/* p1 = owner of the HQ */ +int32 CmdDestroyCompanyHQ(int x, int y, uint32 flags, uint32 p1, uint32 p2) +{ + uint tile = TILE_FROM_XY(x,y); + Player *p; + + if ((int)p1 != OWNER_WATER) // destruction was initiated by player + p = DEREF_PLAYER((byte)p1); + else { // find player that has HQ flooded, and reset their location_of_house + bool dodelete = false; + FOR_ALL_PLAYERS(p) { + if (p->location_of_house == tile) { + dodelete = true; + break; + } + } + if (!dodelete) + return CMD_ERROR; + } + + if (flags & DC_EXEC) { + p->location_of_house = 0; // reset HQ position + DoClearSquare(tile + TILE_XY(0,0)); + DoClearSquare(tile + TILE_XY(0,1)); + DoClearSquare(tile + TILE_XY(1,0)); + DoClearSquare(tile + TILE_XY(1,1)); + InvalidateWindow(WC_COMPANY, (int)p->index); + } + + // cost of relocating company is 1% of company value + return CalculateCompanyValue(p) / 100; +} + + static void ChangeTileOwner_Unmovable(uint tile, byte old_player, byte new_player) { if (_map_owner[tile] != old_player)