avoid NPC pathfinding rebuild if reachable locations didn't change
This commit is contained in:
parent
fdb74df8a4
commit
8713914a1a
|
@ -1,11 +1,16 @@
|
|||
← [README](README.md)
|
||||
|
||||
# Release notes
|
||||
## Upcoming release
|
||||
* For mod authors:
|
||||
* Fixed map edits which change warps sometimes rebuilding the NPC pathfinding cache unnecessarily, which could cause a noticeable delay for players.
|
||||
|
||||
## 3.14.7
|
||||
Released 01 June 2022 for Stardew Valley 1.5.6 or later.
|
||||
|
||||
* For players:
|
||||
* Optimized reflection cache to reduce frame skips for some players.
|
||||
|
||||
* For mod authors:
|
||||
* Removed `runtimeconfig.json` setting which impacted hot reload support.
|
||||
|
||||
|
|
|
@ -465,7 +465,7 @@ namespace StardewModdingAPI.Framework
|
|||
assets: invalidatedAssets.ToDictionary(p => p.Key, p => p.Value),
|
||||
ignoreWorld: Context.IsWorldFullyUnloaded,
|
||||
out IDictionary<IAssetName, bool> propagated,
|
||||
out bool updatedNpcWarps
|
||||
out bool updatedWarpRoutes
|
||||
);
|
||||
|
||||
// log summary
|
||||
|
@ -481,8 +481,8 @@ namespace StardewModdingAPI.Framework
|
|||
? $"Propagated {propagatedKeys.Length} core assets ({FormatKeyList(propagatedKeys)})."
|
||||
: "Propagated 0 core assets."
|
||||
);
|
||||
if (updatedNpcWarps)
|
||||
report.AppendLine("Updated NPC pathfinding cache.");
|
||||
if (updatedWarpRoutes)
|
||||
report.AppendLine("Updated NPC warp route cache.");
|
||||
}
|
||||
this.Monitor.Log(report.ToString().TrimEnd());
|
||||
}
|
||||
|
|
|
@ -85,8 +85,8 @@ namespace StardewModdingAPI.Metadata
|
|||
/// <param name="assets">The asset keys and types to reload.</param>
|
||||
/// <param name="ignoreWorld">Whether the in-game world is fully unloaded (e.g. on the title screen), so there's no need to propagate changes into the world.</param>
|
||||
/// <param name="propagatedAssets">A lookup of asset names to whether they've been propagated.</param>
|
||||
/// <param name="updatedNpcWarps">Whether the NPC pathfinding cache was reloaded.</param>
|
||||
public void Propagate(IDictionary<IAssetName, Type> assets, bool ignoreWorld, out IDictionary<IAssetName, bool> propagatedAssets, out bool updatedNpcWarps)
|
||||
/// <param name="changedWarpRoutes">Whether the NPC pathfinding warp route cache was reloaded.</param>
|
||||
public void Propagate(IDictionary<IAssetName, Type> assets, bool ignoreWorld, out IDictionary<IAssetName, bool> propagatedAssets, out bool changedWarpRoutes)
|
||||
{
|
||||
// get base name lookup
|
||||
propagatedAssets = assets
|
||||
|
@ -107,7 +107,7 @@ namespace StardewModdingAPI.Metadata
|
|||
});
|
||||
|
||||
// reload assets
|
||||
updatedNpcWarps = false;
|
||||
changedWarpRoutes = false;
|
||||
foreach (var bucket in buckets)
|
||||
{
|
||||
switch (bucket.Key)
|
||||
|
@ -126,10 +126,10 @@ namespace StardewModdingAPI.Metadata
|
|||
foreach (var entry in bucket)
|
||||
{
|
||||
bool changed = false;
|
||||
bool curChangedMapWarps = false;
|
||||
bool curChangedMapRoutes = false;
|
||||
try
|
||||
{
|
||||
changed = this.PropagateOther(entry.Key, entry.Value, ignoreWorld, out curChangedMapWarps);
|
||||
changed = this.PropagateOther(entry.Key, entry.Value, ignoreWorld, out curChangedMapRoutes);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -137,14 +137,14 @@ namespace StardewModdingAPI.Metadata
|
|||
}
|
||||
|
||||
propagatedAssets[entry.Key] = changed;
|
||||
updatedNpcWarps = updatedNpcWarps || curChangedMapWarps;
|
||||
changedWarpRoutes = changedWarpRoutes || curChangedMapRoutes;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// reload NPC pathfinding cache if any map changed
|
||||
if (updatedNpcWarps)
|
||||
// reload NPC pathfinding cache if any map routes changed
|
||||
if (changedWarpRoutes)
|
||||
NPC.populateRoutesFromLocationToLocationList();
|
||||
}
|
||||
|
||||
|
@ -156,14 +156,14 @@ namespace StardewModdingAPI.Metadata
|
|||
/// <param name="assetName">The asset name to reload.</param>
|
||||
/// <param name="type">The asset type to reload.</param>
|
||||
/// <param name="ignoreWorld">Whether the in-game world is fully unloaded (e.g. on the title screen), so there's no need to propagate changes into the world.</param>
|
||||
/// <param name="changedWarps">Whether any map warps were changed as part of this propagation.</param>
|
||||
/// <param name="changedWarpRoutes">Whether the locations reachable by warps from this location changed as part of this propagation.</param>
|
||||
/// <returns>Returns whether an asset was loaded. The return value may be true or false, or a non-null value for true.</returns>
|
||||
[SuppressMessage("ReSharper", "StringLiteralTypo", Justification = "These deliberately match the asset names.")]
|
||||
private bool PropagateOther(IAssetName assetName, Type type, bool ignoreWorld, out bool changedWarps)
|
||||
private bool PropagateOther(IAssetName assetName, Type type, bool ignoreWorld, out bool changedWarpRoutes)
|
||||
{
|
||||
var content = this.MainContentManager;
|
||||
string key = assetName.BaseName;
|
||||
changedWarps = false;
|
||||
changedWarpRoutes = false;
|
||||
|
||||
/****
|
||||
** Special case: current map tilesheet
|
||||
|
@ -197,7 +197,7 @@ namespace StardewModdingAPI.Metadata
|
|||
static ISet<string> GetWarpSet(GameLocation location)
|
||||
{
|
||||
return new HashSet<string>(
|
||||
location.warps.Select(p => $"{p.X} {p.Y} {p.TargetName} {p.TargetX} {p.TargetY}")
|
||||
location.warps.Select(p => p.TargetName)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -205,7 +205,7 @@ namespace StardewModdingAPI.Metadata
|
|||
this.UpdateMap(info);
|
||||
var newWarps = GetWarpSet(location);
|
||||
|
||||
changedWarps = changedWarps || oldWarps.Count != newWarps.Count || oldWarps.Any(p => !newWarps.Contains(p));
|
||||
changedWarpRoutes = changedWarpRoutes || oldWarps.Count != newWarps.Count || oldWarps.Any(p => !newWarps.Contains(p));
|
||||
anyChanged = true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue