unmovable_cmd.c
changeset 1796 614d996f6be7
parent 1792 3779566b958f
child 1891 862800791170
equal deleted inserted replaced
1795:06f7b463ee52 1796:614d996f6be7
    10 #include "station.h"
    10 #include "station.h"
    11 #include "economy.h"
    11 #include "economy.h"
    12 #include "town.h"
    12 #include "town.h"
    13 #include "sprite.h"
    13 #include "sprite.h"
    14 
    14 
       
    15 /** Destroy a HQ.
       
    16  * During normal gameplay you can only implicitely destroy a HQ when you are
       
    17  * rebuilding it. Otherwise, only water can destroy it.
       
    18  * @param tile tile coordinates where HQ is located to destroy
       
    19  * @param flags docommand flags of calling function
       
    20  */
       
    21 int32 DestroyCompanyHQ(TileIndex tile, uint32 flags)
       
    22 {
       
    23 	Player *p;
       
    24 
       
    25 	SET_EXPENSES_TYPE(EXPENSES_PROPERTY);
       
    26 
       
    27 	/* Find player that has HQ flooded, and reset their location_of_house */
       
    28 	if (_current_player == OWNER_WATER)	{
       
    29 		bool dodelete = false;
       
    30 
       
    31 		FOR_ALL_PLAYERS(p) {
       
    32 			if (p->location_of_house == tile) {
       
    33 				dodelete = true;
       
    34 				break;
       
    35 			}
       
    36 		}
       
    37 		if (!dodelete) return CMD_ERROR;
       
    38 	} else /* Destruction was initiated by player */
       
    39 		p = DEREF_PLAYER(_current_player);
       
    40 
       
    41 		if (p->location_of_house == 0) return CMD_ERROR;
       
    42 
       
    43 		if (flags & DC_EXEC) {
       
    44 			DoClearSquare(p->location_of_house + TILE_XY(0,0));
       
    45 			DoClearSquare(p->location_of_house + TILE_XY(0,1));
       
    46 			DoClearSquare(p->location_of_house + TILE_XY(1,0));
       
    47 			DoClearSquare(p->location_of_house + TILE_XY(1,1));
       
    48 			p->location_of_house = 0; // reset HQ position
       
    49 			InvalidateWindow(WC_COMPANY, (int)p->index);
       
    50 		}
       
    51 
       
    52 	// cost of relocating company is 1% of company value
       
    53 		return CalculateCompanyValue(p) / 100;
       
    54 }
       
    55 
       
    56 /** Build or relocate the HQ. This depends if the HQ is already built or not
       
    57  * @param x,y the coordinates where the HQ will be built or relocated to
       
    58  * @param p1 relocate HQ (set to some value, usually 1 or true)
       
    59  * @param p2 unused
       
    60  */
       
    61  extern int32 CheckFlatLandBelow(uint tile, uint w, uint h, uint flags, uint invalid_dirs, int *);
       
    62 int32 CmdBuildCompanyHQ(int x, int y, uint32 flags, uint32 p1, uint32 p2)
       
    63 {
       
    64 	TileIndex tile = TILE_FROM_XY(x,y);
       
    65 	Player *p = DEREF_PLAYER(_current_player);
       
    66 	int cost;
       
    67 
       
    68 	SET_EXPENSES_TYPE(EXPENSES_PROPERTY);
       
    69 
       
    70 	cost = CheckFlatLandBelow(tile, 2, 2, flags, 0, NULL);
       
    71 	if (CmdFailed(cost)) return CMD_ERROR;
       
    72 
       
    73 	if (p1) { /* Moving HQ */
       
    74 		int32 ret;
       
    75 
       
    76 		if (p->location_of_house == 0) return CMD_ERROR;
       
    77 
       
    78 		ret = DestroyCompanyHQ(p->location_of_house, flags);
       
    79 
       
    80 		if (CmdFailed(ret)) return CMD_ERROR;
       
    81 
       
    82 		cost += ret;
       
    83 	} else { /* Building new HQ */
       
    84 		if (p->location_of_house != 0) return CMD_ERROR;
       
    85 	}
       
    86 
       
    87 	if (flags & DC_EXEC) {
       
    88 		int score = UpdateCompanyRatingAndValue(p, false);
       
    89 
       
    90 		p->location_of_house = tile;
       
    91 
       
    92 		ModifyTile(tile + TILE_XY(0,0), MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5, 0x80);
       
    93 		ModifyTile(tile + TILE_XY(0,1), MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5, 0x81);
       
    94 		ModifyTile(tile + TILE_XY(1,0), MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5, 0x82);
       
    95 		ModifyTile(tile + TILE_XY(1,1), MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5, 0x83);
       
    96 		UpdatePlayerHouse(p, score);
       
    97 		InvalidateWindow(WC_COMPANY, (int)p->index);
       
    98 	}
       
    99 
       
   100 	return cost;
       
   101 }
       
   102 
    15 typedef struct DrawTileUnmovableStruct {
   103 typedef struct DrawTileUnmovableStruct {
    16 	uint16 image;
   104 	uint16 image;
    17 	byte subcoord_x;
   105 	byte subcoord_x;
    18 	byte subcoord_y;
   106 	byte subcoord_y;
    19 	byte width;
   107 	byte width;
   108 static int32 ClearTile_Unmovable(uint tile, byte flags)
   196 static int32 ClearTile_Unmovable(uint tile, byte flags)
   109 {
   197 {
   110 	byte m5 = _map5[tile];
   198 	byte m5 = _map5[tile];
   111 
   199 
   112 	if (m5 & 0x80) {
   200 	if (m5 & 0x80) {
   113 		if (_current_player == OWNER_WATER)
   201 		if (_current_player == OWNER_WATER) return DestroyCompanyHQ(tile, DC_EXEC);
   114 			return DoCommandByTile(tile, 0, 0, DC_EXEC, CMD_DESTROY_COMPANY_HQ);
       
   115 		return_cmd_error(STR_5804_COMPANY_HEADQUARTERS_IN);
   202 		return_cmd_error(STR_5804_COMPANY_HEADQUARTERS_IN);
   116 	}
   203 	}
   117 
   204 
   118 	if (m5 == 3)	// company owned land
   205 	if (m5 == 3)	// company owned land
   119 		return DoCommandByTile(tile, 0, 0, flags, CMD_SELL_LAND_AREA);
   206 		return DoCommandByTile(tile, 0, 0, flags, CMD_SELL_LAND_AREA);
   305 		_map5[tile] = 1;
   392 		_map5[tile] = 1;
   306 		_map_owner[tile] = OWNER_NONE;
   393 		_map_owner[tile] = OWNER_NONE;
   307 	} while (--i);
   394 	} while (--i);
   308 }
   395 }
   309 
   396 
   310 extern int32 CheckFlatLandBelow(uint tile, uint w, uint h, uint flags, uint invalid_dirs, int *);
       
   311 
       
   312 /** Build or relocate the HQ. This depends if the HQ is already built or not
       
   313  * @param x,y the coordinates where the HQ will be built or relocated to
       
   314  * @param p1 relocate HQ (set to some value, usually 1 or true)
       
   315  * @param p2 unused
       
   316  */
       
   317 int32 CmdBuildCompanyHQ(int x, int y, uint32 flags, uint32 p1, uint32 p2)
       
   318 {
       
   319 	TileIndex tile = TILE_FROM_XY(x,y);
       
   320 	Player *p = DEREF_PLAYER(_current_player);
       
   321 	int cost;
       
   322 
       
   323 	SET_EXPENSES_TYPE(EXPENSES_PROPERTY);
       
   324 
       
   325 	cost = CheckFlatLandBelow(tile, 2, 2, flags, 0, NULL);
       
   326 	if (CmdFailed(cost)) return CMD_ERROR;
       
   327 
       
   328 	if (p1) { /* Moving HQ */
       
   329 		int32 ret;
       
   330 
       
   331 		if (p->location_of_house == 0) return CMD_ERROR;
       
   332 
       
   333 		ret = DoCommandByTile(p->location_of_house, 0, 0, flags, CMD_DESTROY_COMPANY_HQ);
       
   334 
       
   335 		if (CmdFailed(ret)) return CMD_ERROR;
       
   336 
       
   337 		cost += ret;
       
   338 	} else { /* Building new HQ */
       
   339 		if (p->location_of_house != 0) return CMD_ERROR;
       
   340 	}
       
   341 
       
   342 	if (flags & DC_EXEC) {
       
   343 		int score = UpdateCompanyRatingAndValue(p, false);
       
   344 
       
   345 		p->location_of_house = tile;
       
   346 
       
   347 		ModifyTile(tile + TILE_XY(0,0), MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5, 0x80);
       
   348 		ModifyTile(tile + TILE_XY(0,1), MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5, 0x81);
       
   349 		ModifyTile(tile + TILE_XY(1,0), MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5, 0x82);
       
   350 		ModifyTile(tile + TILE_XY(1,1), MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5, 0x83);
       
   351 		UpdatePlayerHouse(p, score);
       
   352 		InvalidateWindow(WC_COMPANY, (int)p->index);
       
   353 	}
       
   354 
       
   355 	return cost;
       
   356 }
       
   357 
       
   358 /** Destroy a HQ.
       
   359  * During normal gameplay you can only implicitely destroy a HQ when you are
       
   360  * rebuilding it. Otherwise, only water can destroy it. Unfortunately there is
       
   361  * no safeguard against a hacked client to call this command, unless we also add
       
   362  * flags to the command table which commands can be called directly and which not.
       
   363  * @param x,y tile coordinates where HQ is located to destroy
       
   364  * @param p1 unused
       
   365  * @param p2 unused
       
   366  */
       
   367 int32 CmdDestroyCompanyHQ(int x, int y, uint32 flags, uint32 p1, uint32 p2)
       
   368 {
       
   369 	TileIndex tile;
       
   370 	Player *p;
       
   371 
       
   372 	SET_EXPENSES_TYPE(EXPENSES_PROPERTY);
       
   373 
       
   374 	/* Find player that has HQ flooded, and reset their location_of_house */
       
   375 	if (_current_player == OWNER_WATER)	{
       
   376 		bool dodelete = false;
       
   377 		tile = TILE_FROM_XY(x,y);
       
   378 
       
   379 		FOR_ALL_PLAYERS(p) {
       
   380 			if (p->location_of_house == tile) {
       
   381 				dodelete = true;
       
   382 				break;
       
   383 			}
       
   384 		}
       
   385 		if (!dodelete) return CMD_ERROR;
       
   386 	} else /* Destruction was initiated by player */
       
   387 		p = DEREF_PLAYER(_current_player);
       
   388 
       
   389 	if (p->location_of_house == 0) return CMD_ERROR;
       
   390 
       
   391 	if (flags & DC_EXEC) {
       
   392 		DoClearSquare(p->location_of_house + TILE_XY(0,0));
       
   393 		DoClearSquare(p->location_of_house + TILE_XY(0,1));
       
   394 		DoClearSquare(p->location_of_house + TILE_XY(1,0));
       
   395 		DoClearSquare(p->location_of_house + TILE_XY(1,1));
       
   396 		p->location_of_house = 0; // reset HQ position
       
   397 		InvalidateWindow(WC_COMPANY, (int)p->index);
       
   398 	}
       
   399 
       
   400 	// cost of relocating company is 1% of company value
       
   401 	return CalculateCompanyValue(p) / 100;
       
   402 }
       
   403 
       
   404 
       
   405 static void ChangeTileOwner_Unmovable(uint tile, byte old_player, byte new_player)
   397 static void ChangeTileOwner_Unmovable(uint tile, byte old_player, byte new_player)
   406 {
   398 {
   407 	if (_map_owner[tile] != old_player)
   399 	if (_map_owner[tile] != old_player)
   408 		return;
   400 		return;
   409 
   401