307 } while (--i); |
307 } while (--i); |
308 } |
308 } |
309 |
309 |
310 extern int32 CheckFlatLandBelow(uint tile, uint w, uint h, uint flags, uint invalid_dirs, int *); |
310 extern int32 CheckFlatLandBelow(uint tile, uint w, uint h, uint flags, uint invalid_dirs, int *); |
311 |
311 |
312 /* p1 = relocate HQ |
312 /** Build or relocate the HQ. This depends if the HQ is already built or not |
313 * p1&0xFF = player whose HQ is up for relocation |
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 |
314 */ |
316 */ |
315 int32 CmdBuildCompanyHQ(int x, int y, uint32 flags, uint32 p1, uint32 p2) |
317 int32 CmdBuildCompanyHQ(int x, int y, uint32 flags, uint32 p1, uint32 p2) |
316 { |
318 { |
317 TileIndex tile = TILE_FROM_XY(x,y); |
319 TileIndex tile = TILE_FROM_XY(x,y); |
318 Player *p = DEREF_PLAYER(_current_player); |
320 Player *p = DEREF_PLAYER(_current_player); |
319 int score; |
321 int cost; |
320 int32 cost = 0; |
|
321 |
322 |
322 SET_EXPENSES_TYPE(EXPENSES_PROPERTY); |
323 SET_EXPENSES_TYPE(EXPENSES_PROPERTY); |
323 |
324 |
324 cost = CheckFlatLandBelow(tile, 2, 2, flags, 0, NULL); |
325 cost = CheckFlatLandBelow(tile, 2, 2, flags, 0, NULL); |
325 |
326 if (CmdFailed(cost)) return CMD_ERROR; |
326 if (cost == CMD_ERROR) |
327 |
327 return CMD_ERROR; |
328 if (p1) { /* Moving HQ */ |
328 |
329 int32 ret; |
329 if (p1) { |
330 |
330 int32 ret = DoCommand( |
331 if (p->location_of_house == 0) return CMD_ERROR; |
331 TileX(p->location_of_house) * 16, TileY(p->location_of_house) * 16, |
332 |
332 p1 & 0xFF, 0, flags, CMD_DESTROY_COMPANY_HQ); |
333 ret = DoCommandByTile(p->location_of_house, 0, 0, flags, CMD_DESTROY_COMPANY_HQ); |
333 |
334 |
334 if (ret == CMD_ERROR) |
335 if (CmdFailed(ret)) return CMD_ERROR; |
335 return CMD_ERROR; |
|
336 |
336 |
337 cost += ret; |
337 cost += ret; |
|
338 } else { /* Building new HQ */ |
|
339 if (p->location_of_house != 0) return CMD_ERROR; |
338 } |
340 } |
339 |
341 |
340 if (flags & DC_EXEC) { |
342 if (flags & DC_EXEC) { |
341 score = UpdateCompanyRatingAndValue(p, false); |
343 int score = UpdateCompanyRatingAndValue(p, false); |
342 |
344 |
343 p->location_of_house = tile; |
345 p->location_of_house = tile; |
344 |
346 |
345 ModifyTile(tile + TILE_XY(0,0), |
347 ModifyTile(tile + TILE_XY(0,0), MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5, 0x80); |
346 MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5, |
348 ModifyTile(tile + TILE_XY(0,1), MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5, 0x81); |
347 0x80 |
349 ModifyTile(tile + TILE_XY(1,0), MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5, 0x82); |
348 ); |
350 ModifyTile(tile + TILE_XY(1,1), MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5, 0x83); |
349 |
|
350 ModifyTile(tile + TILE_XY(0,1), |
|
351 MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5, |
|
352 0x81 |
|
353 ); |
|
354 |
|
355 ModifyTile(tile + TILE_XY(1,0), |
|
356 MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5, |
|
357 0x82 |
|
358 ); |
|
359 |
|
360 ModifyTile(tile + TILE_XY(1,1), |
|
361 MP_SETTYPE(MP_UNMOVABLE) | MP_MAPOWNER_CURRENT | MP_MAP5, |
|
362 0x83 |
|
363 ); |
|
364 UpdatePlayerHouse(p, score); |
351 UpdatePlayerHouse(p, score); |
365 InvalidateWindow(WC_COMPANY, (int)p->index); |
352 InvalidateWindow(WC_COMPANY, (int)p->index); |
366 } |
353 } |
367 |
354 |
368 return cost; |
355 return cost; |
369 } |
356 } |
370 |
357 |
371 /* p1 = owner of the HQ */ |
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 */ |
372 int32 CmdDestroyCompanyHQ(int x, int y, uint32 flags, uint32 p1, uint32 p2) |
367 int32 CmdDestroyCompanyHQ(int x, int y, uint32 flags, uint32 p1, uint32 p2) |
373 { |
368 { |
374 uint tile = TILE_FROM_XY(x,y); |
369 TileIndex tile = TILE_FROM_XY(x,y); |
375 Player *p; |
370 Player *p; |
376 |
371 |
377 SET_EXPENSES_TYPE(EXPENSES_PROPERTY); |
372 SET_EXPENSES_TYPE(EXPENSES_PROPERTY); |
378 |
373 |
379 if ((int)p1 != OWNER_WATER) // destruction was initiated by player |
374 /* Find player that has HQ flooded, and reset their location_of_house */ |
380 p = DEREF_PLAYER((byte)p1); |
375 if (_current_player == OWNER_WATER) { |
381 else { // find player that has HQ flooded, and reset their location_of_house |
|
382 bool dodelete = false; |
376 bool dodelete = false; |
383 FOR_ALL_PLAYERS(p) { |
377 FOR_ALL_PLAYERS(p) { |
384 if (p->location_of_house == tile) { |
378 if (p->location_of_house == tile) { |
385 dodelete = true; |
379 dodelete = true; |
386 break; |
380 break; |
387 } |
381 } |
388 } |
382 } |
389 if (!dodelete) |
383 if (!dodelete) return CMD_ERROR; |
390 return CMD_ERROR; |
384 } else /* Destruction was initiated by player */ |
391 } |
385 p = DEREF_PLAYER(_current_player); |
392 |
386 |
393 if (flags & DC_EXEC) { |
387 if (flags & DC_EXEC) { |
394 p->location_of_house = 0; // reset HQ position |
388 p->location_of_house = 0; // reset HQ position |
395 DoClearSquare(tile + TILE_XY(0,0)); |
389 DoClearSquare(tile + TILE_XY(0,0)); |
396 DoClearSquare(tile + TILE_XY(0,1)); |
390 DoClearSquare(tile + TILE_XY(0,1)); |