diff --git a/src/Loader.cs b/src/Loader.cs index dc49ae6..80e6b63 100644 --- a/src/Loader.cs +++ b/src/Loader.cs @@ -273,7 +273,7 @@ public static void LoadLocalizationFile(Mod mod, Mod.File file) { Loc.BuildAndLoadLocalization(JsonSerializer .Deserialize>>(file.bytes)!); - Plugin.logger.LogInfo($"Registried localization from {mod.id} mod"); + Plugin.logger.LogInfo($"Registered localization from {mod.id} mod"); } catch (Exception e) { @@ -451,8 +451,24 @@ public static void LoadGameLogicDataPatch(Mod mod, JObject gld, JObject patch) Main.embarkNames[unitId] = embarkUnitId; } } + foreach (JToken jtoken in patch.SelectTokens("$.improvementData.*").ToArray()) + { + JObject token = jtoken.Cast(); + if (token["attractsResource"] != null) + { + string improvementId = Util.GetJTokenName(token); + string attractsId = token["attractsResource"].ToString(); + Main.attractsResourceNames[improvementId] = attractsId; + } + if (token["attractsToTerrain"] != null) + { + string improvementId = Util.GetJTokenName(token); + string attractsId = token["attractsToTerrain"].ToString(); + Main.attractsTerrainNames[improvementId] = attractsId; + } + } gld.Merge(patch, new() { MergeArrayHandling = MergeArrayHandling.Replace, MergeNullValueHandling = MergeNullValueHandling.Merge }); - Plugin.logger.LogInfo($"Registried patch from {mod.id} mod"); + Plugin.logger.LogInfo($"Registered patch from {mod.id} mod"); } catch (Exception e) { diff --git a/src/Managers/Main.cs b/src/Managers/Main.cs index 761d17a..cd01ced 100644 --- a/src/Managers/Main.cs +++ b/src/Managers/Main.cs @@ -19,7 +19,10 @@ public static class Main internal static Dictionary embarkNames = new(); internal static Dictionary embarkOverrides = new(); internal static bool currentlyEmbarking = false; - + internal static Dictionary attractsResourceNames = new(); + internal static Dictionary attractsTerrainNames = new(); + internal static Dictionary attractsResourceOverrides = new(); + internal static Dictionary attractsTerrainOverrides = new(); [HarmonyPrefix] [HarmonyPatch(typeof(GameLogicData), nameof(GameLogicData.AddGameLogicPlaceholders))] @@ -47,6 +50,34 @@ private static void GameLogicData_Parse(GameLogicData __instance, JObject rootOb Plugin.logger.LogError($"Embark unit type for {entry.Key} is not valid: {entry.Value}"); } } + foreach (KeyValuePair entry in attractsResourceNames) + { + try + { + ImprovementData.Type improvement = EnumCache.GetType(entry.Key); + ResourceData.Type resource = EnumCache.GetType(entry.Value); + attractsResourceOverrides[improvement] = resource; + Plugin.logger.LogInfo($"Improvement {entry.Key} now attracts {entry.Value}"); + } + catch + { + Plugin.logger.LogError($"Improvement {entry.Key} resource type is not valid: {entry.Value}"); + } + } + foreach (KeyValuePair entry in attractsTerrainNames) + { + try + { + ImprovementData.Type improvement = EnumCache.GetType(entry.Key); + Polytopia.Data.TerrainData.Type terrain = EnumCache.GetType(entry.Value); + attractsTerrainOverrides[improvement] = terrain; + Plugin.logger.LogInfo($"Improvement {entry.Key} now attracts on {entry.Value}"); + } + catch + { + Plugin.logger.LogError($"Improvement {entry.Key} terrain type is not valid: {entry.Value}"); + } + } fullyInitialized = true; } } @@ -211,6 +242,52 @@ private static bool ActionUtils_TrainUnit(ref UnitState __result, GameState game return true; } + [HarmonyPostfix] + [HarmonyPatch(typeof(StartTurnAction), nameof(StartTurnAction.Execute))] + private static void StartTurnAction_Execute(StartTurnAction __instance, GameState state) + { + for (int i = state.ActionStack.Count - 1; i >= 0; i--) + { + if (state.ActionStack[i].GetActionType() == ActionType.CreateResource) + { + state.ActionStack.RemoveAt(i); + } + } + for (int i = 0; i < state.Map.Tiles.Length; i++) + { + TileData tileData = state.Map.Tiles[i]; + if (tileData.owner == __instance.PlayerId && tileData.improvement != null && state.CurrentTurn > 0U) + { + ImprovementData improvementData; + state.GameLogicData.TryGetData(tileData.improvement.type, out improvementData); + if (improvementData != null) + { + if (improvementData.HasAbility(ImprovementAbility.Type.Attract) && tileData.improvement.GetAge(state) % improvementData.growthRate == 0) + { + ResourceData.Type resourceType = ResourceData.Type.Game; + if (attractsResourceOverrides.TryGetValue(tileData.improvement.type, out ResourceData.Type newType)) + { + resourceType = newType; + } + Polytopia.Data.TerrainData.Type targetTerrain = Polytopia.Data.TerrainData.Type.Forest; + if (attractsTerrainOverrides.TryGetValue(tileData.improvement.type, out Polytopia.Data.TerrainData.Type newTerrain)) + { + targetTerrain = newTerrain; + } + foreach (TileData tileData2 in state.Map.GetArea(tileData.coordinates, 1, true, false)) + { + if (tileData2.owner == __instance.PlayerId && tileData2.improvement == null && tileData2.resource == null && tileData2.terrain == targetTerrain) + { + state.ActionStack.Add(new CreateResourceAction(__instance.PlayerId, resourceType, tileData2.coordinates, CreateResourceAction.CreateReason.Attract)); + break; + } + } + } + } + } + } + } + internal static void Init() { stopwatch.Start();