Terraria ModLoader  0.11.4
A framework for Terraria mods
TileLoader.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 Terraria.ID;
6 using Terraria.ObjectData;
7 
8 namespace Terraria.ModLoader
9 {
10  //todo: further documentation
14  public static class TileLoader
15  {
16  //make Terraria.ObjectData.TileObjectData._data internal
17  //make all static Terraria.ObjectData.TileObjectData.StyleName fields public
18  //make Terraria.ObjectData.TileObjectData.LinkedAlternates public
19  //make Terraria.ObjectData.TileObjectData.SubTiles and Alternates internal
20  //at end of Terraria.ObjectData.TileObjectData.Initialize remove TileObjectData.readOnlyData = true;
21  //at beginning of Terraria.WorldGen.PlaceTile remove type too high check
22  //at beginning of Terraria.WorldGen.PlaceObject remove type too high check
23  //in Terraria.WorldGen.Convert remove type too high checks
24  //in Terraria.WorldGen.StartRoomCheck change 419 to WorldGen.houseTile.Length
25  //at end of Terraria.WorldGen.KillWall remove type too high check
26  //in Terraria.Player change adjTile and oldAdjTile size to TileLoader.TileCount()
27  //in Terraria.Player.AdjTiles change 419 to adjTile.Length
28  //in Terraria.Lighting for accOreFinder replace 419 with Main.tileValue.Length
29  //make Terraria.WorldGen public
30  //in Terraria.IO.WorldFile.SaveFileFormatHeader set initial num to TileLoader.TileCount
31  private static int nextTile = TileID.Count;
32  internal static readonly IList<ModTile> tiles = new List<ModTile>();
33  internal static readonly IList<GlobalTile> globalTiles = new List<GlobalTile>();
34  internal static readonly IDictionary<int, ModTree> trees = new Dictionary<int, ModTree>();
35  internal static readonly IDictionary<int, ModPalmTree> palmTrees = new Dictionary<int, ModPalmTree>();
36  internal static readonly IDictionary<int, ModCactus> cacti = new Dictionary<int, ModCactus>();
37  private static bool loaded = false;
38  private static readonly int vanillaChairCount = TileID.Sets.RoomNeeds.CountsAsChair.Length;
39  private static readonly int vanillaTableCount = TileID.Sets.RoomNeeds.CountsAsTable.Length;
40  private static readonly int vanillaTorchCount = TileID.Sets.RoomNeeds.CountsAsTorch.Length;
41  private static readonly int vanillaDoorCount = TileID.Sets.RoomNeeds.CountsAsDoor.Length;
42 
43  private static Func<int, int, int, bool>[] HookKillSound;
44  private delegate void DelegateNumDust(int i, int j, int type, bool fail, ref int num);
45  private static DelegateNumDust[] HookNumDust;
46  private delegate bool DelegateCreateDust(int i, int j, int type, ref int dustType);
47  private static DelegateCreateDust[] HookCreateDust;
48  private delegate void DelegateDropCritterChance(int i, int j, int type, ref int wormChance, ref int grassHopperChance, ref int jungleGrubChance);
49  private static DelegateDropCritterChance[] HookDropCritterChance;
50  private static Func<int, int, int, bool>[] HookDrop;
51  private delegate bool DelegateCanKillTile(int i, int j, int type, ref bool blockDamaged);
52  private static DelegateCanKillTile[] HookCanKillTile;
53  private delegate void DelegateKillTile(int i, int j, int type, ref bool fail, ref bool effectOnly, ref bool noItem);
54  private static DelegateKillTile[] HookKillTile;
55  private static Func<int, int, int, bool>[] HookCanExplode;
56  private static Action<int, int, int, bool>[] HookNearbyEffects;
57  private delegate void DelegateModifyLight(int i, int j, int type, ref float r, ref float g, ref float b);
58  private static DelegateModifyLight[] HookModifyLight;
59  private static Func<int, int, int, Player, bool>[] HookDangersense;
60  private delegate void DelegateSetSpriteEffects(int i, int j, int type, ref SpriteEffects spriteEffects);
61  private static DelegateSetSpriteEffects[] HookSetSpriteEffects;
62  private static Action[] HookAnimateTile;
63  private static Func<int, int, int, SpriteBatch, bool>[] HookPreDraw;
64  private delegate void DelegateDrawEffects(int i, int j, int type, SpriteBatch spriteBatch, ref Color drawColor, ref int nextSpecialDrawIndex);
65  private static DelegateDrawEffects[] HookDrawEffects;
66  private static Action<int, int, int, SpriteBatch>[] HookPostDraw;
67  private static Action<int, int, int, SpriteBatch>[] HookSpecialDraw;
68  private static Action<int, int, int>[] HookRandomUpdate;
69  private delegate bool DelegateTileFrame(int i, int j, int type, ref bool resetFrame, ref bool noBreak);
70  private static DelegateTileFrame[] HookTileFrame;
71  private static Func<int, int, int, bool>[] HookCanPlace;
72  private static Func<int, int[]>[] HookAdjTiles;
73  private static Action<int, int, int>[] HookRightClick;
74  private static Action<int, int, int>[] HookMouseOver;
75  private static Action<int, int, int>[] HookMouseOverFar;
76  private static Func<int, int, int, Item, bool>[] HookAutoSelect;
77  private static Func<int, int, int, bool>[] HookPreHitWire;
78  private static Action<int, int, int>[] HookHitWire;
79  private static Func<int, int, int, bool>[] HookSlope;
80  private static Action<int, Player>[] HookFloorVisuals;
81  private delegate void DelegateChangeWaterfallStyle(int type, ref int style);
82  private static DelegateChangeWaterfallStyle[] HookChangeWaterfallStyle;
83  private delegate int DelegateSaplingGrowthType(int type, ref int style);
84  private static DelegateSaplingGrowthType[] HookSaplingGrowthType;
85  private static Action<int, int, Item>[] HookPlaceInWorld;
86 
87  internal static int ReserveTileID() {
88  if (ModNet.AllowVanillaClients) throw new Exception("Adding tiles breaks vanilla client compatibility");
89 
90  int reserveID = nextTile;
91  nextTile++;
92  return reserveID;
93  }
94 
95  public static int TileCount => nextTile;
96 
102  public static ModTile GetTile(int type) {
103  return type >= TileID.Count && type < TileCount ? tiles[type - TileID.Count] : null;
104  }
105 
106  private static void Resize2DArray<T>(ref T[,] array, int newSize) {
107  int dim1 = array.GetLength(0);
108  int dim2 = array.GetLength(1);
109  T[,] newArray = new T[newSize, dim2];
110  for (int j = 0; j < newSize && j < dim1; j++) {
111  for (int k = 0; k < dim2; k++) {
112  newArray[j, k] = array[j, k];
113  }
114  }
115  array = newArray;
116  }
117 
118  internal static void ResizeArrays(bool unloading = false) {
119  Array.Resize(ref Main.tileSetsLoaded, nextTile);
120  for (int k = TileID.Count; k < nextTile; k++) {
121  Main.tileSetsLoaded[k] = true;
122  }
123  Array.Resize(ref Main.highlightMaskTexture, nextTile);
124  Resize2DArray(ref Main.tileAltTexture, nextTile);
125  Resize2DArray(ref Main.tileAltTextureInit, nextTile);
126  Resize2DArray(ref Main.tileAltTextureDrawn, nextTile);
127  Array.Resize(ref Main.tileTexture, nextTile);
128  Array.Resize(ref Main.tileLighted, nextTile);
129  Array.Resize(ref Main.tileMergeDirt, nextTile);
130  Array.Resize(ref Main.tileCut, nextTile);
131  Array.Resize(ref Main.tileAlch, nextTile);
132  Array.Resize(ref Main.tileShine, nextTile);
133  Array.Resize(ref Main.tileShine2, nextTile);
134  Array.Resize(ref Main.tileStone, nextTile);
135  Array.Resize(ref Main.tileAxe, nextTile);
136  Array.Resize(ref Main.tileHammer, nextTile);
137  Array.Resize(ref Main.tileWaterDeath, nextTile);
138  Array.Resize(ref Main.tileLavaDeath, nextTile);
139  Array.Resize(ref Main.tileTable, nextTile);
140  Array.Resize(ref Main.tileBlockLight, nextTile);
141  Array.Resize(ref Main.tileNoSunLight, nextTile);
142  Array.Resize(ref Main.tileDungeon, nextTile);
143  Array.Resize(ref Main.tileSpelunker, nextTile);
144  Array.Resize(ref Main.tileSolidTop, nextTile);
145  Array.Resize(ref Main.tileSolid, nextTile);
146  Array.Resize(ref Main.tileBouncy, nextTile);
147  Array.Resize(ref Main.tileValue, nextTile);
148  Array.Resize(ref Main.tileLargeFrames, nextTile);
149  Array.Resize(ref Main.tileRope, nextTile);
150  Array.Resize(ref Main.tileBrick, nextTile);
151  Array.Resize(ref Main.tileMoss, nextTile);
152  Array.Resize(ref Main.tileNoAttach, nextTile);
153  Array.Resize(ref Main.tileNoFail, nextTile);
154  Array.Resize(ref Main.tileObsidianKill, nextTile);
155  Array.Resize(ref Main.tileFrameImportant, nextTile);
156  Array.Resize(ref Main.tilePile, nextTile);
157  Array.Resize(ref Main.tileBlendAll, nextTile);
158  Array.Resize(ref Main.tileGlowMask, nextTile);
159  Array.Resize(ref Main.tileContainer, nextTile);
160  Array.Resize(ref Main.tileSign, nextTile);
161  Array.Resize(ref Main.tileMerge, nextTile);
162  for (int k = 0; k < nextTile; k++) //oh dear
163  {
164  Array.Resize(ref Main.tileMerge[k], nextTile);
165  }
166  Array.Resize(ref Main.tileSand, nextTile);
167  Array.Resize(ref Main.tileFlame, nextTile);
168  Array.Resize(ref Main.tileFrame, nextTile);
169  Array.Resize(ref Main.tileFrameCounter, nextTile);
170  Array.Resize(ref Main.screenTileCounts, nextTile);
171  Array.Resize(ref WorldGen.tileCounts, nextTile);
172  Array.Resize(ref WorldGen.houseTile, nextTile);
173  Array.Resize(ref GameContent.Biomes.CaveHouseBiome._blacklistedTiles, nextTile);
174  Array.Resize(ref GameContent.Biomes.CorruptionPitBiome.ValidTiles, nextTile);
175  Array.Resize(ref TileID.Sets.Conversion.Grass, nextTile);
176  Array.Resize(ref TileID.Sets.Conversion.Stone, nextTile);
177  Array.Resize(ref TileID.Sets.Conversion.Ice, nextTile);
178  Array.Resize(ref TileID.Sets.Conversion.Sand, nextTile);
179  Array.Resize(ref TileID.Sets.Conversion.HardenedSand, nextTile);
180  Array.Resize(ref TileID.Sets.Conversion.Sandstone, nextTile);
181  Array.Resize(ref TileID.Sets.Conversion.Thorn, nextTile);
182  Array.Resize(ref TileID.Sets.Conversion.Moss, nextTile);
183  Array.Resize(ref TileID.Sets.ForAdvancedCollision.ForSandshark, nextTile);
184  Array.Resize(ref TileID.Sets.Platforms, nextTile);
185  Array.Resize(ref TileID.Sets.DrawsWalls, nextTile);
186  Array.Resize(ref TileID.Sets.GemsparkFramingTypes, nextTile);
187  Array.Resize(ref TileID.Sets.TeamTiles, nextTile);
188  Array.Resize(ref TileID.Sets.ConveyorDirection, nextTile);
189  Array.Resize(ref TileID.Sets.HasSlopeFrames, nextTile);
190  Array.Resize(ref TileID.Sets.TileInteractRead, nextTile);
191  Array.Resize(ref TileID.Sets.HasOutlines, nextTile);
192  Array.Resize(ref TileID.Sets.AllTiles, nextTile);
193  Array.Resize(ref TileID.Sets.Stone, nextTile);
194  Array.Resize(ref TileID.Sets.Grass, nextTile);
195  Array.Resize(ref TileID.Sets.Mud, nextTile);
196  Array.Resize(ref TileID.Sets.Snow, nextTile);
197  Array.Resize(ref TileID.Sets.Ices, nextTile);
198  Array.Resize(ref TileID.Sets.IcesSlush, nextTile);
199  Array.Resize(ref TileID.Sets.IcesSnow, nextTile);
200  Array.Resize(ref TileID.Sets.GrassSpecial, nextTile);
201  Array.Resize(ref TileID.Sets.JungleSpecial, nextTile);
202  Array.Resize(ref TileID.Sets.HellSpecial, nextTile);
203  Array.Resize(ref TileID.Sets.Leaves, nextTile);
204  Array.Resize(ref TileID.Sets.GeneralPlacementTiles, nextTile);
205  Array.Resize(ref TileID.Sets.BasicChest, nextTile);
206  Array.Resize(ref TileID.Sets.BasicChestFake, nextTile);
207  Array.Resize(ref TileID.Sets.CanBeClearedDuringGeneration, nextTile);
208  Array.Resize(ref TileID.Sets.CanBeClearedDuringOreRunner, nextTile);
209  Array.Resize(ref TileID.Sets.Corrupt, nextTile);
210  Array.Resize(ref TileID.Sets.Hallow, nextTile);
211  Array.Resize(ref TileID.Sets.Crimson, nextTile);
212  Array.Resize(ref TileID.Sets.BlocksStairs, nextTile);
213  Array.Resize(ref TileID.Sets.BlocksStairsAbove, nextTile);
214  Array.Resize(ref TileID.Sets.NotReallySolid, nextTile);
215  Array.Resize(ref TileID.Sets.NeedsGrassFraming, nextTile);
216  Array.Resize(ref TileID.Sets.NeedsGrassFramingDirt, nextTile);
217  Array.Resize(ref TileID.Sets.ChecksForMerge, nextTile);
218  Array.Resize(ref TileID.Sets.FramesOnKillWall, nextTile);
219  Array.Resize(ref TileID.Sets.AvoidedByNPCs, nextTile);
220  Array.Resize(ref TileID.Sets.InteractibleByNPCs, nextTile);
221  Array.Resize(ref TileID.Sets.HousingWalls, nextTile);
222  Array.Resize(ref TileID.Sets.BreakableWhenPlacing, nextTile);
223  Array.Resize(ref TileID.Sets.TouchDamageVines, nextTile);
224  Array.Resize(ref TileID.Sets.TouchDamageSands, nextTile);
225  Array.Resize(ref TileID.Sets.TouchDamageHot, nextTile);
226  Array.Resize(ref TileID.Sets.TouchDamageOther, nextTile);
227  Array.Resize(ref TileID.Sets.Falling, nextTile);
228  Array.Resize(ref TileID.Sets.Ore, nextTile);
229  Array.Resize(ref TileID.Sets.ForceObsidianKill, nextTile);
230  for (int k = TileID.Count; k < nextTile; k++) {
231  TileID.Sets.AllTiles[k] = true;
232  TileID.Sets.GeneralPlacementTiles[k] = true;
233  TileID.Sets.CanBeClearedDuringGeneration[k] = true;
234  }
235  while (TileObjectData._data.Count < nextTile) {
236  TileObjectData._data.Add(null);
237  }
238 
239  ModLoader.BuildGlobalHook(ref HookKillSound, globalTiles, g => g.KillSound);
240  ModLoader.BuildGlobalHook(ref HookNumDust, globalTiles, g => g.NumDust);
241  ModLoader.BuildGlobalHook(ref HookCreateDust, globalTiles, g => g.CreateDust);
242  ModLoader.BuildGlobalHook(ref HookDropCritterChance, globalTiles, g => g.DropCritterChance);
243  ModLoader.BuildGlobalHook(ref HookDrop, globalTiles, g => g.Drop);
244  ModLoader.BuildGlobalHook(ref HookCanKillTile, globalTiles, g => g.CanKillTile);
245  ModLoader.BuildGlobalHook(ref HookKillTile, globalTiles, g => g.KillTile);
246  ModLoader.BuildGlobalHook(ref HookCanExplode, globalTiles, g => g.CanExplode);
247  ModLoader.BuildGlobalHook(ref HookNearbyEffects, globalTiles, g => g.NearbyEffects);
248  ModLoader.BuildGlobalHook(ref HookModifyLight, globalTiles, g => g.ModifyLight);
249  ModLoader.BuildGlobalHook(ref HookDangersense, globalTiles, g => g.Dangersense);
250  ModLoader.BuildGlobalHook(ref HookSetSpriteEffects, globalTiles, g => g.SetSpriteEffects);
251  ModLoader.BuildGlobalHook(ref HookAnimateTile, globalTiles, g => g.AnimateTile);
252  ModLoader.BuildGlobalHook(ref HookPreDraw, globalTiles, g => g.PreDraw);
253  ModLoader.BuildGlobalHook(ref HookDrawEffects, globalTiles, g => g.DrawEffects);
254  ModLoader.BuildGlobalHook(ref HookPostDraw, globalTiles, g => g.PostDraw);
255  ModLoader.BuildGlobalHook(ref HookSpecialDraw, globalTiles, g => g.SpecialDraw);
256  ModLoader.BuildGlobalHook(ref HookRandomUpdate, globalTiles, g => g.RandomUpdate);
257  ModLoader.BuildGlobalHook(ref HookTileFrame, globalTiles, g => g.TileFrame);
258  ModLoader.BuildGlobalHook(ref HookCanPlace, globalTiles, g => g.CanPlace);
259  ModLoader.BuildGlobalHook(ref HookAdjTiles, globalTiles, g => g.AdjTiles);
260  ModLoader.BuildGlobalHook(ref HookRightClick, globalTiles, g => g.RightClick);
261  ModLoader.BuildGlobalHook(ref HookMouseOver, globalTiles, g => g.MouseOver);
262  ModLoader.BuildGlobalHook(ref HookMouseOverFar, globalTiles, g => g.MouseOverFar);
263  ModLoader.BuildGlobalHook(ref HookAutoSelect, globalTiles, g => g.AutoSelect);
264  ModLoader.BuildGlobalHook(ref HookPreHitWire, globalTiles, g => g.PreHitWire);
265  ModLoader.BuildGlobalHook(ref HookHitWire, globalTiles, g => g.HitWire);
266  ModLoader.BuildGlobalHook(ref HookSlope, globalTiles, g => g.Slope);
267  ModLoader.BuildGlobalHook(ref HookFloorVisuals, globalTiles, g => g.FloorVisuals);
268  ModLoader.BuildGlobalHook(ref HookChangeWaterfallStyle, globalTiles, g => g.ChangeWaterfallStyle);
269  ModLoader.BuildGlobalHook(ref HookSaplingGrowthType, globalTiles, g => g.SaplingGrowthType);
270  ModLoader.BuildGlobalHook(ref HookPlaceInWorld, globalTiles, g => g.PlaceInWorld);
271 
272  if (!unloading) {
273  loaded = true;
274  }
275  }
276 
277  internal static void Unload() {
278  loaded = false;
279  tiles.Clear();
280  nextTile = TileID.Count;
281  globalTiles.Clear();
282  trees.Clear();
283  palmTrees.Clear();
284  cacti.Clear();
285  Array.Resize(ref TileID.Sets.RoomNeeds.CountsAsChair, vanillaChairCount);
286  Array.Resize(ref TileID.Sets.RoomNeeds.CountsAsTable, vanillaTableCount);
287  Array.Resize(ref TileID.Sets.RoomNeeds.CountsAsTorch, vanillaTorchCount);
288  Array.Resize(ref TileID.Sets.RoomNeeds.CountsAsDoor, vanillaDoorCount);
289  while (TileObjectData._data.Count > TileID.Count) {
290  TileObjectData._data.RemoveAt(TileObjectData._data.Count - 1);
291  }
292  }
293  //in Terraria.WorldGen.TileFrame after if else chain inside frameImportant if statement before return add
294  // else { TileLoader.CheckModTile(i, j, num); }
295  //in Terraria.TileObject.CanPlace add optional checkStay parameter as false to end
296  // and add && !checkStay to if statement that sets flag4
297  public static void CheckModTile(int i, int j, int type) {
298  if (WorldGen.destroyObject) {
299  return;
300  }
301  TileObjectData tileData = TileObjectData.GetTileData(type, 0, 0);
302  if (tileData == null) {
303  return;
304  }
305  int frameX = Main.tile[i, j].frameX;
306  int frameY = Main.tile[i, j].frameY;
307  int subX = frameX / tileData.CoordinateFullWidth;
308  int subY = frameY / tileData.CoordinateFullHeight;
309  int wrap = tileData.StyleWrapLimit;
310  if (wrap == 0) {
311  wrap = 1;
312  }
313  int subTile = tileData.StyleHorizontal ? subY * wrap + subX : subX * wrap + subY;
314  int style = subTile / tileData.StyleMultiplier;
315  int alternate = subTile % tileData.StyleMultiplier;
316  for (int k = 0; k < tileData.AlternatesCount; k++) {
317  if (alternate >= tileData.Alternates[k].Style && alternate <= tileData.Alternates[k].Style + tileData.RandomStyleRange) {
318  alternate = k;
319  break;
320  }
321  }
322  tileData = TileObjectData.GetTileData(type, style, alternate + 1);
323  int partFrameX = frameX % tileData.CoordinateFullWidth;
324  int partFrameY = frameY % tileData.CoordinateFullHeight;
325  int partX = partFrameX / (tileData.CoordinateWidth + tileData.CoordinatePadding);
326  int partY = 0;
327  int remainingFrameY = partFrameY;
328  while (remainingFrameY > 0) {
329  remainingFrameY -= tileData.CoordinateHeights[partY] + tileData.CoordinatePadding;
330  partY++;
331  }
332  i -= partX;
333  j -= partY;
334  int originX = i + tileData.Origin.X;
335  int originY = j + tileData.Origin.Y;
336  TileObject objectData;
337  bool partiallyDestroyed = false;
338  for (int x = i; x < i + tileData.Width; x++) {
339  for (int y = j; y < j + tileData.Height; y++) {
340  if (!Main.tile[x, y].active() || Main.tile[x, y].type != type) {
341  partiallyDestroyed = true;
342  break;
343  }
344  }
345  if (partiallyDestroyed) {
346  break;
347  }
348  }
349  if (partiallyDestroyed || !TileObject.CanPlace(originX, originY, type, style, 0, out objectData, true, true)) {
350  WorldGen.destroyObject = true;
351  for (int x = i; x < i + tileData.Width; x++) {
352  for (int y = j; y < j + tileData.Height; y++) {
353  if (Main.tile[x, y].type == type && Main.tile[x, y].active()) {
354  WorldGen.KillTile(x, y, false, false, false);
355  }
356  }
357  }
358  KillMultiTile(i, j, frameX - partFrameX, frameY - partFrameY, type);
359  WorldGen.destroyObject = false;
360  for (int x = i - 1; x < i + tileData.Width + 2; x++) {
361  for (int y = j - 1; y < j + tileData.Height + 2; y++) {
362  WorldGen.TileFrame(x, y, false, false);
363  }
364  }
365  }
366  TileObject.objectPreview.Active = false;
367  }
368 
369  public static void DisableSmartCursor(Tile tile, ref bool disable) {
370  if (tile.active()) {
371  ModTile modTile = GetTile(tile.type);
372  if (modTile != null) {
373  disable = modTile.disableSmartCursor;
374  }
375  }
376  }
377 
378  public static void DisableSmartInteract(Tile tile, ref bool disable) {
379  if (tile.active()) {
380  ModTile modTile = GetTile(tile.type);
381  if (modTile != null) {
382  disable = modTile.disableSmartInteract;
383  }
384  }
385  }
386  //in Terraria.WorldGen.OpenDoor replace bad type check with TileLoader.OpenDoorID(Main.tile[i, j]) < 0
387  //in Terraria.WorldGen.OpenDoor replace 11 with (ushort)TileLoader.OpenDoorID
388  //replace all type checks before WorldGen.OpenDoor
389  public static int OpenDoorID(Tile tile) {
390  ModTile modTile = GetTile(tile.type);
391  if (modTile != null) {
392  return modTile.openDoorID;
393  }
394  if (tile.type == TileID.ClosedDoor && (tile.frameY < 594 || tile.frameY > 646 || tile.frameX >= 54)) {
395  return TileID.OpenDoor;
396  }
397  return -1;
398  }
399  //in Terraria.WorldGen.CloseDoor replace bad type check with TileLoader.CloseDoorID(Main.tile[i, j]) < 0
400  //in Terraria.WorldGen.CloseDoor replace 10 with (ushort)TileLoader.CloseDoorID
401  //replace all type checks before WorldGen.CloseDoor
402  //replace type check in WorldGen.CheckRoom
403  public static int CloseDoorID(Tile tile) {
404  ModTile modTile = GetTile(tile.type);
405  if (modTile != null) {
406  return modTile.closeDoorID;
407  }
408  if (tile.type == TileID.OpenDoor) {
409  return TileID.ClosedDoor;
410  }
411  return -1;
412  }
413  public static bool IsClosedDoor(Tile tile) {
414  ModTile modTile = GetTile(tile.type);
415  if (modTile != null) {
416  return modTile.openDoorID > -1;
417  }
418  return tile.type == TileID.ClosedDoor;
419  }
420  //in Terraria.UI.ChestUI add this to Lang lookups
421  public static string ModChestName(int type) {
422  ModTile modTile = GetTile(type);
423  if (modTile != null) {
424  return modTile.chest;
425  }
426  return "";
427  }
428 
429  public static bool IsDresser(int type) {
430  if (type == TileID.Dressers) {
431  return true;
432  }
433  return ModDresserName(type).Length > 0;
434  }
435 
436  public static string ModDresserName(int type) {
437  ModTile modTile = GetTile(type);
438  if (modTile != null) {
439  return modTile.dresser;
440  }
441  return "";
442  }
443  //in Terraria.Player.CheckSpawn add this to bed type check
444  public static bool IsModBed(int type) {
445  ModTile modTile = GetTile(type);
446  if (modTile == null) {
447  return false;
448  }
449  return modTile.bed;
450  }
451 
452  public static bool IsTorch(int type) {
453  ModTile modTile = GetTile(type);
454  if (modTile == null) {
455  return type == TileID.Torches;
456  }
457  return modTile.torch;
458  }
459 
460  public static bool IsSapling(int type) {
461  ModTile modTile = GetTile(type);
462  if (modTile == null) {
463  return type == TileID.Saplings;
464  }
465  return modTile.sapling;
466  }
467 
468  public static bool IsModMusicBox(Tile tile) {
469  return SoundLoader.tileToMusic.ContainsKey(tile.type)
470  && SoundLoader.tileToMusic[tile.type].ContainsKey(tile.frameY / 36 * 36);
471  }
472  //in Terraria.ObjectData.TileObject data make the following public:
473  // newTile, newSubTile, newAlternate, addTile, addSubTile, addAlternate
474  internal static void SetDefaults(ModTile tile) {
475  tile.SetDefaults();
476  if (TileObjectData.newTile.Width > 1 || TileObjectData.newTile.Height > 1) {
477  TileObjectData.FixNewTile();
478  throw new Exception("It appears that you have an error surrounding TileObjectData.AddTile in " + tile.GetType().FullName) { HelpLink = "https://github.com/tModLoader/tModLoader/wiki/Basic-tModLoader-Modding-FAQ#tileobjectdataaddtile-issues" };
479  }
480  if (Main.tileLavaDeath[tile.Type]) {
481  Main.tileObsidianKill[tile.Type] = true;
482  }
483  if (Main.tileSolid[tile.Type]) {
484  Main.tileNoSunLight[tile.Type] = true;
485  }
486  tile.PostSetDefaults();
487  }
488 
489  public static bool HasSmartInteract(int type) {
490  return GetTile(type)?.HasSmartInteract() ?? false;
491  }
492 
493  public static void FixSmartInteractCoords(int type, ref int width, ref int height, ref int frameWidth, ref int frameHeight, ref int extraX, ref int extraY) {
494  ModTile modTile = GetTile(type);
495  if (modTile != null) {
496  TileObjectData data = TileObjectData.GetTileData(type, 0);
497  width = data.Width;
498  height = data.Height;
499  frameWidth = data.CoordinateWidth + data.CoordinatePadding;
500  frameHeight = data.CoordinateHeights[0] + data.CoordinatePadding;
501  extraY = data.CoordinateFullHeight % frameHeight;
502  }
503  }
504  //in Terraria.WorldGen.KillTile inside if (!effectOnly && !WorldGen.stopDrops) for playing sounds
505  // add if(!TileLoader.KillSound(i, j, tile.type)) { } to beginning of if/else chain and turn first if into else if
506  public static bool KillSound(int i, int j, int type) {
507  foreach (var hook in HookKillSound) {
508  if (!hook(i, j, type)) {
509  return false;
510  }
511  }
512  ModTile modTile = GetTile(type);
513  if (modTile != null) {
514  if (!modTile.KillSound(i, j)) {
515  return false;
516  }
517  Main.PlaySound(modTile.soundType, i * 16, j * 16, modTile.soundStyle);
518  return false;
519  }
520  return true;
521  }
522  //in Terraria.WorldGen.KillTile before num14 (num dust iteration) is declared, add
523  // TileLoader.NumDust(i, j, tile.type, ref num13);
524  public static void NumDust(int i, int j, int type, bool fail, ref int numDust) {
525  GetTile(type)?.NumDust(i, j, fail, ref numDust);
526 
527  foreach (var hook in HookNumDust) {
528  hook(i, j, type, fail, ref numDust);
529  }
530  }
531  //in Terraria.WorldGen.KillTile replace if (num15 >= 0) with
532  // if(TileLoader.CreateDust(i, j, tile.type, ref num15) && num15 >= 0)
533  public static bool CreateDust(int i, int j, int type, ref int dustType) {
534  foreach (var hook in HookCreateDust) {
535  if (!hook(i, j, type, ref dustType)) {
536  return false;
537  }
538  }
539  return GetTile(type)?.CreateDust(i, j, ref dustType) ?? true;
540  }
541  //in Terraria.WorldGen.KillTile before if statement checking num43 call
542  // TileLoader.DropCritterChance(i, j, tile.type, ref num43, ref num44, ref num45);
543  public static void DropCritterChance(int i, int j, int type, ref int wormChance, ref int grassHopperChance, ref int jungleGrubChance) {
544  GetTile(type)?.DropCritterChance(i, j, ref wormChance, ref grassHopperChance, ref jungleGrubChance);
545 
546  foreach (var hook in HookDropCritterChance) {
547  hook(i, j, type, ref wormChance, ref grassHopperChance, ref jungleGrubChance);
548  }
549  }
550  //in Terraria.WorldGen.KillTile before if statements checking num49 and num50
551  // add bool vanillaDrop = TileLoader.Drop(i, j, tile.type);
552  // add "vanillaDrop && " to beginning of these if statements
553  public static bool Drop(int i, int j, int type) {
554  foreach (var hook in HookDrop) {
555  if (!hook(i, j, type)) {
556  return false;
557  }
558  }
559  ModTile modTile = GetTile(type);
560  if (modTile != null) {
561  if (!modTile.Drop(i, j)) {
562  return false;
563  }
564  if (modTile.drop > 0) {
565  Item.NewItem(i * 16, j * 16, 16, 16, modTile.drop, 1, false, -1);
566  }
567  return false;
568  }
569  return true;
570  }
571  //in Terraria.WorldGen.CanKillTile after check for tile.active() add
572  // if(!TileLoader.CanKillTile(i, j, tile.type, ref blockDamaged)) { return false; }
573  public static bool CanKillTile(int i, int j, int type, ref bool blockDamaged) {
574  foreach (var hook in HookCanKillTile) {
575  if (!hook(i, j, type, ref blockDamaged)) {
576  return false;
577  }
578  }
579  return GetTile(type)?.CanKillTile(i, j, ref blockDamaged) ?? true;
580  }
581  //in Terraria.WorldGen.KillTile before if (!effectOnly && !WorldGen.stopDrops) add
582  // TileLoader.KillTile(i, j, tile.type, ref fail, ref effectOnly, ref noItem);
583  public static void KillTile(int i, int j, int type, ref bool fail, ref bool effectOnly, ref bool noItem) {
584  GetTile(type)?.KillTile(i, j, ref fail, ref effectOnly, ref noItem);
585 
586  foreach (var hook in HookKillTile) {
587  hook(i, j, type, ref fail, ref effectOnly, ref noItem);
588  }
589  }
590 
591  public static void KillMultiTile(int i, int j, int frameX, int frameY, int type) {
592  GetTile(type)?.KillMultiTile(i, j, frameX, frameY);
593  }
594 
595  public static bool CanExplode(int i, int j) {
596  int type = Main.tile[i, j].type;
597  ModTile modTile = GetTile(type);
598  if (modTile != null && !modTile.CanExplode(i, j)) {
599  return false;
600  }
601  foreach (var hook in HookCanExplode) {
602  if (!hook(i, j, type)) {
603  return false;
604  }
605  }
606  return true;
607  }
608  //in Terraria.Lighting.PreRenderPhase add local closer variable and after setting music box
609  // call TileLoader.NearbyEffects(n, num17, type, closer);
610  public static void NearbyEffects(int i, int j, int type, bool closer) {
611  GetTile(type)?.NearbyEffects(i, j, closer);
612 
613  foreach (var hook in HookNearbyEffects) {
614  hook(i, j, type, closer);
615  }
616  }
617  //in Terraria.Lighting.PreRenderPhase after label after if statement checking Main.tileLighted call
618  // TileLoader.ModifyLight(n, num17, tile.type, ref num18, ref num19, ref num20);
619  public static void ModifyLight(int i, int j, int type, ref float r, ref float g, ref float b) {
620  if (!Main.tileLighted[type]) {
621  return;
622  }
623  GetTile(type)?.ModifyLight(i, j, ref r, ref g, ref b);
624 
625  foreach (var hook in HookModifyLight) {
626  hook(i, j, type, ref r, ref g, ref b);
627  }
628  }
629 
630  public static bool Dangersense(int i, int j, int type, Player player) {
631  ModTile modTile = GetTile(type);
632  if (modTile != null && modTile.Dangersense(i, j, player)) {
633  return true;
634  }
635  foreach (var hook in HookDangersense) {
636  if (hook(i, j, type, player)) {
637  return true;
638  }
639  }
640  return false;
641  }
642  //in Terraria.Main.DrawTiles after if statement setting effects call
643  // TileLoader.SetSpriteEffects(j, i, type, ref effects);
644  public static void SetSpriteEffects(int i, int j, int type, ref SpriteEffects spriteEffects) {
645  GetTile(type)?.SetSpriteEffects(i, j, ref spriteEffects);
646 
647  foreach (var hook in HookSetSpriteEffects) {
648  hook(i, j, type, ref spriteEffects);
649  }
650  }
651  //in Terraria.Main.DrawTiles after if statements setting num11 and num12 call
652  // TileLoader.SetDrawPositions(j, i, ref num9, ref num11, ref num12);
653  public static void SetDrawPositions(int i, int j, ref int width, ref int offsetY, ref int height) {
654  Tile tile = Main.tile[i, j];
655  if (tile.type >= TileID.Count) {
656  TileObjectData tileData = TileObjectData.GetTileData(tile.type, 0, 0);
657  if (tileData != null) {
658  int partFrameY = tile.frameY % tileData.CoordinateFullHeight;
659  int partY = 0;
660  while (partFrameY > 0) {
661  partFrameY -= tileData.CoordinateHeights[partY] + tileData.CoordinatePadding;
662  partY++;
663  }
664  width = tileData.CoordinateWidth;
665  offsetY = tileData.DrawYOffset;
666  height = tileData.CoordinateHeights[partY];
667  }
668  GetTile(tile.type).SetDrawPositions(i, j, ref width, ref offsetY, ref height);
669  }
670  }
671  //in Terraria.Main.Update after vanilla tile animations call TileLoader.AnimateTiles();
672  public static void AnimateTiles() {
673  if (loaded) {
674  for (int i = 0; i < tiles.Count; i++) {
675  ModTile modTile = tiles[i];
676  modTile.AnimateTile(ref Main.tileFrame[modTile.Type], ref Main.tileFrameCounter[modTile.Type]);
677  }
678  foreach (var hook in HookAnimateTile) {
679  hook();
680  }
681  }
682  }
683 
684  //in Terraria.Main.Draw after small if statements setting num15 call
685  // TileLoader.SetAnimationFrame(type, ref num15);
694  public static void SetAnimationFrame(int type, int i, int j, ref int frameXOffset, ref int frameYOffset) {
695  ModTile modTile = GetTile(type);
696  if (modTile != null) {
697  frameYOffset = modTile.animationFrameHeight * Main.tileFrame[type];
698  modTile.AnimateIndividualTile(type, i, j, ref frameXOffset, ref frameYOffset);
699  }
700  }
701 
702  //in Terraria.Main.Draw after calling SetAnimationFrame call
703  // if(!TileLoader.PreDraw(j, i, type, Main.spriteBatch))
704  // { TileLoader.PostDraw(j, i, type, Main.spriteBatch); continue; }
705  public static bool PreDraw(int i, int j, int type, SpriteBatch spriteBatch) {
706  foreach (var hook in HookPreDraw) {
707  if (!hook(i, j, type, spriteBatch)) {
708  return false;
709  }
710  }
711  return GetTile(type)?.PreDraw(i, j, spriteBatch) ?? true;
712  }
713 
714  public static void DrawEffects(int i, int j, int type, SpriteBatch spriteBatch, ref Color drawColor, ref int nextSpecialDrawIndex) {
715  GetTile(type)?.DrawEffects(i, j, spriteBatch, ref drawColor, ref nextSpecialDrawIndex);
716  foreach (var hook in HookDrawEffects) {
717  hook(i, j, type, spriteBatch, ref drawColor, ref nextSpecialDrawIndex);
718  }
719  }
720  //in Terraria.Main.Draw after if statement checking whether texture2D is null call
721  // TileLoader.PostDraw(j, i, type, Main.spriteBatch);
722  public static void PostDraw(int i, int j, int type, SpriteBatch spriteBatch) {
723  GetTile(type)?.PostDraw(i, j, spriteBatch);
724 
725  foreach (var hook in HookPostDraw) {
726  hook(i, j, type, spriteBatch);
727  }
728  }
729 
733  public static void SpecialDraw(int type, int specX, int specY, SpriteBatch spriteBatch) {
734  GetTile(type)?.SpecialDraw(specX, specY, spriteBatch);
735 
736  foreach (var hook in HookSpecialDraw) {
737  hook(specX, specY, type, spriteBatch);
738  }
739  }
740 
741  //in Terraria.WorldGen.UpdateWorld in the while loops updating certain numbers of tiles at end of null check if statements
742  // add TileLoader.RandomUpdate(num7, num8, Main.tile[num7, num8].type; for the first loop
743  // add TileLoader.RandomUpdate(num64, num65, Main.tile[num64, num65].type; for the second loop
744  public static void RandomUpdate(int i, int j, int type) {
745  if (!Main.tile[i, j].active()) {
746  return;
747  }
748  GetTile(type)?.RandomUpdate(i, j);
749 
750  foreach (var hook in HookRandomUpdate) {
751  hook(i, j, type);
752  }
753  }
754  //in Terraria.WorldGen.TileFrame at beginning of block of if(tile.active()) add
755  // if(!TileLoader.TileFrame(i, j, tile.type, ref resetFrame, ref noBreak)) { return; }
756  public static bool TileFrame(int i, int j, int type, ref bool resetFrame, ref bool noBreak) {
757  ModTile modTile = GetTile(type);
758  bool flag = true;
759  if (modTile != null) {
760  flag = modTile.TileFrame(i, j, ref resetFrame, ref noBreak);
761  }
762  foreach (var hook in HookTileFrame) {
763  flag &= hook(i, j, type, ref resetFrame, ref noBreak);
764  }
765  return flag;
766  }
767  //in Terraria.Player.ItemCheck in if statements for mining
768  // replace num222 += item.hammer; with TileLoader.MineDamage(item.hammer, ref num222);
769  // replace num222 += item.axe; with TileLoader.MineDamage(item.axe, ref num222);
770  //in Terraria.Player.PickTile replace num += pickPower; with TileLoader.MineDamage(pickPower, ref num);
771  public static void MineDamage(int minePower, ref int damage) {
772  Tile target = Main.tile[Player.tileTargetX, Player.tileTargetY];
773  ModTile modTile = GetTile(target.type);
774  damage += modTile != null ? (int)(minePower / modTile.mineResist) : minePower;
775  }
776  //in Terraria.Player.ItemCheck at end of else if chain setting num to 0 add
777  // else { TileLoader.PickPowerCheck(tile, pickPower, ref num); }
778  public static void PickPowerCheck(Tile target, int pickPower, ref int damage) {
779  ModTile modTile = GetTile(target.type);
780  if (modTile != null && pickPower < modTile.minPick) {
781  damage = 0;
782  }
783  }
784  //in Terraria.Player.PlaceThing after tileObject is initalized add else to if statement and before add
785  // if(!TileLoader.CanPlace(Player.tileTargetX, Player.tileTargetY)) { }
786  public static bool CanPlace(int i, int j, int type) {
787  foreach (var hook in HookCanPlace) {
788  if (!hook(i, j, type)) {
789  return false;
790  }
791  }
792  return GetTile(type)?.CanPlace(i, j) ?? true;
793  }
794  //in Terraria.Player.AdjTiles in end of if statement checking for tile's active
795  // add TileLoader.AdjTiles(this, Main.tile[j, k].type);
796  public static void AdjTiles(Player player, int type) {
797  ModTile modTile = GetTile(type);
798  if (modTile != null) {
799  foreach (int k in modTile.adjTiles) {
800  player.adjTile[k] = true;
801  }
802  }
803  foreach (var hook in HookAdjTiles) {
804  int[] adjTiles = hook(type);
805  foreach (int k in adjTiles) {
806  player.adjTile[k] = true;
807  }
808  }
809  }
810  //in Terraria.Player.Update in if statements involving controluseTile and releaseUseTile
811  // at end of type-check if else chain add TileLoader.RightClick(Player.tileTargetX, Player.tileTargetY);
812  public static void RightClick(int i, int j) {
813  int type = Main.tile[i, j].type;
814  GetTile(type)?.RightClick(i, j);
815 
816  foreach (var hook in HookRightClick) {
817  hook(i, j, type);
818  }
819  }
820  //in Terraria.Player.Update after if statements setting showItemIcon call
821  // TileLoader.MouseOver(Player.tileTargetX, Player.tileTargetY);
822  public static void MouseOver(int i, int j) {
823  int type = Main.tile[i, j].type;
824  GetTile(type)?.MouseOver(i, j);
825 
826  foreach (var hook in HookMouseOver) {
827  hook(i, j, type);
828  }
829  }
830 
831  public static void MouseOverFar(int i, int j) {
832  int type = Main.tile[i, j].type;
833  GetTile(type)?.MouseOverFar(i, j);
834 
835  foreach (var hook in HookMouseOverFar) {
836  hook(i, j, type);
837  }
838  }
839 
840  public static int AutoSelect(int i, int j, Player player) {
841  if (!Main.tile[i, j].active()) {
842  return -1;
843  }
844  int type = Main.tile[i, j].type;
845  ModTile modTile = GetTile(type);
846  for (int k = 0; k < 50; k++) {
847  Item item = player.inventory[k];
848  if (item.type == 0 || item.stack == 0) {
849  continue;
850  }
851  if (modTile != null && modTile.AutoSelect(i, j, item)) {
852  return k;
853  }
854  foreach (var hook in HookAutoSelect) {
855  if (hook(i, j, type, item)) {
856  return k;
857  }
858  }
859  }
860  return -1;
861  }
862 
863  public static bool PreHitWire(int i, int j, int type) {
864  foreach (var hook in HookPreHitWire) {
865  if (!hook(i, j, type)) {
866  return false;
867  }
868  }
869  return true;
870  }
871  //in Terraria.Wiring make the following public:
872  // _wireList, _toProcess, _teleport, _inPumpX, _inPumpY, _numInPump, _outPumpX, _outPumpY, _numOutPump CheckMech, TripWire
873  //at end of Terraria.Wiring.HitWireSingle inside if statement checking for tile active add
874  // TileLoader.HitWire(i, j, type);
875  public static void HitWire(int i, int j, int type) {
876  GetTile(type)?.HitWire(i, j);
877 
878  foreach (var hook in HookHitWire) {
879  hook(i, j, type);
880  }
881  }
882 
883  public static void FloorVisuals(int type, Player player) {
884  GetTile(type)?.FloorVisuals(player);
885 
886  foreach (var hook in HookFloorVisuals) {
887  hook(type, player);
888  }
889  }
890  //in Terraria.Player.ItemCheck in poundRelease if statement before sloping if statements add
891  // if(TileLoader.Slope(num223, num224, Main.tile[num223, num224].type)) { } else
892  public static bool Slope(int i, int j, int type) {
893  foreach (var hook in HookSlope) {
894  if (!hook(i, j, type)) {
895  return true;
896  }
897  }
898  return !GetTile(type)?.Slope(i, j) ?? false;
899  }
900 
901  public static bool HasWalkDust(int type) {
902  return GetTile(type)?.HasWalkDust() ?? false;
903  }
904 
905  public static void WalkDust(int type, ref int dustType, ref bool makeDust, ref Color color) {
906  GetTile(type)?.WalkDust(ref dustType, ref makeDust, ref color);
907  }
908 
909  public static void ChangeWaterfallStyle(int type, ref int style) {
910  GetTile(type)?.ChangeWaterfallStyle(ref style);
911  foreach (var hook in HookChangeWaterfallStyle) {
912  hook(type, ref style);
913  }
914  }
915 
916  public static bool SaplingGrowthType(int type, ref int saplingType, ref int style) {
917  int originalType = saplingType;
918  int originalStyle = style;
919  bool flag = false;
920  ModTile modTile = GetTile(type);
921  if (modTile != null) {
922  saplingType = modTile.SaplingGrowthType(ref style);
923  if (IsSapling(saplingType)) {
924  originalType = saplingType;
925  originalStyle = style;
926  flag = true;
927  }
928  else {
929  saplingType = originalType;
930  style = originalStyle;
931  }
932  }
933  foreach (var hook in HookSaplingGrowthType) {
934  saplingType = hook(type, ref style);
935  if (IsSapling(saplingType)) {
936  originalType = saplingType;
937  originalStyle = style;
938  flag = true;
939  }
940  else {
941  saplingType = originalType;
942  style = originalStyle;
943  }
944  }
945  return flag;
946  }
947 
948  public static bool CanGrowModTree(int type) {
949  return trees.ContainsKey(type);
950  }
951 
952  public static void TreeDust(Tile tile, ref int dust) {
953  if (tile.active() && trees.ContainsKey(tile.type)) {
954  dust = trees[tile.type].CreateDust();
955  }
956  }
957 
958  public static void TreeGrowthFXGore(int type, ref int gore) {
959  if (trees.ContainsKey(type)) {
960  gore = trees[type].GrowthFXGore();
961  }
962  }
963 
964  public static bool CanDropAcorn(int type) {
965  return trees.ContainsKey(type) ? trees[type].CanDropAcorn() : false;
966  }
967 
968  public static void DropTreeWood(int type, ref int wood) {
969  if (trees.ContainsKey(type)) {
970  wood = trees[type].DropWood();
971  }
972  }
973 
974  public static Texture2D GetTreeTexture(Tile tile) {
975  return tile.active() && trees.ContainsKey(tile.type) ? trees[tile.type].GetTexture() : null;
976  }
977 
978  public static Texture2D GetTreeTopTextures(int type, int i, int j, ref int frame,
979  ref int frameWidth, ref int frameHeight, ref int xOffsetLeft, ref int yOffset) {
980  return trees.ContainsKey(type) ? trees[type].GetTopTextures(i, j, ref frame,
981  ref frameWidth, ref frameHeight, ref xOffsetLeft, ref yOffset) : null;
982  }
983 
984  public static Texture2D GetTreeBranchTextures(int type, int i, int j, int trunkOffset, ref int frame) {
985  return trees.ContainsKey(type) ? trees[type].GetBranchTextures(i, j, trunkOffset, ref frame) : null;
986  }
987 
988  public static bool CanGrowModPalmTree(int type) {
989  return palmTrees.ContainsKey(type);
990  }
991 
992  public static void PalmTreeDust(Tile tile, ref int dust) {
993  if (tile.active() && palmTrees.ContainsKey(tile.type)) {
994  dust = palmTrees[tile.type].CreateDust();
995  }
996  }
997 
998  public static void PalmTreeGrowthFXGore(int type, ref int gore) {
999  if (palmTrees.ContainsKey(type)) {
1000  gore = palmTrees[type].GrowthFXGore();
1001  }
1002  }
1003 
1004  public static void DropPalmTreeWood(int type, ref int wood) {
1005  if (palmTrees.ContainsKey(type)) {
1006  wood = palmTrees[type].DropWood();
1007  }
1008  }
1009 
1010  public static Texture2D GetPalmTreeTexture(Tile tile) {
1011  return tile.active() && palmTrees.ContainsKey(tile.type) ? palmTrees[tile.type].GetTexture() : null;
1012  }
1013 
1014  public static Texture2D GetPalmTreeTopTextures(int type) {
1015  return palmTrees.ContainsKey(type) ? palmTrees[type].GetTopTextures() : null;
1016  }
1017 
1018  public static bool CanGrowModCactus(int type) {
1019  return cacti.ContainsKey(type);
1020  }
1021 
1022  public static Texture2D GetCactusTexture(int type) {
1023  return cacti.ContainsKey(type) ? cacti[type].GetTexture() : null;
1024  }
1025 
1026  public static void PlaceInWorld(int i, int j, Item item) {
1027  int type = item.createTile;
1028  if (type < 0)
1029  return;
1030 
1031  foreach (var hook in HookPlaceInWorld) {
1032  hook(i, j, item);
1033  }
1034 
1035  GetTile(type)?.PlaceInWorld(i, j, item);
1036  }
1037 
1038  public static bool IsLockedChest(int i, int j, int type) {
1039  return GetTile(type)?.IsLockedChest(i, j) ?? false;
1040  }
1041 
1042  public static bool UnlockChest(int i, int j, int type, ref short frameXAdjustment, ref int dustType, ref bool manual) {
1043  return GetTile(type)?.UnlockChest(i, j, ref frameXAdjustment, ref dustType, ref manual) ?? false;
1044  }
1045  }
1046 }
static Func< int, int[]>[] HookAdjTiles
Definition: TileLoader.cs:72
static void NumDust(int i, int j, int type, bool fail, ref int numDust)
Definition: TileLoader.cs:524
static void FixSmartInteractCoords(int type, ref int width, ref int height, ref int frameWidth, ref int frameHeight, ref int extraX, ref int extraY)
Definition: TileLoader.cs:493
static int AutoSelect(int i, int j, Player player)
Definition: TileLoader.cs:840
This class represents a type of tile that can be added by a mod. Only one instance of this class will...
Definition: ModTile.cs:12
static void DropCritterChance(int i, int j, int type, ref int wormChance, ref int grassHopperChance, ref int jungleGrubChance)
Definition: TileLoader.cs:543
static DelegateSaplingGrowthType[] HookSaplingGrowthType
Definition: TileLoader.cs:84
static Action[] HookAnimateTile
Definition: TileLoader.cs:62
static void RandomUpdate(int i, int j, int type)
Definition: TileLoader.cs:744
static void PlaceInWorld(int i, int j, Item item)
Definition: TileLoader.cs:1026
static Func< int, int, int, Player, bool >[] HookDangersense
Definition: TileLoader.cs:59
static void DropPalmTreeWood(int type, ref int wood)
Definition: TileLoader.cs:1004
static Action< int, int, int >[] HookHitWire
Definition: TileLoader.cs:78
static bool AllowVanillaClients
Definition: ModNet.cs:52
int minPick
The minimum pickaxe power required for pickaxes to mine this block. Defaults to 0.
Definition: ModTile.cs:70
static bool CanGrowModTree(int type)
Definition: TileLoader.cs:948
static Func< int, int, int, bool >[] HookPreHitWire
Definition: TileLoader.cs:77
static bool IsModBed(int type)
Definition: TileLoader.cs:444
static string ModDresserName(int type)
Definition: TileLoader.cs:436
int soundStyle
The default style of sound made when this tile is hit. Defaults to 1.
Definition: ModTile.cs:50
static bool TileFrame(int i, int j, int type, ref bool resetFrame, ref bool noBreak)
Definition: TileLoader.cs:756
static bool CanPlace(int i, int j, int type)
Definition: TileLoader.cs:786
static Action< int, int, int, bool >[] HookNearbyEffects
Definition: TileLoader.cs:56
virtual bool CanExplode(int i, int j)
Whether or not the tile at the given coordinates can be killed by an explosion (ie. bombs). Returns true by default; return false to stop an explosion from destroying it.
Definition: ModTile.cs:320
static Texture2D GetTreeTexture(Tile tile)
Definition: TileLoader.cs:974
static Func< int, int, int, bool >[] HookDrop
Definition: TileLoader.cs:50
static bool UnlockChest(int i, int j, int type, ref short frameXAdjustment, ref int dustType, ref bool manual)
Definition: TileLoader.cs:1042
int closeDoorID
The ID of the tile that this door transforms into when it is closed. Defaults to -1, which means this tile isn&#39;t a door.
Definition: ModTile.cs:86
static void KillTile(int i, int j, int type, ref bool fail, ref bool effectOnly, ref bool noItem)
Definition: TileLoader.cs:583
static void PalmTreeDust(Tile tile, ref int dust)
Definition: TileLoader.cs:992
static void MineDamage(int minePower, ref int damage)
Definition: TileLoader.cs:771
static Texture2D GetCactusTexture(int type)
Definition: TileLoader.cs:1022
static DelegateCanKillTile[] HookCanKillTile
Definition: TileLoader.cs:52
static int OpenDoorID(Tile tile)
Definition: TileLoader.cs:389
static void PostDraw(int i, int j, int type, SpriteBatch spriteBatch)
Definition: TileLoader.cs:722
static Func< int, int, int, bool >[] HookCanExplode
Definition: TileLoader.cs:55
static ModTile GetTile(int type)
Gets the ModTile instance with the given type. If no ModTile with the given type exists, returns null.
Definition: TileLoader.cs:102
static Action< int, int, int >[] HookMouseOverFar
Definition: TileLoader.cs:75
static DelegateSetSpriteEffects[] HookSetSpriteEffects
Definition: TileLoader.cs:61
static Texture2D GetPalmTreeTexture(Tile tile)
Definition: TileLoader.cs:1010
This serves as the central class which loads mods. It contains many static fields and methods related...
Definition: ModLoader.cs:25
This serves as the central class from which tile-related functions are supported and carried out...
Definition: TileLoader.cs:14
static Func< int, int, int, bool >[] HookKillSound
Definition: TileLoader.cs:43
static void DrawEffects(int i, int j, int type, SpriteBatch spriteBatch, ref Color drawColor, ref int nextSpecialDrawIndex)
Definition: TileLoader.cs:714
static Texture2D GetTreeBranchTextures(int type, int i, int j, int trunkOffset, ref int frame)
Definition: TileLoader.cs:984
int[] adjTiles
An array of the IDs of tiles that this tile can be considered as when looking for crafting stations...
Definition: ModTile.cs:82
static DelegateDrawEffects[] HookDrawEffects
Definition: TileLoader.cs:65
static void SetSpriteEffects(int i, int j, int type, ref SpriteEffects spriteEffects)
Definition: TileLoader.cs:644
virtual bool AutoSelect(int i, int j, Item item)
Allows you to determine whether the given item can become selected when the cursor is hovering over t...
Definition: ModTile.cs:491
static void ModifyLight(int i, int j, int type, ref float r, ref float g, ref float b)
Definition: TileLoader.cs:619
int drop
The default type of item dropped when this tile is killed. Defaults to 0, which means no item...
Definition: ModTile.cs:58
static void DisableSmartInteract(Tile tile, ref bool disable)
Definition: TileLoader.cs:378
static bool IsModMusicBox(Tile tile)
Definition: TileLoader.cs:468
virtual void SetDrawPositions(int i, int j, ref int width, ref int offsetY, ref int height)
Allows you to customize the position in which this tile is drawn. Width refers to the width of one fr...
Definition: ModTile.cs:362
int animationFrameHeight
The height of a group of animation frames for this tile. Defaults to 0, which disables animations...
Definition: ModTile.cs:62
static int CloseDoorID(Tile tile)
Definition: TileLoader.cs:403
static void ChangeWaterfallStyle(int type, ref int style)
Definition: TileLoader.cs:909
static void PickPowerCheck(Tile target, int pickPower, ref int damage)
Definition: TileLoader.cs:778
static bool IsDresser(int type)
Definition: TileLoader.cs:429
static void TreeGrowthFXGore(int type, ref int gore)
Definition: TileLoader.cs:958
virtual bool Dangersense(int i, int j, Player player)
Allows you to determine whether this block glows red when the given player has the Dangersense buff...
Definition: ModTile.cs:345
static Func< int, int, int, Item, bool >[] HookAutoSelect
Definition: TileLoader.cs:76
static bool PreDraw(int i, int j, int type, SpriteBatch spriteBatch)
Definition: TileLoader.cs:705
static bool IsLockedChest(int i, int j, int type)
Definition: TileLoader.cs:1038
static void MouseOverFar(int i, int j)
Definition: TileLoader.cs:831
static void SetDrawPositions(int i, int j, ref int width, ref int offsetY, ref int height)
Definition: TileLoader.cs:653
static void MouseOver(int i, int j)
Definition: TileLoader.cs:822
This class is used to keep track of and support the existence of custom sounds that have been added t...
Definition: SoundLoader.cs:11
static DelegateTileFrame[] HookTileFrame
Definition: TileLoader.cs:70
static void SpecialDraw(int type, int specX, int specY, SpriteBatch spriteBatch)
Special Draw calls ModTile and GlobalTile SpecialDraw methods. Special Draw is called from DrawTiles ...
Definition: TileLoader.cs:733
static bool CanDropAcorn(int type)
Definition: TileLoader.cs:964
static Texture2D GetPalmTreeTopTextures(int type)
Definition: TileLoader.cs:1014
static bool Drop(int i, int j, int type)
Definition: TileLoader.cs:553
bool bed
Whether or not this tile is a valid spawn point. Defaults to false. If you set this to true...
Definition: ModTile.cs:110
static bool Dangersense(int i, int j, int type, Player player)
Definition: TileLoader.cs:630
bool sapling
Whether or not this tile is a sapling, which can grow into a modded tree or palm tree.
Definition: ModTile.cs:118
static void CheckModTile(int i, int j, int type)
Definition: TileLoader.cs:297
static bool HasWalkDust(int type)
Definition: TileLoader.cs:901
static DelegateNumDust[] HookNumDust
Definition: TileLoader.cs:45
int openDoorID
The ID of the tile that this door transforms into when it is opened. Defaults to -1, which means this tile isn&#39;t a door.
Definition: ModTile.cs:90
static Func< int, int, int, bool >[] HookSlope
Definition: TileLoader.cs:79
string dresser
Same as chest, except use this if your block is a dresser (has a size of 3x2 instead of 2x2)...
Definition: ModTile.cs:102
static DelegateKillTile[] HookKillTile
Definition: TileLoader.cs:54
static DelegateChangeWaterfallStyle[] HookChangeWaterfallStyle
Definition: TileLoader.cs:82
static bool CanKillTile(int i, int j, int type, ref bool blockDamaged)
Definition: TileLoader.cs:573
static void WalkDust(int type, ref int dustType, ref bool makeDust, ref Color color)
Definition: TileLoader.cs:905
static Action< int, int, int, SpriteBatch >[] HookPostDraw
Definition: TileLoader.cs:66
static bool IsSapling(int type)
Definition: TileLoader.cs:460
static bool CanGrowModPalmTree(int type)
Definition: TileLoader.cs:988
static bool IsClosedDoor(Tile tile)
Definition: TileLoader.cs:413
virtual void AnimateTile(ref int frame, ref int frameCounter)
Allows you to animate your tile. Use frameCounter to keep track of how long the current frame has bee...
Definition: ModTile.cs:378
ushort Type
The internal ID of this type of tile.
Definition: ModTile.cs:33
static void RightClick(int i, int j)
Definition: TileLoader.cs:812
static void KillMultiTile(int i, int j, int frameX, int frameY, int type)
Definition: TileLoader.cs:591
static Action< int, int, int >[] HookRandomUpdate
Definition: TileLoader.cs:68
static void DisableSmartCursor(Tile tile, ref bool disable)
Definition: TileLoader.cs:369
static Action< int, int, Item >[] HookPlaceInWorld
Definition: TileLoader.cs:85
bool disableSmartCursor
Whether or not the smart cursor function is disabled when the cursor hovers above this tile...
Definition: ModTile.cs:74
static Func< int, int, int, bool >[] HookCanPlace
Definition: TileLoader.cs:71
float mineResist
A multiplier describing how much this block resists harvesting. Higher values will make it take longe...
Definition: ModTile.cs:66
static bool PreHitWire(int i, int j, int type)
Definition: TileLoader.cs:863
static void AdjTiles(Player player, int type)
Definition: TileLoader.cs:796
virtual void PostSetDefaults()
Allows you to override some default properties of this tile, such as Main.tileNoSunLight and Main...
Definition: ModTile.cs:235
static void PalmTreeGrowthFXGore(int type, ref int gore)
Definition: TileLoader.cs:998
static Func< int, int, int, SpriteBatch, bool >[] HookPreDraw
Definition: TileLoader.cs:63
virtual bool Drop(int i, int j)
Allows you to customize which items the tile at the given coordinates drops. Remember that the x...
Definition: ModTile.cs:286
virtual void AnimateIndividualTile(int type, int i, int j, ref int frameXOffset, ref int frameYOffset)
Animates an individual tile. i and j are the coordinates of the Tile in question. frameXOffset and fr...
Definition: ModTile.cs:390
static string ModChestName(int type)
Definition: TileLoader.cs:421
static DelegateModifyLight[] HookModifyLight
Definition: TileLoader.cs:58
static Action< int, int, int, SpriteBatch >[] HookSpecialDraw
Definition: TileLoader.cs:67
static Texture2D GetTreeTopTextures(int type, int i, int j, ref int frame, ref int frameWidth, ref int frameHeight, ref int xOffsetLeft, ref int yOffset)
Definition: TileLoader.cs:978
static void FloorVisuals(int type, Player player)
Definition: TileLoader.cs:883
static bool Slope(int i, int j, int type)
Definition: TileLoader.cs:892
static void HitWire(int i, int j, int type)
Definition: TileLoader.cs:875
bool torch
Whether or not this tile behaves like a torch. If you are making a torch tile, then setting this to t...
Definition: ModTile.cs:114
static DelegateDropCritterChance[] HookDropCritterChance
Definition: TileLoader.cs:49
static Action< int, Player >[] HookFloorVisuals
Definition: TileLoader.cs:80
static bool SaplingGrowthType(int type, ref int saplingType, ref int style)
Definition: TileLoader.cs:916
string chest
The default name of this chest that is displayed when this 2x2 chest is open. Defaults to the empty s...
Definition: ModTile.cs:94
static void NearbyEffects(int i, int j, int type, bool closer)
Definition: TileLoader.cs:610
static Action< int, int, int >[] HookMouseOver
Definition: TileLoader.cs:74
virtual void SetDefaults()
Allows you to set the properties of this tile. Many properties are stored as arrays throughout Terrar...
Definition: ModTile.cs:229
static bool KillSound(int i, int j, int type)
Definition: TileLoader.cs:506
bool disableSmartInteract
Whether or not the smart tile interaction function is disabled when the cursor hovers above this tile...
Definition: ModTile.cs:78
virtual bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak)
Called whenever this tile updates due to being placed or being next to a tile that is changed...
Definition: ModTile.cs:449
static bool HasSmartInteract(int type)
Definition: TileLoader.cs:489
static bool CreateDust(int i, int j, int type, ref int dustType)
Definition: TileLoader.cs:533
int soundType
The default type of sound made when this tile is hit. Defaults to 0.
Definition: ModTile.cs:46
static bool CanExplode(int i, int j)
Definition: TileLoader.cs:595
static bool IsTorch(int type)
Definition: TileLoader.cs:452
static DelegateCreateDust[] HookCreateDust
Definition: TileLoader.cs:47
virtual int SaplingGrowthType(ref int style)
Allows this tile to support a sapling that can eventually grow into a tree. The type of the sapling s...
Definition: ModTile.cs:547
static void DropTreeWood(int type, ref int wood)
Definition: TileLoader.cs:968
static Action< int, int, int >[] HookRightClick
Definition: TileLoader.cs:73
static bool CanGrowModCactus(int type)
Definition: TileLoader.cs:1018
static void SetAnimationFrame(int type, int i, int j, ref int frameXOffset, ref int frameYOffset)
Sets the animation frame. Sets frameYOffset = modTile.animationFrameHeight * Main.tileFrame[type]; and then calls ModTile.AnimateIndividualTile
Definition: TileLoader.cs:694
virtual bool KillSound(int i, int j)
Allows you to customize which sound you want to play when the tile at the given coordinates is hit...
Definition: ModTile.cs:251
static void TreeDust(Tile tile, ref int dust)
Definition: TileLoader.cs:952