private static void NavigationInfoDebug(ActionMap __instance, get_navDic getNavDic) { var navDic = getNavDic(); var infoDic = __instance.infoDic; var gateInfoDic = __instance.gateInfoDic; var calcGateDic = __instance.calcGateDic; string MapStr(int mapID) => infoDic.ContainsKey(mapID) ? $"{mapID} ({infoDic[mapID].AssetName})" : mapID.ToString(); string GateStr(int gateID) => gateInfoDic.ContainsKey(gateID) ? $"{gateID} ({gateInfoDic[gateID].Name})" : gateID.ToString(); string RouteStr(int[] route) => string.Join(", ", route.Select(GateStr).ToArray()); StringBuilder sb = new StringBuilder(); sb.AppendLine("navDic:"); foreach (var kvp in navDic) { foreach (var kvp2 in kvp.Value) { sb.AppendLine($"\tRoutes: {MapStr(kvp.Key)} to {MapStr(kvp2.Key)}"); foreach (var navigationInfo in kvp2.Value) { sb.AppendLine($"\t\t{navigationInfo.distance}: {RouteStr(navigationInfo.IDs)}"); } } } File.WriteAllText("navDic.txt", sb.ToString()); sb.Length = 0; sb.AppendLine("infoDic:"); foreach (var param in infoDic) { var info = param.Value; sb.AppendLine($"\tMap: {MapStr(param.Key)}"); sb.AppendLine($"\t\tMapName: {info.MapName}"); sb.AppendLine($"\t\tNo: {MapStr(info.No)}"); sb.AppendLine($"\t\tAssetBundleName: {info.AssetBundleName}"); sb.AppendLine($"\t\tAssetName: {info.AssetName}"); sb.AppendLine($"\t\tisGate: {info.isGate}"); sb.AppendLine($"\t\tis2D: {info.is2D}"); sb.AppendLine($"\t\tisWarning: {info.isWarning}"); sb.AppendLine($"\t\tState: {info.State}"); sb.AppendLine($"\t\tLookFor: {info.LookFor}"); sb.AppendLine($"\t\tisOutdoors: {info.isOutdoors}"); sb.AppendLine($"\t\tisFreeH: {info.isFreeH}"); sb.AppendLine($"\t\tisSpH: {info.isSpH}"); sb.AppendLine($"\t\tThumbnailBundle: {info.ThumbnailBundle}"); sb.AppendLine($"\t\tThumbnailAsset: {info.ThumbnailAsset}"); } File.WriteAllText("infoDic.txt", sb.ToString()); sb.Length = 0; sb.AppendLine("gateInfoDic:"); foreach (var gateInfo in gateInfoDic) { var info = gateInfo.Value; sb.AppendLine($"\tGate: {GateStr(gateInfo.Key)}"); sb.AppendLine($"\t\tID: {info.ID}"); sb.AppendLine($"\t\tmapNo: {MapStr(info.mapNo)}"); sb.AppendLine($"\t\tlinkID: {GateStr(info.linkID)}"); sb.AppendLine($"\t\tpos: {info.pos}"); sb.AppendLine($"\t\tang: {info.ang}"); sb.AppendLine($"\t\tName: {info.Name}"); sb.AppendLine($"\t\tplayerPos: {info.playerPos}"); sb.AppendLine($"\t\tplayerAng: {info.playerAng}"); sb.AppendLine($"\t\tplayerHitPos: {info.playerHitPos}"); sb.AppendLine($"\t\tplayerHitSize: {info.playerHitSize}"); sb.AppendLine($"\t\theroineHitPos: {info.heroineHitPos}"); sb.AppendLine($"\t\theroineHitSize: {info.heroineHitSize}"); sb.AppendLine($"\t\ticonPos: {info.iconPos}"); sb.AppendLine($"\t\ticonHitPos: {info.iconHitPos}"); sb.AppendLine($"\t\ticonHitSize: {info.iconHitSize}"); sb.AppendLine($"\t\tmoveType: {info.moveType}"); sb.AppendLine($"\t\tseType: {info.seType}"); sb.AppendLine($"\t\tcalc: {info.calc}"); foreach (var c in info.calc) { sb.AppendLine($"\t\t\t{c.Key}: {string.Join(", ", c.Value.Select(v => v.ToString()).ToArray())}"); } } File.WriteAllText("gateInfoDic.txt", sb.ToString()); sb.Length = 0; sb.AppendLine("calcGateDic:"); foreach (var calc in calcGateDic) { sb.AppendLine($"\tMap: {MapStr(calc.Key)}"); foreach (var info in calc.Value) { sb.AppendLine($"\t\tGate: {GateStr(info.ID)}"); sb.AppendLine($"\t\t\tID: {info.ID}"); sb.AppendLine($"\t\t\tmapNo: {MapStr(info.mapNo)}"); sb.AppendLine($"\t\t\tlinkID: {GateStr(info.linkID)}"); sb.AppendLine($"\t\t\tpos: {info.pos}"); sb.AppendLine($"\t\t\tang: {info.ang}"); sb.AppendLine($"\t\t\tName: {info.Name}"); sb.AppendLine($"\t\t\tplayerPos: {info.playerPos}"); sb.AppendLine($"\t\t\tplayerAng: {info.playerAng}"); sb.AppendLine($"\t\t\tplayerHitPos: {info.playerHitPos}"); sb.AppendLine($"\t\t\tplayerHitSize: {info.playerHitSize}"); sb.AppendLine($"\t\t\theroineHitPos: {info.heroineHitPos}"); sb.AppendLine($"\t\t\theroineHitSize: {info.heroineHitSize}"); sb.AppendLine($"\t\t\ticonPos: {info.iconPos}"); sb.AppendLine($"\t\t\ticonHitPos: {info.iconHitPos}"); sb.AppendLine($"\t\t\ticonHitSize: {info.iconHitSize}"); sb.AppendLine($"\t\t\tmoveType: {info.moveType}"); sb.AppendLine($"\t\t\tseType: {info.seType}"); sb.AppendLine($"\t\t\tcalc: {info.calc}"); foreach (var c in info.calc) { sb.AppendLine($"\t\t\t\t{c.Key}: {string.Join(", ", c.Value.Select(v => v.ToString()).ToArray())}"); } } } File.WriteAllText("calcGateDic.txt", sb.ToString()); }
private static void LoadNavigationInfoPostfix(ActionMap __instance, get_navDic getNavDic) { Logger.LogInfo("Injecting navigation information."); var navDic = getNavDic(); foreach (var kvp in __instance.calcGateDic) { foreach (var gate in kvp.Value) { foreach (var gate2 in kvp.Value) { if (gate == gate2) { continue; } if (!gate.calc.ContainsKey(gate2.ID)) { gate.calc[gate2.ID] = new[] { gate.playerPos, gate2.playerPos }; } } } } Graph aStarGraph = new Graph(); var AMap = new Dictionary <int, Node>(); var AGate = new Dictionary <int, Node>(); foreach (var info in __instance.gateInfoDic) { int startMap = __instance.gateInfoDic[info.Value.linkID].mapNo; int endMap = info.Value.mapNo; int gate = info.Value.ID; int linkGate = info.Value.linkID; if (!AGate.ContainsKey(gate)) { aStarGraph.AddNode(AGate[gate] = new Node(gate, Node.NodeType.Gate)); } if (!AGate.ContainsKey(linkGate)) { aStarGraph.AddNode(AGate[linkGate] = new Node(linkGate, Node.NodeType.Gate)); } if (!AMap.ContainsKey(startMap)) { aStarGraph.AddNode(AMap[startMap] = new Node(startMap, Node.NodeType.Map)); } if (!AMap.ContainsKey(endMap)) { aStarGraph.AddNode(AMap[endMap] = new Node(endMap, Node.NodeType.Map)); } aStarGraph.AddArc(new Arc(AMap[startMap], AGate[gate], 0)); aStarGraph.AddArc(new Arc(AGate[gate], AMap[endMap], 0)); foreach (var gate2 in __instance.calcGateDic[endMap]) { if (info.Value == gate2 || __instance.gateInfoDic[linkGate] == gate2) { continue; } if (!AGate.ContainsKey(gate2.ID)) { aStarGraph.AddNode(AGate[gate2.ID] = new Node(gate2.ID, Node.NodeType.Gate)); } aStarGraph.AddArc(new Arc(AGate[gate], AGate[gate2.ID], GetDistanceBetweenGates(__instance.gateInfoDic[linkGate], gate2))); } foreach (var gate2 in __instance.calcGateDic[startMap]) { if (info.Value == gate2) { continue; } if (!AGate.ContainsKey(gate2.ID)) { aStarGraph.AddNode(AGate[gate2.ID] = new Node(gate2.ID, Node.NodeType.Gate)); } aStarGraph.AddArc(new Arc(AGate[gate], AGate[gate2.ID], GetDistanceBetweenGates(info.Value, gate2))); } } foreach (var startMap in __instance.infoDic) { if (!AMap.ContainsKey(startMap.Key)) { Logger.LogInfo($"Skipping inaccessible map {startMap.Value.AssetName}."); continue; } foreach (var endMap in __instance.infoDic) { if (!AMap.ContainsKey(endMap.Key) || startMap.Key == endMap.Key) { continue; } if (!navDic.ContainsKey(startMap.Key)) { navDic[startMap.Key] = new Dictionary <int, List <ActionMap.NavigationInfo> >(); } if (navDic[startMap.Key].ContainsKey(endMap.Key)) { continue; } AStar aStar = new AStar(aStarGraph); foreach (Arc arc in aStarGraph.Arcs) { if (arc.EndNode.Type == Node.NodeType.Map) { arc.Passable = arc.EndNode.ID == endMap.Key; } } aStar.SearchPath(AMap[startMap.Key], AMap[endMap.Key]); if (aStar.PathFound) { List <int> gates = new List <int>(); List <string> nodesDebug = new List <string>(aStar.PathByNodes.Length); float distance = 0; foreach (var node in aStar.PathByNodes) { nodesDebug.Add(PrintNode(node, __instance)); if (node.Type == Node.NodeType.Gate) { gates.Add(node.ID); } } foreach (var arc in aStar.PathByArcs) { distance += arc.Distance; } Logger.LogInfo($"Added path from {startMap.Value.AssetName} to {endMap.Value.AssetName}:"); Logger.LogInfo($" Nodes: {string.Join(", ", nodesDebug.ToArray())}"); navDic[startMap.Key][endMap.Key] = new List <ActionMap.NavigationInfo> { new ActionMap.NavigationInfo { distance = distance, IDs = gates.ToArray(), } }; } else { Logger.LogWarning($"No path from {startMap.Value.AssetName} to {endMap.Value.AssetName}."); } } } Logger.LogInfo("Finished injecting navigation information."); }