@@ -19,7 +19,10 @@ public static class Main
1919 internal static Dictionary < string , string > embarkNames = new ( ) ;
2020 internal static Dictionary < UnitData . Type , UnitData . Type > embarkOverrides = new ( ) ;
2121 internal static bool currentlyEmbarking = false ;
22-
22+ internal static Dictionary < string , string > attractsResourceNames = new ( ) ;
23+ internal static Dictionary < string , string > attractsTerrainNames = new ( ) ;
24+ internal static Dictionary < ImprovementData . Type , ResourceData . Type > attractsResourceOverrides = new ( ) ;
25+ internal static Dictionary < ImprovementData . Type , Polytopia . Data . TerrainData . Type > attractsTerrainOverrides = new ( ) ;
2326
2427 [ HarmonyPrefix ]
2528 [ HarmonyPatch ( typeof ( GameLogicData ) , nameof ( GameLogicData . AddGameLogicPlaceholders ) ) ]
@@ -47,6 +50,34 @@ private static void GameLogicData_Parse(GameLogicData __instance, JObject rootOb
4750 Plugin . logger . LogError ( $ "Embark unit type for { entry . Key } is not valid: { entry . Value } ") ;
4851 }
4952 }
53+ foreach ( KeyValuePair < string , string > entry in attractsResourceNames )
54+ {
55+ try
56+ {
57+ ImprovementData . Type improvement = EnumCache < ImprovementData . Type > . GetType ( entry . Key ) ;
58+ ResourceData . Type resource = EnumCache < ResourceData . Type > . GetType ( entry . Value ) ;
59+ attractsResourceOverrides [ improvement ] = resource ;
60+ Plugin . logger . LogInfo ( $ "Improvement { entry . Key } now attracts { entry . Value } ") ;
61+ }
62+ catch
63+ {
64+ Plugin . logger . LogError ( $ "Improvement { entry . Key } resource type is not valid: { entry . Value } ") ;
65+ }
66+ }
67+ foreach ( KeyValuePair < string , string > entry in attractsTerrainNames )
68+ {
69+ try
70+ {
71+ ImprovementData . Type improvement = EnumCache < ImprovementData . Type > . GetType ( entry . Key ) ;
72+ Polytopia . Data . TerrainData . Type terrain = EnumCache < Polytopia . Data . TerrainData . Type > . GetType ( entry . Value ) ;
73+ attractsTerrainOverrides [ improvement ] = terrain ;
74+ Plugin . logger . LogInfo ( $ "Improvement { entry . Key } now attracts on { entry . Value } ") ;
75+ }
76+ catch
77+ {
78+ Plugin . logger . LogError ( $ "Improvement { entry . Key } terrain type is not valid: { entry . Value } ") ;
79+ }
80+ }
5081 fullyInitialized = true ;
5182 }
5283 }
@@ -211,6 +242,52 @@ private static bool ActionUtils_TrainUnit(ref UnitState __result, GameState game
211242 return true ;
212243 }
213244
245+ [ HarmonyPostfix ]
246+ [ HarmonyPatch ( typeof ( StartTurnAction ) , nameof ( StartTurnAction . Execute ) ) ]
247+ private static void StartTurnAction_Execute ( StartTurnAction __instance , GameState state )
248+ {
249+ for ( int i = state . ActionStack . Count - 1 ; i >= 0 ; i -- )
250+ {
251+ if ( state . ActionStack [ i ] . GetActionType ( ) == ActionType . CreateResource )
252+ {
253+ state . ActionStack . RemoveAt ( i ) ;
254+ }
255+ }
256+ for ( int i = 0 ; i < state . Map . Tiles . Length ; i ++ )
257+ {
258+ TileData tileData = state . Map . Tiles [ i ] ;
259+ if ( tileData . owner == __instance . PlayerId && tileData . improvement != null && state . CurrentTurn > 0U )
260+ {
261+ ImprovementData improvementData ;
262+ state . GameLogicData . TryGetData ( tileData . improvement . type , out improvementData ) ;
263+ if ( improvementData != null )
264+ {
265+ if ( improvementData . HasAbility ( ImprovementAbility . Type . Attract ) && tileData . improvement . GetAge ( state ) % improvementData . growthRate == 0 )
266+ {
267+ ResourceData . Type resourceType = ResourceData . Type . Game ;
268+ if ( attractsResourceOverrides . TryGetValue ( tileData . improvement . type , out ResourceData . Type newType ) )
269+ {
270+ resourceType = newType ;
271+ }
272+ Polytopia . Data . TerrainData . Type targetTerrain = Polytopia . Data . TerrainData . Type . Forest ;
273+ if ( attractsTerrainOverrides . TryGetValue ( tileData . improvement . type , out Polytopia . Data . TerrainData . Type newTerrain ) )
274+ {
275+ targetTerrain = newTerrain ;
276+ }
277+ foreach ( TileData tileData2 in state . Map . GetArea ( tileData . coordinates , 1 , true , false ) )
278+ {
279+ if ( tileData2 . owner == __instance . PlayerId && tileData2 . improvement == null && tileData2 . resource == null && tileData2 . terrain == targetTerrain )
280+ {
281+ state . ActionStack . Add ( new CreateResourceAction ( __instance . PlayerId , resourceType , tileData2 . coordinates , CreateResourceAction . CreateReason . Attract ) ) ;
282+ break ;
283+ }
284+ }
285+ }
286+ }
287+ }
288+ }
289+ }
290+
214291 internal static void Init ( )
215292 {
216293 stopwatch . Start ( ) ;
0 commit comments