(svn r20227) -Fix [FS#3985]: Don't spend cash when building a statue fails.

replace/41b28d7194a279bdc17475d4fbe2ea6ec885a466
terkhen 14 years ago
parent 5ed982bbff
commit 4f9b49653b

@ -3448,6 +3448,7 @@ STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... ther
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}The town will not build roads. You can enable building of roads via Advanced Settings->Economy->Towns. STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}The town will not build roads. You can enable building of roads via Advanced Settings->Economy->Towns.
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Road works in progress STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Road works in progress
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Can't delete this town...{}A station or depot is referring to the town or a town owned tile can't be removed STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Can't delete this town...{}A station or depot is referring to the town or a town owned tile can't be removed
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... there is no suitable place for a statue in the center of this town
# Industry related errors # Industry related errors
STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... too many industries STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... too many industries

@ -2341,37 +2341,55 @@ const byte _town_action_costs[TACT_COUNT] = {
2, 4, 9, 35, 48, 53, 117, 175 2, 4, 9, 35, 48, 53, 117, 175
}; };
static void TownActionAdvertiseSmall(Town *t) static CommandCost TownActionAdvertiseSmall(Town *t, DoCommandFlag flags)
{ {
ModifyStationRatingAround(t->xy, _current_company, 0x40, 10); if (flags & DC_EXEC) {
ModifyStationRatingAround(t->xy, _current_company, 0x40, 10);
}
return CommandCost();
} }
static void TownActionAdvertiseMedium(Town *t) static CommandCost TownActionAdvertiseMedium(Town *t, DoCommandFlag flags)
{ {
ModifyStationRatingAround(t->xy, _current_company, 0x70, 15); if (flags & DC_EXEC) {
ModifyStationRatingAround(t->xy, _current_company, 0x70, 15);
}
return CommandCost();
} }
static void TownActionAdvertiseLarge(Town *t) static CommandCost TownActionAdvertiseLarge(Town *t, DoCommandFlag flags)
{ {
ModifyStationRatingAround(t->xy, _current_company, 0xA0, 20); if (flags & DC_EXEC) {
ModifyStationRatingAround(t->xy, _current_company, 0xA0, 20);
}
return CommandCost();
} }
static void TownActionRoadRebuild(Town *t) static CommandCost TownActionRoadRebuild(Town *t, DoCommandFlag flags)
{ {
t->road_build_months = 6; if (flags & DC_EXEC) {
t->road_build_months = 6;
char company_name[MAX_LENGTH_COMPANY_NAME_BYTES]; char company_name[MAX_LENGTH_COMPANY_NAME_BYTES];
SetDParam(0, _current_company); SetDParam(0, _current_company);
GetString(company_name, STR_COMPANY_NAME, lastof(company_name)); GetString(company_name, STR_COMPANY_NAME, lastof(company_name));
char *cn = strdup(company_name); char *cn = strdup(company_name);
SetDParam(0, t->index); SetDParam(0, t->index);
SetDParamStr(1, cn); SetDParamStr(1, cn);
AddNewsItem(STR_NEWS_ROAD_REBUILDING, NS_GENERAL, NR_TOWN, t->index, NR_NONE, UINT32_MAX, cn); AddNewsItem(STR_NEWS_ROAD_REBUILDING, NS_GENERAL, NR_TOWN, t->index, NR_NONE, UINT32_MAX, cn);
}
return CommandCost();
} }
static bool DoBuildStatueOfCompany(TileIndex tile, TownID town_id) /**
* Search callback function for TownActionBuildStatue.
* @param tile Tile on which to perform the search.
* @param user_data Unused.
* @return Result of the test.
*/
static bool SearchTileForStatue(TileIndex tile, void *user_data)
{ {
/* Statues can be build on slopes, just like houses. Only the steep slopes is a no go. */ /* Statues can be build on slopes, just like houses. Only the steep slopes is a no go. */
if (IsSteepSlope(GetTileSlope(tile, NULL))) return false; if (IsSteepSlope(GetTileSlope(tile, NULL))) return false;
@ -2385,96 +2403,98 @@ static bool DoBuildStatueOfCompany(TileIndex tile, TownID town_id)
} }
Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE); Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
CommandCost r = DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); CommandCost r = DoCommand(tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR);
cur_company.Restore(); cur_company.Restore();
if (r.Failed()) return false; if (r.Failed()) return false;
MakeStatue(tile, _current_company, town_id);
MarkTileDirtyByTile(tile);
return true; return true;
} }
/**
* Search callback function for TownActionBuildStatue
* @param tile on which to perform the search
* @param user_data The town_id for which we want a statue
* @return the result of the test
*/
static bool SearchTileForStatue(TileIndex tile, void *user_data)
{
TownID *town_id = (TownID *)user_data;
return DoBuildStatueOfCompany(tile, *town_id);
}
/** /**
* Perform a 9x9 tiles circular search from the center of the town * Perform a 9x9 tiles circular search from the center of the town
* in order to find a free tile to place a statue * in order to find a free tile to place a statue
* @param t town to search in * @param t town to search in
* @param flags Used to check if the statue must be built or not.
* @return Empty cost or an error.
*/ */
static void TownActionBuildStatue(Town *t) static CommandCost TownActionBuildStatue(Town *t, DoCommandFlag flags)
{ {
TileIndex tile = t->xy; TileIndex tile = t->xy;
if (CircularTileSearch(&tile, 9, SearchTileForStatue, NULL)) {
if (CircularTileSearch(&tile, 9, SearchTileForStatue, &t->index)) { if (flags & DC_EXEC) {
SetBit(t->statues, _current_company); // Once found and built, "inform" the Town DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
MakeStatue(tile, _current_company, t->index);
SetBit(t->statues, _current_company); // Once found and built, "inform" the Town.
MarkTileDirtyByTile(tile);
}
return CommandCost();
} }
return_cmd_error(STR_ERROR_STATUE_NO_SUITABLE_PLACE);
} }
static void TownActionFundBuildings(Town *t) static CommandCost TownActionFundBuildings(Town *t, DoCommandFlag flags)
{ {
/* Build next tick */ if (flags & DC_EXEC) {
t->grow_counter = 1; /* Build next tick */
/* If we were not already growing */ t->grow_counter = 1;
SetBit(t->flags, TOWN_IS_FUNDED); /* If we were not already growing */
/* And grow for 3 months */ SetBit(t->flags, TOWN_IS_FUNDED);
t->fund_buildings_months = 3; /* And grow for 3 months */
t->fund_buildings_months = 3;
}
return CommandCost();
} }
static void TownActionBuyRights(Town *t) static CommandCost TownActionBuyRights(Town *t, DoCommandFlag flags)
{ {
/* Check if it's allowed to by the rights */ /* Check if it's allowed to by the rights */
if (!_settings_game.economy.exclusive_rights) return; if (!_settings_game.economy.exclusive_rights) return CMD_ERROR;
t->exclusive_counter = 12; if (flags & DC_EXEC) {
t->exclusivity = _current_company; t->exclusive_counter = 12;
t->exclusivity = _current_company;
ModifyStationRatingAround(t->xy, _current_company, 130, 17); ModifyStationRatingAround(t->xy, _current_company, 130, 17);
}
return CommandCost();
} }
static void TownActionBribe(Town *t) static CommandCost TownActionBribe(Town *t, DoCommandFlag flags)
{ {
if (Chance16(1, 14)) { if (flags & DC_EXEC) {
/* set as unwanted for 6 months */ if (Chance16(1, 14)) {
t->unwanted[_current_company] = 6; /* set as unwanted for 6 months */
t->unwanted[_current_company] = 6;
/* set all close by station ratings to 0 */
Station *st; /* set all close by station ratings to 0 */
FOR_ALL_STATIONS(st) { Station *st;
if (st->town == t && st->owner == _current_company) { FOR_ALL_STATIONS(st) {
for (CargoID i = 0; i < NUM_CARGO; i++) st->goods[i].rating = 0; if (st->town == t && st->owner == _current_company) {
for (CargoID i = 0; i < NUM_CARGO; i++) st->goods[i].rating = 0;
}
} }
}
/* only show errormessage to the executing player. All errors are handled command.c /* only show errormessage to the executing player. All errors are handled command.c
* but this is special, because it can only 'fail' on a DC_EXEC */ * but this is special, because it can only 'fail' on a DC_EXEC */
if (IsLocalCompany()) ShowErrorMessage(STR_ERROR_BRIBE_FAILED, STR_ERROR_BRIBE_FAILED_2, WL_INFO); if (IsLocalCompany()) ShowErrorMessage(STR_ERROR_BRIBE_FAILED, STR_ERROR_BRIBE_FAILED_2, WL_INFO);
/* decrease by a lot! /* decrease by a lot!
* ChangeTownRating is only for stuff in demolishing. Bribe failure should * ChangeTownRating is only for stuff in demolishing. Bribe failure should
* be independent of any cheat settings * be independent of any cheat settings
*/ */
if (t->ratings[_current_company] > RATING_BRIBE_DOWN_TO) { if (t->ratings[_current_company] > RATING_BRIBE_DOWN_TO) {
t->ratings[_current_company] = RATING_BRIBE_DOWN_TO; t->ratings[_current_company] = RATING_BRIBE_DOWN_TO;
SetWindowDirty(WC_TOWN_AUTHORITY, t->index); SetWindowDirty(WC_TOWN_AUTHORITY, t->index);
}
} else {
ChangeTownRating(t, RATING_BRIBE_UP_STEP, RATING_BRIBE_MAXIMUM, DC_EXEC);
} }
} else {
ChangeTownRating(t, RATING_BRIBE_UP_STEP, RATING_BRIBE_MAXIMUM, DC_EXEC);
} }
return CommandCost();
} }
typedef void TownActionProc(Town *t); typedef CommandCost TownActionProc(Town *t, DoCommandFlag flags);
static TownActionProc * const _town_action_proc[] = { static TownActionProc * const _town_action_proc[] = {
TownActionAdvertiseSmall, TownActionAdvertiseSmall,
TownActionAdvertiseMedium, TownActionAdvertiseMedium,
@ -2547,8 +2567,10 @@ CommandCost CmdDoTownAction(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
CommandCost cost(EXPENSES_OTHER, _price[PR_TOWN_ACTION] * _town_action_costs[p2] >> 8); CommandCost cost(EXPENSES_OTHER, _price[PR_TOWN_ACTION] * _town_action_costs[p2] >> 8);
CommandCost ret = _town_action_proc[p2](t, flags);
if (ret.Failed()) return ret;
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
_town_action_proc[p2](t);
SetWindowDirty(WC_TOWN_AUTHORITY, p1); SetWindowDirty(WC_TOWN_AUTHORITY, p1);
} }

Loading…
Cancel
Save