Skip to content

Commit

Permalink
Merge pull request #605 from FFXIV-CombatReborn/mergeWIP
Browse files Browse the repository at this point in the history
fixed obstacle maps and traps
  • Loading branch information
CarnifexOptimus authored Feb 14, 2025
2 parents 15041ff + 961048f commit d910b84
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 31 deletions.
9 changes: 8 additions & 1 deletion BossMod/BossModReborn.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,16 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<EmbeddedResource Include="Modules\Global\DeepDungeon\*.json" />
<EmbeddedResource Include="Modules\Global\DeepDungeon\*.sqlite3" />
</ItemGroup>

<ItemGroup Condition="'$(Configuration)' == 'Release'">
<ItemGroup>
<EmbeddedResource Include="Pathfinding\ObstacleMaps\*" />
</ItemGroup>

<ItemGroup>
<Content Include="System.Data.SQLite.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
82 changes: 55 additions & 27 deletions BossMod/Modules/Global/DeepDungeon/AutoClear.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ protected AutoClear(WorldState ws, int LevelCap) : base(ws)
})
);

_trapsCurrentZone = PalacePalInterop.GetTrapLocationsForZone(ws.CurrentZone);
_trapsCurrentZone = DDTrapsData.GetTrapLocationsForZone(ws.CurrentZone);

LoadedFloors = JsonSerializer.Deserialize<Dictionary<string, Floor<Wall>>>(GetEmbeddedResource("Walls.json"))!;
ProblematicTrapLocations = JsonSerializer.Deserialize<List<WPos>>(GetEmbeddedResource("BadTraps.json"))!;
Expand All @@ -142,6 +142,7 @@ protected override void Dispose(bool disposing)
_subscriptions.Dispose();
_obstacles.Dispose();
base.Dispose(disposing);
DDTrapsData.CleanupTemporaryDatabase();
}

protected virtual void OnCastStarted(Actor actor) { }
Expand Down Expand Up @@ -830,45 +831,72 @@ private static bool IsBlocked(Bitmap map, Vector2 point, Vector2 origin, float m
return false;
}

private Stream GetEmbeddedResource(string name) => Assembly.GetExecutingAssembly().GetManifestResourceStream($"BossMod.Modules.Global.DeepDungeon.{name}") ?? throw new InvalidDataException($"Missing embedded resource {name}");
private Stream GetEmbeddedResource(string name) => Assembly.GetExecutingAssembly().GetManifestResourceStream($"BossModReborn.Modules.Global.DeepDungeon.{name}") ?? throw new InvalidDataException($"Missing embedded resource {name}");
}

static class PalacePalInterop
static class DDTrapsData
{
// TODO make an IPC for this? wouldn't work in uidev
private static readonly string PalacePalDbFile = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "XIVLauncher", "pluginConfigs", "PalacePal", "palace-pal.data.sqlite3");
private const string EmbeddedDbResourceName = "BossModReborn.Modules.Global.DeepDungeon.DDTrapsData.sqlite3";
private static string? _tempDbFilePath;

public static List<WPos> GetTrapLocationsForZone(uint zone)
private static string GetTempDbFilePath()
{
List<WPos> locations = [];
if (_tempDbFilePath != null)
{
return _tempDbFilePath;
}

var tempFileName = Path.GetTempFileName() + ".sqlite3";
_tempDbFilePath = tempFileName;

try
using (var resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(EmbeddedDbResourceName))
{
using (var connection = new SQLiteConnection($"Data Source={PalacePalDbFile}"))
if (resourceStream == null)
{
connection.Open();
throw new FileNotFoundException($"Embedded resource '{EmbeddedDbResourceName}' not found.");
}

var command = connection.CreateCommand();
command.CommandText = @"
select X,Z from Locations where Type = 1 and TerritoryType = $tt
";
command.Parameters.AddWithValue("$tt", zone);
using var fileStream = new FileStream(tempFileName, FileMode.Create, FileAccess.Write);
resourceStream.CopyTo(fileStream);
}
return tempFileName;
}

using var reader = command.ExecuteReader();
while (reader.Read())
{
var x = reader.GetFloat(0);
var z = reader.GetFloat(1);
locations.Add(new(x, z));
}
}
public static List<WPos> GetTrapLocationsForZone(uint zone)
{
List<WPos> locations = [];
var tempDbPath = GetTempDbFilePath();
using (var connection = new SQLiteConnection($"Data Source={tempDbPath};Version=3;Read Only=True;"))
{
connection.Open();

return locations;
var command = connection.CreateCommand();
command.CommandText = @"select X,Z from Locations where Type = 1 and TerritoryType = $tt";
command.Parameters.AddWithValue("$tt", zone);

using var reader = command.ExecuteReader();
while (reader.Read())
{
var x = reader.GetFloat(0);
var z = reader.GetFloat(1);
locations.Add(new(x, z));
}
}
catch (SQLiteException e)
return locations;
}

public static void CleanupTemporaryDatabase()
{
if (_tempDbFilePath != null)
{
Service.Log($"unable to load traps for zone ${zone}: ${e}");
return [];
var baseTempPath = Path.GetFileNameWithoutExtension(_tempDbFilePath);
var tempDirPath = Path.GetDirectoryName(_tempDbFilePath) ?? "";

string[] extensions = [".sqlite3", ".sqlite3-shm", ".sqlite3-wal", ""];

for (var i = 0; i < 4; ++i)
File.Delete(Path.Combine(tempDirPath, baseTempPath + extensions[i]));
}
_tempDbFilePath = null;
}
}
2 changes: 1 addition & 1 deletion BossMod/Modules/Global/DeepDungeon/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public enum ClearBehavior
public bool Enable = true;
[PropertyDisplay("Enable minimap")]
public bool EnableMinimap = true;
[PropertyDisplay("Try to avoid traps", tooltip: "Avoid known trap locations sourced from PalacePal data. (Traps revealed by a Pomander of Sight will always be avoided regardless of this setting.)")]
[PropertyDisplay("Try to avoid traps", tooltip: "Avoid known trap locations sourced from PalacePal data. Does not need PalacePal installed since data is embedded into BMR. (Traps revealed by a Pomander of Sight will always be avoided regardless of this setting.)")]
public bool TrapHints = true;
[PropertyDisplay("Automatically navigate to Cairn of Passage")]
public bool AutoPassage = true;
Expand Down
Binary file not shown.
4 changes: 2 additions & 2 deletions BossMod/Pathfinding/ObstacleMapManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public sealed class ObstacleMapConfig : ConfigNode
[PropertyDisplay("Developer mode: load obstacle maps from source rather than from plugin distribution")]
public bool LoadFromSource;

[PropertyDisplay("Developer mode: source path", tooltip: "Should be <repo root>/BossMod/Pathfinding/ObstacleMaps/maplist.json")]
[PropertyDisplay("Developer mode: source path", tooltip: "Should be <repo root>/BossModReborn/Pathfinding/ObstacleMaps/maplist.json")]
public string SourcePath = "";
}

Expand Down Expand Up @@ -92,5 +92,5 @@ private void LoadMaps(ushort zoneId, ushort cfcId)
}
}

private Stream GetEmbeddedResource(string name) => Assembly.GetExecutingAssembly().GetManifestResourceStream($"BossMod.Pathfinding.ObstacleMaps.{name}") ?? throw new InvalidDataException($"Missing embedded resource {name}");
private Stream GetEmbeddedResource(string name) => Assembly.GetExecutingAssembly().GetManifestResourceStream($"BossModReborn.Pathfinding.ObstacleMaps.{name}") ?? throw new InvalidDataException($"Missing embedded resource {name}");
}
Binary file added BossMod/System.Data.SQLite.dll
Binary file not shown.

0 comments on commit d910b84

Please sign in to comment.