tModLoader v0.11.8.9
A mod to make and play Terraria mods
NPCLoader.cs
Go to the documentation of this file.
1using Microsoft.Xna.Framework;
2using Microsoft.Xna.Framework.Graphics;
3using System;
4using System.Collections.Generic;
5using System.IO;
6using System.Linq;
7using System.Linq.Expressions;
8using System.Reflection;
9using Terraria.GameContent.UI;
10using Terraria.ID;
11using Terraria.Localization;
12
13namespace Terraria.ModLoader
14{
15 //todo: further documentation
19 public static class NPCLoader
20 {
21 internal static bool loaded = false;
22 private static int nextNPC = NPCID.Count;
23 internal static readonly IList<ModNPC> npcs = new List<ModNPC>();
24 internal static readonly IList<GlobalNPC> globalNPCs = new List<GlobalNPC>();
25 internal static GlobalNPC[] InstancedGlobals = new GlobalNPC[0];
26 internal static readonly IDictionary<string, int> globalIndexes = new Dictionary<string, int>();
27 internal static readonly IDictionary<Type, int> globalIndexesByType = new Dictionary<Type, int>();
28 internal static readonly IDictionary<int, int> bannerToItem = new Dictionary<int, int>();
29 private static int vanillaSkeletonCount = NPCID.Sets.Skeletons.Count;
30 private static readonly int[] shopToNPC = new int[Main.MaxShopIDs - 1];
34 public static readonly IList<int> blockLoot = new List<int>();
35
36 private class HookList
37 {
38 public GlobalNPC[] arr = new GlobalNPC[0];
39 public readonly MethodInfo method;
40
41 public HookList(MethodInfo method) {
42 this.method = method;
43 }
44 }
45
46 private static List<HookList> hooks = new List<HookList>();
47
48 private static HookList AddHook<F>(Expression<Func<GlobalNPC, F>> func) {
49 var hook = new HookList(ModLoader.Method(func));
50 hooks.Add(hook);
51 return hook;
52 }
53
54 static NPCLoader() {
55 shopToNPC[1] = NPCID.Merchant;
56 shopToNPC[2] = NPCID.ArmsDealer;
57 shopToNPC[3] = NPCID.Dryad;
58 shopToNPC[4] = NPCID.Demolitionist;
59 shopToNPC[5] = NPCID.Clothier;
60 shopToNPC[6] = NPCID.GoblinTinkerer;
61 shopToNPC[7] = NPCID.Wizard;
62 shopToNPC[8] = NPCID.Mechanic;
63 shopToNPC[9] = NPCID.SantaClaus;
64 shopToNPC[10] = NPCID.Truffle;
65 shopToNPC[11] = NPCID.Steampunker;
66 shopToNPC[12] = NPCID.DyeTrader;
67 shopToNPC[13] = NPCID.PartyGirl;
68 shopToNPC[14] = NPCID.Cyborg;
69 shopToNPC[15] = NPCID.Painter;
70 shopToNPC[16] = NPCID.WitchDoctor;
71 shopToNPC[17] = NPCID.Pirate;
72 shopToNPC[18] = NPCID.Stylist;
73 shopToNPC[19] = NPCID.TravellingMerchant;
74 shopToNPC[20] = NPCID.SkeletonMerchant;
75 shopToNPC[21] = NPCID.DD2Bartender;
76 }
77
78 internal static int ReserveNPCID() {
79 if (ModNet.AllowVanillaClients) throw new Exception("Adding npcs breaks vanilla client compatibility");
80
81 int reserveID = nextNPC;
82 nextNPC++;
83 return reserveID;
84 }
85
86 public static int NPCCount => nextNPC;
87
93 public static ModNPC GetNPC(int type) {
94 return type >= NPCID.Count && type < NPCCount ? npcs[type - NPCID.Count] : null;
95 }
96 //change initial size of Terraria.Player.npcTypeNoAggro and NPCBannerBuff to NPCLoader.NPCCount()
97 //in Terraria.Main.MouseText replace 251 with NPCLoader.NPCCount()
98 //in Terraria.Main.DrawNPCs and Terraria.NPC.NPCLoot remove type too high check
99 //replace a lot of 540 immediates
100 //in Terraria.GameContent.UI.EmoteBubble make CountNPCs internal
101 internal static void ResizeArrays(bool unloading) {
102 Array.Resize(ref Main.NPCLoaded, nextNPC);
103 Array.Resize(ref Main.townNPCCanSpawn, nextNPC);
104 Array.Resize(ref Main.slimeRainNPC, nextNPC);
105 Array.Resize(ref Main.npcTexture, nextNPC);
106 Array.Resize(ref Main.npcAltTextures, nextNPC);
107 Array.Resize(ref Main.npcCatchable, nextNPC);
108 Array.Resize(ref Main.npcFrameCount, nextNPC);
109 Array.Resize(ref NPC.killCount, nextNPC);
110 Array.Resize(ref NPC.npcsFoundForCheckActive, nextNPC);
111 Array.Resize(ref Lang._npcNameCache, nextNPC);
112 Array.Resize(ref EmoteBubble.CountNPCs, nextNPC);
113 Array.Resize(ref WorldGen.TownManager._hasRoom, nextNPC);
114 Array.Resize(ref NPCID.Sets.TrailingMode, nextNPC);
115 Array.Resize(ref NPCID.Sets.BelongsToInvasionOldOnesArmy, nextNPC);
116 Array.Resize(ref NPCID.Sets.TeleportationImmune, nextNPC);
117 Array.Resize(ref NPCID.Sets.UsesNewTargetting, nextNPC);
118 Array.Resize(ref NPCID.Sets.FighterUsesDD2PortalAppearEffect, nextNPC);
119 Array.Resize(ref NPCID.Sets.StatueSpawnedDropRarity, nextNPC);
120 Array.Resize(ref NPCID.Sets.NoEarlymodeLootWhenSpawnedFromStatue, nextNPC);
121 Array.Resize(ref NPCID.Sets.NeedsExpertScaling, nextNPC);
122 Array.Resize(ref NPCID.Sets.ProjectileNPC, nextNPC);
123 Array.Resize(ref NPCID.Sets.SavesAndLoads, nextNPC);
124 Array.Resize(ref NPCID.Sets.TrailCacheLength, nextNPC);
125 Array.Resize(ref NPCID.Sets.MPAllowedEnemies, nextNPC);
126 Array.Resize(ref NPCID.Sets.TownCritter, nextNPC);
127 Array.Resize(ref NPCID.Sets.HatOffsetY, nextNPC);
128 Array.Resize(ref NPCID.Sets.FaceEmote, nextNPC);
129 Array.Resize(ref NPCID.Sets.ExtraFramesCount, nextNPC);
130 Array.Resize(ref NPCID.Sets.AttackFrameCount, nextNPC);
131 Array.Resize(ref NPCID.Sets.DangerDetectRange, nextNPC);
132 Array.Resize(ref NPCID.Sets.AttackTime, nextNPC);
133 Array.Resize(ref NPCID.Sets.AttackAverageChance, nextNPC);
134 Array.Resize(ref NPCID.Sets.AttackType, nextNPC);
135 Array.Resize(ref NPCID.Sets.PrettySafe, nextNPC);
136 Array.Resize(ref NPCID.Sets.MagicAuraColor, nextNPC);
137 Array.Resize(ref NPCID.Sets.BossHeadTextures, nextNPC);
138 Array.Resize(ref NPCID.Sets.ExcludedFromDeathTally, nextNPC);
139 Array.Resize(ref NPCID.Sets.TechnicallyABoss, nextNPC);
140 Array.Resize(ref NPCID.Sets.MustAlwaysDraw, nextNPC);
141 Array.Resize(ref NPCID.Sets.ExtraTextureCount, nextNPC);
142 Array.Resize(ref NPCID.Sets.NPCFramingGroup, nextNPC);
143 Array.Resize(ref NPCID.Sets.TownNPCsFramingGroups, nextNPC);
144 for (int k = NPCID.Count; k < nextNPC; k++) {
145 Main.NPCLoaded[k] = true;
146 Main.npcFrameCount[k] = 1;
147 Lang._npcNameCache[k] = LocalizedText.Empty;
148 NPCID.Sets.TrailingMode[k] = -1;
149 NPCID.Sets.StatueSpawnedDropRarity[k] = -1f;
150 NPCID.Sets.TrailCacheLength[k] = 10;
151 NPCID.Sets.DangerDetectRange[k] = -1;
152 NPCID.Sets.AttackTime[k] = -1;
153 NPCID.Sets.AttackAverageChance[k] = 1;
154 NPCID.Sets.AttackType[k] = -1;
155 NPCID.Sets.PrettySafe[k] = -1;
156 NPCID.Sets.MagicAuraColor[k] = Color.White;
157 NPCID.Sets.BossHeadTextures[k] = -1;
158 }
159
160 InstancedGlobals = globalNPCs.Where(g => g.InstancePerEntity).ToArray();
161 for (int i = 0; i < InstancedGlobals.Length; i++) {
162 InstancedGlobals[i].instanceIndex = i;
163 }
164 foreach (var hook in hooks) {
165 hook.arr = ModLoader.BuildGlobalHook(globalNPCs, hook.method);
166 }
167
168 if (!unloading) {
169 loaded = true;
170 }
171 }
172
173 internal static void Unload() {
174 loaded = false;
175 npcs.Clear();
176 nextNPC = NPCID.Count;
177 globalNPCs.Clear();
178 globalIndexes.Clear();
179 globalIndexesByType.Clear();
180 bannerToItem.Clear();
181 while (NPCID.Sets.Skeletons.Count > vanillaSkeletonCount) {
182 NPCID.Sets.Skeletons.RemoveAt(NPCID.Sets.Skeletons.Count - 1);
183 }
184 }
185
186 internal static bool IsModNPC(NPC npc) {
187 return npc.type >= NPCID.Count;
188 }
189
190 private static HookList HookSetDefaults = AddHook<Action<NPC>>(g => g.SetDefaults);
191
192 internal static void SetDefaults(NPC npc, bool createModNPC = true) {
193 if (IsModNPC(npc)) {
194 if (createModNPC) {
195 npc.modNPC = GetNPC(npc.type).NewInstance(npc);
196 }
197 else //the default NPCs created and bound to ModNPCs are initialized before ResizeArrays. They come here during SetupContent.
198 {
199 Array.Resize(ref npc.buffImmune, BuffLoader.BuffCount);
200 }
201 }
202 npc.globalNPCs = InstancedGlobals.Select(g => g.NewInstance(npc)).ToArray();
203 npc.modNPC?.SetDefaults();
204 foreach (GlobalNPC g in HookSetDefaults.arr) {
205 g.Instance(npc).SetDefaults(npc);
206 }
207 }
208
209 internal static GlobalNPC GetGlobalNPC(NPC npc, Mod mod, string name) {
210 int index;
211 return globalIndexes.TryGetValue(mod.Name + ':' + name, out index) ? globalNPCs[index].Instance(npc) : null;
212 }
213
214 internal static GlobalNPC GetGlobalNPC(NPC npc, Type type) {
215 int index;
216 return globalIndexesByType.TryGetValue(type, out index) ? (index > -1 ? globalNPCs[index].Instance(npc) : null) : null;
217 }
218
219 private static HookList HookScaleExpertStats = AddHook<Action<NPC, int, float>>(g => g.ScaleExpertStats);
220
221 public static void ScaleExpertStats(NPC npc, int numPlayers, float bossLifeScale) {
222 npc.modNPC?.ScaleExpertStats(numPlayers, bossLifeScale);
223
224 foreach (GlobalNPC g in HookScaleExpertStats.arr) {
225 g.Instance(npc).ScaleExpertStats(npc, numPlayers, bossLifeScale);
226 }
227 }
228
229 private static HookList HookResetEffects = AddHook<Action<NPC>>(g => g.ResetEffects);
230
231 public static void ResetEffects(NPC npc) {
232 npc.modNPC?.ResetEffects();
233
234 foreach (GlobalNPC g in HookResetEffects.arr) {
235 g.Instance(npc).ResetEffects(npc);
236 }
237 }
238
239 public static void NPCAI(NPC npc) {
240 if (PreAI(npc)) {
241 int type = npc.type;
242 bool useAiType = npc.modNPC != null && npc.modNPC.aiType > 0;
243 if (useAiType) {
244 npc.type = npc.modNPC.aiType;
245 }
246 npc.VanillaAI();
247 if (useAiType) {
248 npc.type = type;
249 }
250 AI(npc);
251 }
252 PostAI(npc);
253 }
254
255 private static HookList HookPreAI = AddHook<Func<NPC, bool>>(g => g.PreAI);
256
257 public static bool PreAI(NPC npc) {
258 bool result = true;
259 foreach (GlobalNPC g in HookPreAI.arr) {
260 result &= g.Instance(npc).PreAI(npc);
261 }
262 if (result && npc.modNPC != null) {
263 return npc.modNPC.PreAI();
264 }
265 return result;
266 }
267
268 private static HookList HookAI = AddHook<Action<NPC>>(g => g.AI);
269
270 public static void AI(NPC npc) {
271 npc.modNPC?.AI();
272
273 foreach (GlobalNPC g in HookAI.arr) {
274 g.Instance(npc).AI(npc);
275 }
276 }
277
278 private static HookList HookPostAI = AddHook<Action<NPC>>(g => g.PostAI);
279
280 public static void PostAI(NPC npc) {
281 npc.modNPC?.PostAI();
282
283 foreach (GlobalNPC g in HookPostAI.arr) {
284 g.Instance(npc).PostAI(npc);
285 }
286 }
287
288 public static void SendExtraAI(NPC npc, BinaryWriter writer) {
289 if (npc.modNPC != null) {
290 byte[] data;
291 using (MemoryStream stream = new MemoryStream()) {
292 using (BinaryWriter modWriter = new BinaryWriter(stream)) {
293 npc.modNPC.SendExtraAI(modWriter);
294 modWriter.Flush();
295 data = stream.ToArray();
296 }
297 }
298 writer.Write((byte)data.Length);
299 if (data.Length > 0) {
300 writer.Write(data);
301 }
302 }
303 }
304
305 public static void ReceiveExtraAI(NPC npc, BinaryReader reader) {
306 if (npc.modNPC != null) {
307 byte[] extraAI = reader.ReadBytes(reader.ReadByte());
308 if (extraAI.Length > 0) {
309 using (MemoryStream stream = new MemoryStream(extraAI)) {
310 using (BinaryReader modReader = new BinaryReader(stream)) {
311 npc.modNPC.ReceiveExtraAI(modReader);
312 }
313 }
314 }
315 }
316 }
317
318 private static HookList HookFindFrame = AddHook<Action<NPC, int>>(g => g.FindFrame);
319
320 public static void FindFrame(NPC npc, int frameHeight) {
321 int type = npc.type;
322 if (npc.modNPC != null && npc.modNPC.animationType > 0) {
323 npc.type = npc.modNPC.animationType;
324 }
325 npc.VanillaFindFrame(frameHeight);
326 npc.type = type;
327 npc.modNPC?.FindFrame(frameHeight);
328
329 foreach (GlobalNPC g in HookFindFrame.arr) {
330 g.Instance(npc).FindFrame(npc, frameHeight);
331 }
332 }
333
334 private static HookList HookHitEffect = AddHook<Action<NPC, int, double>>(g => g.HitEffect);
335
336 public static void HitEffect(NPC npc, int hitDirection, double damage) {
337 npc.VanillaHitEffect(hitDirection, damage);
338 npc.modNPC?.HitEffect(hitDirection, damage);
339
340 foreach (GlobalNPC g in HookHitEffect.arr) {
341 g.Instance(npc).HitEffect(npc, hitDirection, damage);
342 }
343 }
344
345 private delegate void DelegateUpdateLifeRegen(NPC npc, ref int damage);
346 private static HookList HookUpdateLifeRegen = AddHook<DelegateUpdateLifeRegen>(g => g.UpdateLifeRegen);
347
348 public static void UpdateLifeRegen(NPC npc, ref int damage) {
349 npc.modNPC?.UpdateLifeRegen(ref damage);
350
351 foreach (GlobalNPC g in HookUpdateLifeRegen.arr) {
352 g.Instance(npc).UpdateLifeRegen(npc, ref damage);
353 }
354 }
355
356 private static HookList HookCheckActive = AddHook<Func<NPC, bool>>(g => g.CheckActive);
357
358 public static bool CheckActive(NPC npc) {
359 if (npc.modNPC != null && !npc.modNPC.CheckActive()) {
360 return false;
361 }
362 foreach (GlobalNPC g in HookCheckActive.arr) {
363 if (!g.Instance(npc).CheckActive(npc)) {
364 return false;
365 }
366 }
367 return true;
368 }
369
370 private static HookList HookCheckDead = AddHook<Func<NPC, bool>>(g => g.CheckDead);
371
372 public static bool CheckDead(NPC npc) {
373 bool result = true;
374
375 if (npc.modNPC != null) {
376 result = npc.modNPC.CheckDead();
377 }
378
379 foreach (GlobalNPC g in HookCheckDead.arr) {
380 result &= g.Instance(npc).CheckDead(npc);
381 }
382
383 return result;
384 }
385
386 private static HookList HookSpecialNPCLoot = AddHook<Func<NPC, bool>>(g => g.SpecialNPCLoot);
387
388 public static bool SpecialNPCLoot(NPC npc) {
389 foreach (GlobalNPC g in HookSpecialNPCLoot.arr) {
390 if (g.Instance(npc).SpecialNPCLoot(npc)) {
391 return true;
392 }
393 }
394 if (npc.modNPC != null) {
395 return npc.modNPC.SpecialNPCLoot();
396 }
397 return false;
398 }
399
400 private static HookList HookPreNPCLoot = AddHook<Func<NPC, bool>>(g => g.PreNPCLoot);
401
402 public static bool PreNPCLoot(NPC npc) {
403 bool result = true;
404 foreach (GlobalNPC g in HookPreNPCLoot.arr) {
405 result &= g.Instance(npc).PreNPCLoot(npc);
406 }
407
408 if (result && npc.modNPC != null) {
409 result = npc.modNPC.PreNPCLoot();
410 }
411
412 if (!result) {
413 blockLoot.Clear();
414 return false;
415 }
416
417 return true;
418 }
419
420 private static HookList HookNPCLoot = AddHook<Action<NPC>>(g => g.NPCLoot);
421
422 public static void NPCLoot(NPC npc) {
423 npc.modNPC?.NPCLoot();
424
425 foreach (GlobalNPC g in HookNPCLoot.arr) {
426 g.Instance(npc).NPCLoot(npc);
427 }
428 blockLoot.Clear();
429 }
430
431 public static void BossLoot(NPC npc, ref string name, ref int potionType) {
432 npc.modNPC?.BossLoot(ref name, ref potionType);
433 }
434
435 public static void BossBag(NPC npc, ref int bagType) {
436 if (npc.modNPC != null) {
437 bagType = npc.modNPC.bossBag;
438 }
439 }
440
441 private static HookList HookOnCatchNPC = AddHook<Action<NPC, Player, Item>>(g => g.OnCatchNPC);
442
443 public static void OnCatchNPC(NPC npc, Player player, Item item) {
444 npc.modNPC?.OnCatchNPC(player, item);
445
446 foreach (GlobalNPC g in HookOnCatchNPC.arr) {
447 g.Instance(npc).OnCatchNPC(npc, player, item);
448 }
449 }
450
451 private delegate bool DelegateCanHitPlayer(NPC npc, Player target, ref int cooldownSlot);
452 private static HookList HookCanHitPlayer = AddHook<DelegateCanHitPlayer>(g => g.CanHitPlayer);
453
454 public static bool CanHitPlayer(NPC npc, Player target, ref int cooldownSlot) {
455 foreach (GlobalNPC g in HookCanHitPlayer.arr) {
456 if (!g.Instance(npc).CanHitPlayer(npc, target, ref cooldownSlot)) {
457 return false;
458 }
459 }
460 if (npc.modNPC != null) {
461 return npc.modNPC.CanHitPlayer(target, ref cooldownSlot);
462 }
463 return true;
464 }
465
466 private delegate void DelegateModifyHitPlayer(NPC npc, Player target, ref int damage, ref bool crit);
467 private static HookList HookModifyHitPlayer = AddHook<DelegateModifyHitPlayer>(g => g.ModifyHitPlayer);
468
469 public static void ModifyHitPlayer(NPC npc, Player target, ref int damage, ref bool crit) {
470 npc.modNPC?.ModifyHitPlayer(target, ref damage, ref crit);
471
472 foreach (GlobalNPC g in HookModifyHitPlayer.arr) {
473 g.Instance(npc).ModifyHitPlayer(npc, target, ref damage, ref crit);
474 }
475 }
476
477 private static HookList HookOnHitPlayer = AddHook<Action<NPC, Player, int, bool>>(g => g.OnHitPlayer);
478
479 public static void OnHitPlayer(NPC npc, Player target, int damage, bool crit) {
480 npc.modNPC?.OnHitPlayer(target, damage, crit);
481
482 foreach (GlobalNPC g in HookOnHitPlayer.arr) {
483 g.Instance(npc).OnHitPlayer(npc, target, damage, crit);
484 }
485 }
486
487 private static HookList HookCanHitNPC = AddHook<Func<NPC, NPC, bool?>>(g => g.CanHitNPC);
488
489 public static bool? CanHitNPC(NPC npc, NPC target) {
490 bool? flag = null;
491 foreach (GlobalNPC g in HookCanHitNPC.arr) {
492 bool? canHit = g.Instance(npc).CanHitNPC(npc, target);
493 if (canHit.HasValue && !canHit.Value) {
494 return false;
495 }
496 if (canHit.HasValue) {
497 flag = canHit.Value;
498 }
499 }
500 if (npc.modNPC != null) {
501 bool? canHit = npc.modNPC.CanHitNPC(target);
502 if (canHit.HasValue && !canHit.Value) {
503 return false;
504 }
505 if (canHit.HasValue) {
506 flag = canHit.Value;
507 }
508 }
509 return flag;
510 }
511
512 private delegate void DelegateModifyHitNPC(NPC npc, NPC target, ref int damage, ref float knockback, ref bool crit);
513 private static HookList HookModifyHitNPC = AddHook<DelegateModifyHitNPC>(g => g.ModifyHitNPC);
514
515 public static void ModifyHitNPC(NPC npc, NPC target, ref int damage, ref float knockback, ref bool crit) {
516 npc.modNPC?.ModifyHitNPC(target, ref damage, ref knockback, ref crit);
517
518 foreach (GlobalNPC g in HookModifyHitNPC.arr) {
519 g.Instance(npc).ModifyHitNPC(npc, target, ref damage, ref knockback, ref crit);
520 }
521 }
522
523 private static HookList HookOnHitNPC = AddHook<Action<NPC, NPC, int, float, bool>>(g => g.OnHitNPC);
524
525 public static void OnHitNPC(NPC npc, NPC target, int damage, float knockback, bool crit) {
526 npc.modNPC?.OnHitNPC(target, damage, knockback, crit);
527 foreach (GlobalNPC g in HookOnHitNPC.arr) {
528 g.Instance(npc).OnHitNPC(npc, target, damage, knockback, crit);
529 }
530 }
531
532 private static HookList HookCanBeHitByItem = AddHook<Func<NPC, Player, Item, bool?>>(g => g.CanBeHitByItem);
533
534 public static bool? CanBeHitByItem(NPC npc, Player player, Item item) {
535 bool? flag = null;
536 foreach (GlobalNPC g in HookCanBeHitByItem.arr) {
537 bool? canHit = g.Instance(npc).CanBeHitByItem(npc, player, item);
538 if (canHit.HasValue && !canHit.Value) {
539 return false;
540 }
541 if (canHit.HasValue) {
542 flag = canHit.Value;
543 }
544 }
545 if (npc.modNPC != null) {
546 bool? canHit = npc.modNPC.CanBeHitByItem(player, item);
547 if (canHit.HasValue && !canHit.Value) {
548 return false;
549 }
550 if (canHit.HasValue) {
551 flag = canHit.Value;
552 }
553 }
554 return flag;
555 }
556
557 private delegate void DelegateModifyHitByItem(NPC npc, Player player, Item item, ref int damage, ref float knockback, ref bool crit);
558 private static HookList HookModifyHitByItem = AddHook<DelegateModifyHitByItem>(g => g.ModifyHitByItem);
559
560 public static void ModifyHitByItem(NPC npc, Player player, Item item, ref int damage, ref float knockback, ref bool crit) {
561 npc.modNPC?.ModifyHitByItem(player, item, ref damage, ref knockback, ref crit);
562
563 foreach (GlobalNPC g in HookModifyHitByItem.arr) {
564 g.Instance(npc).ModifyHitByItem(npc, player, item, ref damage, ref knockback, ref crit);
565 }
566 }
567
568 private static HookList HookOnHitByItem = AddHook<Action<NPC, Player, Item, int, float, bool>>(g => g.OnHitByItem);
569
570 public static void OnHitByItem(NPC npc, Player player, Item item, int damage, float knockback, bool crit) {
571 npc.modNPC?.OnHitByItem(player, item, damage, knockback, crit);
572
573 foreach (GlobalNPC g in HookOnHitByItem.arr) {
574 g.Instance(npc).OnHitByItem(npc, player, item, damage, knockback, crit);
575 }
576 }
577
578 private static HookList HookCanBeHitByProjectile = AddHook<Func<NPC, Projectile, bool?>>(g => g.CanBeHitByProjectile);
579
580 public static bool? CanBeHitByProjectile(NPC npc, Projectile projectile) {
581 bool? flag = null;
582 foreach (GlobalNPC g in HookCanBeHitByProjectile.arr) {
583 bool? canHit = g.Instance(npc).CanBeHitByProjectile(npc, projectile);
584 if (canHit.HasValue && !canHit.Value) {
585 return false;
586 }
587 if (canHit.HasValue) {
588 flag = canHit.Value;
589 }
590 }
591 if (npc.modNPC != null) {
592 bool? canHit = npc.modNPC.CanBeHitByProjectile(projectile);
593 if (canHit.HasValue && !canHit.Value) {
594 return false;
595 }
596 if (canHit.HasValue) {
597 flag = canHit.Value;
598 }
599 }
600 return flag;
601 }
602
603 private delegate void DelegateModifyHitByProjectile(NPC npc, Projectile projectile, ref int damage, ref float knockback, ref bool crit, ref int hitDirection);
604 private static HookList HookModifyHitByProjectile = AddHook<DelegateModifyHitByProjectile>(g => g.ModifyHitByProjectile);
605
606 public static void ModifyHitByProjectile(NPC npc, Projectile projectile, ref int damage, ref float knockback, ref bool crit, ref int hitDirection) {
607 npc.modNPC?.ModifyHitByProjectile(projectile, ref damage, ref knockback, ref crit, ref hitDirection);
608
610 g.Instance(npc).ModifyHitByProjectile(npc, projectile, ref damage, ref knockback, ref crit, ref hitDirection);
611 }
612 }
613
614 private static HookList HookOnHitByProjectile = AddHook<Action<NPC, Projectile, int, float, bool>>(g => g.OnHitByProjectile);
615
616 public static void OnHitByProjectile(NPC npc, Projectile projectile, int damage, float knockback, bool crit) {
617 npc.modNPC?.OnHitByProjectile(projectile, damage, knockback, crit);
618
619 foreach (GlobalNPC g in HookOnHitByProjectile.arr) {
620 g.Instance(npc).OnHitByProjectile(npc, projectile, damage, knockback, crit);
621 }
622 }
623
624 private delegate bool DelegateStrikeNPC(NPC npc, ref double damage, int defense, ref float knockback, int hitDirection, ref bool crit);
625 private static HookList HookStrikeNPC = AddHook<DelegateStrikeNPC>(g => g.StrikeNPC);
626
627 public static bool StrikeNPC(NPC npc, ref double damage, int defense, ref float knockback, int hitDirection, ref bool crit) {
628 bool flag = true;
629 if (npc.modNPC != null) {
630 flag = npc.modNPC.StrikeNPC(ref damage, defense, ref knockback, hitDirection, ref crit);
631 }
632 foreach (GlobalNPC g in HookStrikeNPC.arr) {
633 if (!g.Instance(npc).StrikeNPC(npc, ref damage, defense, ref knockback, hitDirection, ref crit)) {
634 flag = false;
635 }
636 }
637 return flag;
638 }
639
640 private delegate void DelegateBossHeadSlot(NPC npc, ref int index);
641 private static HookList HookBossHeadSlot = AddHook<DelegateBossHeadSlot>(g => g.BossHeadSlot);
642
643 public static void BossHeadSlot(NPC npc, ref int index) {
644 npc.modNPC?.BossHeadSlot(ref index);
645
646 foreach (GlobalNPC g in HookBossHeadSlot.arr) {
647 g.Instance(npc).BossHeadSlot(npc, ref index);
648 }
649 }
650
651 private delegate void DelegateBossHeadRotation(NPC npc, ref float rotation);
652 private static HookList HookBossHeadRotation = AddHook<DelegateBossHeadRotation>(g => g.BossHeadRotation);
653
654 public static void BossHeadRotation(NPC npc, ref float rotation) {
655 npc.modNPC?.BossHeadRotation(ref rotation);
656
657 foreach (GlobalNPC g in HookBossHeadRotation.arr) {
658 g.Instance(npc).BossHeadRotation(npc, ref rotation);
659 }
660 }
661
662 private delegate void DelegateBossHeadSpriteEffects(NPC npc, ref SpriteEffects spriteEffects);
663 private static HookList HookBossHeadSpriteEffects = AddHook<DelegateBossHeadSpriteEffects>(g => g.BossHeadSpriteEffects);
664
665 public static void BossHeadSpriteEffects(NPC npc, ref SpriteEffects spriteEffects) {
666 npc.modNPC?.BossHeadSpriteEffects(ref spriteEffects);
667
669 g.Instance(npc).BossHeadSpriteEffects(npc, ref spriteEffects);
670 }
671 }
672
673 private static HookList HookGetAlpha = AddHook<Func<NPC, Color, Color?>>(g => g.GetAlpha);
674
675 public static Color? GetAlpha(NPC npc, Color lightColor) {
676 foreach (GlobalNPC g in HookGetAlpha.arr) {
677 Color? color = g.Instance(npc).GetAlpha(npc, lightColor);
678 if (color.HasValue) {
679 return color.Value;
680 }
681 }
682 return npc.modNPC?.GetAlpha(lightColor);
683 }
684
685 private delegate void DelegateDrawEffects(NPC npc, ref Color drawColor);
686 private static HookList HookDrawEffects = AddHook<DelegateDrawEffects>(g => g.DrawEffects);
687
688 public static void DrawEffects(NPC npc, ref Color drawColor) {
689 npc.modNPC?.DrawEffects(ref drawColor);
690
691 foreach (GlobalNPC g in HookDrawEffects.arr) {
692 g.Instance(npc).DrawEffects(npc, ref drawColor);
693 }
694 }
695
696 private static HookList HookPreDraw = AddHook<Func<NPC, SpriteBatch, Color, bool>>(g => g.PreDraw);
697
698 public static bool PreDraw(NPC npc, SpriteBatch spriteBatch, Color drawColor) {
699 bool result = true;
700 foreach (GlobalNPC g in HookPreDraw.arr) {
701 result &= g.Instance(npc).PreDraw(npc, spriteBatch, drawColor);
702 }
703 if (result && npc.modNPC != null) {
704 return npc.modNPC.PreDraw(spriteBatch, drawColor);
705 }
706 return result;
707 }
708
709 private static HookList HookPostDraw = AddHook<Action<NPC, SpriteBatch, Color>>(g => g.PostDraw);
710
711 public static void PostDraw(NPC npc, SpriteBatch spriteBatch, Color drawColor) {
712 npc.modNPC?.PostDraw(spriteBatch, drawColor);
713
714 foreach (GlobalNPC g in HookPostDraw.arr) {
715 g.Instance(npc).PostDraw(npc, spriteBatch, drawColor);
716 }
717 }
718
719 private static HookList HookDrawBehind = AddHook<Action<NPC, int>>(g => g.DrawBehind);
720
721 internal static void DrawBehind(NPC npc, int index)
722 {
723 npc.modNPC?.DrawBehind(index);
724
725 foreach (GlobalNPC g in HookDrawBehind.arr) {
726 g.Instance(npc).DrawBehind(npc, index);
727 }
728 }
729
730 private delegate bool? DelegateDrawHealthBar(NPC npc, byte bhPosition, ref float scale, ref Vector2 position);
731 private static HookList HookDrawHealthBar = AddHook<DelegateDrawHealthBar>(g => g.DrawHealthBar);
732
733 public static bool DrawHealthBar(NPC npc, ref float scale) {
734 Vector2 position = new Vector2(npc.position.X + npc.width / 2, npc.position.Y + npc.gfxOffY);
735 if (Main.HealthBarDrawSettings == 1) {
736 position.Y += npc.height + 10f + Main.NPCAddHeight(npc.whoAmI);
737 }
738 else if (Main.HealthBarDrawSettings == 2) {
739 position.Y -= 24f + Main.NPCAddHeight(npc.whoAmI) / 2f;
740 }
741 foreach (GlobalNPC g in HookDrawHealthBar.arr) {
742 bool? result = g.Instance(npc).DrawHealthBar(npc, Main.HealthBarDrawSettings, ref scale, ref position);
743 if (result.HasValue) {
744 if (result.Value) {
745 DrawHealthBar(npc, position, scale);
746 }
747 return false;
748 }
749 }
750 if (NPCLoader.IsModNPC(npc)) {
751 bool? result = npc.modNPC.DrawHealthBar(Main.HealthBarDrawSettings, ref scale, ref position);
752 if (result.HasValue) {
753 if (result.Value) {
754 DrawHealthBar(npc, position, scale);
755 }
756 return false;
757 }
758 }
759 return true;
760 }
761
762 private static void DrawHealthBar(NPC npc, Vector2 position, float scale) {
763 float alpha = Lighting.Brightness((int)(npc.Center.X / 16f), (int)(npc.Center.Y / 16f));
764 Main.instance.DrawHealthBar(position.X, position.Y, npc.life, npc.lifeMax, alpha, scale);
765 }
766
767 private delegate void DelegateEditSpawnRate(Player player, ref int spawnRate, ref int maxSpawns);
768 private static HookList HookEditSpawnRate = AddHook<DelegateEditSpawnRate>(g => g.EditSpawnRate);
769
770 public static void EditSpawnRate(Player player, ref int spawnRate, ref int maxSpawns) {
771 foreach (GlobalNPC g in HookEditSpawnRate.arr) {
772 g.EditSpawnRate(player, ref spawnRate, ref maxSpawns);
773 }
774 }
775
776 private delegate void DelegateEditSpawnRange(Player player, ref int spawnRangeX, ref int spawnRangeY,
777 ref int safeRangeX, ref int safeRangeY);
778 private static HookList HookEditSpawnRange = AddHook<DelegateEditSpawnRange>(g => g.EditSpawnRange);
779
780 public static void EditSpawnRange(Player player, ref int spawnRangeX, ref int spawnRangeY,
781 ref int safeRangeX, ref int safeRangeY) {
782 foreach (GlobalNPC g in HookEditSpawnRange.arr) {
783 g.EditSpawnRange(player, ref spawnRangeX, ref spawnRangeY, ref safeRangeX, ref safeRangeY);
784 }
785 }
786
787 private static HookList HookEditSpawnPool = AddHook<Action<Dictionary<int, float>, NPCSpawnInfo>>(g => g.EditSpawnPool);
788
789 public static int? ChooseSpawn(NPCSpawnInfo spawnInfo) {
790 NPCSpawnHelper.Reset();
791 NPCSpawnHelper.DoChecks(spawnInfo);
792 IDictionary<int, float> pool = new Dictionary<int, float>();
793 pool[0] = 1f;
794 foreach (ModNPC npc in npcs) {
795 float weight = npc.SpawnChance(spawnInfo);
796 if (weight > 0f) {
797 pool[npc.npc.type] = weight;
798 }
799 }
800 foreach (GlobalNPC g in HookEditSpawnPool.arr) {
801 g.EditSpawnPool(pool, spawnInfo);
802 }
803 float totalWeight = 0f;
804 foreach (int type in pool.Keys) {
805 if (pool[type] < 0f) {
806 pool[type] = 0f;
807 }
808 totalWeight += pool[type];
809 }
810 float choice = (float)Main.rand.NextDouble() * totalWeight;
811 foreach (int type in pool.Keys) {
812 float weight = pool[type];
813 if (choice < weight) {
814 return type;
815 }
816 choice -= weight;
817 }
818 return null;
819 }
820
821 private static HookList HookSpawnNPC = AddHook<Action<int, int, int>>(g => g.SpawnNPC);
822
823 public static int SpawnNPC(int type, int tileX, int tileY) {
824 var npc = type >= NPCID.Count ?
825 GetNPC(type).SpawnNPC(tileX, tileY) :
826 NPC.NewNPC(tileX * 16 + 8, tileY * 16, type);
827
828 foreach (GlobalNPC g in HookSpawnNPC.arr) {
829 g.Instance(Main.npc[npc]).SpawnNPC(npc, tileX, tileY);
830 }
831
832 return npc;
833 }
834
835 public static void CanTownNPCSpawn(int numTownNPCs, int money) {
836 foreach (ModNPC npc in npcs) {
837 if (npc.npc.townNPC && NPC.TypeToHeadIndex(npc.npc.type) >= 0 && !NPC.AnyNPCs(npc.npc.type) &&
838 npc.CanTownNPCSpawn(numTownNPCs, money)) {
839 Main.townNPCCanSpawn[npc.npc.type] = true;
840 if (WorldGen.prioritizedTownNPC == 0) {
841 WorldGen.prioritizedTownNPC = npc.npc.type;
842 }
843 }
844 }
845 }
846
847 public static bool CheckConditions(int type) {
848 return GetNPC(type)?.CheckConditions(WorldGen.roomX1, WorldGen.roomX2, WorldGen.roomY1, WorldGen.roomY2) ?? true;
849 }
850
851 public static string TownNPCName(int type) {
852 return GetNPC(type)?.TownNPCName() ?? "";
853 }
854
855 public static bool UsesPartyHat(NPC npc) {
856 return npc.modNPC?.UsesPartyHat() ?? true;
857 }
858
859 private static HookList HookCanChat = AddHook<Func<NPC, bool?>>(g => g.CanChat);
860
861 public static bool CanChat(NPC npc, bool vanillaCanChat) {
862 bool defaultCanChat = npc.modNPC?.CanChat() ?? vanillaCanChat;
863
864 foreach (GlobalNPC g in HookCanChat.arr) {
865 bool? canChat = g.Instance(npc).CanChat(npc);
866 if (canChat.HasValue) {
867 if (!canChat.Value) {
868 return false;
869 }
870 defaultCanChat = true;
871 }
872 }
873
874 return defaultCanChat;
875 }
876
877 private delegate void DelegateGetChat(NPC npc, ref string chat);
878 private static HookList HookGetChat = AddHook<DelegateGetChat>(g => g.GetChat);
879
880 public static void GetChat(NPC npc, ref string chat) {
881 if (npc.modNPC != null) {
882 chat = npc.modNPC.GetChat();
883 }
884 else if (chat.Equals("")) {
885 chat = Language.GetTextValue("tModLoader.DefaultTownNPCChat");
886 }
887 foreach (GlobalNPC g in HookGetChat.arr) {
888 g.Instance(npc).GetChat(npc, ref chat);
889 }
890 }
891
892 public static void SetChatButtons(ref string button, ref string button2) {
893 if (Main.player[Main.myPlayer].talkNPC >= 0) {
894 NPC npc = Main.npc[Main.player[Main.myPlayer].talkNPC];
895 npc.modNPC?.SetChatButtons(ref button, ref button2);
896 }
897 }
898
899 private static HookList HookPreChatButtonClicked = AddHook<Func<NPC, bool, bool>>(g => g.PreChatButtonClicked);
900
901 public static bool PreChatButtonClicked(bool firstButton) {
902 NPC npc = Main.npc[Main.LocalPlayer.talkNPC];
903
904 bool result = true;
905 foreach (GlobalNPC g in HookPreChatButtonClicked.arr) {
906 result &= g.Instance(npc).PreChatButtonClicked(npc, firstButton);
907 }
908
909 if (!result) {
910 Main.PlaySound(SoundID.MenuTick);
911 return false;
912 }
913
914 return true;
915 }
916
917 private delegate void DelegateOnChatButtonClicked(NPC npc, bool firstButton);
918 private static HookList HookOnChatButtonClicked = AddHook<DelegateOnChatButtonClicked>(g => g.OnChatButtonClicked);
919
920 public static void OnChatButtonClicked(bool firstButton) {
921 NPC npc = Main.npc[Main.LocalPlayer.talkNPC];
922 bool shop = false;
923
924 if (npc.modNPC != null) {
925 npc.modNPC.OnChatButtonClicked(firstButton, ref shop);
926 Main.PlaySound(SoundID.MenuTick);
927 if (shop) {
928 Main.playerInventory = true;
929 Main.npcChatText = "";
930 Main.npcShop = Main.MaxShopIDs - 1;
931 Main.instance.shop[Main.npcShop].SetupShop(npc.type);
932 }
933 }
934 foreach (GlobalNPC g in HookOnChatButtonClicked.arr) {
935 g.Instance(npc).OnChatButtonClicked(npc, firstButton);
936 }
937 }
938
939 private delegate void DelegateSetupShop(int type, Chest shop, ref int nextSlot);
940 private static HookList HookSetupShop = AddHook<DelegateSetupShop>(g => g.SetupShop);
941
942 public static void SetupShop(int type, Chest shop, ref int nextSlot) {
943 if (type < shopToNPC.Length) {
944 type = shopToNPC[type];
945 }
946 else {
947 GetNPC(type)?.SetupShop(shop, ref nextSlot);
948 }
949 foreach (GlobalNPC g in HookSetupShop.arr) {
950 g.SetupShop(type, shop, ref nextSlot);
951 }
952 }
953
954 private delegate void DelegateSetupTravelShop(int[] shop, ref int nextSlot);
955 private static HookList HookSetupTravelShop = AddHook<DelegateSetupTravelShop>(g => g.SetupTravelShop);
956
957 public static void SetupTravelShop(int[] shop, ref int nextSlot) {
958 foreach (GlobalNPC g in HookSetupTravelShop.arr) {
959 g.SetupTravelShop(shop, ref nextSlot);
960 }
961 }
962
963 private static HookList HookCanGoToStatue = AddHook<Func<NPC, bool, bool?>>(g => g.CanGoToStatue);
964
965 public static bool CanGoToStatue(NPC npc, bool toKingStatue, bool vanillaCanGo) {
966 bool defaultCanGo = npc.modNPC?.CanGoToStatue(toKingStatue) ?? vanillaCanGo;
967
968 foreach (GlobalNPC g in HookCanGoToStatue.arr) {
969 bool? canGo = g.Instance(npc).CanGoToStatue(npc, toKingStatue);
970 if (canGo.HasValue) {
971 if (!canGo.Value) {
972 return false;
973 }
974 defaultCanGo = true;
975 }
976 }
977
978 return defaultCanGo;
979 }
980
981 private static HookList HookOnGoToStatue = AddHook<Action<NPC, bool>>(g => g.OnGoToStatue);
982
983 public static void OnGoToStatue(NPC npc, bool toKingStatue) {
984 npc.modNPC?.OnGoToStatue(toKingStatue);
985
986 foreach (GlobalNPC g in HookOnGoToStatue.arr) {
987 g.OnGoToStatue(npc, toKingStatue);
988 }
989 }
990
991 private delegate void DelegateBuffTownNPC(ref float damageMult, ref int defense);
992 private static HookList HookBuffTownNPC = AddHook<DelegateBuffTownNPC>(g => g.BuffTownNPC);
993
994 public static void BuffTownNPC(ref float damageMult, ref int defense) {
995 foreach (GlobalNPC g in HookBuffTownNPC.arr) {
996 g.BuffTownNPC(ref damageMult, ref defense);
997 }
998 }
999 //attack type 0 = throwing
1000 // num405 = type, num406 = damage, knockBack, scaleFactor7 = speed multiplier, num407 = attack delay
1001 // num408 = unknown, maxValue3 = unknown, num409 = gravity correction factor, num411 = random speed offset
1002 //attack type 1 = shooting
1003 // num413 = type, num414 = damage, scaleFactor8 = speed multiplier, num415 = attack delay,
1004 // num416 = unknown, maxValue4 = unknown, knockBack2, num417 = gravity correction,
1005 // flag53 = in between shots, num418 = random speed offset
1006 //attack type 2 = magic
1007 // num423 = type, num424 = damage, scaleFactor9 = speed multiplier, num425 = attack delay,
1008 // num426 = unknown, maxValue5 = unknown, knockBack3, num427 = gravity correction factor,
1009 // num429 = aura light multiplier, num430 = random speed offset
1010 //attack type 3 = swinging
1011 // num439 = unknown, maxValue6 = unknown, num440 = damage, num441 = knockback,
1012 // num442 = item width, num443 = item height
1013 //unknowns are associated with ai[1], localAI[1], and localAI[3] when ai[0] is either 0 or 8
1014 //check patch files for town NPC attacks
1015 private delegate void DelegateTownNPCAttackStrength(NPC npc, ref int damage, ref float knockback);
1016 private static HookList HookTownNPCAttackStrength = AddHook<DelegateTownNPCAttackStrength>(g => g.TownNPCAttackStrength);
1017
1018 public static void TownNPCAttackStrength(NPC npc, ref int damage, ref float knockback) {
1019 npc.modNPC?.TownNPCAttackStrength(ref damage, ref knockback);
1020
1021 foreach (GlobalNPC g in HookTownNPCAttackStrength.arr) {
1022 g.Instance(npc).TownNPCAttackStrength(npc, ref damage, ref knockback);
1023 }
1024 }
1025
1026 private delegate void DelegateTownNPCAttackCooldown(NPC npc, ref int cooldown, ref int randExtraCooldown);
1027 private static HookList HookTownNPCAttackCooldown = AddHook<DelegateTownNPCAttackCooldown>(g => g.TownNPCAttackCooldown);
1028
1029 public static void TownNPCAttackCooldown(NPC npc, ref int cooldown, ref int randExtraCooldown) {
1030 npc.modNPC?.TownNPCAttackCooldown(ref cooldown, ref randExtraCooldown);
1031
1032 foreach (GlobalNPC g in HookTownNPCAttackCooldown.arr) {
1033 g.Instance(npc).TownNPCAttackCooldown(npc, ref cooldown, ref randExtraCooldown);
1034 }
1035 }
1036
1037 private delegate void DelegateTownNPCAttackProj(NPC npc, ref int projType, ref int attackDelay);
1038 private static HookList HookTownNPCAttackProj = AddHook<DelegateTownNPCAttackProj>(g => g.TownNPCAttackProj);
1039
1040 public static void TownNPCAttackProj(NPC npc, ref int projType, ref int attackDelay) {
1041 npc.modNPC?.TownNPCAttackProj(ref projType, ref attackDelay);
1042
1043 foreach (GlobalNPC g in HookTownNPCAttackProj.arr) {
1044 g.Instance(npc).TownNPCAttackProj(npc, ref projType, ref attackDelay);
1045 }
1046 }
1047
1048 private delegate void DelegateTownNPCAttackProjSpeed(NPC npc, ref float multiplier, ref float gravityCorrection,
1049 ref float randomOffset);
1050 private static HookList HookTownNPCAttackProjSpeed = AddHook<DelegateTownNPCAttackProjSpeed>(g => g.TownNPCAttackProjSpeed);
1051
1052 public static void TownNPCAttackProjSpeed(NPC npc, ref float multiplier, ref float gravityCorrection,
1053 ref float randomOffset) {
1054 npc.modNPC?.TownNPCAttackProjSpeed(ref multiplier, ref gravityCorrection, ref randomOffset);
1055
1057 g.Instance(npc).TownNPCAttackProjSpeed(npc, ref multiplier, ref gravityCorrection, ref randomOffset);
1058 }
1059 }
1060
1061 private delegate void DelegateTownNPCAttackShoot(NPC npc, ref bool inBetweenShots);
1062 private static HookList HookTownNPCAttackShoot = AddHook<DelegateTownNPCAttackShoot>(g => g.TownNPCAttackShoot);
1063
1064 public static void TownNPCAttackShoot(NPC npc, ref bool inBetweenShots) {
1065 npc.modNPC?.TownNPCAttackShoot(ref inBetweenShots);
1066
1067 foreach (GlobalNPC g in HookTownNPCAttackShoot.arr) {
1068 g.Instance(npc).TownNPCAttackShoot(npc, ref inBetweenShots);
1069 }
1070 }
1071
1072 private delegate void DelegateTownNPCAttackMagic(NPC npc, ref float auraLightMultiplier);
1073 private static HookList HookTownNPCAttackMagic = AddHook<DelegateTownNPCAttackMagic>(g => g.TownNPCAttackMagic);
1074
1075 public static void TownNPCAttackMagic(NPC npc, ref float auraLightMultiplier) {
1076 npc.modNPC?.TownNPCAttackMagic(ref auraLightMultiplier);
1077
1078 foreach (GlobalNPC g in HookTownNPCAttackMagic.arr) {
1079 g.Instance(npc).TownNPCAttackMagic(npc, ref auraLightMultiplier);
1080 }
1081 }
1082
1083 private delegate void DelegateTownNPCAttackSwing(NPC npc, ref int itemWidth, ref int itemHeight);
1084 private static HookList HookTownNPCAttackSwing = AddHook<DelegateTownNPCAttackSwing>(g => g.TownNPCAttackSwing);
1085
1086 public static void TownNPCAttackSwing(NPC npc, ref int itemWidth, ref int itemHeight) {
1087 npc.modNPC?.TownNPCAttackSwing(ref itemWidth, ref itemHeight);
1088
1089 foreach (GlobalNPC g in HookTownNPCAttackSwing.arr) {
1090 g.Instance(npc).TownNPCAttackSwing(npc, ref itemWidth, ref itemHeight);
1091 }
1092 }
1093
1094 private delegate void DelegateDrawTownAttackGun(NPC npc, ref float scale, ref int item, ref int closeness);
1095 private static HookList HookDrawTownAttackGun = AddHook<DelegateDrawTownAttackGun>(g => g.DrawTownAttackGun);
1096
1097 public static void DrawTownAttackGun(NPC npc, ref float scale, ref int item, ref int closeness) {
1098 npc.modNPC?.DrawTownAttackGun(ref scale, ref item, ref closeness);
1099
1100 foreach (GlobalNPC g in HookDrawTownAttackGun.arr) {
1101 g.Instance(npc).DrawTownAttackGun(npc, ref scale, ref item, ref closeness);
1102 }
1103 }
1104
1105 private delegate void DelegateDrawTownAttackSwing(NPC npc, ref Texture2D item, ref int itemSize, ref float scale, ref Vector2 offset);
1106 private static HookList HookDrawTownAttackSwing = AddHook<DelegateDrawTownAttackSwing>(g => g.DrawTownAttackSwing);
1107
1108 public static void DrawTownAttackSwing(NPC npc, ref Texture2D item, ref int itemSize, ref float scale, ref Vector2 offset) {
1109 npc.modNPC?.DrawTownAttackSwing(ref item, ref itemSize, ref scale, ref offset);
1110
1111 foreach (GlobalNPC g in HookDrawTownAttackSwing.arr) {
1112 g.Instance(npc).DrawTownAttackSwing(npc, ref item, ref itemSize, ref scale, ref offset);
1113 }
1114 }
1115
1116 private static bool HasMethod(Type t, string method, params Type[] args) {
1117 return t.GetMethod(method, args).DeclaringType != typeof(GlobalNPC);
1118 }
1119
1120 internal static void VerifyGlobalNPC(GlobalNPC npc) {
1121 var type = npc.GetType();
1122
1123 bool hasInstanceFields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
1124 .Any(f => f.DeclaringType != typeof(GlobalNPC));
1125 if (hasInstanceFields) {
1126 if (!npc.InstancePerEntity) {
1127 throw new Exception(type + " has instance fields but does not set InstancePerEntity to true. Either use static fields, or per instance globals");
1128 }
1129 }
1130 }
1131 }
1132}
This serves as the central class from which buff-related functions are supported and carried out.
Definition: BuffLoader.cs:15
This class allows you to modify and use hooks for all NPCs, including vanilla mobs....
Definition: GlobalNPC.cs:12
virtual void TownNPCAttackMagic(NPC npc, ref float auraLightMultiplier)
Allows you to control the brightness of the light emitted by a town NPC's aura when it performs a mag...
Definition: GlobalNPC.cs:598
virtual bool CanHitPlayer(NPC npc, Player target, ref int cooldownSlot)
Allows you to determine whether an NPC can hit the given player. Return false to block the NPC from h...
Definition: GlobalNPC.cs:210
virtual ? bool CanBeHitByItem(NPC npc, Player player, Item item)
Allows you to determine whether an NPC can be hit by the given melee weapon when swung....
Definition: GlobalNPC.cs:273
virtual void DrawBehind(NPC npc, int index)
When used in conjunction with "npc.hide = true", allows you to specify that this npc should be drawn ...
Definition: GlobalNPC.cs:415
virtual ? bool DrawHealthBar(NPC npc, byte hbPosition, ref float scale, ref Vector2 position)
Allows you to control how the health bar for the given NPC is drawn. The hbPosition parameter is the ...
Definition: GlobalNPC.cs:427
virtual void BossHeadRotation(NPC npc, ref float rotation)
Allows you to customize the rotation of an NPC's boss head icon on the map.
Definition: GlobalNPC.cs:361
virtual void OnHitByItem(NPC npc, Player player, Item item, int damage, float knockback, bool crit)
Allows you to create special effects when an NPC is hit by a melee weapon.
Definition: GlobalNPC.cs:298
virtual ? Color GetAlpha(NPC npc, Color drawColor)
Allows you to determine the color and transparency in which an NPC is drawn. Return null to use the d...
Definition: GlobalNPC.cs:378
virtual void BossHeadSlot(NPC npc, ref int index)
Allows you to customize the boss head texture used by an NPC based on its state. Set index to -1 to s...
Definition: GlobalNPC.cs:353
virtual void TownNPCAttackStrength(NPC npc, ref int damage, ref float knockback)
Allows you to determine the damage and knockback of a town NPC's attack before the damage is scaled....
Definition: GlobalNPC.cs:553
virtual void SetupTravelShop(int[] shop, ref int nextSlot)
Allows you to add items to the traveling merchant's shop. Add an item by setting shop[nextSlot] to th...
Definition: GlobalNPC.cs:518
virtual bool StrikeNPC(NPC npc, ref double damage, int defense, ref float knockback, int hitDirection, ref bool crit)
Allows you to use a custom damage formula for when an NPC takes damage from any source....
Definition: GlobalNPC.cs:344
virtual ? bool CanChat(NPC npc)
Allows you to determine whether this NPC can talk with the player. Return true to allow talking with ...
Definition: GlobalNPC.cs:474
virtual void OnHitPlayer(NPC npc, Player target, int damage, bool crit)
Allows you to create special effects when an NPC hits a player (for example, inflicting debuffs).
Definition: GlobalNPC.cs:231
virtual void TownNPCAttackSwing(NPC npc, ref int itemWidth, ref int itemHeight)
Allows you to determine the width and height of the item a town NPC swings when it attacks,...
Definition: GlobalNPC.cs:607
virtual void SetupShop(int type, Chest shop, ref int nextSlot)
Allows you to add items to an NPC's shop. The type parameter is the type of the NPC that this shop be...
Definition: GlobalNPC.cs:510
virtual bool PreDraw(NPC npc, SpriteBatch spriteBatch, Color drawColor)
Allows you to draw things behind an NPC, or to modify the way the NPC is drawn. Return false to stop ...
Definition: GlobalNPC.cs:397
virtual void EditSpawnRate(Player player, ref int spawnRate, ref int maxSpawns)
Allows you to modify the chance of NPCs spawning around the given player and the maximum number of NP...
Definition: GlobalNPC.cs:437
virtual bool CheckActive(NPC npc)
Whether or not to run the code for checking whether an NPC will remain active. Return false to stop t...
Definition: GlobalNPC.cs:157
virtual void GetChat(NPC npc, ref string chat)
Allows you to modify the chat message of any NPC that the player can talk to.
Definition: GlobalNPC.cs:483
virtual void UpdateLifeRegen(NPC npc, ref int damage)
Allows you to make the NPC either regenerate health or take damage over time by setting npc....
Definition: GlobalNPC.cs:149
virtual void PostAI(NPC npc)
Allows you to determine how any NPC behaves. This will be called regardless of what PreAI returns.
Definition: GlobalNPC.cs:124
virtual void ResetEffects(NPC npc)
This is where you reset any fields you add to your subclass to their default states....
Definition: GlobalNPC.cs:101
virtual void OnChatButtonClicked(NPC npc, bool firstButton)
Allows you to make something happen whenever a button is clicked on this NPC's chat window....
Definition: GlobalNPC.cs:501
virtual bool InstancePerEntity
Whether to create a new GlobalNPC instance for every NPC that exists. Useful for storing information ...
Definition: GlobalNPC.cs:46
virtual void TownNPCAttackProjSpeed(NPC npc, ref float multiplier, ref float gravityCorrection, ref float randomOffset)
Allows you to determine the speed at which a town NPC throws a projectile when it attacks....
Definition: GlobalNPC.cs:581
GlobalNPC Instance(NPC npc)
virtual void SpawnNPC(int npc, int tileX, int tileY)
Allows you to customize an NPC (for example, its position or ai array) after it naturally spawns and ...
Definition: GlobalNPC.cs:466
virtual void ModifyHitPlayer(NPC npc, Player target, ref int damage, ref bool crit)
Allows you to modify the damage, etc., that an NPC does to a player.
Definition: GlobalNPC.cs:221
virtual void ModifyHitByItem(NPC npc, Player player, Item item, ref int damage, ref float knockback, ref bool crit)
Allows you to modify the damage, knockback, etc., that an NPC takes from a melee weapon.
Definition: GlobalNPC.cs:286
virtual ? bool CanHitNPC(NPC npc, NPC target)
Allows you to determine whether an NPC can hit the given friendly NPC. Return true to allow hitting t...
Definition: GlobalNPC.cs:240
virtual bool PreNPCLoot(NPC npc)
Allows you to determine whether or not the NPC will drop anything at all. Return false to stop the NP...
Definition: GlobalNPC.cs:183
virtual void PostDraw(NPC npc, SpriteBatch spriteBatch, Color drawColor)
Allows you to draw things in front of this NPC. This method is called even if PreDraw returns false.
Definition: GlobalNPC.cs:407
virtual void TownNPCAttackShoot(NPC npc, ref bool inBetweenShots)
Allows you to tell the game that a town NPC has already created a projectile and will still create mo...
Definition: GlobalNPC.cs:590
virtual void EditSpawnRange(Player player, ref int spawnRangeX, ref int spawnRangeY, ref int safeRangeX, ref int safeRangeY)
Allows you to modify the range at which NPCs can spawn around the given player. The spawnRanges deter...
Definition: GlobalNPC.cs:448
virtual bool PreChatButtonClicked(NPC npc, bool firstButton)
Allows you to determine if something can happen whenever a button is clicked on this NPC's chat windo...
Definition: GlobalNPC.cs:492
virtual void BossHeadSpriteEffects(NPC npc, ref SpriteEffects spriteEffects)
Allows you to flip an NPC's boss head icon on the map.
Definition: GlobalNPC.cs:369
virtual void OnHitByProjectile(NPC npc, Projectile projectile, int damage, float knockback, bool crit)
Allows you to create special effects when an NPC is hit by a projectile.
Definition: GlobalNPC.cs:331
virtual void ScaleExpertStats(NPC npc, int numPlayers, float bossLifeScale)
Allows you to customize an NPC's stats in expert mode.
Definition: GlobalNPC.cs:94
virtual void DrawTownAttackSwing(NPC npc, ref Texture2D item, ref int itemSize, ref float scale, ref Vector2 offset)
Allows you to customize how a town NPC's weapon is drawn when the NPC is swinging it (the NPC must ha...
Definition: GlobalNPC.cs:628
virtual void AI(NPC npc)
Allows you to determine how any NPC behaves. This will only be called if PreAI returns true.
Definition: GlobalNPC.cs:117
virtual void OnCatchNPC(NPC npc, Player player, Item item)
Allows you to make things happen when an NPC is caught. Ran Serverside.
Definition: GlobalNPC.cs:200
virtual void ModifyHitByProjectile(NPC npc, Projectile projectile, ref int damage, ref float knockback, ref bool crit, ref int hitDirection)
Allows you to modify the damage, knockback, etc., that an NPC takes from a projectile.
Definition: GlobalNPC.cs:320
virtual void DrawEffects(NPC npc, ref Color drawColor)
Allows you to add special visual effects to an NPC (such as creating dust), and modify the color in w...
Definition: GlobalNPC.cs:387
virtual ? bool CanBeHitByProjectile(NPC npc, Projectile projectile)
Allows you to determine whether an NPC can be hit by the given projectile. Return true to allow hitti...
Definition: GlobalNPC.cs:307
virtual void ModifyHitNPC(NPC npc, NPC target, ref int damage, ref float knockback, ref bool crit)
Allows you to modify the damage, knockback, etc., that an NPC does to a friendly NPC.
Definition: GlobalNPC.cs:252
virtual void BuffTownNPC(ref float damageMult, ref int defense)
Allows you to modify the stats of town NPCs. Useful for buffing town NPCs when certain bosses are def...
Definition: GlobalNPC.cs:544
virtual void SetDefaults(NPC npc)
Allows you to set the properties of any and every NPC that gets created.
Definition: GlobalNPC.cs:85
virtual void DrawTownAttackGun(NPC npc, ref float scale, ref int item, ref int closeness)
Allows you to customize how a town NPC's weapon is drawn when the NPC is shooting (the NPC must have ...
Definition: GlobalNPC.cs:617
virtual void OnGoToStatue(NPC npc, bool toKingStatue)
Allows you to make things happen when this NPC teleports to a King or Queen statue....
Definition: GlobalNPC.cs:536
virtual bool PreAI(NPC npc)
Allows you to determine how any NPC behaves. Return false to stop the vanilla AI and the AI hook from...
Definition: GlobalNPC.cs:109
virtual void NPCLoot(NPC npc)
Allows you to make things happen when an NPC dies (for example, dropping items and setting ModWorld f...
Definition: GlobalNPC.cs:191
virtual void EditSpawnPool(IDictionary< int, float > pool, NPCSpawnInfo spawnInfo)
Allows you to control which NPCs can spawn and how likely each one is to spawn. The pool parameter ma...
Definition: GlobalNPC.cs:457
virtual bool SpecialNPCLoot(NPC npc)
Allows you to call NPCLoot on your own when the NPC dies, rather then letting vanilla call it on its ...
Definition: GlobalNPC.cs:174
virtual void TownNPCAttackCooldown(NPC npc, ref int cooldown, ref int randExtraCooldown)
Allows you to determine the cooldown between each of a town NPC's attack. The cooldown will be a numb...
Definition: GlobalNPC.cs:562
virtual ? bool CanGoToStatue(NPC npc, bool toKingStatue)
Whether this NPC can be telported a King or Queen statue. Return true to allow the NPC to teleport to...
Definition: GlobalNPC.cs:526
virtual void FindFrame(NPC npc, int frameHeight)
Allows you to modify the frame from an NPC's texture that is drawn, which is necessary in order to an...
Definition: GlobalNPC.cs:132
virtual void HitEffect(NPC npc, int hitDirection, double damage)
Allows you to make things happen whenever an NPC is hit, such as creating dust or gores....
Definition: GlobalNPC.cs:141
virtual void TownNPCAttackProj(NPC npc, ref int projType, ref int attackDelay)
Allows you to determine the projectile type of a town NPC's attack, and how long it takes for the pro...
Definition: GlobalNPC.cs:571
virtual bool CheckDead(NPC npc)
Whether or not an NPC should be killed when it reaches 0 health. You may program extra effects in thi...
Definition: GlobalNPC.cs:166
virtual void OnHitNPC(NPC npc, NPC target, int damage, float knockback, bool crit)
Allows you to create special effects when an NPC hits a friendly NPC.
Definition: GlobalNPC.cs:263
Mod is an abstract class that you will override. It serves as a central place from which the mod's co...
Definition: Mod.cs:25
virtual string Name
Stores the name of the mod. This name serves as the mod's identification, and also helps with saving ...
Definition: Mod.cs:42
This serves as the central class which loads mods. It contains many static fields and methods related...
Definition: ModLoader.cs:29
This class serves as a place for you to place all your properties and hooks for each NPC....
Definition: ModNPC.cs:15
virtual string TownNPCName()
Allows you to give this town NPC any name when it spawns. By default returns something embarrassing.
Definition: ModNPC.cs:596
NPC npc
The NPC object that this ModNPC controls.
Definition: ModNPC.cs:21
virtual bool CheckConditions(int left, int right, int top, int bottom)
Allows you to define special conditions required for this town NPC's house. For example,...
Definition: ModNPC.cs:588
virtual bool CanTownNPCSpawn(int numTownNPCs, int money)
Whether or not the conditions have been met for this town NPC to be able to move into town....
Definition: ModNPC.cs:576
virtual void SetupShop(Chest shop, ref int nextSlot)
Allows you to add items to this NPC's shop. Add an item by setting the defaults of shop....
Definition: ModNPC.cs:645
virtual ModNPC NewInstance(NPC npcClone)
Create a new instance of this ModNPC for an NPC instance. Called at the end of NPC....
Definition: ModNPC.cs:153
virtual int SpawnNPC(int tileX, int tileY)
Allows you to customize how this NPC is created when it naturally spawns (for example,...
Definition: ModNPC.cs:566
virtual float SpawnChance(NPCSpawnInfo spawnInfo)
Whether or not this NPC can spawn with the given spawning conditions. Return the weight for the chanc...
Definition: ModNPC.cs:556
static bool AllowVanillaClients
Definition: ModNet.cs:53
This serves as the central class from which NPC-related functions are carried out....
Definition: NPCLoader.cs:20
static void DrawHealthBar(NPC npc, Vector2 position, float scale)
Definition: NPCLoader.cs:762
static void OnHitByItem(NPC npc, Player player, Item item, int damage, float knockback, bool crit)
Definition: NPCLoader.cs:570
static void BossBag(NPC npc, ref int bagType)
Definition: NPCLoader.cs:435
delegate void DelegateTownNPCAttackProj(NPC npc, ref int projType, ref int attackDelay)
static bool CheckConditions(int type)
Definition: NPCLoader.cs:847
static HookList HookModifyHitNPC
Definition: NPCLoader.cs:513
static int SpawnNPC(int type, int tileX, int tileY)
Definition: NPCLoader.cs:823
static HookList HookUpdateLifeRegen
Definition: NPCLoader.cs:346
delegate void DelegateTownNPCAttackSwing(NPC npc, ref int itemWidth, ref int itemHeight)
delegate void DelegateTownNPCAttackShoot(NPC npc, ref bool inBetweenShots)
static HookList HookTownNPCAttackShoot
Definition: NPCLoader.cs:1062
static HookList HookCanBeHitByProjectile
Definition: NPCLoader.cs:578
static string TownNPCName(int type)
Definition: NPCLoader.cs:851
static void GetChat(NPC npc, ref string chat)
Definition: NPCLoader.cs:880
static void UpdateLifeRegen(NPC npc, ref int damage)
Definition: NPCLoader.cs:348
static void TownNPCAttackStrength(NPC npc, ref int damage, ref float knockback)
Definition: NPCLoader.cs:1018
static HookList HookTownNPCAttackCooldown
Definition: NPCLoader.cs:1027
static ModNPC GetNPC(int type)
Gets the ModNPC instance corresponding to the specified type.
Definition: NPCLoader.cs:93
static void HitEffect(NPC npc, int hitDirection, double damage)
Definition: NPCLoader.cs:336
static bool CanChat(NPC npc, bool vanillaCanChat)
Definition: NPCLoader.cs:861
static HookList HookGetAlpha
Definition: NPCLoader.cs:673
delegate void DelegateSetupTravelShop(int[] shop, ref int nextSlot)
delegate void DelegateBossHeadSlot(NPC npc, ref int index)
static HookList HookSetupShop
Definition: NPCLoader.cs:940
static void DrawTownAttackGun(NPC npc, ref float scale, ref int item, ref int closeness)
Definition: NPCLoader.cs:1097
static bool SpecialNPCLoot(NPC npc)
Definition: NPCLoader.cs:388
static HookList HookBossHeadSlot
Definition: NPCLoader.cs:641
static void AI(NPC npc)
Definition: NPCLoader.cs:270
static HookList HookPreDraw
Definition: NPCLoader.cs:696
static HookList HookTownNPCAttackStrength
Definition: NPCLoader.cs:1016
delegate void DelegateGetChat(NPC npc, ref string chat)
static HookList HookHitEffect
Definition: NPCLoader.cs:334
delegate? bool DelegateDrawHealthBar(NPC npc, byte bhPosition, ref float scale, ref Vector2 position)
static HookList HookSpawnNPC
Definition: NPCLoader.cs:821
static void ResetEffects(NPC npc)
Definition: NPCLoader.cs:231
delegate void DelegateDrawEffects(NPC npc, ref Color drawColor)
static HookList HookSpecialNPCLoot
Definition: NPCLoader.cs:386
static void SendExtraAI(NPC npc, BinaryWriter writer)
Definition: NPCLoader.cs:288
static HookList HookStrikeNPC
Definition: NPCLoader.cs:625
static HookList HookEditSpawnPool
Definition: NPCLoader.cs:787
static bool CheckDead(NPC npc)
Definition: NPCLoader.cs:372
static void DrawTownAttackSwing(NPC npc, ref Texture2D item, ref int itemSize, ref float scale, ref Vector2 offset)
Definition: NPCLoader.cs:1108
static readonly IList< int > blockLoot
Allows you to stop an NPC from dropping loot by adding item IDs to this list. This list will be clear...
Definition: NPCLoader.cs:34
static List< HookList > hooks
Definition: NPCLoader.cs:46
static void NPCAI(NPC npc)
Definition: NPCLoader.cs:239
delegate void DelegateDrawTownAttackGun(NPC npc, ref float scale, ref int item, ref int closeness)
static HookList HookEditSpawnRate
Definition: NPCLoader.cs:768
static bool CheckActive(NPC npc)
Definition: NPCLoader.cs:358
delegate void DelegateTownNPCAttackMagic(NPC npc, ref float auraLightMultiplier)
static HookList HookCanHitPlayer
Definition: NPCLoader.cs:452
static HookList AddHook< F >(Expression< Func< GlobalNPC, F > > func)
Definition: NPCLoader.cs:48
static HookList HookOnGoToStatue
Definition: NPCLoader.cs:981
static void SetupTravelShop(int[] shop, ref int nextSlot)
Definition: NPCLoader.cs:957
static HookList HookDrawBehind
Definition: NPCLoader.cs:719
static ? int ChooseSpawn(NPCSpawnInfo spawnInfo)
Definition: NPCLoader.cs:789
static HookList HookGetChat
Definition: NPCLoader.cs:878
delegate bool DelegateCanHitPlayer(NPC npc, Player target, ref int cooldownSlot)
delegate void DelegateEditSpawnRange(Player player, ref int spawnRangeX, ref int spawnRangeY, ref int safeRangeX, ref int safeRangeY)
static void OnHitByProjectile(NPC npc, Projectile projectile, int damage, float knockback, bool crit)
Definition: NPCLoader.cs:616
static void TownNPCAttackMagic(NPC npc, ref float auraLightMultiplier)
Definition: NPCLoader.cs:1075
static bool CanHitPlayer(NPC npc, Player target, ref int cooldownSlot)
Definition: NPCLoader.cs:454
static HookList HookDrawTownAttackSwing
Definition: NPCLoader.cs:1106
delegate void DelegateDrawTownAttackSwing(NPC npc, ref Texture2D item, ref int itemSize, ref float scale, ref Vector2 offset)
static HookList HookDrawTownAttackGun
Definition: NPCLoader.cs:1095
static void ModifyHitByProjectile(NPC npc, Projectile projectile, ref int damage, ref float knockback, ref bool crit, ref int hitDirection)
Definition: NPCLoader.cs:606
static void TownNPCAttackProj(NPC npc, ref int projType, ref int attackDelay)
Definition: NPCLoader.cs:1040
static void PostDraw(NPC npc, SpriteBatch spriteBatch, Color drawColor)
Definition: NPCLoader.cs:711
static void PostAI(NPC npc)
Definition: NPCLoader.cs:280
static HookList HookNPCLoot
Definition: NPCLoader.cs:420
static HookList HookScaleExpertStats
Definition: NPCLoader.cs:219
static HookList HookCanChat
Definition: NPCLoader.cs:859
static HookList HookBuffTownNPC
Definition: NPCLoader.cs:992
static HookList HookOnHitByItem
Definition: NPCLoader.cs:568
static ? bool CanBeHitByItem(NPC npc, Player player, Item item)
Definition: NPCLoader.cs:534
static HookList HookOnHitNPC
Definition: NPCLoader.cs:523
static HookList HookModifyHitByProjectile
Definition: NPCLoader.cs:604
static HookList HookCanBeHitByItem
Definition: NPCLoader.cs:532
static void DrawEffects(NPC npc, ref Color drawColor)
Definition: NPCLoader.cs:688
static void TownNPCAttackShoot(NPC npc, ref bool inBetweenShots)
Definition: NPCLoader.cs:1064
delegate void DelegateTownNPCAttackStrength(NPC npc, ref int damage, ref float knockback)
delegate void DelegateEditSpawnRate(Player player, ref int spawnRate, ref int maxSpawns)
static void OnHitNPC(NPC npc, NPC target, int damage, float knockback, bool crit)
Definition: NPCLoader.cs:525
delegate void DelegateModifyHitByItem(NPC npc, Player player, Item item, ref int damage, ref float knockback, ref bool crit)
static void ReceiveExtraAI(NPC npc, BinaryReader reader)
Definition: NPCLoader.cs:305
static HookList HookPreChatButtonClicked
Definition: NPCLoader.cs:899
static HookList HookPreAI
Definition: NPCLoader.cs:255
static bool PreChatButtonClicked(bool firstButton)
Definition: NPCLoader.cs:901
static void FindFrame(NPC npc, int frameHeight)
Definition: NPCLoader.cs:320
static void OnChatButtonClicked(bool firstButton)
Definition: NPCLoader.cs:920
delegate void DelegateBuffTownNPC(ref float damageMult, ref int defense)
static void TownNPCAttackSwing(NPC npc, ref int itemWidth, ref int itemHeight)
Definition: NPCLoader.cs:1086
static void TownNPCAttackProjSpeed(NPC npc, ref float multiplier, ref float gravityCorrection, ref float randomOffset)
Definition: NPCLoader.cs:1052
static void SetChatButtons(ref string button, ref string button2)
Definition: NPCLoader.cs:892
static HookList HookBossHeadRotation
Definition: NPCLoader.cs:652
static HookList HookTownNPCAttackSwing
Definition: NPCLoader.cs:1084
delegate void DelegateBossHeadRotation(NPC npc, ref float rotation)
static HookList HookCanGoToStatue
Definition: NPCLoader.cs:963
static HookList HookCheckDead
Definition: NPCLoader.cs:370
delegate void DelegateModifyHitNPC(NPC npc, NPC target, ref int damage, ref float knockback, ref bool crit)
static HookList HookDrawEffects
Definition: NPCLoader.cs:686
delegate void DelegateUpdateLifeRegen(NPC npc, ref int damage)
static HookList HookCheckActive
Definition: NPCLoader.cs:356
static bool StrikeNPC(NPC npc, ref double damage, int defense, ref float knockback, int hitDirection, ref bool crit)
Definition: NPCLoader.cs:627
delegate void DelegateOnChatButtonClicked(NPC npc, bool firstButton)
delegate void DelegateBossHeadSpriteEffects(NPC npc, ref SpriteEffects spriteEffects)
static HookList HookEditSpawnRange
Definition: NPCLoader.cs:778
static HookList HookTownNPCAttackProjSpeed
Definition: NPCLoader.cs:1050
static void TownNPCAttackCooldown(NPC npc, ref int cooldown, ref int randExtraCooldown)
Definition: NPCLoader.cs:1029
static void BossHeadSlot(NPC npc, ref int index)
Definition: NPCLoader.cs:643
static void BossHeadRotation(NPC npc, ref float rotation)
Definition: NPCLoader.cs:654
static void EditSpawnRate(Player player, ref int spawnRate, ref int maxSpawns)
Definition: NPCLoader.cs:770
static bool DrawHealthBar(NPC npc, ref float scale)
Definition: NPCLoader.cs:733
static HookList HookPreNPCLoot
Definition: NPCLoader.cs:400
static void ModifyHitByItem(NPC npc, Player player, Item item, ref int damage, ref float knockback, ref bool crit)
Definition: NPCLoader.cs:560
static HookList HookOnCatchNPC
Definition: NPCLoader.cs:441
static void ModifyHitNPC(NPC npc, NPC target, ref int damage, ref float knockback, ref bool crit)
Definition: NPCLoader.cs:515
static HookList HookTownNPCAttackProj
Definition: NPCLoader.cs:1038
static HookList HookPostAI
Definition: NPCLoader.cs:278
static void OnHitPlayer(NPC npc, Player target, int damage, bool crit)
Definition: NPCLoader.cs:479
static ? bool CanHitNPC(NPC npc, NPC target)
Definition: NPCLoader.cs:489
static bool PreDraw(NPC npc, SpriteBatch spriteBatch, Color drawColor)
Definition: NPCLoader.cs:698
static HookList HookOnChatButtonClicked
Definition: NPCLoader.cs:918
static bool PreAI(NPC npc)
Definition: NPCLoader.cs:257
delegate void DelegateTownNPCAttackProjSpeed(NPC npc, ref float multiplier, ref float gravityCorrection, ref float randomOffset)
static int vanillaSkeletonCount
Definition: NPCLoader.cs:29
static void BossLoot(NPC npc, ref string name, ref int potionType)
Definition: NPCLoader.cs:431
delegate void DelegateSetupShop(int type, Chest shop, ref int nextSlot)
static HookList HookOnHitPlayer
Definition: NPCLoader.cs:477
static bool HasMethod(Type t, string method, params Type[] args)
Definition: NPCLoader.cs:1116
static HookList HookSetupTravelShop
Definition: NPCLoader.cs:955
delegate bool DelegateStrikeNPC(NPC npc, ref double damage, int defense, ref float knockback, int hitDirection, ref bool crit)
static HookList HookResetEffects
Definition: NPCLoader.cs:229
delegate void DelegateModifyHitByProjectile(NPC npc, Projectile projectile, ref int damage, ref float knockback, ref bool crit, ref int hitDirection)
static void ScaleExpertStats(NPC npc, int numPlayers, float bossLifeScale)
Definition: NPCLoader.cs:221
static HookList HookFindFrame
Definition: NPCLoader.cs:318
static void SetupShop(int type, Chest shop, ref int nextSlot)
Definition: NPCLoader.cs:942
static HookList HookAI
Definition: NPCLoader.cs:268
static HookList HookTownNPCAttackMagic
Definition: NPCLoader.cs:1073
static void NPCLoot(NPC npc)
Definition: NPCLoader.cs:422
delegate void DelegateModifyHitPlayer(NPC npc, Player target, ref int damage, ref bool crit)
static bool CanGoToStatue(NPC npc, bool toKingStatue, bool vanillaCanGo)
Definition: NPCLoader.cs:965
static bool UsesPartyHat(NPC npc)
Definition: NPCLoader.cs:855
static readonly int[] shopToNPC
Definition: NPCLoader.cs:30
static ? Color GetAlpha(NPC npc, Color lightColor)
Definition: NPCLoader.cs:675
static HookList HookDrawHealthBar
Definition: NPCLoader.cs:731
static HookList HookModifyHitByItem
Definition: NPCLoader.cs:558
static HookList HookOnHitByProjectile
Definition: NPCLoader.cs:614
static void BuffTownNPC(ref float damageMult, ref int defense)
Definition: NPCLoader.cs:994
static bool PreNPCLoot(NPC npc)
Definition: NPCLoader.cs:402
static void OnCatchNPC(NPC npc, Player player, Item item)
Definition: NPCLoader.cs:443
static HookList HookCanHitNPC
Definition: NPCLoader.cs:487
static void EditSpawnRange(Player player, ref int spawnRangeX, ref int spawnRangeY, ref int safeRangeX, ref int safeRangeY)
Definition: NPCLoader.cs:780
static HookList HookSetDefaults
Definition: NPCLoader.cs:190
delegate void DelegateTownNPCAttackCooldown(NPC npc, ref int cooldown, ref int randExtraCooldown)
static HookList HookBossHeadSpriteEffects
Definition: NPCLoader.cs:663
static void OnGoToStatue(NPC npc, bool toKingStatue)
Definition: NPCLoader.cs:983
static void BossHeadSpriteEffects(NPC npc, ref SpriteEffects spriteEffects)
Definition: NPCLoader.cs:665
static void ModifyHitPlayer(NPC npc, Player target, ref int damage, ref bool crit)
Definition: NPCLoader.cs:469
static ? bool CanBeHitByProjectile(NPC npc, Projectile projectile)
Definition: NPCLoader.cs:580
static HookList HookModifyHitPlayer
Definition: NPCLoader.cs:467
static void CanTownNPCSpawn(int numTownNPCs, int money)
Definition: NPCLoader.cs:835
static HookList HookPostDraw
Definition: NPCLoader.cs:709
This server as a central class to help modders spawn their npcs. It's basically the vanilla spawn cod...
A struct that stores information regarding where an NPC is naturally spawning and the player it is sp...
Definition: NPCSpawnInfo.cs:7