Page 1 of 1
How to detect a bridge on the water?
Posted: 20 Dec 2010 00:27
by tristanb
Hi all. I'm playing around with a ship building AI, at the very early stages - so far all it does it try to detect the "best" place to put a dock in a city.
To check if a dock is buildable, I test that the slope faces onto a water tile with
AITile.IsWaterTile. My problem is with bridges.
If there is a bridge, the AI API still detects this as a water tile - which I'm okay about. The problem is, I cannot find any other function to exclude a bridge being there. I have tried
AIBridge.GetBridgeID (to see if not -1) and
AITile.HasTransportType (testing for road or rail). But the former must only work on the bridge end tiles.
What are my options? Will I need to enumerate through all the bridges to check none of them intersect my water tile?
I've attached a picture to show what I mean. The AI wants to build a dock where the pink arrow ends - it has no way of detecting that the water tile in front onto has a bridge over it.

- How do you detect a bridge in front of where the AI would like to build a dock?
- how_do_you_detect_a_bridge.png (59.47 KiB) Viewed 1806 times
Thanks for your help. I've done a bit of searching through other code, but can't find any quick answer.
Re: How to detect a bridge on the water?
Posted: 20 Dec 2010 07:11
by Zuu
You need to iterate in the +/-90 degree direction from the tile you want to check until you find a bridge head in order to check if there is a bridge or not. This is the same as how to find a bridge on land.
I've implemented a function for this in my SuperLib library: SuperLib::Tile::GetBridgeAboveStart(tile, bridge_search_direction)
Note that bridge_search_direction is a Direction constant found in SuperLib::Direction.
Code: Select all
function _SuperLib_Tile::GetBridgeAboveStart(tile, bridge_search_direction)
{
if (!_SuperLib_Direction.IsMainDir(bridge_search_direction))
{
_SuperLib_Log.Error("Tile::GetBridgeAboveStart(tile, bridge_search_direction) was called with a non-main direction", _SuperLib_Log.LVL_INFO);
return -1;
}
local max_height = AITile.GetMaxHeight(tile);
for (local curr_tile = _SuperLib_Direction.GetAdjacentTileInDirection(tile, bridge_search_direction);
AIMap.IsValidTile(curr_tile);
curr_tile = _SuperLib_Direction.GetAdjacentTileInDirection(curr_tile, bridge_search_direction))
{
local curr_tile_height = AITile.GetMaxHeight(curr_tile);
if (curr_tile_height < max_height)
{
// The down slope at the other side of a hill has been found -> There can't be a bridge to 'tile'.
return -1;
}
max_height = Helper.Max(max_height, curr_tile_height);
if (AIBridge.IsBridgeTile(curr_tile))
{
// A bridge was found
// Check that the bridge goes in the right direction
local other_end = AIBridge.GetOtherBridgeEnd(curr_tile);
local found_bridge_dir = _SuperLib_Direction.GetDirectionToTile(curr_tile, other_end);
// Return -1 if the bridge direction is wrong eg. 90 deg of bridge_search_direction or away from the tile 'tile'
return found_bridge_dir == bridge_search_direction? curr_tile : -1;
}
}
return -1;
}
Re: How to detect a bridge on the water?
Posted: 20 Dec 2010 09:14
by Michiel
Alternatively, keep a list of the best spots you found and just try to build the dock at the first one. If it fails, try the next (and maybe plant a sign with the error message on the first spot). That way, you don't have to specifically handle this unfortunate case, or others you didn't think of yet.
Re: How to detect a bridge on the water?
Posted: 21 Dec 2010 09:25
by tristanb
Hey thanks both for your help.
I'll use a combination of both the lateral-search, but later I guess I'll need a robust repositioning in case there's a stray boat or something else unexpected blocking the way.
Interesting to see your library, Zuu. It looks like incredibly useful, and contains functions that I have thought about myself. I'm planning to only ever use boats, so I probably won't use it, but it'll be a great reference for working out how to do things.
Re: How to detect a bridge on the water?
Posted: 21 Dec 2010 09:28
by planetmaker
tristanb wrote:
It looks like incredibly useful, and contains functions that I have thought about myself. I'm planning to only ever use boats, so I probably won't use it, but it'll be a great reference for working out how to do things.
Even if you only use boats: what's the point of re-inventing the wheel instead of using an existing library which exists, is readily on bananas and - as you say - provides those functions you need?
Re: How to detect a bridge on the water?
Posted: 21 Dec 2010 15:08
by Lord Aro
As discussed on irc, it is very easy to implement a function that provides this (line 58 of bridge_map.h

)