@@ -11,18 +11,22 @@ namespace Exiled.Events.Patches.Events.Map
1111 using System . Reflection . Emit ;
1212
1313 using API . Features . Doors ;
14- using API . Features . Pickups ;
1514 using API . Features . Pools ;
1615
17- using Exiled . Events . Attributes ;
18- using Exiled . Events . EventArgs . Map ;
19- using Handlers ;
16+ using Attributes ;
17+
18+ using EventArgs . Map ;
19+
2020 using HarmonyLib ;
21+
2122 using Interactables . Interobjects . DoorUtils ;
23+
2224 using MapGeneration . Distributors ;
2325
2426 using static HarmonyLib . AccessTools ;
2527
28+ using Map = Handlers . Map ;
29+
2630 /// <summary>
2731 /// Patches <see cref="ItemDistributor.ServerRegisterPickup" />.
2832 /// Adds the <see cref="Map.SpawningItem" /> event.
@@ -40,6 +44,9 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
4044 LocalBuilder ev = generator . DeclareLocal ( typeof ( SpawningItemEventArgs ) ) ;
4145
4246 Label skip = generator . DefineLabel ( ) ;
47+ Label allowOriginalLogic = generator . DefineLabel ( ) ;
48+ Label loadGameObjectLocation = generator . DefineLabel ( ) ;
49+ Label storeData = generator . DefineLabel ( ) ;
4350 Label skipdoorSpawn = generator . DefineLabel ( ) ;
4451 Label doorSpawn = generator . DefineLabel ( ) ;
4552 Label returnLabel = generator . DefineLabel ( ) ;
@@ -57,24 +64,21 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
5764 new CodeInstruction ( OpCodes . Ldc_I4_1 ) . MoveLabelsFrom ( newInstructions [ index ] ) ,
5865 new ( OpCodes . Stloc_S , initiallySpawn . LocalIndex ) ,
5966
60- // door = null
61- new ( OpCodes . Ldnull ) ,
62- new ( OpCodes . Stloc_S , door . LocalIndex ) ,
63-
64- // goto skip
65- new ( OpCodes . Br_S , skip ) ,
66-
67- // initiallySpawn = false
68- new CodeInstruction ( OpCodes . Ldc_I4_0 ) . MoveLabelsFrom ( newInstructions [ lastIndex ] ) ,
67+ // initiallySpawn = true
68+ new CodeInstruction ( OpCodes . Ldc_I4_1 ) ,
6969 new ( OpCodes . Stloc_S , initiallySpawn . LocalIndex ) ,
7070
71- // door = doorNametagExtension.TargetDoor
72- new ( OpCodes . Ldloc_2 ) ,
71+ // door = doorNametagExtension.TargetDoor if not null, otherwise, null door
72+ new ( OpCodes . Ldloc_1 ) ,
73+ new ( OpCodes . Brfalse , skip ) ,
74+ new ( OpCodes . Ldloc_1 ) ,
7375 new ( OpCodes . Ldfld , Field ( typeof ( DoorVariantExtension ) , nameof ( DoorVariantExtension . TargetDoor ) ) ) ,
74- new ( OpCodes . Stloc_S , door . LocalIndex ) ,
76+ new ( OpCodes . Br , storeData ) ,
77+ new CodeInstruction ( OpCodes . Ldnull ) . WithLabels ( skip ) ,
78+ new CodeInstruction ( OpCodes . Stloc , door . LocalIndex ) . WithLabels ( storeData ) ,
7579
7680 // ipb
77- new CodeInstruction ( OpCodes . Ldloc_1 ) . WithLabels ( skip ) ,
81+ new CodeInstruction ( OpCodes . Ldarg_1 ) ,
7882
7983 // initiallySpawn
8084 new ( OpCodes . Ldloc_S , initiallySpawn . LocalIndex ) ,
@@ -117,20 +121,27 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
117121 // "base.RegisterUnspawnedObject(doorNametagExtension.TargetDoor, itemPickupBase.gameObject);"
118122 // with "base.RegisterUnspawnedObject(ev.Door.Base, itemPickupBase.gameObject);"
119123 offset = - 1 ;
120- index = newInstructions . FindLastIndex ( i => i . opcode == OpCodes . Ldfld ) + offset ;
124+ index = newInstructions . FindLastIndex ( i => i . LoadsField ( Field ( typeof ( DoorVariantExtension ) , nameof ( DoorVariantExtension . TargetDoor ) ) ) ) + offset ;
125+
126+ newInstructions [ index ] . WithLabels ( allowOriginalLogic ) ;
121127
122- newInstructions . RemoveRange ( index , 2 ) ;
128+ int temp_instr = newInstructions . FindLastIndex ( i => i . Calls ( PropertyGetter ( typeof ( UnityEngine . Component ) , nameof ( UnityEngine . Component . gameObject ) ) ) ) - 1 ;
129+ newInstructions [ temp_instr ] . WithLabels ( loadGameObjectLocation ) ;
123130
124131 newInstructions . InsertRange ( index , new [ ]
125132 {
126133 // ev.Door.Base
127- new CodeInstruction ( OpCodes . Ldloc_S , ev . LocalIndex ) ,
134+ new CodeInstruction ( OpCodes . Ldloc , ev . LocalIndex ) ,
135+ new ( OpCodes . Brfalse , allowOriginalLogic ) ,
136+ new CodeInstruction ( OpCodes . Ldloc , ev . LocalIndex ) ,
137+ new ( OpCodes . Callvirt , PropertyGetter ( typeof ( SpawningItemEventArgs ) , nameof ( SpawningItemEventArgs . TriggerDoor ) ) ) ,
138+ new ( OpCodes . Brfalse , allowOriginalLogic ) ,
139+ new CodeInstruction ( OpCodes . Ldloc , ev . LocalIndex ) ,
128140 new ( OpCodes . Callvirt , PropertyGetter ( typeof ( SpawningItemEventArgs ) , nameof ( SpawningItemEventArgs . TriggerDoor ) ) ) ,
129141 new ( OpCodes . Callvirt , PropertyGetter ( typeof ( Door ) , nameof ( Door . Base ) ) ) ,
142+ new ( OpCodes . Br , loadGameObjectLocation ) ,
130143 } ) ;
131-
132144 newInstructions [ newInstructions . Count - 1 ] . WithLabels ( returnLabel ) ;
133-
134145 for ( int z = 0 ; z < newInstructions . Count ; z ++ )
135146 yield return newInstructions [ z ] ;
136147
0 commit comments