After some digging, found and fixed a defect in StructureTemplate.bsf/StructureTpl_ListforbiddenTerrainCats(). Revised code below:
Code: Select all
FUNCTION StructureTpl_ListForbiddenTerrainCats(strucTplID)
{
int handle; // dynamic array reference
int count; // array length / number of items
int idx; // loop iteration index
// {pre: global contains valid DA handle}
if (gHStructuresTplForbiddenTerrainCats[strucTplID] == 0) // Create the DA for further use
{
gHStructuresTplForbiddenTerrainCats[strucTplID] = CreateDynamicArray();
}
handle = gHStructuresTplForbiddenTerrainCats[strucTplID];
// {invariant: DA content duplicates loaded StructureTemplateArray}
count = GetStructureTemplateArrayLength(strucTplID, $STRUCTURE_FORBIDDENTERRAINCATS);
if (count != GetDynamicArrayLength(handle)) // size mismatch implies DA has stale data
{
ClearDynamicArray(handle);
ResizeDynamicArray(handle, count);
for (idx = 0; idx < count; idx++)
{
SetDynamicArray(handle, idx, GetStructureTemplateInt(strucTplID, $STRUCTURE_FORBIDDENTERRAINCATS, idx));
}
// assume no need to update DA further ...
}
{post: global contains valid handle to DA containing duplicate of data loaded to StructureTemplateArray}
return handle;
}
The relevant portion is:
Code: Select all
// Terrain tests -
// Must be Adjacent to a river?
value = StructureTpl_MustBeAdjRiver(strucTplID);
if ((value > 0) && (Region_IsAdjacentToRiver_Strait(regionID, TRUE, FALSE) == FALSE))
{
gStructureConstructErrorCode = STRUCTURE_CONSTRUCT_ERROR_WRONG_TERRAIN;
return FALSE;
}
// Required Area
value = StructureTpl_RequiredArea(strucTplID);
if ((value > 0) && (Region_GetGeoArea(regionID) != value)) // Area_HasRegion(value, regionID) == FALSE
{
gStructureConstructErrorCode = STRUCTURE_CONSTRUCT_ERROR_WRONG_AREA;
return FALSE;
}
// Required terrain
value = StructureTpl_RequiredTerrainCat(strucTplID);
if ((value > 0) && (Region_GetTerrain(regionID) != value))
{
gStructureConstructErrorCode = STRUCTURE_CONSTRUCT_ERROR_WRONG_TERRAIN;
return FALSE;
}
// Forbidden terrain - More expensive test, multiple forbidden terrain cats are possible
daHandle = StructureTpl_ListForbiddenTerrainCats(strucTplID); // @TODO: this really wants to be a bitset
count = GetDynamicArrayLength(daHandle);
for (idx = 0; idx < count; idx++)
{
value = GetDynamicArray(daHandle, idx); // value is one of TERRAIN_CAT_ values
if ((value > 0) && (Terrain_IsThisTerrainCat(terrainID, value, Region_FetchWeather(regionID)) == TRUE))
{
gStructureConstructErrorCode = STRUCTURE_CONSTRUCT_ERROR_WRONG_TERRAIN;
return FALSE;
}
}