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 |