Terraria ModLoader  0.11.4
A framework for Terraria mods
ItemLoader.cs
Go to the documentation of this file.
1 using Microsoft.Xna.Framework;
2 using Microsoft.Xna.Framework.Graphics;
3 using System;
4 using System.Collections.Generic;
5 using System.Collections.ObjectModel;
6 using System.IO;
7 using System.Linq;
8 using System.Linq.Expressions;
9 using System.Reflection;
10 using Terraria.ID;
11 using Terraria.Localization;
12 using Terraria.ModLoader.IO;
13 using Terraria.UI;
14 using Terraria.Utilities;
15 
16 namespace Terraria.ModLoader
17 {
21  public static class ItemLoader
22  {
23  private static int nextItem = ItemID.Count;
24  internal static readonly IList<ModItem> items = new List<ModItem>();
25  internal static readonly IList<GlobalItem> globalItems = new List<GlobalItem>();
26  internal static GlobalItem[] InstancedGlobals = new GlobalItem[0];
27  internal static GlobalItem[] NetGlobals;
28  internal static readonly IDictionary<string, int> globalIndexes = new Dictionary<string, int>();
29  internal static readonly IDictionary<Type, int> globalIndexesByType = new Dictionary<Type, int>();
30  internal static readonly ISet<int> animations = new HashSet<int>();
31  internal static readonly int vanillaQuestFishCount = Main.anglerQuestItemNetIDs.Length;
32  internal static readonly int[] vanillaWings = new int[Main.maxWings];
33 
34  private class HookList
35  {
36  public GlobalItem[] arr = new GlobalItem[0];
37  public readonly MethodInfo method;
38 
39  public HookList(MethodInfo method) {
40  this.method = method;
41  }
42  }
43 
44  private static List<HookList> hooks = new List<HookList>();
45 
46  private static HookList AddHook<F>(Expression<Func<GlobalItem, F>> func) {
47  var hook = new HookList(ModLoader.Method(func));
48  hooks.Add(hook);
49  return hook;
50  }
51 
52  private static void FindVanillaWings() {
53  if (vanillaWings[1] != 0)
54  return;
55 
56  Item item = new Item();
57  for (int k = 0; k < ItemID.Count; k++) {
58  item.SetDefaults(k);
59  if (item.wingSlot > 0) {
60  vanillaWings[item.wingSlot] = k;
61  }
62  }
63  }
64 
65  internal static int ReserveItemID() {
66  if (ModNet.AllowVanillaClients) throw new Exception("Adding items breaks vanilla client compatibility");
67 
68  int reserveID = nextItem;
69  nextItem++;
70  return reserveID;
71  }
72 
76  public static ModItem GetItem(int type) {
77  return type >= ItemID.Count && type < ItemCount ? items[type - ItemID.Count] : null;
78  }
79 
80  public static int ItemCount => nextItem;
81 
82  internal static void ResizeArrays(bool unloading) {
83  Array.Resize(ref Main.itemTexture, nextItem);
84  Array.Resize(ref Main.itemFlameLoaded, nextItem);
85  Array.Resize(ref Main.itemFlameTexture, nextItem);
86  Array.Resize(ref Main.itemAnimations, nextItem);
87  Array.Resize(ref Item.itemCaches, nextItem);
88  Array.Resize(ref Item.staff, nextItem);
89  Array.Resize(ref Item.claw, nextItem);
90  Array.Resize(ref Lang._itemNameCache, nextItem);
91  Array.Resize(ref Lang._itemTooltipCache, nextItem);
92  Array.Resize(ref ItemID.Sets.BannerStrength, nextItem);
93  Array.Resize(ref ItemID.Sets.KillsToBanner, nextItem);
94  Array.Resize(ref ItemID.Sets.CanFishInLava, nextItem);
95  //Array.Resize(ref ItemID.Sets.TextureCopyLoad, nextItem); //not needed?
96  Array.Resize(ref ItemID.Sets.TrapSigned, nextItem);
97  Array.Resize(ref ItemID.Sets.Deprecated, nextItem);
98  Array.Resize(ref ItemID.Sets.NeverShiny, nextItem);
99  Array.Resize(ref ItemID.Sets.ItemIconPulse, nextItem);
100  Array.Resize(ref ItemID.Sets.ItemNoGravity, nextItem);
101  Array.Resize(ref ItemID.Sets.ExtractinatorMode, nextItem);
102  Array.Resize(ref ItemID.Sets.StaffMinionSlotsRequired, nextItem);
103  Array.Resize(ref ItemID.Sets.ExoticPlantsForDyeTrade, nextItem);
104  Array.Resize(ref ItemID.Sets.NebulaPickup, nextItem);
105  Array.Resize(ref ItemID.Sets.AnimatesAsSoul, nextItem);
106  Array.Resize(ref ItemID.Sets.gunProj, nextItem);
107  Array.Resize(ref ItemID.Sets.SortingPriorityBossSpawns, nextItem);
108  Array.Resize(ref ItemID.Sets.SortingPriorityWiring, nextItem);
109  Array.Resize(ref ItemID.Sets.SortingPriorityMaterials, nextItem);
110  Array.Resize(ref ItemID.Sets.SortingPriorityExtractibles, nextItem);
111  Array.Resize(ref ItemID.Sets.SortingPriorityRopes, nextItem);
112  Array.Resize(ref ItemID.Sets.SortingPriorityPainting, nextItem);
113  Array.Resize(ref ItemID.Sets.SortingPriorityTerraforming, nextItem);
114  Array.Resize(ref ItemID.Sets.GamepadExtraRange, nextItem);
115  Array.Resize(ref ItemID.Sets.GamepadWholeScreenUseRange, nextItem);
116  Array.Resize(ref ItemID.Sets.GamepadSmartQuickReach, nextItem);
117  Array.Resize(ref ItemID.Sets.Yoyo, nextItem);
118  Array.Resize(ref ItemID.Sets.AlsoABuildingItem, nextItem);
119  Array.Resize(ref ItemID.Sets.LockOnIgnoresCollision, nextItem);
120  Array.Resize(ref ItemID.Sets.LockOnAimAbove, nextItem);
121  Array.Resize(ref ItemID.Sets.LockOnAimCompensation, nextItem);
122  Array.Resize(ref ItemID.Sets.SingleUseInGamepad, nextItem);
123  ItemID.Sets.IsAMaterial = new bool[nextItem]; // clears it, which is desired.
124  for (int k = ItemID.Count; k < nextItem; k++) {
125  Lang._itemNameCache[k] = LocalizedText.Empty;
126  Lang._itemTooltipCache[k] = ItemTooltip.None;
127  ItemID.Sets.BannerStrength[k] = new ItemID.BannerEffect(1f);
128  ItemID.Sets.KillsToBanner[k] = 50;
129  Item.itemCaches[k] = -1;
130  //ItemID.Sets.TextureCopyLoad[k] = -1;
131  ItemID.Sets.ExtractinatorMode[k] = -1;
132  ItemID.Sets.StaffMinionSlotsRequired[k] = 1;
133  ItemID.Sets.SortingPriorityBossSpawns[k] = -1;
134  ItemID.Sets.SortingPriorityWiring[k] = -1;
135  ItemID.Sets.SortingPriorityMaterials[k] = -1;
136  ItemID.Sets.SortingPriorityExtractibles[k] = -1;
137  ItemID.Sets.SortingPriorityRopes[k] = -1;
138  ItemID.Sets.SortingPriorityPainting[k] = -1;
139  ItemID.Sets.SortingPriorityTerraforming[k] = -1;
140  }
141 
142  if (unloading)
143  Array.Resize(ref Main.anglerQuestItemNetIDs, vanillaQuestFishCount);
144  else
145  Main.anglerQuestItemNetIDs = Main.anglerQuestItemNetIDs
146  .Concat(items.Where(modItem => modItem.IsQuestFish()).Select(modItem => modItem.item.type))
147  .ToArray();
148 
149  FindVanillaWings();
150 
151  InstancedGlobals = globalItems.Where(g => g.InstancePerEntity).ToArray();
152  for (int i = 0; i < InstancedGlobals.Length; i++) {
153  InstancedGlobals[i].instanceIndex = i;
154  }
155  NetGlobals = ModLoader.BuildGlobalHook<GlobalItem, Action<Item, BinaryWriter>>(globalItems, g => g.NetSend);
156  foreach (var hook in hooks)
157  hook.arr = ModLoader.BuildGlobalHook(globalItems, hook.method);
158  }
159 
160  internal static void Unload() {
161  items.Clear();
162  nextItem = ItemID.Count;
163  globalItems.Clear();
164  globalIndexes.Clear();
165  globalIndexesByType.Clear();
166  animations.Clear();
167  }
168 
169  internal static bool IsModItem(int index) {
170  return index >= ItemID.Count;
171  }
172 
173  private static bool GeneralPrefix(Item item) {
174  return item.maxStack == 1 && item.damage > 0 && item.ammo == 0 && !item.accessory;
175  }
176  //add to Terraria.Item.Prefix
177  internal static bool MeleePrefix(Item item) {
178  return item.modItem != null && GeneralPrefix(item) && item.melee && !item.noUseGraphic;
179  }
180  //add to Terraria.Item.Prefix
181  internal static bool WeaponPrefix(Item item) {
182  return item.modItem != null && GeneralPrefix(item) && item.melee && item.noUseGraphic;
183  }
184  //add to Terraria.Item.Prefix
185  internal static bool RangedPrefix(Item item) {
186  return item.modItem != null && GeneralPrefix(item) && (item.ranged || item.thrown);
187  }
188  //add to Terraria.Item.Prefix
189  internal static bool MagicPrefix(Item item) {
190  return item.modItem != null && GeneralPrefix(item) && (item.magic || item.summon);
191  }
192 
193  private static HookList HookSetDefaults = AddHook<Action<Item>>(g => g.SetDefaults);
194 
195  internal static void SetDefaults(Item item, bool createModItem = true) {
196  if (IsModItem(item.type) && createModItem)
197  item.modItem = GetItem(item.type).NewInstance(item);
198 
199  item.globalItems = InstancedGlobals.Select(g => g.NewInstance(item)).ToArray();
200 
201  item.modItem?.AutoDefaults();
202  item.modItem?.SetDefaults();
203 
204  foreach (var g in HookSetDefaults.arr)
205  g.Instance(item).SetDefaults(item);
206  }
207 
208  internal static GlobalItem GetGlobalItem(Item item, Mod mod, string name) {
209  int index;
210  return globalIndexes.TryGetValue(mod.Name + ':' + name, out index) ? globalItems[index].Instance(item) : null;
211  }
212 
213  internal static GlobalItem GetGlobalItem(Item item, Type type) {
214  int index;
215  return globalIndexesByType.TryGetValue(type, out index) ? (index > -1 ? globalItems[index].Instance(item) : null) : null;
216  }
217 
218  //near end of Terraria.Main.DrawItem before default drawing call
219  // if(ItemLoader.animations.Contains(item.type))
220  // { ItemLoader.DrawAnimatedItem(item, whoAmI, color, alpha, rotation, scale); return; }
221  internal static void DrawAnimatedItem(Item item, int whoAmI, Color color, Color alpha, float rotation, float scale) {
222  int frameCount = Main.itemAnimations[item.type].FrameCount;
223  int frameDuration = Main.itemAnimations[item.type].TicksPerFrame;
224  Main.itemFrameCounter[whoAmI]++;
225  if (Main.itemFrameCounter[whoAmI] >= frameDuration) {
226  Main.itemFrameCounter[whoAmI] = 0;
227  Main.itemFrame[whoAmI]++;
228  }
229  if (Main.itemFrame[whoAmI] >= frameCount) {
230  Main.itemFrame[whoAmI] = 0;
231  }
232  Rectangle frame = Main.itemTexture[item.type].Frame(1, frameCount, 0, Main.itemFrame[whoAmI]);
233  float offX = (float)(item.width / 2 - frame.Width / 2);
234  float offY = (float)(item.height - frame.Height);
235  Main.spriteBatch.Draw(Main.itemTexture[item.type], new Vector2(item.position.X - Main.screenPosition.X + (float)(frame.Width / 2) + offX, item.position.Y - Main.screenPosition.Y + (float)(frame.Height / 2) + offY), new Rectangle?(frame), alpha, rotation, frame.Size() / 2f, scale, SpriteEffects.None, 0f);
236  if (item.color != default(Color)) {
237  Main.spriteBatch.Draw(Main.itemTexture[item.type], new Vector2(item.position.X - Main.screenPosition.X + (float)(frame.Width / 2) + offX, item.position.Y - Main.screenPosition.Y + (float)(frame.Height / 2) + offY), new Rectangle?(frame), item.GetColor(color), rotation, frame.Size() / 2f, scale, SpriteEffects.None, 0f);
238  }
239  }
240 
241  private static Rectangle AnimatedItemFrame(Item item) {
242  int frameCount = Main.itemAnimations[item.type].FrameCount;
243  int frameDuration = Main.itemAnimations[item.type].TicksPerFrame;
244  return Main.itemAnimations[item.type].GetFrame(Main.itemTexture[item.type]);
245  }
246 
247  private static HookList HookChoosePrefix = AddHook<Func<Item, UnifiedRandom, int>>(g => g.ChoosePrefix);
248 
249  public static int ChoosePrefix(Item item, UnifiedRandom rand) {
250  foreach (var g in HookChoosePrefix.arr) {
251  int pre = g.Instance(item).ChoosePrefix(item, rand);
252  if (pre >= 0) {
253  return pre;
254  }
255  }
256  if (item.modItem != null) {
257  return item.modItem.ChoosePrefix(rand);
258  }
259  return -1;
260  }
261 
262  private static HookList HookCanUseItem = AddHook<Func<Item, Player, bool>>(g => g.CanUseItem);
263  //in Terraria.Player.ItemCheck
264  // inside block if (this.controlUseItem && this.itemAnimation == 0 && this.releaseUseItem && item.useStyle > 0)
265  // set initial flag2 to ItemLoader.CanUseItem(item, this)
272  public static bool CanUseItem(Item item, Player player) {
273  bool flag = true;
274  if (item.modItem != null)
275  flag &= item.modItem.CanUseItem(player);
276 
277  foreach (var g in HookCanUseItem.arr)
278  flag &= g.Instance(item).CanUseItem(item, player);
279 
280  return flag;
281  }
282 
283  private static HookList HookUseStyle = AddHook<Action<Item, Player>>(g => g.UseStyle);
284  //in Terraria.Player.ItemCheck after useStyle if/else chain call ItemLoader.UseStyle(item, this)
288  public static void UseStyle(Item item, Player player) {
289  if (item.IsAir)
290  return;
291 
292  item.modItem?.UseStyle(player);
293 
294  foreach (var g in HookUseStyle.arr)
295  g.Instance(item).UseStyle(item, player);
296  }
297 
298  private static HookList HookHoldStyle = AddHook<Action<Item, Player>>(g => g.HoldStyle);
299  //in Terraria.Player.ItemCheck after holdStyle if/else chain call ItemLoader.HoldStyle(item, this)
303  public static void HoldStyle(Item item, Player player) {
304  if (item.IsAir || player.pulley || player.itemAnimation > 0)
305  return;
306 
307  item.modItem?.HoldStyle(player);
308 
309  foreach (var g in HookHoldStyle.arr)
310  g.Instance(item).HoldStyle(item, player);
311  }
312 
313  private static HookList HookHoldItem = AddHook<Action<Item, Player>>(g => g.HoldItem);
314  //in Terraria.Player.ItemCheck before this.controlUseItem setting this.releaseUseItem call ItemLoader.HoldItem(item, this)
318  public static void HoldItem(Item item, Player player) {
319  if (item.IsAir)
320  return;
321 
322  item.modItem?.HoldItem(player);
323 
324  foreach (var g in HookHoldItem.arr)
325  g.Instance(item).HoldItem(item, player);
326  }
327 
328  private static HookList HookUseTimeMultiplier = AddHook<Func<Item, Player, float>>(g => g.UseTimeMultiplier);
329  public static float UseTimeMultiplier(Item item, Player player) {
330  if (item.IsAir)
331  return 1f;
332 
333  float multiplier = item.modItem?.UseTimeMultiplier(player) ?? 1f;
334 
335  foreach (var g in HookUseTimeMultiplier.arr)
336  multiplier *= g.Instance(item).UseTimeMultiplier(item, player);
337 
338  return multiplier;
339  }
340 
341  private static HookList HookMeleeSpeedMultiplier = AddHook<Func<Item, Player, float>>(g => g.MeleeSpeedMultiplier);
342  public static float MeleeSpeedMultiplier(Item item, Player player) {
343  if (item.IsAir)
344  return 1f;
345 
346  float multiplier = item.modItem?.MeleeSpeedMultiplier(player) ?? 1f;
347 
348  foreach (var g in HookMeleeSpeedMultiplier.arr)
349  multiplier *= g.Instance(item).MeleeSpeedMultiplier(item, player);
350 
351  return multiplier;
352  }
353 
354  private delegate void DelegateGetHealLife(Item item, Player player, bool quickHeal, ref int healValue);
355  private static HookList HookGetHealLife = AddHook<DelegateGetHealLife>(g => g.GetHealLife);
359  public static void GetHealLife(Item item, Player player, bool quickHeal, ref int healValue) {
360  if (item.IsAir)
361  return;
362 
363  item.modItem?.GetHealLife(player, quickHeal, ref healValue);
364 
365  foreach (var g in HookGetHealLife.arr)
366  g.Instance(item).GetHealLife(item, player, quickHeal, ref healValue);
367  }
368 
369  private delegate void DelegateGetHealMana(Item item, Player player, bool quickHeal, ref int healValue);
370  private static HookList HookGetHealMana = AddHook<DelegateGetHealMana>(g => g.GetHealMana);
374  public static void GetHealMana(Item item, Player player, bool quickHeal, ref int healValue) {
375  if (item.IsAir)
376  return;
377 
378  item.modItem?.GetHealMana(player, quickHeal, ref healValue);
379 
380  foreach (var g in HookGetHealMana.arr)
381  g.Instance(item).GetHealMana(item, player, quickHeal, ref healValue);
382  }
383 
384  private delegate void DelegateModifyManaCost(Item item, Player player, ref float reduce, ref float mult);
385  private static HookList HookModifyManaCost = AddHook<DelegateModifyManaCost>(g => g.ModifyManaCost);
389  public static void ModifyManaCost(Item item, Player player, ref float reduce, ref float mult) {
390  if (item.IsAir)
391  return;
392 
393  item.modItem?.ModifyManaCost(player, ref reduce, ref mult);
394 
395  foreach (var g in HookModifyManaCost.arr) {
396  g.Instance(item).ModifyManaCost(item, player, ref reduce, ref mult);
397  }
398  }
399 
400  private static HookList HookOnMissingMana = AddHook<Action<Item, Player, int>>(g => g.OnMissingMana);
404  public static void OnMissingMana(Item item, Player player, int neededMana) {
405  if (item.IsAir)
406  return;
407 
408  item.modItem?.OnMissingMana(player, neededMana);
409 
410  foreach (var g in HookOnMissingMana.arr) {
411  g.Instance(item).OnMissingMana(item, player, neededMana);
412  }
413  }
414 
415  private static HookList HookOnConsumeMana = AddHook<Action<Item, Player, int>>(g => g.OnConsumeMana);
419  public static void OnConsumeMana(Item item, Player player, int manaConsumed) {
420  if (item.IsAir)
421  return;
422 
423  item.modItem?.OnConsumeMana(player, manaConsumed);
424 
425  foreach (var g in HookOnConsumeMana.arr) {
426  g.Instance(item).OnConsumeMana(item, player, manaConsumed);
427  }
428  }
429 
430  private delegate void DelegateGetWeaponDamage(Item item, Player player, ref int damage);
431  [Obsolete]
432  private static HookList HookGetWeaponDamage = AddHook<DelegateGetWeaponDamage>(g => g.GetWeaponDamage);
436  [Obsolete]
437  public static void GetWeaponDamage(Item item, Player player, ref int damage) {
438  if (item.IsAir)
439  return;
440 
441  item.modItem?.GetWeaponDamage(player, ref damage);
442 
443  foreach (var g in HookGetWeaponDamage.arr)
444  g.Instance(item).GetWeaponDamage(item, player, ref damage);
445  }
446 
447  private delegate void DelegateModifyWeaponDamageOld(Item item, Player player, ref float add, ref float mult);
448  private static HookList HookModifyWeaponDamageOld = AddHook<DelegateModifyWeaponDamage>(g => g.ModifyWeaponDamage);
449  private delegate void DelegateModifyWeaponDamage(Item item, Player player, ref float add, ref float mult, ref float flat);
450  private static HookList HookModifyWeaponDamage = AddHook<DelegateModifyWeaponDamage>(g => g.ModifyWeaponDamage);
454  public static void ModifyWeaponDamage(Item item, Player player, ref float add, ref float mult, ref float flat) {
455  if (item.IsAir)
456  return;
457 
458  item.modItem?.ModifyWeaponDamage(player, ref add, ref mult);
459  item.modItem?.ModifyWeaponDamage(player, ref add, ref mult, ref flat);
460 
461  foreach (var g in HookModifyWeaponDamageOld.arr)
462  g.Instance(item).ModifyWeaponDamage(item, player, ref add, ref mult);
463  foreach (var g in HookModifyWeaponDamage.arr)
464  g.Instance(item).ModifyWeaponDamage(item, player, ref add, ref mult, ref flat);
465  }
466 
467  private delegate void DelegateGetWeaponKnockback(Item item, Player player, ref float knockback);
468  private static HookList HookGetWeaponKnockback = AddHook<DelegateGetWeaponKnockback>(g => g.GetWeaponKnockback);
472  public static void GetWeaponKnockback(Item item, Player player, ref float knockback) {
473  if (item.IsAir)
474  return;
475 
476  item.modItem?.GetWeaponKnockback(player, ref knockback);
477 
478  foreach (var g in HookGetWeaponKnockback.arr)
479  g.Instance(item).GetWeaponKnockback(item, player, ref knockback);
480  }
481 
482 
483  private delegate void DelegateGetWeaponCrit(Item item, Player player, ref int crit);
484  private static HookList HookGetWeaponCrit = AddHook<DelegateGetWeaponCrit>(g => g.GetWeaponCrit);
488  public static void GetWeaponCrit(Item item, Player player, ref int crit) {
489  if (item.IsAir)
490  return;
491 
492  item.modItem?.GetWeaponCrit(player, ref crit);
493 
494  foreach (var g in HookGetWeaponCrit.arr)
495  g.Instance(item).GetWeaponCrit(item, player, ref crit);
496  }
497 
501  public static bool CheckProjOnSwing(Player player, Item item) {
502  return item.modItem == null || !item.modItem.OnlyShootOnSwing || player.itemAnimation == player.itemAnimationMax - 1;
503  }
504 
505  private delegate void DelegateOldPickAmmo(Item item, Player player, ref int type, ref float speed, ref int damage, ref float knockback); // deprecated
506  private static HookList HookOldPickAmmo = AddHook<DelegateOldPickAmmo>(g => g.PickAmmo); // deprecated
507 
508  private delegate void DelegatePickAmmo(Item weapon, Item ammo, Player player, ref int type, ref float speed, ref int damage, ref float knockback);
509  private static HookList HookPickAmmo = AddHook<DelegatePickAmmo>(g => g.PickAmmo);
513  public static void PickAmmo(Item weapon, Item ammo, Player player, ref int type, ref float speed, ref int damage, ref float knockback) {
514  ammo.modItem?.PickAmmo(weapon, player, ref type, ref speed, ref damage, ref knockback);
515  ammo.modItem?.PickAmmo(player, ref type, ref speed, ref damage, ref knockback); // deprecated
516 
517  foreach (var g in HookPickAmmo.arr) {
518  g.Instance(ammo).PickAmmo(weapon, ammo, player, ref type, ref speed, ref damage, ref knockback);
519  }
520  foreach (var g in HookOldPickAmmo.arr) {
521  g.Instance(ammo).PickAmmo(ammo, player, ref type, ref speed, ref damage, ref knockback); // deprecated
522  }
523  }
524 
525  private static HookList HookConsumeAmmo = AddHook<Func<Item, Player, bool>>(g => g.ConsumeAmmo);
526  //near end of Terraria.Player.PickAmmo before flag2 is checked add
527  // if(!ItemLoader.ConsumeAmmo(sItem, item, this)) { flag2 = true; }
531  public static bool ConsumeAmmo(Item item, Item ammo, Player player) {
532  if (item.modItem != null && !item.modItem.ConsumeAmmo(player) ||
533  ammo.modItem != null && !ammo.modItem.ConsumeAmmo(player))
534  return false;
535 
536  foreach (var g in HookConsumeAmmo.arr) {
537  if (!g.Instance(item).ConsumeAmmo(item, player) ||
538  !g.Instance(ammo).ConsumeAmmo(ammo, player))
539  return false;
540  }
541 
542  return true;
543  }
544 
545  private static HookList HookOnConsumeAmmo = AddHook<Action<Item, Player>>(g => g.OnConsumeAmmo);
549  public static void OnConsumeAmmo(Item item, Item ammo, Player player) {
550  if (item.IsAir)
551  return;
552 
553  item.modItem?.OnConsumeAmmo(player);
554  ammo.modItem?.OnConsumeAmmo(player);
555 
556  foreach (var g in HookOnConsumeAmmo.arr) {
557  g.Instance(item).OnConsumeAmmo(item, player);
558  g.Instance(ammo).OnConsumeAmmo(ammo, player);
559  }
560  }
561 
562  private delegate bool DelegateShoot(Item item, Player player, ref Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack);
563  private static HookList HookShoot = AddHook<DelegateShoot>(g => g.Shoot);
564  //in Terraria.Player.ItemCheck at end of if/else chain for shooting place if on last else
565  // if(ItemLoader.Shoot(item, this, ref vector2, ref num78, ref num79, ref num71, ref num73, ref num74))
578  public static bool Shoot(Item item, Player player, ref Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack) {
579  bool result = true;
580 
581  foreach (var g in HookShoot.arr) {
582  result &= g.Instance(item).Shoot(item, player, ref position, ref speedX, ref speedY, ref type, ref damage, ref knockBack);
583  }
584 
585  if (result && item.modItem != null) {
586  return item.modItem.Shoot(player, ref position, ref speedX, ref speedY, ref type, ref damage, ref knockBack);
587  }
588 
589  return result;
590  }
591 
592  private delegate void DelegateUseItemHitbox(Item item, Player player, ref Rectangle hitbox, ref bool noHitbox);
593  private static HookList HookUseItemHitbox = AddHook<DelegateUseItemHitbox>(g => g.UseItemHitbox);
594  //in Terraria.Player.ItemCheck after end of useStyle if/else chain for melee hitbox
595  // call ItemLoader.UseItemHitbox(item, this, ref r2, ref flag17)
599  public static void UseItemHitbox(Item item, Player player, ref Rectangle hitbox, ref bool noHitbox) {
600  item.modItem?.UseItemHitbox(player, ref hitbox, ref noHitbox);
601 
602  foreach (var g in HookUseItemHitbox.arr)
603  g.Instance(item).UseItemHitbox(item, player, ref hitbox, ref noHitbox);
604  }
605 
606  private static HookList HookMeleeEffects = AddHook<Action<Item, Player, Rectangle>>(g => g.MeleeEffects);
607  //in Terraria.Player.ItemCheck after magma stone dust effect for melee weapons
608  // call ItemLoader.MeleeEffects(item, this, r2)
612  public static void MeleeEffects(Item item, Player player, Rectangle hitbox) {
613  item.modItem?.MeleeEffects(player, hitbox);
614 
615  foreach (var g in HookMeleeEffects.arr)
616  g.Instance(item).MeleeEffects(item, player, hitbox);
617  }
618 
619  private static HookList HookCanHitNPC = AddHook<Func<Item, Player, NPC, bool?>>(g => g.CanHitNPC);
620  //in Terraria.Player.ItemCheck before checking whether npc type can be hit add
621  // bool? modCanHit = ItemLoader.CanHitNPC(item, this, Main.npc[num292]);
622  // if(modCanHit.HasValue && !modCanHit.Value) { continue; }
623  //in if statement afterwards add || (modCanHit.HasValue && modCanHit.Value)
630  public static bool? CanHitNPC(Item item, Player player, NPC target) {
631  bool? canHit = item.modItem?.CanHitNPC(player, target);
632  if (canHit.HasValue && !canHit.Value) {
633  return false;
634  }
635  foreach (var g in HookCanHitNPC.arr) {
636  bool? globalCanHit = g.Instance(item).CanHitNPC(item, player, target);
637  if (globalCanHit.HasValue) {
638  if (globalCanHit.Value) {
639  canHit = true;
640  }
641  else {
642  return false;
643  }
644  }
645  }
646  return canHit;
647  }
648 
649  private delegate void DelegateModifyHitNPC(Item item, Player player, NPC target, ref int damage, ref float knockBack, ref bool crit);
650  private static HookList HookModifyHitNPC = AddHook<DelegateModifyHitNPC>(g => g.ModifyHitNPC);
651  //in Terraria.Player.ItemCheck for melee attacks after damage variation
652  // call ItemLoader.ModifyHitNPC(item, this, Main.npc[num292], ref num282, ref num283, ref flag18)
656  public static void ModifyHitNPC(Item item, Player player, NPC target, ref int damage, ref float knockBack, ref bool crit) {
657  item.modItem?.ModifyHitNPC(player, target, ref damage, ref knockBack, ref crit);
658 
659  foreach (var g in HookModifyHitNPC.arr)
660  g.Instance(item).ModifyHitNPC(item, player, target, ref damage, ref knockBack, ref crit);
661  }
662 
663  private static HookList HookOnHitNPC = AddHook<Action<Item, Player, NPC, int, float, bool>>(g => g.OnHitNPC);
664  //in Terraria.Player.ItemCheck for melee attacks before updating informational accessories
665  // call ItemLoader.OnHitNPC(item, this, Main.npc[num292], num295, num283, flag18)
669  public static void OnHitNPC(Item item, Player player, NPC target, int damage, float knockBack, bool crit) {
670  item.modItem?.OnHitNPC(player, target, damage, knockBack, crit);
671 
672  foreach (var g in HookOnHitNPC.arr)
673  g.Instance(item).OnHitNPC(item, player, target, damage, knockBack, crit);
674  }
675 
676  private static HookList HookCanHitPvp = AddHook<Func<Item, Player, Player, bool>>(g => g.CanHitPvp);
677  //in Terraria.Player.ItemCheck add to beginning of pvp collision check
682  public static bool CanHitPvp(Item item, Player player, Player target) {
683  foreach (var g in HookCanHitPvp.arr)
684  if (!g.Instance(item).CanHitPvp(item, player, target))
685  return false;
686 
687  return item.modItem == null || item.modItem.CanHitPvp(player, target);
688  }
689 
690  private delegate void DelegateModifyHitPvp(Item item, Player player, Player target, ref int damage, ref bool crit);
691  private static HookList HookModifyHitPvp = AddHook<DelegateModifyHitPvp>(g => g.ModifyHitPvp);
692  //in Terraria.Player.ItemCheck for pvp melee attacks after damage variation
693  // call ItemLoader.ModifyHitPvp(item, this, Main.player[num302], ref num282, ref flag20)
697  public static void ModifyHitPvp(Item item, Player player, Player target, ref int damage, ref bool crit) {
698  item.modItem?.ModifyHitPvp(player, target, ref damage, ref crit);
699 
700  foreach (var g in HookModifyHitPvp.arr)
701  g.Instance(item).ModifyHitPvp(item, player, target, ref damage, ref crit);
702  }
703 
704  private static HookList HookOnHitPvp = AddHook<Action<Item, Player, Player, int, bool>>(g => g.OnHitPvp);
705  //in Terraria.Player.ItemCheck for pvp melee attacks before NetMessage stuff
706  // call ItemLoader.OnHitPvp(item, this, Main.player[num302], num304, flag20)
710  public static void OnHitPvp(Item item, Player player, Player target, int damage, bool crit) {
711  item.modItem?.OnHitPvp(player, target, damage, crit);
712 
713  foreach (var g in HookOnHitPvp.arr)
714  g.Instance(item).OnHitPvp(item, player, target, damage, crit);
715  }
716 
717  private static HookList HookUseItem = AddHook<Func<Item, Player, bool>>(g => g.UseItem);
722  public static bool UseItem(Item item, Player player) {
723  if (item.IsAir)
724  return false;
725 
726  bool flag = false;
727  if (item.modItem != null)
728  flag |= item.modItem.UseItem(player);
729 
730  foreach (var g in HookUseItem.arr)
731  flag |= g.Instance(item).UseItem(item, player);
732 
733  return flag;
734  }
735 
736  private static HookList HookConsumeItem = AddHook<Func<Item, Player, bool>>(g => g.ConsumeItem);
737  //near end of Terraria.Player.ItemCheck
738  // if (flag22 && ItemLoader.ConsumeItem(item, this))
742  public static bool ConsumeItem(Item item, Player player) {
743  if (item.IsAir) return true;
744  if (item.modItem != null && !item.modItem.ConsumeItem(player))
745  return false;
746 
747  foreach (var g in HookConsumeItem.arr)
748  if (!g.Instance(item).ConsumeItem(item, player))
749  return false;
750 
751  OnConsumeItem(item, player);
752  return true;
753  }
754 
755  private static HookList HookOnConsumeItem = AddHook<Action<Item, Player>>(g => g.OnConsumeItem);
759  public static void OnConsumeItem(Item item, Player player) {
760  if (item.IsAir)
761  return;
762 
763  item.modItem?.OnConsumeItem(player);
764 
765  foreach (var g in HookOnConsumeItem.arr)
766  g.Instance(item).OnConsumeItem(item, player);
767  }
768 
769  private static HookList HookUseItemFrame = AddHook<Func<Item, Player, bool>>(g => g.UseItemFrame);
770  //in Terraria.Player.PlayerFrame at end of useStyle if/else chain
771  // call if(ItemLoader.UseItemFrame(this.inventory[this.selectedItem], this)) { return; }
775  public static bool UseItemFrame(Item item, Player player) {
776  if (item.modItem != null && item.modItem.UseItemFrame(player))
777  return true;
778 
779  foreach (var g in HookUseItemFrame.arr)
780  if (g.Instance(item).UseItemFrame(item, player))
781  return true;
782 
783  return false;
784  }
785 
786  private static HookList HookHoldItemFrame = AddHook<Func<Item, Player, bool>>(g => g.HoldItemFrame);
787  //in Terraria.Player.PlayerFrame at end of holdStyle if statements
788  // call if(ItemLoader.HoldItemFrame(this.inventory[this.selectedItem], this)) { return; }
792  public static bool HoldItemFrame(Item item, Player player) {
793  if (item.IsAir)
794  return false;
795 
796  if (item.modItem != null && item.modItem.HoldItemFrame(player))
797  return true;
798 
799  foreach (var g in HookHoldItemFrame.arr)
800  if (g.Instance(item).HoldItemFrame(item, player))
801  return true;
802 
803  return false;
804  }
805 
806  private static HookList HookAltFunctionUse = AddHook<Func<Item, Player, bool>>(g => g.AltFunctionUse);
810  public static bool AltFunctionUse(Item item, Player player) {
811  if (item.IsAir)
812  return false;
813 
814  if (item.modItem != null && item.modItem.AltFunctionUse(player))
815  return true;
816 
817  foreach (var g in HookAltFunctionUse.arr)
818  if (g.Instance(item).AltFunctionUse(item, player))
819  return true;
820 
821  return false;
822  }
823 
824  private static HookList HookUpdateInventory = AddHook<Action<Item, Player>>(g => g.UpdateInventory);
825  //place at end of first for loop in Terraria.Player.UpdateEquips
826  // call ItemLoader.UpdateInventory(this.inventory[j], this)
830  public static void UpdateInventory(Item item, Player player) {
831  if (item.IsAir)
832  return;
833 
834  item.modItem?.UpdateInventory(player);
835 
836  foreach (var g in HookUpdateInventory.arr)
837  g.Instance(item).UpdateInventory(item, player);
838  }
839 
840  private static HookList HookUpdateEquip = AddHook<Action<Item, Player>>(g => g.UpdateEquip);
841  //place in second for loop of Terraria.Player.UpdateEquips before prefix checking
842  // call ItemLoader.UpdateEquip(this.armor[k], this)
846  public static void UpdateEquip(Item item, Player player) {
847  if (item.IsAir)
848  return;
849 
850  item.modItem?.UpdateEquip(player);
851 
852  foreach (var g in HookUpdateEquip.arr)
853  g.Instance(item).UpdateEquip(item, player);
854  }
855 
856  private static HookList HookUpdateAccessory = AddHook<Action<Item, Player, bool>>(g => g.UpdateAccessory);
857  //place at end of third for loop of Terraria.Player.UpdateEquips
858  // call ItemLoader.UpdateAccessory(this.armor[l], this, this.hideVisual[l])
862  public static void UpdateAccessory(Item item, Player player, bool hideVisual) {
863  if (item.IsAir)
864  return;
865 
866  item.modItem?.UpdateAccessory(player, hideVisual);
867 
868  foreach (var g in HookUpdateAccessory.arr)
869  g.Instance(item).UpdateAccessory(item, player, hideVisual);
870  }
871 
875  public static void UpdateVanity(Player player) {
876  foreach (EquipType type in EquipLoader.EquipTypes) {
877  int slot = EquipLoader.GetPlayerEquip(player, type);
878  EquipTexture texture = EquipLoader.GetEquipTexture(type, slot);
879  texture?.UpdateVanity(player, type);
880  }
881  }
882 
883  private static HookList HookUpdateArmorSet = AddHook<Action<Player, string>>(g => g.UpdateArmorSet);
884  //at end of Terraria.Player.UpdateArmorSets call ItemLoader.UpdateArmorSet(this, this.armor[0], this.armor[1], this.armor[2])
888  public static void UpdateArmorSet(Player player, Item head, Item body, Item legs) {
889  if (head.modItem != null && head.modItem.IsArmorSet(head, body, legs))
890  head.modItem.UpdateArmorSet(player);
891 
892  if (body.modItem != null && body.modItem.IsArmorSet(head, body, legs))
893  body.modItem.UpdateArmorSet(player);
894 
895  if (legs.modItem != null && legs.modItem.IsArmorSet(head, body, legs))
896  legs.modItem.UpdateArmorSet(player);
897 
898  foreach (GlobalItem globalItem in HookUpdateArmorSet.arr) {
899  string set = globalItem.IsArmorSet(head, body, legs);
900  if (!string.IsNullOrEmpty(set))
901  globalItem.UpdateArmorSet(player, set);
902  }
903  }
904 
905  private static HookList HookPreUpdateVanitySet = AddHook<Action<Player, string>>(g => g.PreUpdateVanitySet);
906  //in Terraria.Player.PlayerFrame after setting armor effects fields call this
910  public static void PreUpdateVanitySet(Player player) {
911  EquipTexture headTexture = EquipLoader.GetEquipTexture(EquipType.Head, player.head);
912  EquipTexture bodyTexture = EquipLoader.GetEquipTexture(EquipType.Body, player.body);
913  EquipTexture legTexture = EquipLoader.GetEquipTexture(EquipType.Legs, player.legs);
914  if (headTexture != null && headTexture.IsVanitySet(player.head, player.body, player.legs))
915  headTexture.PreUpdateVanitySet(player);
916 
917  if (bodyTexture != null && bodyTexture.IsVanitySet(player.head, player.body, player.legs))
918  bodyTexture.PreUpdateVanitySet(player);
919 
920  if (legTexture != null && legTexture.IsVanitySet(player.head, player.body, player.legs))
921  legTexture.PreUpdateVanitySet(player);
922 
923  foreach (GlobalItem globalItem in HookPreUpdateVanitySet.arr) {
924  string set = globalItem.IsVanitySet(player.head, player.body, player.legs);
925  if (!string.IsNullOrEmpty(set))
926  globalItem.PreUpdateVanitySet(player, set);
927  }
928  }
929 
930  private static HookList HookUpdateVanitySet = AddHook<Action<Player, string>>(g => g.UpdateVanitySet);
931  //in Terraria.Player.PlayerFrame after armor sets creating dust call this
935  public static void UpdateVanitySet(Player player) {
936  EquipTexture headTexture = EquipLoader.GetEquipTexture(EquipType.Head, player.head);
937  EquipTexture bodyTexture = EquipLoader.GetEquipTexture(EquipType.Body, player.body);
938  EquipTexture legTexture = EquipLoader.GetEquipTexture(EquipType.Legs, player.legs);
939  if (headTexture != null && headTexture.IsVanitySet(player.head, player.body, player.legs))
940  headTexture.UpdateVanitySet(player);
941 
942  if (bodyTexture != null && bodyTexture.IsVanitySet(player.head, player.body, player.legs))
943  bodyTexture.UpdateVanitySet(player);
944 
945  if (legTexture != null && legTexture.IsVanitySet(player.head, player.body, player.legs))
946  legTexture.UpdateVanitySet(player);
947 
948  foreach (GlobalItem globalItem in HookUpdateVanitySet.arr) {
949  string set = globalItem.IsVanitySet(player.head, player.body, player.legs);
950  if (!string.IsNullOrEmpty(set))
951  globalItem.UpdateVanitySet(player, set);
952  }
953  }
954 
955  private static HookList HookArmorSetShadows = AddHook<Action<Player, string>>(g => g.ArmorSetShadows);
956  //in Terraria.Main.DrawPlayers after armor combinations setting flags call
957  // ItemLoader.ArmorSetShadows(player);
961  public static void ArmorSetShadows(Player player) {
962  EquipTexture headTexture = EquipLoader.GetEquipTexture(EquipType.Head, player.head);
963  EquipTexture bodyTexture = EquipLoader.GetEquipTexture(EquipType.Body, player.body);
964  EquipTexture legTexture = EquipLoader.GetEquipTexture(EquipType.Legs, player.legs);
965  if (headTexture != null && headTexture.IsVanitySet(player.head, player.body, player.legs))
966  headTexture.ArmorSetShadows(player);
967 
968  if (bodyTexture != null && bodyTexture.IsVanitySet(player.head, player.body, player.legs))
969  bodyTexture.ArmorSetShadows(player);
970 
971  if (legTexture != null && legTexture.IsVanitySet(player.head, player.body, player.legs))
972  legTexture.ArmorSetShadows(player);
973 
974  foreach (GlobalItem globalItem in HookArmorSetShadows.arr) {
975  string set = globalItem.IsVanitySet(player.head, player.body, player.legs);
976  if (!string.IsNullOrEmpty(set))
977  globalItem.ArmorSetShadows(player, set);
978  }
979  }
980 
981  private delegate void DelegateSetMatch(int armorSlot, int type, bool male, ref int equipSlot, ref bool robes);
982  private static HookList HookSetMatch = AddHook<DelegateSetMatch>(g => g.SetMatch);
986  public static void SetMatch(int armorSlot, int type, bool male, ref int equipSlot, ref bool robes) {
987  EquipTexture texture = EquipLoader.GetEquipTexture((EquipType)armorSlot, type);
988  texture?.SetMatch(male, ref equipSlot, ref robes);
989 
990  foreach (var g in HookSetMatch.arr)
991  g.SetMatch(armorSlot, type, male, ref equipSlot, ref robes);
992  }
993 
994  private static HookList HookCanRightClick = AddHook<Func<Item, bool>>(g => g.CanRightClick);
995  //in Terraria.UI.ItemSlot.RightClick in end of item-opening if/else chain before final else
996  // make else if(ItemLoader.CanRightClick(inv[slot]))
1000  public static bool CanRightClick(Item item) {
1001  if (item.IsAir || !Main.mouseRight)
1002  return false;
1003 
1004  if (item.modItem != null && item.modItem.CanRightClick())
1005  return true;
1006 
1007  foreach (var g in HookCanRightClick.arr)
1008  if (g.Instance(item).CanRightClick(item))
1009  return true;
1010 
1011  return false;
1012  }
1013 
1014  private static HookList HookRightClick = AddHook<Action<Item, Player>>(g => g.RightClick);
1015  //in Terraria.UI.ItemSlot in block from CanRightClick call ItemLoader.RightClick(inv[slot], player)
1027  public static void RightClick(Item item, Player player) {
1028  if (!Main.mouseRightRelease)
1029  return;
1030 
1031  item.modItem?.RightClick(player);
1032 
1033  foreach (var g in HookRightClick.arr)
1034  g.Instance(item).RightClick(item, player);
1035 
1036  if (ConsumeItem(item, player) && --item.stack == 0)
1037  item.SetDefaults();
1038 
1039  Main.PlaySound(7);
1040  Main.stackSplit = 30;
1041  Main.mouseRightRelease = false;
1042  Recipe.FindRecipes();
1043  }
1044 
1045  //in Terraria.UI.ItemSlot add this to boss bag check
1049  public static bool IsModBossBag(Item item) {
1050  return item.modItem != null && item.modItem.BossBagNPC > 0;
1051  }
1052 
1053  //in Terraria.Player.OpenBossBag after setting num14 call
1054  // ItemLoader.OpenBossBag(type, this, ref num14);
1058  public static void OpenBossBag(int type, Player player, ref int npc) {
1059  ModItem modItem = GetItem(type);
1060  if (modItem != null && modItem.BossBagNPC > 0) {
1061  modItem.OpenBossBag(player);
1062  npc = modItem.BossBagNPC;
1063  }
1064  }
1065 
1066  private static HookList HookPreOpenVanillaBag = AddHook<Func<string, Player, int, bool>>(g => g.PreOpenVanillaBag);
1067  //in beginning of Terraria.Player.openBag methods add
1068  // if(!ItemLoader.PreOpenVanillaBag("bagName", this, arg)) { return; }
1069  //at the end of the following methods in Player.cs, add: NPCLoader.blockLoot.Clear(); // clear blockloot
1070  //methods: OpenBossBag, openCrate, openGoodieBag, openHerbBag, openLockbox, openPresent
1074  public static bool PreOpenVanillaBag(string context, Player player, int arg) {
1075  bool result = true;
1076  foreach (var g in HookPreOpenVanillaBag.arr)
1077  result &= g.PreOpenVanillaBag(context, player, arg);
1078 
1079  if (!result) {
1080  NPCLoader.blockLoot.Clear(); // clear blockloot
1081  return false;
1082  }
1083 
1084  return true;
1085  }
1086 
1087  private static HookList HookOpenVanillaBag = AddHook<Action<string, Player, int>>(g => g.OpenVanillaBag);
1088  //in Terraria.Player.openBag methods after PreOpenVanillaBag if statements
1089  // add ItemLoader.OpenVanillaBag("bagname", this, arg);
1093  public static void OpenVanillaBag(string context, Player player, int arg) {
1094  foreach (var g in HookOpenVanillaBag.arr)
1095  g.OpenVanillaBag(context, player, arg);
1096  }
1097 
1098  private delegate bool DelegateReforgePrice(Item item, ref int reforgePrice, ref bool canApplyDiscount);
1099  private static HookList HookReforgePrice = AddHook<DelegateReforgePrice>(g => g.ReforgePrice);
1105  public static bool ReforgePrice(Item item, ref int reforgePrice, ref bool canApplyDiscount) {
1106  bool b = item.modItem?.ReforgePrice(ref reforgePrice, ref canApplyDiscount) ?? true;
1107  foreach (var g in HookReforgePrice.arr)
1108  b &= g.Instance(item).ReforgePrice(item, ref reforgePrice, ref canApplyDiscount);
1109  return b;
1110  }
1111 
1112  // @todo: PreReforge marked obsolete until v0.11
1113  private static HookList HookPreReforge = AddHook<Func<Item, bool>>(g => g.NewPreReforge);
1117  public static bool PreReforge(Item item) {
1118  bool b = item.modItem?.NewPreReforge() ?? true;
1119  foreach (var g in HookPreReforge.arr)
1120  b &= g.Instance(item).NewPreReforge(item);
1121  return b;
1122  }
1123 
1124  private static HookList HookPostReforge = AddHook<Action<Item>>(g => g.PostReforge);
1128  public static void PostReforge(Item item) {
1129  item.modItem?.PostReforge();
1130  foreach (var g in HookPostReforge.arr)
1131  g.Instance(item).PostReforge(item);
1132  }
1133 
1134  private delegate void DelegateDrawHands(int body, ref bool drawHands, ref bool drawArms);
1135  private static HookList HookDrawHands = AddHook<DelegateDrawHands>(g => g.DrawHands);
1139  public static void DrawHands(Player player, ref bool drawHands, ref bool drawArms) {
1140  EquipTexture texture = EquipLoader.GetEquipTexture(EquipType.Body, player.body);
1141  texture?.DrawHands(ref drawHands, ref drawArms);
1142 
1143  foreach (var g in HookDrawHands.arr)
1144  g.DrawHands(player.body, ref drawHands, ref drawArms);
1145  }
1146 
1147  private delegate void DelegateDrawHair(int body, ref bool drawHair, ref bool drawAltHair);
1148  private static HookList HookDrawHair = AddHook<DelegateDrawHair>(g => g.DrawHair);
1149  //in Terraria.Main.DrawPlayerHead after if statement that sets flag2 to true
1150  // call ItemLoader.DrawHair(drawPlayer, ref flag, ref flag2)
1151  //in Terraria.Main.DrawPlayer after if statement that sets flag5 to true
1152  // call ItemLoader.DrawHair(drawPlayer, ref flag4, ref flag5)
1156  public static void DrawHair(Player player, ref bool drawHair, ref bool drawAltHair) {
1157  EquipTexture texture = EquipLoader.GetEquipTexture(EquipType.Head, player.head);
1158  texture?.DrawHair(ref drawHair, ref drawAltHair);
1159 
1160  foreach (var g in HookDrawHair.arr)
1161  g.DrawHair(player.body, ref drawHair, ref drawAltHair);
1162  }
1163 
1164  private static HookList HookDrawHead = AddHook<Func<int, bool>>(g => g.DrawHead);
1165  //in Terraria.Main.DrawPlayerHead in if statement after ItemLoader.DrawHair
1166  //and in Terraria.Main.DrawPlayer in if (!drawPlayer.invis && drawPlayer.head != 38 && drawPlayer.head != 135)
1167  // use && with ItemLoader.DrawHead(drawPlayer)
1171  public static bool DrawHead(Player player) {
1172  EquipTexture texture = EquipLoader.GetEquipTexture(EquipType.Head, player.head);
1173  if (texture != null && !texture.DrawHead())
1174  return false;
1175 
1176  foreach (var g in HookDrawHead.arr)
1177  if (!g.DrawHead(player.head))
1178  return false;
1179 
1180  return true;
1181  }
1182 
1183  private static HookList HookDrawBody = AddHook<Func<int, bool>>(g => g.DrawBody);
1187  public static bool DrawBody(Player player) {
1188  EquipTexture texture = EquipLoader.GetEquipTexture(EquipType.Body, player.body);
1189  if (texture != null && !texture.DrawBody())
1190  return false;
1191 
1192  foreach (var g in HookDrawBody.arr)
1193  if (!g.DrawBody(player.body))
1194  return false;
1195 
1196  return true;
1197  }
1198 
1199  private static HookList HookDrawLegs = AddHook<Func<int, int, bool>>(g => g.DrawLegs);
1203  public static bool DrawLegs(Player player) {
1204  EquipTexture texture = EquipLoader.GetEquipTexture(EquipType.Legs, player.legs);
1205  if (texture != null && !texture.DrawLegs())
1206  return false;
1207 
1208  texture = EquipLoader.GetEquipTexture(EquipType.Shoes, player.shoe);
1209  if (texture != null && !texture.DrawLegs())
1210  return false;
1211 
1212  foreach (var g in HookDrawLegs.arr)
1213  if (!g.DrawLegs(player.legs, player.shoe))
1214  return false;
1215 
1216  return true;
1217  }
1218 
1219  private delegate void DelegateDrawArmorColor(EquipType type, int slot, Player drawPlayer, float shadow, ref Color color, ref int glowMask, ref Color glowMaskColor);
1220  private static HookList HookDrawArmorColor = AddHook<DelegateDrawArmorColor>(g => g.DrawArmorColor);
1224  public static void DrawArmorColor(EquipType type, int slot, Player drawPlayer, float shadow, ref Color color,
1225  ref int glowMask, ref Color glowMaskColor) {
1226  EquipTexture texture = EquipLoader.GetEquipTexture(type, slot);
1227  texture?.DrawArmorColor(drawPlayer, shadow, ref color, ref glowMask, ref glowMaskColor);
1228 
1229  foreach (var g in HookDrawArmorColor.arr)
1230  g.DrawArmorColor(type, slot, drawPlayer, shadow, ref color, ref glowMask, ref glowMaskColor);
1231  }
1232 
1233  private delegate void DelegateArmorArmGlowMask(int slot, Player drawPlayer, float shadow, ref int glowMask, ref Color color);
1234  private static HookList HookArmorArmGlowMask = AddHook<DelegateArmorArmGlowMask>(g => g.ArmorArmGlowMask);
1238  public static void ArmorArmGlowMask(int slot, Player drawPlayer, float shadow, ref int glowMask, ref Color color) {
1239  EquipTexture texture = EquipLoader.GetEquipTexture(EquipType.Body, slot);
1240  texture?.ArmorArmGlowMask(drawPlayer, shadow, ref glowMask, ref color);
1241 
1242  foreach (var g in HookArmorArmGlowMask.arr)
1243  g.ArmorArmGlowMask(slot, drawPlayer, shadow, ref glowMask, ref color);
1244  }
1245 
1249  public static Item GetWing(Player player) {
1250  Item item = null;
1251  for (int k = 3; k < 8 + player.extraAccessorySlots; k++) {
1252  if (player.armor[k].wingSlot == player.wingsLogic) {
1253  item = player.armor[k];
1254  }
1255  }
1256  if (item != null) {
1257  return item;
1258  }
1259  if (player.wingsLogic > 0 && player.wingsLogic < Main.maxWings) {
1260  item = new Item();
1261  item.SetDefaults(vanillaWings[player.wingsLogic]);
1262  return item;
1263  }
1264  if (player.wingsLogic >= Main.maxWings) {
1265  EquipTexture texture = EquipLoader.GetEquipTexture(EquipType.Wings, player.wingsLogic);
1266  if (texture?.item != null)
1267  return texture.item.item;
1268  }
1269  return null;
1270  }
1271 
1272  private delegate void DelegateVerticalWingSpeeds(Item item, Player player, ref float ascentWhenFalling, ref float ascentWhenRising, ref float maxCanAscendMultiplier, ref float maxAscentMultiplier, ref float constantAscend);
1273  private static HookList HookVerticalWingSpeeds = AddHook<DelegateVerticalWingSpeeds>(g => g.VerticalWingSpeeds);
1274  //in Terraria.Player.WingMovement after if statements that set num1-5
1275  // call ItemLoader.VerticalWingSpeeds(this, ref num2, ref num5, ref num4, ref num3, ref num)
1279  public static void VerticalWingSpeeds(Player player, ref float ascentWhenFalling, ref float ascentWhenRising,
1280  ref float maxCanAscendMultiplier, ref float maxAscentMultiplier, ref float constantAscend) {
1281  Item item = GetWing(player);
1282  if (item == null) {
1283  EquipTexture texture = EquipLoader.GetEquipTexture(EquipType.Wings, player.wingsLogic);
1284  texture?.VerticalWingSpeeds(
1285  player, ref ascentWhenFalling, ref ascentWhenRising, ref maxCanAscendMultiplier,
1286  ref maxAscentMultiplier, ref constantAscend);
1287  return;
1288  }
1289 
1290  item.modItem?.VerticalWingSpeeds(player, ref ascentWhenFalling, ref ascentWhenRising, ref maxCanAscendMultiplier,
1291  ref maxAscentMultiplier, ref constantAscend);
1292 
1293  foreach (var g in HookVerticalWingSpeeds.arr)
1294  g.Instance(item).VerticalWingSpeeds(item, player, ref ascentWhenFalling, ref ascentWhenRising,
1295  ref maxCanAscendMultiplier, ref maxAscentMultiplier, ref constantAscend);
1296  }
1297 
1298  private delegate void DelegateHorizontalWingSpeeds(Item item, Player player, ref float speed, ref float acceleration);
1299  private static HookList HookHorizontalWingSpeeds = AddHook<DelegateHorizontalWingSpeeds>(g => g.HorizontalWingSpeeds);
1300  //in Terraria.Player.Update after wingsLogic if statements modifying accRunSpeed and runAcceleration
1301  // call ItemLoader.HorizontalWingSpeeds(this)
1305  public static void HorizontalWingSpeeds(Player player) {
1306  Item item = GetWing(player);
1307  if (item == null) {
1308  EquipTexture texture = EquipLoader.GetEquipTexture(EquipType.Wings, player.wingsLogic);
1309  texture?.HorizontalWingSpeeds(player, ref player.accRunSpeed, ref player.runAcceleration);
1310  return;
1311  }
1312 
1313  item.modItem?.HorizontalWingSpeeds(player, ref player.accRunSpeed, ref player.runAcceleration);
1314 
1315  foreach (var g in HookHorizontalWingSpeeds.arr)
1316  g.Instance(item).HorizontalWingSpeeds(item, player, ref player.accRunSpeed, ref player.runAcceleration);
1317  }
1318 
1319  private static HookList HookWingUpdate = AddHook<Func<int, Player, bool, bool>>(g => g.WingUpdate);
1323  public static bool WingUpdate(Player player, bool inUse) {
1324  if (player.wings <= 0)
1325  return false;
1326 
1327  EquipTexture texture = EquipLoader.GetEquipTexture(EquipType.Wings, player.wings);
1328  bool? retVal = texture?.WingUpdate(player, inUse);
1329 
1330  foreach (var g in HookWingUpdate.arr)
1331  retVal |= g.WingUpdate(player.wings, player, inUse);
1332 
1333  return retVal ?? false;
1334  }
1335 
1336  private delegate void DelegateUpdate(Item item, ref float gravity, ref float maxFallSpeed);
1337  private static HookList HookUpdate = AddHook<DelegateUpdate>(g => g.Update);
1338  //in Terraria.Item.UpdateItem before item movement (denoted by ItemID.Sets.ItemNoGravity)
1339  // call ItemLoader.Update(this, ref num, ref num2)
1343  public static void Update(Item item, ref float gravity, ref float maxFallSpeed) {
1344  item.modItem?.Update(ref gravity, ref maxFallSpeed);
1345 
1346  foreach (var g in HookUpdate.arr)
1347  g.Instance(item).Update(item, ref gravity, ref maxFallSpeed);
1348  }
1349 
1350  private static HookList HookPostUpdate = AddHook<Action<Item>>(g => g.PostUpdate);
1354  public static void PostUpdate(Item item) {
1355  item.modItem?.PostUpdate();
1356 
1357  foreach (var g in HookPostUpdate.arr)
1358  g.Instance(item).PostUpdate(item);
1359  }
1360 
1361  private delegate void DelegateGrabRange(Item item, Player player, ref int grabRange);
1362  private static HookList HookGrabRange = AddHook<DelegateGrabRange>(g => g.GrabRange);
1363  //in Terraria.Player.GrabItems after increasing grab range add
1364  // ItemLoader.GrabRange(Main.item[j], this, ref num);
1368  public static void GrabRange(Item item, Player player, ref int grabRange) {
1369  item.modItem?.GrabRange(player, ref grabRange);
1370 
1371  foreach (var g in HookGrabRange.arr)
1372  g.Instance(item).GrabRange(item, player, ref grabRange);
1373  }
1374 
1375  private static HookList HookGrabStyle = AddHook<Func<Item, Player, bool>>(g => g.GrabStyle);
1376  //in Terraria.Player.GrabItems between setting beingGrabbed to true and grab styles add
1377  // if(ItemLoader.GrabStyle(Main.item[j], this)) { } else
1381  public static bool GrabStyle(Item item, Player player) {
1382  foreach (var g in HookGrabStyle.arr)
1383  if (g.Instance(item).GrabStyle(item, player))
1384  return true;
1385 
1386  return item.modItem != null && item.modItem.GrabStyle(player);
1387  }
1388 
1389  private static HookList HookCanPickup = AddHook<Func<Item, Player, bool>>(g => g.CanPickup);
1390  //in Terraria.Player.GrabItems first per item if statement add
1391  // && ItemLoader.CanPickup(Main.item[j], this)
1392  public static bool CanPickup(Item item, Player player) {
1393  foreach (var g in HookCanPickup.arr)
1394  if (!g.Instance(item).CanPickup(item, player))
1395  return false;
1396 
1397  return item.modItem?.CanPickup(player) ?? true;
1398  }
1399 
1400  private static HookList HookOnPickup = AddHook<Func<Item, Player, bool>>(g => g.OnPickup);
1401  //in Terraria.Player.GrabItems before special pickup effects add
1402  // if(!ItemLoader.OnPickup(Main.item[j], this)) { Main.item[j] = new Item(); continue; }
1406  public static bool OnPickup(Item item, Player player) {
1407  foreach (var g in HookOnPickup.arr)
1408  if (!g.Instance(item).OnPickup(item, player))
1409  return false;
1410 
1411  return item.modItem?.OnPickup(player) ?? true;
1412  }
1413 
1414  private static HookList HookItemSpace = AddHook<Func<Item, Player, bool>>(g => g.ItemSpace);
1415  //in Terraria.Player.GrabItems before grab effect
1416  // (this.ItemSpace(Main.item[j]) || ItemLoader.ExtraPickupSpace(Main.item[j], this)
1417  public static bool ItemSpace(Item item, Player player) {
1418  foreach (var g in HookItemSpace.arr)
1419  if (g.Instance(item).ItemSpace(item, player))
1420  return true;
1421 
1422  return item.modItem?.ItemSpace(player) ?? false;
1423  }
1424 
1425  private static HookList HookGetAlpha = AddHook<Func<Item, Color, Color?>>(g => g.GetAlpha);
1426  //in Terraria.UI.ItemSlot.GetItemLight remove type too high check
1427  //in beginning of Terraria.Item.GetAlpha call
1428  // Color? modColor = ItemLoader.GetAlpha(this, newColor);
1429  // if(modColor.HasValue) { return modColor.Value; }
1433  public static Color? GetAlpha(Item item, Color lightColor) {
1434  if (item.IsAir)
1435  return null;
1436 
1437  foreach (var g in HookGetAlpha.arr) {
1438  Color? color = g.Instance(item).GetAlpha(item, lightColor);
1439  if (color.HasValue)
1440  return color;
1441  }
1442 
1443  return item.modItem?.GetAlpha(lightColor);
1444  }
1445 
1446  private delegate bool DelegatePreDrawInWorld(Item item, SpriteBatch spriteBatch, Color lightColor, Color alphaColor, ref float rotation, ref float scale, int whoAmI);
1447  private static HookList HookPreDrawInWorld = AddHook<DelegatePreDrawInWorld>(g => g.PreDrawInWorld);
1448  //in Terraria.Main.DrawItem after ItemSlot.GetItemLight call
1449  // if(!ItemLoader.PreDrawInWorld(item, Main.spriteBatch, color, alpha, ref rotation, ref scale)) { return; }
1453  public static bool PreDrawInWorld(Item item, SpriteBatch spriteBatch, Color lightColor, Color alphaColor, ref float rotation, ref float scale, int whoAmI) {
1454  bool flag = true;
1455  if (item.modItem != null)
1456  flag &= item.modItem.PreDrawInWorld(spriteBatch, lightColor, alphaColor, ref rotation, ref scale, whoAmI);
1457 
1458  foreach (var g in HookPreDrawInWorld.arr)
1459  flag &= g.Instance(item).PreDrawInWorld(item, spriteBatch, lightColor, alphaColor, ref rotation, ref scale, whoAmI);
1460 
1461  return flag;
1462  }
1463 
1464  private static HookList HookPostDrawInWorld = AddHook<Action<Item, SpriteBatch, Color, Color, float, float, int>>(g => g.PostDrawInWorld);
1465  //in Terraria.Main.DrawItem before every return (including for PreDrawInWorld) and at end of method call
1466  // ItemLoader.PostDrawInWorld(item, Main.spriteBatch, color, alpha, rotation, scale)
1470  public static void PostDrawInWorld(Item item, SpriteBatch spriteBatch, Color lightColor, Color alphaColor, float rotation, float scale, int whoAmI) {
1471  item.modItem?.PostDrawInWorld(spriteBatch, lightColor, alphaColor, rotation, scale, whoAmI);
1472 
1473  foreach (var g in HookPostDrawInWorld.arr)
1474  g.Instance(item).PostDrawInWorld(item, spriteBatch, lightColor, alphaColor, rotation, scale, whoAmI);
1475  }
1476 
1477  private static HookList HookPreDrawInInventory = AddHook<Func<Item, SpriteBatch, Vector2, Rectangle, Color, Color, Vector2, float, bool>>(g => g.PreDrawInInventory);
1478  //in Terraria.UI.ItemSlot.Draw place item-drawing code inside if statement
1479  // if(ItemLoader.PreDrawInInventory(item, spriteBatch, position2, rectangle2, item.GetAlpha(newColor),
1480  // item.GetColor(color), origin, num4 * num3))
1484  public static bool PreDrawInInventory(Item item, SpriteBatch spriteBatch, Vector2 position, Rectangle frame,
1485  Color drawColor, Color itemColor, Vector2 origin, float scale) {
1486  bool flag = true;
1487  foreach (var g in HookPreDrawInInventory.arr)
1488  flag &= g.Instance(item).PreDrawInInventory(item, spriteBatch, position, frame, drawColor, itemColor, origin, scale);
1489 
1490  if (item.modItem != null)
1491  flag &= item.modItem.PreDrawInInventory(spriteBatch, position, frame, drawColor, itemColor, origin, scale);
1492 
1493  return flag;
1494  }
1495 
1496  private static HookList HookPostDrawInInventory = AddHook<Action<Item, SpriteBatch, Vector2, Rectangle, Color, Color, Vector2, float>>(g => g.PostDrawInInventory);
1497  //in Terraria.UI.ItemSlot.Draw after if statement for PreDrawInInventory call
1498  // ItemLoader.PostDrawInInventory(item, spriteBatch, position2, rectangle2, item.GetAlpha(newColor),
1499  // item.GetColor(color), origin, num4 * num3);
1503  public static void PostDrawInInventory(Item item, SpriteBatch spriteBatch, Vector2 position, Rectangle frame,
1504  Color drawColor, Color itemColor, Vector2 origin, float scale) {
1505  item.modItem?.PostDrawInInventory(spriteBatch, position, frame, drawColor, itemColor, origin, scale);
1506 
1507  foreach (var g in HookPostDrawInInventory.arr)
1508  g.Instance(item).PostDrawInInventory(item, spriteBatch, position, frame, drawColor, itemColor, origin, scale);
1509  }
1510 
1511  private static HookList HookHoldoutOffset = AddHook<Func<int, Vector2?>>(g => g.HoldoutOffset);
1512  public static void HoldoutOffset(float gravDir, int type, ref Vector2 offset) {
1513  ModItem modItem = GetItem(type);
1514  if (modItem != null) {
1515  Vector2? modOffset = modItem.HoldoutOffset();
1516  if (modOffset.HasValue) {
1517  offset.X = modOffset.Value.X;
1518  offset.Y += gravDir * modOffset.Value.Y;
1519  }
1520  }
1521  foreach (var g in HookHoldoutOffset.arr) {
1522  Vector2? modOffset = g.HoldoutOffset(type);
1523  if (modOffset.HasValue) {
1524  offset.X = modOffset.Value.X;
1525  offset.Y = Main.itemTexture[type].Height / 2f + gravDir * modOffset.Value.Y;
1526  }
1527  }
1528  }
1529 
1530  private static HookList HookHoldoutOrigin = AddHook<Func<int, Vector2?>>(g => g.HoldoutOrigin);
1531  public static void HoldoutOrigin(Player player, ref Vector2 origin) {
1532  Item item = player.inventory[player.selectedItem];
1533  Vector2 modOrigin = Vector2.Zero;
1534  if (item.modItem != null) {
1535  Vector2? modOrigin2 = item.modItem.HoldoutOrigin();
1536  if (modOrigin2.HasValue) {
1537  modOrigin = modOrigin2.Value;
1538  }
1539  }
1540  foreach (var g in HookHoldoutOrigin.arr) {
1541  Vector2? modOrigin2 = g.Instance(item).HoldoutOrigin(item.type);
1542  if (modOrigin2.HasValue) {
1543  modOrigin = modOrigin2.Value;
1544  }
1545  }
1546  modOrigin.X *= player.direction;
1547  modOrigin.Y *= -player.gravDir;
1548  origin += modOrigin;
1549  }
1550 
1551  private static HookList HookCanEquipAccessory = AddHook<Func<Item, Player, int, bool>>(g => g.CanEquipAccessory);
1552  //in Terraria.UI.ItemSlot.AccCheck replace 2nd and 3rd return false with
1553  // return !ItemLoader.CanEquipAccessory(item, slot)
1554  public static bool CanEquipAccessory(Item item, int slot) {
1555  Player player = Main.player[Main.myPlayer];
1556  if (item.modItem != null && !item.modItem.CanEquipAccessory(player, slot))
1557  return false;
1558 
1559  foreach (var g in HookCanEquipAccessory.arr)
1560  if (!g.Instance(item).CanEquipAccessory(item, player, slot))
1561  return false;
1562 
1563  return true;
1564  }
1565 
1566  private delegate void DelegateExtractinatorUse(int extractType, ref int resultType, ref int resultStack);
1567  private static HookList HookExtractinatorUse = AddHook<DelegateExtractinatorUse>(g => g.ExtractinatorUse);
1568  public static void ExtractinatorUse(ref int resultType, ref int resultStack, int extractType) {
1569  GetItem(extractType)?.ExtractinatorUse(ref resultType, ref resultStack);
1570 
1571  foreach (var g in HookExtractinatorUse.arr)
1572  g.ExtractinatorUse(extractType, ref resultType, ref resultStack);
1573  }
1574 
1575  public static void AutoLightSelect(Item item, ref bool dryTorch, ref bool wetTorch, ref bool glowstick) {
1576  if (item.modItem != null) {
1577  item.modItem.AutoLightSelect(ref dryTorch, ref wetTorch, ref glowstick);
1578  if (wetTorch) {
1579  dryTorch = false;
1580  glowstick = false;
1581  }
1582  if (dryTorch) {
1583  glowstick = false;
1584  }
1585  }
1586  }
1587 
1588  private delegate void DelegateCaughtFishStack(int type, ref int stack);
1589  private static HookList HookCaughtFishStack = AddHook<DelegateCaughtFishStack>(g => g.CaughtFishStack);
1590  public static void CaughtFishStack(Item item) {
1591  item.modItem?.CaughtFishStack(ref item.stack);
1592 
1593  foreach (var g in HookCaughtFishStack.arr)
1594  g.Instance(item).CaughtFishStack(item.type, ref item.stack);
1595  }
1596 
1597  private static HookList HookIsAnglerQuestAvailable = AddHook<Func<int, bool>>(g => g.IsAnglerQuestAvailable);
1598  public static void IsAnglerQuestAvailable(int itemID, ref bool notAvailable) {
1599  ModItem modItem = GetItem(itemID);
1600  if (modItem != null)
1601  notAvailable |= !modItem.IsAnglerQuestAvailable();
1602 
1603  foreach (var g in HookIsAnglerQuestAvailable.arr)
1604  notAvailable |= !g.IsAnglerQuestAvailable(itemID);
1605  }
1606 
1607  private delegate void DelegateAnglerChat(int type, ref string chat, ref string catchLocation);
1608  private static HookList HookAnglerChat = AddHook<DelegateAnglerChat>(g => g.AnglerChat);
1609  public static string AnglerChat(int type) {
1610  string chat = "";
1611  string catchLocation = "";
1612  GetItem(type)?.AnglerQuestChat(ref chat, ref catchLocation);
1613 
1614  foreach (var g in HookAnglerChat.arr)
1615  g.AnglerChat(type, ref chat, ref catchLocation);
1616 
1617  if (string.IsNullOrEmpty(chat) || string.IsNullOrEmpty(catchLocation))
1618  return null;
1619 
1620  return chat + "\n\n(" + catchLocation + ")";
1621  }
1622 
1623  private static HookList HookOnCraft = AddHook<Action<Item, Recipe>>(g => g.OnCraft);
1624  public static void OnCraft(Item item, Recipe recipe) {
1625  item.modItem?.OnCraft(recipe);
1626  foreach (var g in HookOnCraft.arr)
1627  g.Instance(item).OnCraft(item, recipe);
1628  }
1629 
1630  private delegate bool DelegatePreDrawTooltip(Item item, ReadOnlyCollection<TooltipLine> lines, ref int x, ref int y);
1631  private static HookList HookPreDrawTooltip = AddHook<DelegatePreDrawTooltip>(g => g.PreDrawTooltip);
1632  public static bool PreDrawTooltip(Item item, ReadOnlyCollection<TooltipLine> lines, ref int x, ref int y) {
1633  bool modItemPreDraw = item.modItem?.PreDrawTooltip(lines, ref x, ref y) ?? true;
1634  List<bool> globalItemPreDraw = new List<bool>();
1635  foreach (var g in HookPreDrawTooltip.arr)
1636  globalItemPreDraw.Add(g.PreDrawTooltip(item, lines, ref x, ref y));
1637  return modItemPreDraw && globalItemPreDraw.All(z => z);
1638  }
1639 
1640  private delegate void DelegatePostDrawTooltip(Item item, ReadOnlyCollection<DrawableTooltipLine> lines);
1641  private static HookList HookPostDrawTooltip = AddHook<DelegatePostDrawTooltip>(g => g.PostDrawTooltip);
1642  public static void PostDrawTooltip(Item item, ReadOnlyCollection<DrawableTooltipLine> lines) {
1643  item.modItem?.PostDrawTooltip(lines);
1644  foreach (var g in HookPostDrawTooltip.arr)
1645  g.Instance(item).PostDrawTooltip(item, lines);
1646  }
1647 
1648  private delegate bool DelegatePreDrawTooltipLine(Item item, DrawableTooltipLine line, ref int yOffset);
1649  private static HookList HookPreDrawTooltipLine = AddHook<DelegatePreDrawTooltipLine>(g => g.PreDrawTooltipLine);
1650  public static bool PreDrawTooltipLine(Item item, DrawableTooltipLine line, ref int yOffset) {
1651  bool modItemPreDrawLine = item.modItem?.PreDrawTooltipLine(line, ref yOffset) ?? true;
1652  List<bool> globalItemPreDrawLine = new List<bool>();
1653  foreach (var g in HookPreDrawTooltipLine.arr)
1654  globalItemPreDrawLine.Add(g.PreDrawTooltipLine(item, line, ref yOffset));
1655  return modItemPreDrawLine && globalItemPreDrawLine.All(x => x);
1656  }
1657 
1658  private delegate void DelegatePostDrawTooltipLine(Item item, DrawableTooltipLine line);
1659  private static HookList HookPostDrawTooltipLine = AddHook<DelegatePostDrawTooltipLine>(g => g.PostDrawTooltipLine);
1660  public static void PostDrawTooltipLine(Item item, DrawableTooltipLine line) {
1661  item.modItem?.PostDrawTooltipLine(line);
1662  foreach (var g in HookPostDrawTooltipLine.arr)
1663  g.Instance(item).PostDrawTooltipLine(item, line);
1664  }
1665 
1666  private static HookList HookModifyTooltips = AddHook<Action<Item, List<TooltipLine>>>(g => g.ModifyTooltips);
1667  public static List<TooltipLine> ModifyTooltips(Item item, ref int numTooltips, string[] names, ref string[] text,
1668  ref bool[] modifier, ref bool[] badModifier, ref int oneDropLogo, out Color?[] overrideColor) {
1669  List<TooltipLine> tooltips = new List<TooltipLine>();
1670  for (int k = 0; k < numTooltips; k++) {
1671  TooltipLine tooltip = new TooltipLine(names[k], text[k]);
1672  tooltip.isModifier = modifier[k];
1673  tooltip.isModifierBad = badModifier[k];
1674  if (k == oneDropLogo) {
1675  tooltip.oneDropLogo = true;
1676  }
1677  tooltips.Add(tooltip);
1678  }
1679  item.modItem?.ModifyTooltips(tooltips);
1680  foreach (var g in HookModifyTooltips.arr)
1681  g.Instance(item).ModifyTooltips(item, tooltips);
1682 
1683  numTooltips = tooltips.Count;
1684  text = new string[numTooltips];
1685  modifier = new bool[numTooltips];
1686  badModifier = new bool[numTooltips];
1687  oneDropLogo = -1;
1688  overrideColor = new Color?[numTooltips];
1689  for (int k = 0; k < numTooltips; k++) {
1690  text[k] = tooltips[k].text;
1691  modifier[k] = tooltips[k].isModifier;
1692  badModifier[k] = tooltips[k].isModifierBad;
1693  if (tooltips[k].oneDropLogo) {
1694  oneDropLogo = k;
1695  }
1696  overrideColor[k] = tooltips[k].overrideColor;
1697  }
1698 
1699  return tooltips;
1700  }
1701 
1702  private static HookList HookNeedsSaving = AddHook<Func<Item, bool>>(g => g.NeedsSaving);
1703  public static bool NeedsModSaving(Item item) {
1704  return item.type != 0 && (item.modItem != null || item.prefix >= PrefixID.Count || HookNeedsSaving.arr.Count(g => g.Instance(item).NeedsSaving(item)) > 0);
1705  }
1706 
1707  internal static void WriteNetGlobalOrder(BinaryWriter w) {
1708  w.Write((short)NetGlobals.Length);
1709  foreach (var globalItem in NetGlobals) {
1710  w.Write(globalItem.mod.netID);
1711  w.Write(globalItem.Name);
1712  }
1713  }
1714 
1715  internal static void ReadNetGlobalOrder(BinaryReader r) {
1716  short n = r.ReadInt16();
1717  NetGlobals = new GlobalItem[n];
1718  for (short i = 0; i < n; i++)
1719  NetGlobals[i] = ModNet.GetMod(r.ReadInt16()).GetGlobalItem(r.ReadString());
1720  }
1721 
1722  private static bool HasMethod(Type t, string method, params Type[] args) {
1723  return t.GetMethod(method, args).DeclaringType != typeof(GlobalItem);
1724  }
1725 
1726  internal static void VerifyGlobalItem(GlobalItem item) {
1727  var type = item.GetType();
1728  int saveMethods = 0;
1729  if (HasMethod(type, "NeedsSaving", typeof(Item))) saveMethods++;
1730  if (HasMethod(type, "Save", typeof(Item))) saveMethods++;
1731  if (HasMethod(type, "Load", typeof(Item), typeof(TagCompound))) saveMethods++;
1732  if (saveMethods > 0 && saveMethods < 3)
1733  throw new Exception(type + " must override all of (NeedsSaving/Save/Load) or none");
1734 
1735  int netMethods = 0;
1736  if (HasMethod(type, "NetSend", typeof(Item), typeof(BinaryWriter))) netMethods++;
1737  if (HasMethod(type, "NetReceive", typeof(Item), typeof(BinaryReader))) netMethods++;
1738  if (netMethods == 1)
1739  throw new Exception(type + " must override both of (NetSend/NetReceive) or none");
1740 
1741  bool hasInstanceFields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
1742  .Any(f => f.DeclaringType != typeof(GlobalItem));
1743 
1744  if (hasInstanceFields) {
1745  if (!item.InstancePerEntity)
1746  throw new Exception(type + " has instance fields but does not set InstancePerEntity to true. Either use static fields, or per instance globals");
1747 
1748  if (!item.CloneNewInstances &&
1749  !HasMethod(type, "NewInstance", typeof(Item)) &&
1750  !HasMethod(type, "Clone", typeof(Item), typeof(Item)))
1751  throw new Exception(type + " has InstancePerEntity but must either set CloneNewInstances to true, or override NewInstance(Item) or Clone(Item, Item)");
1752  }
1753  }
1754  }
1755 }
virtual void UpdateVanitySet(Player player)
Allows you to create special effects (such as dust) when the player wears this equipment texture&#39;s va...
Definition: EquipTexture.cs:97
virtual string IsArmorSet(Item head, Item body, Item legs)
Allows you to determine whether the player is wearing an armor set, and return a name for this set...
Definition: GlobalItem.cs:425
static bool Shoot(Item item, Player player, ref Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack)
Calls each GlobalItem.Shoot hook, then ModItem.Shoot, until one of them returns false. If all of them return true, returns true.
Definition: ItemLoader.cs:578
static bool CanPickup(Item item, Player player)
Definition: ItemLoader.cs:1392
virtual int BossBagNPC
The type of NPC that drops this boss bag. Used to determine how many coins this boss bag contains...
Definition: ModItem.cs:979
static void HoldItem(Item item, Player player)
Calls ModItem.HoldItem and all GlobalItem.HoldItem hooks.
Definition: ItemLoader.cs:318
virtual bool IsAnglerQuestAvailable()
Whether or not specific conditions have been satisfied for the Angler to be able to request this item...
Definition: ModItem.cs:959
static void OnConsumeItem(Item item, Player player)
Calls ModItem.OnConsumeItem and all GlobalItem.OnConsumeItem hooks.
Definition: ItemLoader.cs:759
static void OpenBossBag(int type, Player player, ref int npc)
If the item is a modded item and ModItem.bossBagNPC is greater than 0, calls ModItem.OpenBossBag and sets npc to ModItem.bossBagNPC.
Definition: ItemLoader.cs:1058
static void IsAnglerQuestAvailable(int itemID, ref bool notAvailable)
Definition: ItemLoader.cs:1598
static void UseItemHitbox(Item item, Player player, ref Rectangle hitbox, ref bool noHitbox)
Calls ModItem.UseItemHitbox, then all GlobalItem.UseItemHitbox hooks.
Definition: ItemLoader.cs:599
static readonly EquipType[] EquipTypes
Definition: EquipLoader.cs:32
virtual void UpdateVanitySet(Player player, string set)
Allows you to create special effects (such as dust) when the player wears the vanity set with the giv...
Definition: GlobalItem.cs:475
static EquipTexture GetEquipTexture(EquipType type, int slot)
Gets the equipment texture for the specified equipment type and ID.
Definition: EquipLoader.cs:56
static bool AllowVanillaClients
Definition: ModNet.cs:52
static void GetWeaponCrit(Item item, Player player, ref int crit)
Calls ModItem.GetWeaponCrit, then all GlobalItem.GetWeaponCrit hooks.
Definition: ItemLoader.cs:488
static Item GetWing(Player player)
s Returns the wing item that the player is functionally using. If player.wingsLogic has been modified...
Definition: ItemLoader.cs:1249
static void MeleeEffects(Item item, Player player, Rectangle hitbox)
Calls ModItem.MeleeEffects and all GlobalItem.MeleeEffects hooks.
Definition: ItemLoader.cs:612
static void OnHitPvp(Item item, Player player, Player target, int damage, bool crit)
Calls ModItem.OnHitPvp and all GlobalItem.OnHitPvp hooks.
Definition: ItemLoader.cs:710
virtual void VerticalWingSpeeds(Player player, ref float ascentWhenFalling, ref float ascentWhenRising, ref float maxCanAscendMultiplier, ref float maxAscentMultiplier, ref float constantAscend)
Allows you to modify vertical wing speeds.
static void ArmorSetShadows(Player player)
If the player&#39;s head texture&#39;s IsVanitySet returns true, calls the equipment texture&#39;s ArmorSetShadow...
Definition: ItemLoader.cs:961
static bool PreDrawInWorld(Item item, SpriteBatch spriteBatch, Color lightColor, Color alphaColor, ref float rotation, ref float scale, int whoAmI)
Returns the "and" operator on the results of ModItem.PreDrawInWorld and all GlobalItem.PreDrawInWorld hooks.
Definition: ItemLoader.cs:1453
static bool WingUpdate(Player player, bool inUse)
If wings can be seen on the player, calls the player&#39;s wing&#39;s equipment texture&#39;s WingUpdate and all ...
Definition: ItemLoader.cs:1323
static bool CheckProjOnSwing(Player player, Item item)
If the item is a modded item, ModItem.checkProjOnSwing is true, and the player is not at the beginnin...
Definition: ItemLoader.cs:501
static bool CanRightClick(Item item)
Calls ModItem.CanRightClick, then all GlobalItem.CanRightClick hooks, until one of the returns true...
Definition: ItemLoader.cs:1000
static bool ConsumeAmmo(Item item, Item ammo, Player player)
Calls ModItem.ConsumeAmmo for the weapon, ModItem.ConsumeAmmo for the ammo, then each GlobalItem...
Definition: ItemLoader.cs:531
static void PickAmmo(Item weapon, Item ammo, Player player, ref int type, ref float speed, ref int damage, ref float knockback)
Calls ModItem.PickAmmo, then all GlobalItem.PickAmmo hooks.
Definition: ItemLoader.cs:513
This serves as a place for you to program behaviors of equipment textures. This is useful for equipme...
Definition: EquipTexture.cs:8
static void PostDrawTooltip(Item item, ReadOnlyCollection< DrawableTooltipLine > lines)
Definition: ItemLoader.cs:1642
This class serves as a way to store information about a line of tooltip for an item. You will create and manipulate objects of this class if you use the ModifyTooltips hook.
Definition: TooltipLine.cs:8
virtual Vector2 HoldoutOffset()
Allows you to determine the offset of this item&#39;s sprite when used by the player. This is only used f...
Definition: ModItem.cs:904
Item item
The item object that this ModItem controls.
Definition: ModItem.cs:26
static bool CanUseItem(Item item, Player player)
Returns the "and" operation on the results of ModItem.CanUseItem and all GlobalItem.CanUseItem hooks. Does not fail fast (every hook is called).
Definition: ItemLoader.cs:272
static float UseTimeMultiplier(Item item, Player player)
Definition: ItemLoader.cs:329
virtual void PreUpdateVanitySet(Player player)
Allows you to create special effects (such as the necro armor&#39;s hurt noise) when the player wears thi...
Definition: EquipTexture.cs:87
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
This serves as the central class which loads mods. It contains many static fields and methods related...
Definition: ModLoader.cs:25
virtual bool DrawBody()
Return false to hide the player&#39;s body when this body equipment texture is worn. By default this will...
static void AutoLightSelect(Item item, ref bool dryTorch, ref bool wetTorch, ref bool glowstick)
Definition: ItemLoader.cs:1575
static Rectangle AnimatedItemFrame(Item item)
Definition: ItemLoader.cs:241
static bool OnPickup(Item item, Player player)
Calls all GlobalItem.OnPickup hooks then ModItem.OnPickup, until one of the returns false...
Definition: ItemLoader.cs:1406
static bool DrawHead(Player player)
Calls the item&#39;s head equipment texture&#39;s DrawHead hook, then all GlobalItem.DrawHead hooks...
Definition: ItemLoader.cs:1171
static void Update(Item item, ref float gravity, ref float maxFallSpeed)
Calls ModItem.Update, then all GlobalItem.Update hooks.
Definition: ItemLoader.cs:1343
static void OnMissingMana(Item item, Player player, int neededMana)
Calls ModItem.OnMissingMana, then all GlobalItem.OnMissingMana hooks.
Definition: ItemLoader.cs:404
static bool ReforgePrice(Item item, ref int reforgePrice, ref bool canApplyDiscount)
Call all ModItem.ReforgePrice, then GlobalItem.ReforgePrice hooks.
Definition: ItemLoader.cs:1105
static void FindVanillaWings()
Definition: ItemLoader.cs:52
static void ModifyHitPvp(Item item, Player player, Player target, ref int damage, ref bool crit)
Calls ModItem.ModifyHitPvp, then all GlobalItem.ModifyHitPvp hooks.
Definition: ItemLoader.cs:697
static void ModifyHitNPC(Item item, Player player, NPC target, ref int damage, ref float knockBack, ref bool crit)
Calls ModItem.ModifyHitNPC, then all GlobalItem.ModifyHitNPC hooks.
Definition: ItemLoader.cs:656
static void PostDrawInInventory(Item item, SpriteBatch spriteBatch, Vector2 position, Rectangle frame, Color drawColor, Color itemColor, Vector2 origin, float scale)
Calls ModItem.PostDrawInInventory, then all GlobalItem.PostDrawInInventory hooks. ...
Definition: ItemLoader.cs:1503
static void HorizontalWingSpeeds(Player player)
If the player is using wings, this uses the result of GetWing, and calls ModItem.HorizontalWingSpeeds...
Definition: ItemLoader.cs:1305
static void ModifyWeaponDamage(Item item, Player player, ref float add, ref float mult, ref float flat)
Calls ModItem.HookModifyWeaponDamage, then all GlobalItem.HookModifyWeaponDamage hooks.
Definition: ItemLoader.cs:454
static bool CanHitNPC(Item item, Player player, NPC target)
Gathers the results of ModItem.CanHitNPC and all GlobalItem.CanHitNPC hooks. If any of them returns f...
Definition: ItemLoader.cs:630
static bool UseItem(Item item, Player player)
Returns true if any of ModItem.UseItem or GlobalItem.UseItem return true Does not fail fast (calls ev...
Definition: ItemLoader.cs:722
static ModItem GetItem(int type)
Gets the ModItem instance corresponding to the specified type. Returns null if no modded item has the...
Definition: ItemLoader.cs:76
static void PostDrawTooltipLine(Item item, DrawableTooltipLine line)
Definition: ItemLoader.cs:1660
static void UpdateEquip(Item item, Player player)
Calls ModItem.UpdateEquip and all GlobalItem.UpdateEquip hooks.
Definition: ItemLoader.cs:846
This serves as a central place to store equipment slots and their corresponding textures. You will use this to obtain the IDs for your equipment textures.
Definition: EquipLoader.cs:11
static void OnConsumeAmmo(Item item, Item ammo, Player player)
Calls ModItem.OnConsumeAmmo for the weapon, ModItem.OnConsumeAmmo for the ammo, then each GlobalItem...
Definition: ItemLoader.cs:549
static void GetHealMana(Item item, Player player, bool quickHeal, ref int healValue)
Calls ModItem.GetHealMana, then all GlobalItem.GetHealMana hooks.
Definition: ItemLoader.cs:374
static bool CanHitPvp(Item item, Player player, Player target)
Calls all GlobalItem.CanHitPvp hooks, then ModItem.CanHitPvp, until one of them returns false...
Definition: ItemLoader.cs:682
static int ChoosePrefix(Item item, UnifiedRandom rand)
Definition: ItemLoader.cs:249
EquipType
This is an enum of all the types of equipment that exist. An equipment type is defined as a type or l...
Definition: EquipType.cs:6
static Mod GetMod(int netID)
virtual bool WingUpdate(Player player, bool inUse)
Allows for wing textures to do various things while in use. "inUse" is whether or not the jump button...
static Color GetAlpha(Item item, Color lightColor)
Calls all GlobalItem.GetAlpha hooks then ModItem.GetAlpha, until one of them returns a color...
Definition: ItemLoader.cs:1433
static void CaughtFishStack(Item item)
Definition: ItemLoader.cs:1590
static void OnHitNPC(Item item, Player player, NPC target, int damage, float knockBack, bool crit)
Calls ModItem.OnHitNPC and all GlobalItem.OnHitNPC hooks.
Definition: ItemLoader.cs:669
This class allows you to modify and use hooks for all items, including vanilla items. Create an instance of an overriding class then call Mod.AddGlobalItem to use this.
Definition: GlobalItem.cs:15
static void OpenVanillaBag(string context, Player player, int arg)
Calls all GlobalItem.OpenVanillaBag hooks.
Definition: ItemLoader.cs:1093
virtual bool CloneNewInstances
Whether instances of this GlobalItem are created through Clone or constructor (by default implementat...
Definition: GlobalItem.cs:56
static void DrawArmorColor(EquipType type, int slot, Player drawPlayer, float shadow, ref Color color, ref int glowMask, ref Color glowMaskColor)
Calls the item&#39;s equipment texture&#39;s DrawArmorColor hook, then all GlobalItem.DrawArmorColor hooks...
Definition: ItemLoader.cs:1224
static void PreUpdateVanitySet(Player player)
If the player&#39;s head texture&#39;s IsVanitySet returns true, calls the equipment texture&#39;s PreUpdateVanit...
Definition: ItemLoader.cs:910
static string AnglerChat(int type)
Definition: ItemLoader.cs:1609
bool isModifier
Whether or not this tooltip gives prefix information. This will make it so that the tooltip is colore...
Definition: TooltipLine.cs:25
static bool DrawBody(Player player)
Calls the item&#39;s body equipment texture&#39;s DrawBody hook, then all GlobalItem.DrawBody hooks...
Definition: ItemLoader.cs:1187
virtual void DrawArmorColor(Player drawPlayer, float shadow, ref Color color, ref int glowMask, ref Color glowMaskColor)
Allows you to modify the colors in which this armor texture and surrounding accessories are drawn...
static bool UseItemFrame(Item item, Player player)
Calls ModItem.UseItemFrame, then all GlobalItem.UseItemFrame hooks, until one of them returns true...
Definition: ItemLoader.cs:775
virtual void UpdateArmorSet(Player player, string set)
Allows you to give set bonuses to your armor set with the given name. The set name will be the same a...
Definition: GlobalItem.cs:435
static void ArmorArmGlowMask(int slot, Player drawPlayer, float shadow, ref int glowMask, ref Color color)
Calls the item&#39;s body equipment texture&#39;s ArmorArmGlowMask hook, then all GlobalItem.ArmorArmGlowMask hooks.
Definition: ItemLoader.cs:1238
static bool NeedsModSaving(Item item)
Definition: ItemLoader.cs:1703
This serves as the central class from which item-related functions are carried out. It also stores a list of mod items by ID.
Definition: ItemLoader.cs:21
static void UpdateArmorSet(Player player, Item head, Item body, Item legs)
If the head&#39;s ModItem.IsArmorSet returns true, calls the head&#39;s ModItem.UpdateArmorSet. This is then repeated for the body, then the legs. Then for each GlobalItem, if GlobalItem.IsArmorSet returns a non-empty string, calls GlobalItem.UpdateArmorSet with that string.
Definition: ItemLoader.cs:888
static void VerticalWingSpeeds(Player player, ref float ascentWhenFalling, ref float ascentWhenRising, ref float maxCanAscendMultiplier, ref float maxAscentMultiplier, ref float constantAscend)
If the player is using wings, this uses the result of GetWing, and calls ModItem.VerticalWingSpeeds t...
Definition: ItemLoader.cs:1279
static bool GrabStyle(Item item, Player player)
Calls all GlobalItem.GrabStyle hooks then ModItem.GrabStyle, until one of them returns true...
Definition: ItemLoader.cs:1381
ModItem item
The item that is associated with this equipment texture. Null if no item is associated with this...
Definition: EquipTexture.cs:53
virtual void ArmorSetShadows(Player player)
Allows you to determine special visual effects this vanity set has on the player without having to co...
static void DrawHands(Player player, ref bool drawHands, ref bool drawArms)
Calls the item&#39;s body equipment texture&#39;s DrawHands hook, then all GlobalItem.DrawHands hooks...
Definition: ItemLoader.cs:1139
static void RightClick(Item item, Player player)
If Main.mouseRightRelease is true, the following steps are taken:
Definition: ItemLoader.cs:1027
bool isModifierBad
If isModifier is true, this determines whether the tooltip is colored green or red.
Definition: TooltipLine.cs:29
static void GetWeaponKnockback(Item item, Player player, ref float knockback)
Calls ModItem.GetWeaponKnockback, then all GlobalItem.GetWeaponKnockback hooks.
Definition: ItemLoader.cs:472
static void HoldStyle(Item item, Player player)
If the player is not holding onto a rope and is not in the middle of using an item, calls ModItem.HoldStyle and all GlobalItem.HoldStyle hooks.
Definition: ItemLoader.cs:303
static bool CanEquipAccessory(Item item, int slot)
Definition: ItemLoader.cs:1554
static void ModifyManaCost(Item item, Player player, ref float reduce, ref float mult)
Calls ModItem.ModifyManaCost, then all GlobalItem.ModifyManaCost hooks.
Definition: ItemLoader.cs:389
static bool AltFunctionUse(Item item, Player player)
Calls ModItem.AltFunctionUse, then all GlobalItem.AltFunctionUse hooks, until one of them returns tru...
Definition: ItemLoader.cs:810
virtual void SetMatch(bool male, ref int equipSlot, ref bool robes)
Allows you to modify the equipment that the player appears to be wearing. This hook will only be call...
static void UpdateVanitySet(Player player)
If the player&#39;s head texture&#39;s IsVanitySet returns true, calls the equipment texture&#39;s UpdateVanitySe...
Definition: ItemLoader.cs:935
static bool ItemSpace(Item item, Player player)
Definition: ItemLoader.cs:1417
virtual bool IsVanitySet(int head, int body, int legs)
Returns whether or not the head armor, body armor, and leg armor textures make up a set...
Definition: EquipTexture.cs:76
virtual void PreUpdateVanitySet(Player player, string set)
Allows you to create special effects (such as the necro armor&#39;s hurt noise) when the player wears the...
Definition: GlobalItem.cs:467
static void GetWeaponDamage(Item item, Player player, ref int damage)
Calls ModItem.GetWeaponDamage, then all GlobalItem.GetWeaponDamage hooks.
Definition: ItemLoader.cs:437
static List< TooltipLine > ModifyTooltips(Item item, ref int numTooltips, string[] names, ref string[] text, ref bool[] modifier, ref bool[] badModifier, ref int oneDropLogo, out Color?[] overrideColor)
Definition: ItemLoader.cs:1667
static void OnConsumeMana(Item item, Player player, int manaConsumed)
Calls ModItem.OnConsumeMana, then all GlobalItem.OnConsumeMana hooks.
Definition: ItemLoader.cs:419
static bool PreReforge(Item item)
Calls ModItem.PreReforge, then all GlobalItem.PreReforge hooks.
Definition: ItemLoader.cs:1117
virtual void DrawHair(ref bool drawHair, ref bool drawAltHair)
Allows you to determine whether the player&#39;s hair or alt (hat) hair draws when this head equipment te...
static bool PreDrawInInventory(Item item, SpriteBatch spriteBatch, Vector2 position, Rectangle frame, Color drawColor, Color itemColor, Vector2 origin, float scale)
Returns the "and" operator on the results of all GlobalItem.PreDrawInInventory hooks and ModItem...
Definition: ItemLoader.cs:1484
virtual void UpdateVanity(Player player, EquipType type)
Allows you to create special effects (such as dust) when this equipment texture is displayed on the p...
Definition: EquipTexture.cs:63
static void HoldoutOrigin(Player player, ref Vector2 origin)
Definition: ItemLoader.cs:1531
virtual string Name
Stores the name of the mod. This name serves as the mod&#39;s identification, and also helps with saving ...
Definition: Mod.cs:41
This serves as the central class from which NPC-related functions are carried out. It also stores a list of mod NPCs by ID.
Definition: NPCLoader.cs:19
static void UpdateInventory(Item item, Player player)
Calls ModItem.UpdateInventory and all GlobalItem.UpdateInventory hooks.
Definition: ItemLoader.cs:830
static bool HasMethod(Type t, string method, params Type[] args)
Definition: ItemLoader.cs:1722
static float MeleeSpeedMultiplier(Item item, Player player)
Definition: ItemLoader.cs:342
GlobalItem Instance(Item item)
virtual void OpenBossBag(Player player)
Allows you to give items to the given player when this item is right-clicked in the inventory if the ...
Definition: ModItem.cs:651
Mod is an abstract class that you will override. It serves as a central place from which the mod&#39;s co...
Definition: Mod.cs:23
static bool PreDrawTooltipLine(Item item, DrawableTooltipLine line, ref int yOffset)
Definition: ItemLoader.cs:1650
static void UseStyle(Item item, Player player)
Calls ModItem.UseStyle and all GlobalItem.UseStyle hooks.
Definition: ItemLoader.cs:288
This class serves as a place for you to place all your properties and hooks for each item...
Definition: ModItem.cs:16
static void ExtractinatorUse(ref int resultType, ref int resultStack, int extractType)
Definition: ItemLoader.cs:1568
virtual bool DrawHead()
Return false to hide the player&#39;s head when this head equipment texture is worn. By default this will...
static void GetHealLife(Item item, Player player, bool quickHeal, ref int healValue)
Calls ModItem.GetHealLife, then all GlobalItem.GetHealLife hooks.
Definition: ItemLoader.cs:359
This class serves as a way to store information about a line that will be drawn of tooltip for an ite...
static bool IsModBossBag(Item item)
Returns whether ModItem.bossBagNPC is greater than 0. Returns false if item is not a modded item...
Definition: ItemLoader.cs:1049
static bool ConsumeItem(Item item, Player player)
If ModItem.ConsumeItem or any of the GlobalItem.ConsumeItem hooks returns false, sets consume to fals...
Definition: ItemLoader.cs:742
static void OnCraft(Item item, Recipe recipe)
Definition: ItemLoader.cs:1624
static void UpdateVanity(Player player)
Calls each of the item&#39;s equipment texture&#39;s UpdateVanity hook.
Definition: ItemLoader.cs:875
static void UpdateAccessory(Item item, Player player, bool hideVisual)
Calls ModItem.UpdateAccessory and all GlobalItem.UpdateAccessory hooks.
Definition: ItemLoader.cs:862
static bool PreOpenVanillaBag(string context, Player player, int arg)
Calls each GlobalItem.PreOpenVanillaBag hook until one of them returns false. Returns true if all of ...
Definition: ItemLoader.cs:1074
virtual void ArmorSetShadows(Player player, string set)
Allows you to determine special visual effects a vanity has on the player without having to code them...
Definition: GlobalItem.cs:484
static void HoldoutOffset(float gravDir, int type, ref Vector2 offset)
Definition: ItemLoader.cs:1512
virtual bool DrawLegs()
Return false to hide the player&#39;s legs when this leg or shoe equipment texture is worn...
virtual void DrawHands(ref bool drawHands, ref bool drawArms)
Allows you to determine whether the skin/shirt on the player&#39;s arms and hands are drawn when this bod...
static void DrawHair(Player player, ref bool drawHair, ref bool drawAltHair)
Calls the item&#39;s head equipment texture&#39;s DrawHair hook, then all GlobalItem.DrawHair hooks...
Definition: ItemLoader.cs:1156
static bool GeneralPrefix(Item item)
Definition: ItemLoader.cs:173
virtual bool InstancePerEntity
Whether to create a new GlobalItem instance for every Item that exists. Useful for storing informatio...
Definition: GlobalItem.cs:48
static void PostDrawInWorld(Item item, SpriteBatch spriteBatch, Color lightColor, Color alphaColor, float rotation, float scale, int whoAmI)
Calls ModItem.PostDrawInWorld, then all GlobalItem.PostDrawInWorld hooks.
Definition: ItemLoader.cs:1470
static bool HoldItemFrame(Item item, Player player)
Calls ModItem.HoldItemFrame, then all GlobalItem.HoldItemFrame hooks, until one of them returns true...
Definition: ItemLoader.cs:792
static void PostUpdate(Item item)
Calls ModItem.PostUpdate and all GlobalItem.PostUpdate hooks.
Definition: ItemLoader.cs:1354
virtual void HorizontalWingSpeeds(Player player, ref float speed, ref float acceleration)
Allows you to modify horizontal wing speeds.
virtual void ArmorArmGlowMask(Player drawPlayer, float shadow, ref int glowMask, ref Color color)
Allows you to modify which glow mask and in what color is drawn on the player&#39;s arms. Note that this is only called for body equipment textures. By default this will call the associated ModItem&#39;s ArmorArmGlowMask if there is an associated ModItem.
static bool PreDrawTooltip(Item item, ReadOnlyCollection< TooltipLine > lines, ref int x, ref int y)
Definition: ItemLoader.cs:1632
static void GrabRange(Item item, Player player, ref int grabRange)
Calls ModItem.GrabRange, then all GlobalItem.GrabRange hooks.
Definition: ItemLoader.cs:1368
static bool DrawLegs(Player player)
Calls the item&#39;s leg equipment texture&#39;s DrawLegs hook, then the item&#39;s shoe equipment texture&#39;s Draw...
Definition: ItemLoader.cs:1203
virtual string IsVanitySet(int head, int body, int legs)
Returns whether or not the head armor, body armor, and leg armor textures make up a set...
Definition: GlobalItem.cs:445
static void PostReforge(Item item)
Calls ModItem.PostReforge, then all GlobalItem.PostReforge hooks.
Definition: ItemLoader.cs:1128
static void SetMatch(int armorSlot, int type, bool male, ref int equipSlot, ref bool robes)
Calls EquipTexture.SetMatch, then all GlobalItem.SetMatch hooks.
Definition: ItemLoader.cs:986