Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Algorithm for calculating "distance"
- public static class DistanceCalculator
- {
- // We remember the calculations for all static maps, since they *shouldnt* change during gameplay
- private static Dictionary<string, double> _Cache = new Dictionary<string, double>();
- // The extra "distance" added for every floor down into the skull cave (Always 121 or more floors)
- private const double SkullDepthPenalty = 0.2;
- // The extra "distance" added for every floor down into mines (Never more then 120 floors)
- private const double MineDepthPenalty = 0.1;
- // The extra "distance" added for every warp that has to be used
- private const double DistancePenalty = 1;
- // The name of the "leyline" map property to pay attention to
- private const string LeylineProperty = "AlchemyLeyline";
- private class Entry
- {
- public GameLocation loc;
- public double dist;
- public Entry(GameLocation loc, double dist)
- {
- this.loc = loc;
- this.dist = dist;
- }
- }
- public static void Explore()
- {
- _Cache.Clear();
- foreach ( var loc in Game1.locations )
- {
- if (loc.map.Properties.ContainsKey(LeylineProperty))
- ExploreFrom(loc);
- }
- }
- private static void ExploreFrom( GameLocation start )
- {
- Dictionary<string, double> did = new Dictionary<string, double>();
- Queue<Entry> q = new Queue<Entry>();
- q.Enqueue(new Entry(start, start.map.Properties[LeylineProperty]));
- did.Add(start.name, start.map.Properties[LeylineProperty]);
- while ( q.Count > 0 )
- {
- var entry = q.Dequeue();
- foreach ( var warp in entry.loc.warps )
- {
- if ( !did.ContainsKey( warp.TargetName ) || entry.dist + DistancePenalty < did[ warp.TargetName ] )
- {
- did[warp.TargetName] = entry.dist + DistancePenalty;
- q.Enqueue(new Entry(Game1.getLocationFromName(warp.TargetName), entry.dist + DistancePenalty));
- }
- }
- for (int x = 0; x < entry.loc.map.Layers[0].LayerSize.Width; x++)
- {
- for (int y = 0; y < entry.loc.map.Layers[0].LayerSize.Height; y++)
- {
- string prop = entry.loc.doesTileHaveProperty(x, y, "Action", "Buildings");
- if (prop == null)
- continue;
- switch (prop)
- {
- case "WarpCommunityCenter":
- case "WarpGreenhouse":
- string targetName = prop.Substring(4);
- if (!did.ContainsKey(targetName) || did[targetName] < entry.dist + DistancePenalty)
- {
- did[targetName] = entry.dist + DistancePenalty;
- q.Enqueue(new Entry(Game1.getLocationFromName(targetName), entry.dist + DistancePenalty));
- }
- break;
- case "EnterSewer":
- targetName = "Sewer";
- if (!did.ContainsKey(targetName) || did[targetName] < entry.dist + DistancePenalty)
- {
- did[targetName] = entry.dist + DistancePenalty;
- q.Enqueue(new Entry(Game1.getLocationFromName(targetName), entry.dist + DistancePenalty));
- }
- break;
- case "WizardHatch":
- targetName = "WizardHouseBasement";
- if (!did.ContainsKey(targetName) || did[targetName] < entry.dist + DistancePenalty)
- {
- did[targetName] = entry.dist + DistancePenalty;
- q.Enqueue(new Entry(Game1.getLocationFromName(targetName), entry.dist + DistancePenalty));
- }
- break;
- default:
- var props = prop.Split(' ');
- if ((props[0].Equals("Warp") || props[0].Equals("LockedDoorWarp") || props[0].Equals("WarpMensLocker") || props[0].Equals("WarpWomensLocker")) && Game1.getLocationFromName(props[3]) != null)
- {
- Log.trace(prop);
- if (!did.ContainsKey(props[3]) || entry.dist + DistancePenalty < did[props[3]])
- {
- did[props[3]] = entry.dist + DistancePenalty;
- q.Enqueue(new Entry(Game1.getLocationFromName(props[3]), entry.dist + DistancePenalty));
- }
- }
- break;
- }
- }
- }
- }
- foreach ( var entry in did )
- {
- if (!_Cache.ContainsKey(entry.Key) || _Cache[entry.Key] > entry.Value)
- _Cache[entry.Key] = entry.Value;
- }
- }
- public static double GetPathDistance( GameLocation loc )
- {
- if (_Cache.Count == 0)
- Explore();
- /*
- Log.trace(_Cache.Count + " " + Game1.locations.Count);
- foreach ( var val in _Cache )
- {
- Log.trace(val.Key + " = " + val.Value);
- }*/
- var dist = double.MaxValue;
- if (_Cache.ContainsKey(loc.name))
- dist = _Cache[loc.name];
- if ( loc is StardewValley.Locations.MineShaft shaft )
- {
- if (shaft.mineLevel > 120) // SkullCave
- dist += shaft.mineLevel * SkullDepthPenalty;
- else // Mines
- dist += shaft.mineLevel * MineDepthPenalty;
- }
- return dist;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement