@@ -15,28 +15,30 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1515
1616You should have received a copy of the GNU General Public License
1717along with this program. If not, see <http://www.gnu.org/licenses/>.
18- */
18+ */
1919#if ! tModLoaderServer_V1_3
2020using ModFramework ;
21- using Mono . Cecil ;
22- using Mono . Cecil . Cil ;
23- using MonoMod ;
21+ using Mono . Cecil ;
22+ using Mono . Cecil . Cil ;
23+ using MonoMod ;
2424using System ;
25- using System . Linq ;
26-
27- /// <summary>
28- /// @doc Adds a Terraria.Entity entity parameter to Terraria.NPC.StrikeNPC.
29- /// </summary>
30- [ MonoModIgnore ]
31- partial class NpcStrikeArgs
32- {
33- //static ParameterDefinition Entity { get; set; }
34- // static MethodDefinition StrikeNPC { get; set; }
35-
36- [ Modification ( ModType . PreMerge , "Patching in entity source for NPC strike" ) ]
37- static void PatchNpcStrikeArgs ( ModFwModder modder )
38- {
25+ using System . Linq ;
26+
27+ /// <summary>
28+ /// @doc Adds a Terraria.Entity entity parameter to Terraria.NPC.StrikeNPC.
29+ /// </summary>
30+ [ MonoModIgnore ]
31+ partial class NpcStrikeArgs
32+ {
33+ [ Modification ( ModType . PreMerge , "Patching in entity source for NPC strike" ) ]
34+ static void PatchNpcStrikeArgs ( ModFwModder modder )
35+ {
36+ #if TerrariaServer_1450_OrAbove || Terraria__1450_OrAbove || tModLoader_1450_OrAbove
37+ var csr = modder . GetILCursor ( ( ) => ( new Terraria . NPC ( ) ) . StrikeNPC ( 0 , 0 , 0 , false , false , false , 0 ) ) ;
38+ #else
3939 var csr = modder . GetILCursor ( ( ) => ( new Terraria . NPC ( ) ) . StrikeNPC ( 0 , 0 , 0 , false , false , false ) ) ;
40+ #endif
41+
4042 var redirects = csr . Method . DeclaringType . Methods
4143 . Where ( x => ( HookEmitter . HookMethodNamePrefix + x . Name ) == csr . Method . Name || ( "orig_" + x . Name ) == csr . Method . Name )
4244 . Select ( x => x . GetILCursor ( ) )
@@ -45,16 +47,16 @@ static void PatchNpcStrikeArgs(ModFwModder modder)
4547 foreach ( var method in redirects . Append ( csr ) )
4648 {
4749 ParameterDefinition Entity ;
48- method . Method . Parameters . Add ( Entity = new ( "entity" ,
49- ParameterAttributes . HasDefault | ParameterAttributes . Optional ,
50-
51- modder . Module . ImportReference ( modder . GetDefinition < Terraria . Entity > ( ) )
50+ method . Method . Parameters . Add ( Entity = new ( "entity" ,
51+ ParameterAttributes . HasDefault | ParameterAttributes . Optional ,
52+
53+ modder . Module . ImportReference ( modder . GetDefinition < Terraria . Entity > ( ) )
5254 )
5355 {
5456 Constant = null
5557 } ) ;
5658
57- modder . OnRewritingMethodBody += ( MonoModder modder , MethodBody body , Instruction instr , int instri ) =>
59+ modder . OnRewritingMethodBody += ( MonoModder modder , MethodBody body , Instruction instr , int instri ) =>
5860 {
5961 if ( instr . Operand is MethodReference methodReference )
6062 {
@@ -71,12 +73,22 @@ static void PatchNpcStrikeArgs(ModFwModder modder)
7173 switch ( methodName . Replace ( HookEmitter . HookMethodNamePrefix , "" ) )
7274 {
7375 case "MessageBuffer.GetData" :
76+ var playerRef = Instruction . Create ( OpCodes . Ldsfld , modder . Module . ImportReference ( modder . GetFieldDefinition ( ( ) => Terraria . Main . player ) ) ) ;
77+ body . GetILProcessor ( ) . InsertBefore ( instr , playerRef ) ;
7478 body . GetILProcessor ( ) . InsertBefore ( instr ,
75- new { OpCodes . Ldsfld , Operand = modder . Module . ImportReference ( modder . GetFieldDefinition ( ( ) => Terraria . Main . player ) ) } ,
76- new { OpCodes . Ldarg_0 } ,
77- new { OpCodes . Ldfld , Operand = modder . Module . ImportReference ( modder . GetFieldDefinition ( ( ) => ( new Terraria . MessageBuffer ( ) ) . whoAmI ) ) } ,
78- new { OpCodes . Ldelem_Ref }
79- ) ;
79+ new { OpCodes . Ldarg_0 } ,
80+ new { OpCodes . Ldfld , Operand = modder . Module . ImportReference ( modder . GetFieldDefinition ( ( ) => ( new Terraria . MessageBuffer ( ) ) . whoAmI ) ) } ,
81+ new { OpCodes . Ldelem_Ref }
82+ ) ;
83+
84+ var hasWhoAmI = instr . Previous . OpCode == OpCodes . Ldfld &&
85+ instr . Previous . Operand is FieldReference fieldReference &&
86+ fieldReference . Name == "whoAmI" ;
87+ if ( hasWhoAmI ) { // 145+
88+ // rewire the branching
89+ var brs = instr . Previous ( x => x . OpCode == OpCodes . Br_S ) ;
90+ brs . Operand = playerRef ;
91+ }
8092 break ;
8193
8294 case "NPC.StrikeNPCNoInteraction" :
@@ -96,13 +108,21 @@ static void PatchNpcStrikeArgs(ModFwModder modder)
96108 ) ;
97109 break ;
98110
111+ case "Projectile.Damage_PVE_Inner" :
112+ // find the NPC parameter
113+ var prm = body . Method . Parameters . Single ( x => x . ParameterType . FullName == "Terraria.NPC" ) ;
114+ body . GetILProcessor ( ) . InsertBefore ( instr ,
115+ new { OpCodes . Ldarg , Operand = prm }
116+ ) ;
117+ break ;
118+
99119 default :
100- throw new NotImplementedException ( $ "{ body . Method . Name } is not a supported caller for this modification") ;
120+ throw new NotImplementedException ( $ "{ body . Method . FullName } is not a supported caller for this modification") ;
101121 }
102122 }
103123 }
104124 } ;
105- }
106- }
125+ }
126+ }
107127}
108128#endif
0 commit comments