Bug #3862

an application to AIRail.IsRailTilesConnect

Added by krinn over 7 years ago.

Status:NewStart date:2012-03-23
Priority:NormalDue date:
Assignee:-% Done:


Target version:-


Here's a function i use to validate a vehicle can reach a point in the map, i use it to not create another route (you can also do the same with the pathfinder, but pathfinder will answer could your vehicle find its way to point X using the best possible path), this one just answer could it reach X using any path (non optimized or straigh to target). This highly reduce number of road build
- I also use it to detect damage on my road (as i use others player roads, a dead player will have its bridge removed, or i use town roads and a player destroy it, or my AI destroy a road to build a station, and another road vehicle was using it and could be lost.

Anyway, multi usage for myself, but maybe someone else would like it (and maybe we get a bit less road everywhere too)
Not really optimized, i check if i'm going to the wrong direction and giveup if going too far away, but my first choice at intersection isn't going to the best direction (the one closest to the target), but to a fixed one (i think i goes left, up, right, down... i'm not sure but it's the order in directions=[]
It should be far better to choose going to the closest direction to the target, something i should have done, but as it work, i'm doing something else :)

It's not in SuperLib format,the transition should be easy, i put //* for needed change

function cBuilder::RoadRunner(source, target, road_type, walkedtiles=null, origin=null)
// Follow all directions to walk through the path starting at source, ending at target
// check if the path is valid by using road_type (railtype, road)
// return true if we reach target by running the path
local max_wrong_direction=15; // we will gave up if we're going that number of tiles in the wrong direction
if (origin == null)    origin=AITile.GetDistanceManhattanToTile(source, target);
if (walkedtiles == null)    { walkedtiles=AIList(); }
local valid=false;
local direction=null;
local found=(source == target);
local directions=[AIMap.GetTileIndex(0, 1), AIMap.GetTileIndex(1, 0), AIMap.GetTileIndex(-1, 0), AIMap.GetTileIndex(0, -1)];
foreach (voisin in directions)
    if (AIBridge.IsBridgeTile(source) || AITunnel.IsTunnelTile(source))
        local endat=null;
        endat=AIBridge.IsBridgeTile(source) ? AIBridge.GetOtherBridgeEnd(source) : AITunnel.GetOtherTunnelEnd(source);
        // i will jump at bridge/tunnel exit, check tiles around it to see if we are connect to someone (guessTile)
        // if we are connect to someone, i reset "source" to be "someone" and continue
        local guessTile=null;    
        foreach (where in directions)
            if (road_type == AIVehicle.VT_ROAD)
                if (AIRoad.AreRoadTilesConnected(endat, endat+where))    { guessTile=endat+where; }
            if (road_type == AIVehicle.VT_RAIL)
                if (cBuilder.AreRailTilesConnected(endat, endat+where))    { guessTile=endat+where; } // *
        if (guessTile != null)
    if (road_type==AIVehicle.VT_ROAD)    valid=AIRoad.AreRoadTilesConnected(source, direction);
    if (road_type==AIVehicle.VT_RAIL)    valid=cBuilder.AreRailTilesConnected(source, direction); // *
    local currdistance=AITile.GetDistanceManhattanToTile(direction, target);
    if (currdistance > origin+max_wrong_direction)    { valid=false; }
    if (walkedtiles.HasItem(direction))    { valid=false; } 
    if (valid)    walkedtiles.AddItem(direction,0);
//    if (valid && INSTANCE.debug)    PutSign(direction,"*"); // * i have comment it, but leaving it here for an hint to see what is going on, you'll see * on the path taken, this speak better
    if (!found && valid)    found=cBuilder.RoadRunner(direction, target, road_type, walkedtiles, origin);
    if (found) return found;
return found;

Also available in: Atom PDF