summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfrosch <frosch@openttd.org>2011-11-08 17:26:49 +0000
committerfrosch <frosch@openttd.org>2011-11-08 17:26:49 +0000
commit30874b5e81af0fff2f42d34b9b105ee86666b8ac (patch)
tree6fd8200f08019910de826cf6f1b9b6e92f7d2d69
parentb98c7763de42eda4b3d19604bc3f33452b9b05e4 (diff)
downloadopenttd-30874b5e81af0fff2f42d34b9b105ee86666b8ac.tar.xz
(svn r23147) -Change: [NewGRF v8] Unify the return values of boolean callbacks, and check the results for validity.
-rw-r--r--src/industry_cmd.cpp24
-rw-r--r--src/newgrf_airporttiles.cpp2
-rw-r--r--src/newgrf_commons.cpp39
-rw-r--r--src/newgrf_commons.h2
-rw-r--r--src/newgrf_house.cpp6
-rw-r--r--src/newgrf_industries.cpp2
-rw-r--r--src/newgrf_industrytiles.cpp2
-rw-r--r--src/object_cmd.cpp2
-rw-r--r--src/rail_gui.cpp28
-rw-r--r--src/station_cmd.cpp5
-rw-r--r--src/town_cmd.cpp6
11 files changed, 90 insertions, 28 deletions
diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp
index c7ed3f7a6..aa6cce7b4 100644
--- a/src/industry_cmd.cpp
+++ b/src/industry_cmd.cpp
@@ -381,7 +381,7 @@ static Foundation GetFoundation_Industry(TileIndex tile, Slope tileh)
const IndustryTileSpec *indts = GetIndustryTileSpec(gfx);
if (indts->grf_prop.spritegroup[0] != NULL && HasBit(indts->callback_mask, CBM_INDT_DRAW_FOUNDATIONS)) {
uint32 callback_res = GetIndustryTileCallback(CBID_INDTILE_DRAW_FOUNDATIONS, 0, 0, gfx, Industry::GetByTile(tile), tile);
- if (callback_res == 0) return FOUNDATION_NONE;
+ if (callback_res != CALLBACK_FAILED && !ConvertBooleanCallback(indts->grf_prop.grffile, CBID_INDTILE_DRAW_FOUNDATIONS, callback_res)) return FOUNDATION_NONE;
}
}
return FlatteningFoundation(tileh);
@@ -1103,9 +1103,14 @@ static void ProduceIndustryGoods(Industry *i)
i->produced_cargo_waiting[1] = min(0xffff, i->produced_cargo_waiting[1] + i->production_rate[1]);
if ((indbehav & INDUSTRYBEH_PLANT_FIELDS) != 0) {
- bool plant;
+ uint16 cb_res = CALLBACK_FAILED;
if (HasBit(indsp->callback_mask, CBM_IND_SPECIAL_EFFECT)) {
- plant = (GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, Random(), 0, i, i->type, i->location.tile) != 0);
+ cb_res = GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, Random(), 0, i, i->type, i->location.tile);
+ }
+
+ bool plant;
+ if (cb_res != CALLBACK_FAILED) {
+ plant = ConvertBooleanCallback(indsp->grf_prop.grffile, CBID_INDUSTRY_SPECIAL_EFFECT, cb_res);
} else {
plant = Chance16(1, 8);
}
@@ -1113,9 +1118,16 @@ static void ProduceIndustryGoods(Industry *i)
if (plant) PlantRandomFarmField(i);
}
if ((indbehav & INDUSTRYBEH_CUT_TREES) != 0) {
- bool cut = ((i->counter % INDUSTRY_CUT_TREE_TICKS) == 0);
+ uint16 cb_res = CALLBACK_FAILED;
if (HasBit(indsp->callback_mask, CBM_IND_SPECIAL_EFFECT)) {
- cut = (GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, Random(), 1, i, i->type, i->location.tile) != 0);
+ cb_res = GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, Random(), 1, i, i->type, i->location.tile);
+ }
+
+ bool cut;
+ if (cb_res != CALLBACK_FAILED) {
+ cut = ConvertBooleanCallback(indsp->grf_prop.grffile, CBID_INDUSTRY_SPECIAL_EFFECT, cb_res);
+ } else {
+ cut = ((i->counter % INDUSTRY_CUT_TREE_TICKS) == 0);
}
if (cut) ChopLumberMillTrees(i);
@@ -2734,7 +2746,7 @@ static CommandCost TerraformTile_Industry(TileIndex tile, DoCommandFlag flags, i
if (HasBit(itspec->callback_mask, CBM_INDT_AUTOSLOPE)) {
/* If the callback fails, allow autoslope. */
uint16 res = GetIndustryTileCallback(CBID_INDTILE_AUTOSLOPE, 0, 0, gfx, Industry::GetByTile(tile), tile);
- if ((res == 0) || (res == CALLBACK_FAILED)) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
+ if (res == CALLBACK_FAILED || !ConvertBooleanCallback(itspec->grf_prop.grffile, CBID_INDTILE_AUTOSLOPE, res)) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
} else {
/* allow autoslope */
return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
diff --git a/src/newgrf_airporttiles.cpp b/src/newgrf_airporttiles.cpp
index abb468bc1..cf61d024d 100644
--- a/src/newgrf_airporttiles.cpp
+++ b/src/newgrf_airporttiles.cpp
@@ -287,7 +287,7 @@ bool DrawNewAirportTile(TileInfo *ti, Station *st, StationGfx gfx, const Airport
if (HasBit(airts->callback_mask, CBM_AIRT_DRAW_FOUNDATIONS)) {
/* Called to determine the type (if any) of foundation to draw */
uint32 callback_res = GetAirportTileCallback(CBID_AIRPTILE_DRAW_FOUNDATIONS, 0, 0, airts, st, ti->tile);
- draw_old_one = (callback_res != 0);
+ if (callback_res != CALLBACK_FAILED) draw_old_one = ConvertBooleanCallback(airts->grf_prop.grffile, CBID_AIRPTILE_DRAW_FOUNDATIONS, callback_res);
}
if (draw_old_one) DrawFoundation(ti, FOUNDATION_LEVELED);
diff --git a/src/newgrf_commons.cpp b/src/newgrf_commons.cpp
index 2f49c51c7..5f2ada887 100644
--- a/src/newgrf_commons.cpp
+++ b/src/newgrf_commons.cpp
@@ -538,6 +538,45 @@ void ErrorUnknownCallbackResult(uint32 grfid, uint16 cbid, uint16 cb_res)
DEBUG(grf, 0, "%s", buffer + 3);
}
+/**
+ * Converts a callback result into a boolean.
+ * For grf version < 8 the result is checked for zero or non-zero.
+ * For grf version >= 8 the callback result must be 0 or 1.
+ * @param grffile NewGRF returning the value.
+ * @param cbid Callback returning the value.
+ * @param cb_res Callback result.
+ * @return Boolean value. True if cb_res != 0.
+ */
+bool ConvertBooleanCallback(const GRFFile *grffile, uint16 cbid, uint16 cb_res)
+{
+ assert(cb_res != CALLBACK_FAILED); // We do not know what to return
+
+ if (grffile->grf_version < 8) return cb_res != 0;
+
+ if (cb_res > 1) ErrorUnknownCallbackResult(grffile->grfid, cbid, cb_res);
+ return cb_res != 0;
+}
+
+/**
+ * Converts a callback result into a boolean.
+ * For grf version < 8 the first 8 bit of the result are checked for zero or non-zero.
+ * For grf version >= 8 the callback result must be 0 or 1.
+ * @param grffile NewGRF returning the value.
+ * @param cbid Callback returning the value.
+ * @param cb_res Callback result.
+ * @return Boolean value. True if cb_res != 0.
+ */
+bool Convert8bitBooleanCallback(const GRFFile *grffile, uint16 cbid, uint16 cb_res)
+{
+ assert(cb_res != CALLBACK_FAILED); // We do not know what to return
+
+ if (grffile->grf_version < 8) return GB(cb_res, 0, 8) != 0;
+
+ if (cb_res > 1) ErrorUnknownCallbackResult(grffile->grfid, cbid, cb_res);
+ return cb_res != 0;
+}
+
+
/* static */ SmallVector<DrawTileSeqStruct, 8> NewGRFSpriteLayout::result_seq;
/**
diff --git a/src/newgrf_commons.h b/src/newgrf_commons.h
index ad1c8f408..99a124caa 100644
--- a/src/newgrf_commons.h
+++ b/src/newgrf_commons.h
@@ -301,6 +301,8 @@ uint32 GetCompanyInfo(CompanyID owner, const struct Livery *l = NULL);
CommandCost GetErrorMessageFromLocationCallbackResult(uint16 cb_res, uint32 grfid, StringID default_error);
void ErrorUnknownCallbackResult(uint32 grfid, uint16 cbid, uint16 cb_res);
+bool ConvertBooleanCallback(const struct GRFFile *grffile, uint16 cbid, uint16 cb_res);
+bool Convert8bitBooleanCallback(const struct GRFFile *grffile, uint16 cbid, uint16 cb_res);
/**
* Data related to the handling of grf files.
diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp
index 6b44277c0..5e841b7d1 100644
--- a/src/newgrf_house.cpp
+++ b/src/newgrf_house.cpp
@@ -489,7 +489,7 @@ void DrawNewHouseTile(TileInfo *ti, HouseID house_id)
if (HasBit(hs->callback_mask, CBM_HOUSE_DRAW_FOUNDATIONS)) {
/* Called to determine the type (if any) of foundation to draw for the house tile */
uint32 callback_res = GetHouseCallback(CBID_HOUSE_DRAW_FOUNDATIONS, 0, 0, house_id, Town::GetByTile(ti->tile), ti->tile);
- draw_old_one = (callback_res != 0);
+ if (callback_res != CALLBACK_FAILED) draw_old_one = ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DRAW_FOUNDATIONS, callback_res);
}
if (draw_old_one) DrawFoundation(ti, FOUNDATION_LEVELED);
@@ -552,7 +552,7 @@ bool CanDeleteHouse(TileIndex tile)
if (HasBit(hs->callback_mask, CBM_HOUSE_DENY_DESTRUCTION)) {
uint16 callback_res = GetHouseCallback(CBID_HOUSE_DENY_DESTRUCTION, 0, 0, GetHouseType(tile), Town::GetByTile(tile), tile);
- return (callback_res == CALLBACK_FAILED || callback_res == 0);
+ return (callback_res == CALLBACK_FAILED || !ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DENY_DESTRUCTION, callback_res));
} else {
return !(hs->extra_flags & BUILDING_IS_PROTECTED);
}
@@ -600,7 +600,7 @@ bool NewHouseTileLoop(TileIndex tile)
/* Check callback 21, which determines if a house should be destroyed. */
if (HasBit(hs->callback_mask, CBM_HOUSE_DESTRUCTION)) {
uint16 callback_res = GetHouseCallback(CBID_HOUSE_DESTRUCTION, 0, 0, GetHouseType(tile), Town::GetByTile(tile), tile);
- if (callback_res != CALLBACK_FAILED && GB(callback_res, 0, 8) > 0) {
+ if (callback_res != CALLBACK_FAILED && Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DESTRUCTION, callback_res)) {
ClearTownHouse(Town::GetByTile(tile), tile);
return false;
}
diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp
index 2f469dc71..4d61dd4bf 100644
--- a/src/newgrf_industries.cpp
+++ b/src/newgrf_industries.cpp
@@ -661,7 +661,7 @@ bool IndustryTemporarilyRefusesCargo(Industry *ind, CargoID cargo_type)
uint16 res = GetIndustryCallback(CBID_INDUSTRY_REFUSE_CARGO,
0, GetReverseCargoTranslation(cargo_type, indspec->grf_prop.grffile),
ind, ind->type, ind->location.tile);
- return res == 0;
+ if (res != CALLBACK_FAILED) return !ConvertBooleanCallback(indspec->grf_prop.grffile, CBID_INDUSTRY_REFUSE_CARGO, res);
}
return false;
}
diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp
index 187a63ddc..0014a0bd8 100644
--- a/src/newgrf_industrytiles.cpp
+++ b/src/newgrf_industrytiles.cpp
@@ -248,7 +248,7 @@ bool DrawNewIndustryTile(TileInfo *ti, Industry *i, IndustryGfx gfx, const Indus
if (HasBit(inds->callback_mask, CBM_INDT_DRAW_FOUNDATIONS)) {
/* Called to determine the type (if any) of foundation to draw for industry tile */
uint32 callback_res = GetIndustryTileCallback(CBID_INDTILE_DRAW_FOUNDATIONS, 0, 0, gfx, i, ti->tile);
- draw_old_one = (callback_res != 0);
+ if (callback_res != CALLBACK_FAILED) draw_old_one = ConvertBooleanCallback(inds->grf_prop.grffile, CBID_INDTILE_DRAW_FOUNDATIONS, callback_res);
}
if (draw_old_one) DrawFoundation(ti, FOUNDATION_LEVELED);
diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp
index e613c7705..44b221457 100644
--- a/src/object_cmd.cpp
+++ b/src/object_cmd.cpp
@@ -741,7 +741,7 @@ static CommandCost TerraformTile_Object(TileIndex tile, DoCommandFlag flags, int
if (HasBit(spec->callback_mask, CBM_OBJ_AUTOSLOPE)) {
/* If the callback fails, allow autoslope. */
uint16 res = GetObjectCallback(CBID_OBJECT_AUTOSLOPE, 0, 0, spec, Object::GetByTile(tile), tile);
- if ((res == 0) || (res == CALLBACK_FAILED)) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
+ if (res == CALLBACK_FAILED || !ConvertBooleanCallback(spec->grf_prop.grffile, CBID_OBJECT_AUTOSLOPE, res)) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
} else if (spec->enabled) {
/* allow autoslope */
return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp
index 3f8d167d4..9008ffb31 100644
--- a/src/rail_gui.cpp
+++ b/src/rail_gui.cpp
@@ -67,6 +67,20 @@ static void ShowBuildWaypointPicker(Window *parent);
static void ShowStationBuilder(Window *parent);
static void ShowSignalBuilder(Window *parent);
+/**
+ * Check whether a station type can be build.
+ * @return true if building is allowed.
+ */
+static bool IsStationAvailable(const StationSpec *statspec)
+{
+ if (statspec == NULL || !HasBit(statspec->callback_mask, CBM_STATION_AVAIL)) return true;
+
+ uint16 cb_res = GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE);
+ if (cb_res == CALLBACK_FAILED) return true;
+
+ return Convert8bitBooleanCallback(statspec->grf_prop.grffile, CBID_STATION_AVAILABILITY, cb_res);
+}
+
void CcPlaySound1E(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
{
if (result.Succeeded()) SndPlayTileFx(SND_20_SPLAT_2, tile);
@@ -1163,8 +1177,7 @@ public:
assert(type < _railstation.station_count);
/* Check station availability callback */
const StationSpec *statspec = StationClass::Get(_railstation.station_class, type);
- if (statspec != NULL && HasBit(statspec->callback_mask, CBM_STATION_AVAIL) &&
- GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) {
+ if (!IsStationAvailable(statspec)) {
GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK, FILLRECT_CHECKER);
}
@@ -1358,8 +1371,7 @@ public:
/* Check station availability callback */
const StationSpec *statspec = StationClass::Get(_railstation.station_class, y);
- if (statspec != NULL && HasBit(statspec->callback_mask, CBM_STATION_AVAIL) &&
- GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) return;
+ if (!IsStationAvailable(statspec)) return;
_railstation.station_type = y;
@@ -1814,9 +1826,7 @@ struct BuildRailWaypointWindow : PickerWindowBase {
const StationSpec *statspec = StationClass::Get(STAT_CLASS_WAYP, type);
DrawWaypointSprite(r.left + TILE_PIXELS, r.bottom - TILE_PIXELS, type, _cur_railtype);
- if (statspec != NULL &&
- HasBit(statspec->callback_mask, CBM_STATION_AVAIL) &&
- GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) {
+ if (!IsStationAvailable(statspec)) {
GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK, FILLRECT_CHECKER);
}
}
@@ -1832,9 +1842,7 @@ struct BuildRailWaypointWindow : PickerWindowBase {
/* Check station availability callback */
const StationSpec *statspec = StationClass::Get(STAT_CLASS_WAYP, type);
- if (statspec != NULL &&
- HasBit(statspec->callback_mask, CBM_STATION_AVAIL) &&
- GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) return;
+ if (!IsStationAvailable(statspec)) return;
_cur_waypoint_type = type;
this->GetWidget<NWidgetMatrix>(BRWW_WAYPOINT_MATRIX)->SetClicked(_cur_waypoint_type);
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
index 00152246c..a1fb6e2c4 100644
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -1187,8 +1187,9 @@ CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32
}
/* Check if the station is buildable */
- if (HasBit(statspec->callback_mask, CBM_STATION_AVAIL) && GB(GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE), 0, 8) == 0) {
- return CMD_ERROR;
+ if (HasBit(statspec->callback_mask, CBM_STATION_AVAIL)) {
+ uint16 cb_res = GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE);
+ if (cb_res != CALLBACK_FAILED && !Convert8bitBooleanCallback(statspec->grf_prop.grffile, CBID_STATION_AVAILABILITY, cb_res)) return CMD_ERROR;
}
}
diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp
index eb741923b..a1d87e716 100644
--- a/src/town_cmd.cpp
+++ b/src/town_cmd.cpp
@@ -273,7 +273,7 @@ static Foundation GetFoundation_Town(TileIndex tile, Slope tileh)
const HouseSpec *hs = HouseSpec::Get(hid);
if (hs->grf_prop.spritegroup[0] != NULL && HasBit(hs->callback_mask, CBM_HOUSE_DRAW_FOUNDATIONS)) {
uint32 callback_res = GetHouseCallback(CBID_HOUSE_DRAW_FOUNDATIONS, 0, 0, hid, Town::GetByTile(tile), tile);
- if (callback_res == 0) return FOUNDATION_NONE;
+ if (callback_res != CALLBACK_FAILED && !ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DRAW_FOUNDATIONS, callback_res)) return FOUNDATION_NONE;
}
}
return FlatteningFoundation(tileh);
@@ -2207,7 +2207,7 @@ static bool BuildTownHouse(Town *t, TileIndex tile)
if (HasBit(hs->callback_mask, CBM_HOUSE_ALLOW_CONSTRUCTION)) {
uint16 callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile, true, random_bits);
- if (callback_res != CALLBACK_FAILED && GB(callback_res, 0, 8) == 0) continue;
+ if (callback_res != CALLBACK_FAILED && !Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_ALLOW_CONSTRUCTION, callback_res)) continue;
}
/* build the house */
@@ -3068,7 +3068,7 @@ static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlag flags, int z
if (HasBit(hs->callback_mask, CBM_HOUSE_AUTOSLOPE)) {
/* If the callback fails, allow autoslope. */
uint16 res = GetHouseCallback(CBID_HOUSE_AUTOSLOPE, 0, 0, house, Town::GetByTile(tile), tile);
- if ((res != 0) && (res != CALLBACK_FAILED)) allow_terraform = false;
+ if (res != CALLBACK_FAILED && ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_AUTOSLOPE, res)) allow_terraform = false;
}
if (allow_terraform) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);