public List<pos> GetPath(int r,int c,int max_distance,bool smart_pathing_near_difficult_terrain,bool deterministic_results,UnknownTilePathingPreference unknown_tile_pref) { pos goal = new pos(r,c); U.BooleanPositionDelegate is_blocked = x=>{ if(x.Equals(goal)){ return false; } if(!M.tile[x].seen){ if(unknown_tile_pref == UnknownTilePathingPreference.UnknownTilesAreOpen && x.BoundsCheck(M.tile,false)){ return false; } if(unknown_tile_pref == UnknownTilePathingPreference.UnknownTilesAreClosed){ return true; } } if(max_distance != -1 && DistanceFrom(x) > max_distance){ return true; } if(M.tile[x].Is(TileType.CHASM,TileType.FIRE_RIFT)){ //chasm is currently unused return true; } if(M.tile[x].passable || M.tile[x].Is(TileType.RUBBLE) || (HasAttr(AttrType.HUMANOID_INTELLIGENCE) && M.tile[x].Is(TileType.DOOR_C))){ return false; } if(this == player && M.tile[x].type == TileType.STONE_SLAB){ return false; } return true; }; List<pos> threatened_positions = new List<pos>(); if(this == player){ foreach(Actor a in tiebreakers){ //testing this as a replacement for AllActors() if(a != null && a.HasAttr(AttrType.IMMOBILE) && CanSee(a)){ foreach(pos neighbor in a.PositionsWithinDistance(1)){ threatened_positions.Add(neighbor); } } } foreach(Tile t in TilesAtDistance(1)){ if(GetDangerRating(t) > 0){ threatened_positions.Add(t.p); } } } U.IntegerPositionDelegate get_cost = x => GetCost(x,smart_pathing_near_difficult_terrain,threatened_positions,unknown_tile_pref); List<pos> new_path = M.tile.GetAStarPath(p,goal,is_blocked,get_cost,10,deterministic_results); if(new_path != null){ return new_path; } else{ return new List<pos>(); } }
public int GetCost(pos x,bool smart_pathing_near_difficult_terrain,List<pos> threatened_positions,UnknownTilePathingPreference unknown_tile_pref) { if(smart_pathing_near_difficult_terrain && threatened_positions.Contains(x)){ return 20000; //todo: hope this doesn't break anything. } if(unknown_tile_pref == UnknownTilePathingPreference.UnknownTilesAreOpen && !M.tile[x].seen){ return 20; } if(HasAttr(AttrType.HUMANOID_INTELLIGENCE) && M.tile[x].Is(TileType.DOOR_C)){ return 20; } if(M.tile[x].Is(TileType.RUBBLE) && !HasAttr(AttrType.SMALL)){ if(this == player){ return 2000; //made more expensive for the player because it exhausts } else{ return 20; } } if(M.tile[x].Is(TileType.STONE_SLAB)){ return 20000; } if(smart_pathing_near_difficult_terrain){ bool known_trap = M.tile[x].IsKnownTrap() || (M.tile[x].IsTrap() && this != player); bool flying = HasAttr(AttrType.FLYING) && !HasAttr(AttrType.DESCENDING); bool safe_trap = (this == player && M.tile[x].name.Contains("safe")); if(known_trap){ if(flying || safe_trap){ //this'd be better if I could cheaply consider remaining flight duration return 30; } else{ return 20000; } } if(M.tile[x].Is(FeatureType.WEB) && !HasAttr(AttrType.BRUTISH_STRENGTH,AttrType.OIL_COVERED,AttrType.SLIMED)){ if(this == player){ return 5000; } else{ return 100; } } if(M.tile[x].Is(TileType.POPPY_FIELD) && !HasAttr(AttrType.NONLIVING,AttrType.MENTAL_IMMUNITY)){ //return M.poppy_distance_map[x] * 10; //todo: testing this if(M.poppy_distance_map[x] == 1){ return 19; } else{ if(M.poppy_distance_map[x].IsValidDijkstraValue()){ return 200; } } } bool can_slip = M.tile[x].IsSlippery() && (magic_trinkets == null || !magic_trinkets.Contains(MagicTrinketType.BOOTS_OF_GRIPPING)); if(can_slip || M.tile[x].Is(TileType.GRAVE_DIRT)){ return 15; } if(this == player){ if(M.tile[x].Is(TileType.TOMBSTONE)){ if(M.tile[x].color == Color.White){ return 20000; } else{ return 11; } } } } return 10; }