tModLoader v0.11.8.9
A mod to make and play Terraria mods
TileLoader.cs
Go to the documentation of this file.
1using Microsoft.Xna.Framework;
2using Microsoft.Xna.Framework.Graphics;
3using System;
4using System.Collections.Generic;
5using Terraria.ID;
6using Terraria.ObjectData;
7
8namespace 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);
48 private delegate void DelegateDropCritterChance(int i, int j, int type, ref int wormChance, ref int grassHopperChance, ref int jungleGrubChance);
50 private static Func<int, int, int, bool>[] HookDrop;
51 private delegate bool DelegateCanKillTile(int i, int j, int type, ref bool blockDamaged);
53 private delegate void DelegateKillTile(int i, int j, int type, ref bool fail, ref bool effectOnly, ref bool noItem);
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);
59 private static Func<int, int, int, Player, bool>[] HookDangersense;
60 private delegate void DelegateSetSpriteEffects(int i, int j, int type, ref SpriteEffects spriteEffects);
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);
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);
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);
83 private delegate int DelegateSaplingGrowthType(int type, ref int style);
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 bool RightClick(int i, int j) {
813 bool returnValue = false;
814 int type = Main.tile[i, j].type;
815 GetTile(type)?.RightClick(i, j);
816 if (GetTile(type)?.NewRightClick(i, j) ?? false)
817 returnValue = true;
818
819 foreach (var hook in HookRightClick) {
820 hook(i, j, type);
821 }
822 return returnValue;
823 }
824 //in Terraria.Player.Update after if statements setting showItemIcon call
825 // TileLoader.MouseOver(Player.tileTargetX, Player.tileTargetY);
826 public static void MouseOver(int i, int j) {
827 int type = Main.tile[i, j].type;
828 GetTile(type)?.MouseOver(i, j);
829
830 foreach (var hook in HookMouseOver) {
831 hook(i, j, type);
832 }
833 }
834
835 public static void MouseOverFar(int i, int j) {
836 int type = Main.tile[i, j].type;
837 GetTile(type)?.MouseOverFar(i, j);
838
839 foreach (var hook in HookMouseOverFar) {
840 hook(i, j, type);
841 }
842 }
843
844 public static int AutoSelect(int i, int j, Player player) {
845 if (!Main.tile[i, j].active()) {
846 return -1;
847 }
848 int type = Main.tile[i, j].type;
849 ModTile modTile = GetTile(type);
850 for (int k = 0; k < 50; k++) {
851 Item item = player.inventory[k];
852 if (item.type == 0 || item.stack == 0) {
853 continue;
854 }
855 if (modTile != null && modTile.AutoSelect(i, j, item)) {
856 return k;
857 }
858 foreach (var hook in HookAutoSelect) {
859 if (hook(i, j, type, item)) {
860 return k;
861 }
862 }
863 }
864 return -1;
865 }
866
867 public static bool PreHitWire(int i, int j, int type) {
868 foreach (var hook in HookPreHitWire) {
869 if (!hook(i, j, type)) {
870 return false;
871 }
872 }
873 return true;
874 }
875 //in Terraria.Wiring make the following public:
876 // _wireList, _toProcess, _teleport, _inPumpX, _inPumpY, _numInPump, _outPumpX, _outPumpY, _numOutPump CheckMech, TripWire
877 //at end of Terraria.Wiring.HitWireSingle inside if statement checking for tile active add
878 // TileLoader.HitWire(i, j, type);
879 public static void HitWire(int i, int j, int type) {
880 GetTile(type)?.HitWire(i, j);
881
882 foreach (var hook in HookHitWire) {
883 hook(i, j, type);
884 }
885 }
886
887 public static void FloorVisuals(int type, Player player) {
888 GetTile(type)?.FloorVisuals(player);
889
890 foreach (var hook in HookFloorVisuals) {
891 hook(type, player);
892 }
893 }
894 //in Terraria.Player.ItemCheck in poundRelease if statement before sloping if statements add
895 // if(TileLoader.Slope(num223, num224, Main.tile[num223, num224].type)) { } else
896 public static bool Slope(int i, int j, int type) {
897 foreach (var hook in HookSlope) {
898 if (!hook(i, j, type)) {
899 return true;
900 }
901 }
902 return !GetTile(type)?.Slope(i, j) ?? false;
903 }
904
905 public static bool HasWalkDust(int type) {
906 return GetTile(type)?.HasWalkDust() ?? false;
907 }
908
909 public static void WalkDust(int type, ref int dustType, ref bool makeDust, ref Color color) {
910 GetTile(type)?.WalkDust(ref dustType, ref makeDust, ref color);
911 }
912
913 public static void ChangeWaterfallStyle(int type, ref int style) {
914 GetTile(type)?.ChangeWaterfallStyle(ref style);
915 foreach (var hook in HookChangeWaterfallStyle) {
916 hook(type, ref style);
917 }
918 }
919
920 public static bool SaplingGrowthType(int type, ref int saplingType, ref int style) {
921 int originalType = saplingType;
922 int originalStyle = style;
923 bool flag = false;
924 ModTile modTile = GetTile(type);
925 if (modTile != null) {
926 saplingType = modTile.SaplingGrowthType(ref style);
927 if (IsSapling(saplingType)) {
928 originalType = saplingType;
929 originalStyle = style;
930 flag = true;
931 }
932 else {
933 saplingType = originalType;
934 style = originalStyle;
935 }
936 }
937 foreach (var hook in HookSaplingGrowthType) {
938 saplingType = hook(type, ref style);
939 if (IsSapling(saplingType)) {
940 originalType = saplingType;
941 originalStyle = style;
942 flag = true;
943 }
944 else {
945 saplingType = originalType;
946 style = originalStyle;
947 }
948 }
949 return flag;
950 }
951
952 public static bool CanGrowModTree(int type) {
953 return trees.ContainsKey(type);
954 }
955
956 public static void TreeDust(Tile tile, ref int dust) {
957 if (tile.active() && trees.ContainsKey(tile.type)) {
958 dust = trees[tile.type].CreateDust();
959 }
960 }
961
962 public static void TreeGrowthFXGore(int type, ref int gore) {
963 if (trees.ContainsKey(type)) {
964 gore = trees[type].GrowthFXGore();
965 }
966 }
967
968 public static bool CanDropAcorn(int type) {
969 return trees.ContainsKey(type) ? trees[type].CanDropAcorn() : false;
970 }
971
972 public static void DropTreeWood(int type, ref int wood) {
973 if (trees.ContainsKey(type)) {
974 wood = trees[type].DropWood();
975 }
976 }
977
978 public static Texture2D GetTreeTexture(Tile tile) {
979 return tile.active() && trees.ContainsKey(tile.type) ? trees[tile.type].GetTexture() : null;
980 }
981
982 public static Texture2D GetTreeTopTextures(int type, int i, int j, ref int frame,
983 ref int frameWidth, ref int frameHeight, ref int xOffsetLeft, ref int yOffset) {
984 return trees.ContainsKey(type) ? trees[type].GetTopTextures(i, j, ref frame,
985 ref frameWidth, ref frameHeight, ref xOffsetLeft, ref yOffset) : null;
986 }
987
988 public static Texture2D GetTreeBranchTextures(int type, int i, int j, int trunkOffset, ref int frame) {
989 return trees.ContainsKey(type) ? trees[type].GetBranchTextures(i, j, trunkOffset, ref frame) : null;
990 }
991
992 public static bool CanGrowModPalmTree(int type) {
993 return palmTrees.ContainsKey(type);
994 }
995
996 public static void PalmTreeDust(Tile tile, ref int dust) {
997 if (tile.active() && palmTrees.ContainsKey(tile.type)) {
998 dust = palmTrees[tile.type].CreateDust();
999 }
1000 }
1001
1002 public static void PalmTreeGrowthFXGore(int type, ref int gore) {
1003 if (palmTrees.ContainsKey(type)) {
1004 gore = palmTrees[type].GrowthFXGore();
1005 }
1006 }
1007
1008 public static void DropPalmTreeWood(int type, ref int wood) {
1009 if (palmTrees.ContainsKey(type)) {
1010 wood = palmTrees[type].DropWood();
1011 }
1012 }
1013
1014 public static Texture2D GetPalmTreeTexture(Tile tile) {
1015 return tile.active() && palmTrees.ContainsKey(tile.type) ? palmTrees[tile.type].GetTexture() : null;
1016 }
1017
1018 public static Texture2D GetPalmTreeTopTextures(int type) {
1019 return palmTrees.ContainsKey(type) ? palmTrees[type].GetTopTextures() : null;
1020 }
1021
1022 public static bool CanGrowModCactus(int type) {
1023 return cacti.ContainsKey(type);
1024 }
1025
1026 public static Texture2D GetCactusTexture(int type) {
1027 return cacti.ContainsKey(type) ? cacti[type].GetTexture() : null;
1028 }
1029
1030 public static void PlaceInWorld(int i, int j, Item item) {
1031 int type = item.createTile;
1032 if (type < 0)
1033 return;
1034
1035 foreach (var hook in HookPlaceInWorld) {
1036 hook(i, j, item);
1037 }
1038
1039 GetTile(type)?.PlaceInWorld(i, j, item);
1040 }
1041
1042 public static bool IsLockedChest(int i, int j, int type) {
1043 return GetTile(type)?.IsLockedChest(i, j) ?? false;
1044 }
1045
1046 public static bool UnlockChest(int i, int j, int type, ref short frameXAdjustment, ref int dustType, ref bool manual) {
1047 return GetTile(type)?.UnlockChest(i, j, ref frameXAdjustment, ref dustType, ref manual) ?? false;
1048 }
1049 }
1050}
static bool AllowVanillaClients
Definition: ModNet.cs:53
This class represents a type of tile that can be added by a mod. Only one instance of this class will...
Definition: ModTile.cs:13
virtual void RandomUpdate(int i, int j)
Called whenever the world randomly decides to update this tile in a given tick. Useful for things suc...
Definition: ModTile.cs:441
virtual void MouseOver(int i, int j)
Allows you to make something happen when the mouse hovers over this tile. Useful for showing item ico...
Definition: ModTile.cs:486
virtual void MouseOverFar(int i, int j)
Allows you to make something happen when the mouse hovers over this tile, even when the player is far...
Definition: ModTile.cs:494
virtual void SetDefaults()
Allows you to set the properties of this tile. Many properties are stored as arrays throughout Terrar...
Definition: ModTile.cs:229
bool disableSmartCursor
Whether or not the smart cursor function is disabled when the cursor hovers above this tile....
Definition: ModTile.cs:74
int soundType
The default type of sound made when this tile is hit. Defaults to 0.
Definition: ModTile.cs:46
virtual void NearbyEffects(int i, int j, bool closer)
Allows you to make things happen when this tile is within a certain range of the player (around the s...
Definition: ModTile.cs:329
virtual bool UnlockChest(int i, int j, ref short frameXAdjustment, ref int dustType, ref bool manual)
Allows customization of how a chest unlock is accomplished. By default, frameXAdjustment will be -36,...
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
ushort Type
The internal ID of this type of tile.
Definition: ModTile.cs:33
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:502
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
virtual void ModifyLight(int i, int j, ref float r, ref float g, ref float b)
Allows you to determine how much light this block emits. Make sure you set Main.tileLighted[Type] to ...
Definition: ModTile.cs:337
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
bool sapling
Whether or not this tile is a sapling, which can grow into a modded tree or palm tree.
Definition: ModTile.cs:118
virtual void WalkDust(ref int dustType, ref bool makeDust, ref Color color)
Allows you to modify the dust created when the player walks on this tile. The makeDust parameter is w...
Definition: ModTile.cs:543
int drop
The default type of item dropped when this tile is killed. Defaults to 0, which means no item.
Definition: ModTile.cs:58
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
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
virtual void HitWire(int i, int j)
Allows you to make something happen when a wire current passes through this tile.
Definition: ModTile.cs:511
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
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 NumDust(int i, int j, bool fail, ref int num)
Allows you to change how many dust particles are created when the tile at the given coordinates is hi...
Definition: ModTile.cs:260
int openDoorID
The ID of the tile that this door transforms into when it is opened. Defaults to -1,...
Definition: ModTile.cs:90
virtual bool PreDraw(int i, int j, SpriteBatch spriteBatch)
Allows you to draw things behind the tile at the given coordinates. Return false to stop the game fro...
Definition: ModTile.cs:398
int closeDoorID
The ID of the tile that this door transforms into when it is closed. Defaults to -1,...
Definition: ModTile.cs:86
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
virtual void DrawEffects(int i, int j, SpriteBatch spriteBatch, ref Color drawColor, ref int nextSpecialDrawIndex)
Allows you to make stuff happen whenever the tile at the given coordinates is drawn....
Definition: ModTile.cs:408
virtual bool IsLockedChest(int i, int j)
Return true if this Tile corresponds to a chest that is locked. Prevents Quick Stacking items into th...
virtual void SetSpriteEffects(int i, int j, ref SpriteEffects spriteEffects)
Allows you to determine whether or not the tile will draw itself flipped in the world.
Definition: ModTile.cs:354
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
virtual void KillMultiTile(int i, int j, int frameX, int frameY)
This hook is called exactly once whenever a block encompassing multiple tiles is destroyed....
Definition: ModTile.cs:312
int soundStyle
The default style of sound made when this tile is hit. Defaults to 1.
Definition: ModTile.cs:50
virtual bool HasSmartInteract()
Whether or not the smart interact function can select this tile. Useful for things like chests....
Definition: ModTile.cs:242
virtual void KillTile(int i, int j, ref bool fail, ref bool effectOnly, ref bool noItem)
Allows you to determine what happens when the tile at the given coordinates is killed or hit with a p...
Definition: ModTile.cs:304
virtual void DropCritterChance(int i, int j, ref int wormChance, ref int grassHopperChance, ref int jungleGrubChance)
Allows you to modify the chance the tile at the given coordinates has of spawning a certain critter w...
Definition: ModTile.cs:278
virtual void RightClick(int i, int j)
Allows you to make something happen when this tile is right-clicked by the player.
Definition: ModTile.cs:468
virtual bool CreateDust(int i, int j, ref int type)
Allows you to modify the default type of dust created when the tile at the given coordinates is hit....
Definition: ModTile.cs:268
virtual void PostSetDefaults()
Allows you to override some default properties of this tile, such as Main.tileNoSunLight and Main....
Definition: ModTile.cs:235
virtual bool HasWalkDust()
Whether or not this tile creates dust when the player walks on it. Returns false by default.
Definition: ModTile.cs:533
virtual bool CanPlace(int i, int j)
Allows you to stop this tile from being placed at the given coordinates. Return false to block the ti...
Definition: ModTile.cs:458
virtual void SpecialDraw(int i, int j, SpriteBatch spriteBatch)
Special Draw. Only called if coordinates are placed in Main.specX/Y during DrawEffects....
Definition: ModTile.cs:424
virtual void FloorVisuals(Player player)
Allows you to make something happen when a player stands on this type of tile. For example,...
Definition: ModTile.cs:527
float mineResist
A multiplier describing how much this block resists harvesting. Higher values will make it take longe...
Definition: ModTile.cs:66
virtual bool CanExplode(int i, int j)
Whether or not the tile at the given coordinates can be killed by an explosion (ie....
Definition: ModTile.cs:320
bool disableSmartInteract
Whether or not the smart tile interaction function is disabled when the cursor hovers above this tile...
Definition: ModTile.cs:78
int minPick
The minimum pickaxe power required for pickaxes to mine this block. Defaults to 0.
Definition: ModTile.cs:70
virtual void PostDraw(int i, int j, SpriteBatch spriteBatch)
Allows you to draw things in front of the tile at the given coordinates. This can also be used to do ...
Definition: ModTile.cs:416
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
virtual void PlaceInWorld(int i, int j, Item item)
Allows you to do something when this tile is placed. Called on the local Client and Single Player.
Definition: ModTile.cs:568
virtual bool CanKillTile(int i, int j, ref bool blockDamaged)
Allows you to determine whether or not the tile at the given coordinates can be hit by anything....
Definition: ModTile.cs:295
virtual bool Slope(int i, int j)
Allows you to control how hammers slope this tile. Return true to allow it to slope normally....
Definition: ModTile.cs:519
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:558
virtual void ChangeWaterfallStyle(ref int style)
Allows you to change the style of waterfall that passes through or over this type of tile.
Definition: ModTile.cs:550
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
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
This class is used to keep track of and support the existence of custom sounds that have been added t...
Definition: SoundLoader.cs:12
This serves as the central class from which tile-related functions are supported and carried out.
Definition: TileLoader.cs:15
static void PalmTreeGrowthFXGore(int type, ref int gore)
Definition: TileLoader.cs:1002
static ModTile GetTile(int type)
Gets the ModTile instance with the given type. If no ModTile with the given type exists,...
Definition: TileLoader.cs:102
static Action< int, int, int >[] HookMouseOverFar
Definition: TileLoader.cs:75
static bool UnlockChest(int i, int j, int type, ref short frameXAdjustment, ref int dustType, ref bool manual)
Definition: TileLoader.cs:1046
static void TreeGrowthFXGore(int type, ref int gore)
Definition: TileLoader.cs:962
static void HitWire(int i, int j, int type)
Definition: TileLoader.cs:879
static readonly int vanillaChairCount
Definition: TileLoader.cs:38
static void DropTreeWood(int type, ref int wood)
Definition: TileLoader.cs:972
static void WalkDust(int type, ref int dustType, ref bool makeDust, ref Color color)
Definition: TileLoader.cs:909
static Action< int, int, int, SpriteBatch >[] HookPostDraw
Definition: TileLoader.cs:66
static DelegateTileFrame[] HookTileFrame
Definition: TileLoader.cs:70
static Texture2D GetPalmTreeTopTextures(int type)
Definition: TileLoader.cs:1018
static DelegateCanKillTile[] HookCanKillTile
Definition: TileLoader.cs:52
static Func< int, int, int, SpriteBatch, bool >[] HookPreDraw
Definition: TileLoader.cs:63
static bool CanPlace(int i, int j, int type)
Definition: TileLoader.cs:786
static bool IsLockedChest(int i, int j, int type)
Definition: TileLoader.cs:1042
static Func< int, int, int, bool >[] HookDrop
Definition: TileLoader.cs:50
static Func< int, int[]>[] HookAdjTiles
Definition: TileLoader.cs:72
static Action< int, int, int >[] HookMouseOver
Definition: TileLoader.cs:74
static void TreeDust(Tile tile, ref int dust)
Definition: TileLoader.cs:956
static bool IsDresser(int type)
Definition: TileLoader.cs:429
static bool SaplingGrowthType(int type, ref int saplingType, ref int style)
Definition: TileLoader.cs:920
static readonly int vanillaTorchCount
Definition: TileLoader.cs:40
static Texture2D GetCactusTexture(int type)
Definition: TileLoader.cs:1026
static void MouseOverFar(int i, int j)
Definition: TileLoader.cs:835
static Action< int, int, Item >[] HookPlaceInWorld
Definition: TileLoader.cs:85
delegate void DelegateSetSpriteEffects(int i, int j, int type, ref SpriteEffects spriteEffects)
static void MouseOver(int i, int j)
Definition: TileLoader.cs:826
static DelegateNumDust[] HookNumDust
Definition: TileLoader.cs:45
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:982
static void NumDust(int i, int j, int type, bool fail, ref int numDust)
Definition: TileLoader.cs:524
static void PalmTreeDust(Tile tile, ref int dust)
Definition: TileLoader.cs:996
static Action< int, int, int >[] HookRightClick
Definition: TileLoader.cs:73
static string ModChestName(int type)
Definition: TileLoader.cs:421
static DelegateDropCritterChance[] HookDropCritterChance
Definition: TileLoader.cs:49
static void KillMultiTile(int i, int j, int frameX, int frameY, int type)
Definition: TileLoader.cs:591
static string ModDresserName(int type)
Definition: TileLoader.cs:436
static bool IsTorch(int type)
Definition: TileLoader.cs:452
static void FloorVisuals(int type, Player player)
Definition: TileLoader.cs:887
static Texture2D GetPalmTreeTexture(Tile tile)
Definition: TileLoader.cs:1014
static Func< int, int, int, bool >[] HookKillSound
Definition: TileLoader.cs:43
static Texture2D GetTreeBranchTextures(int type, int i, int j, int trunkOffset, ref int frame)
Definition: TileLoader.cs:988
static bool IsModMusicBox(Tile tile)
Definition: TileLoader.cs:468
static bool PreDraw(int i, int j, int type, SpriteBatch spriteBatch)
Definition: TileLoader.cs:705
static void SetDrawPositions(int i, int j, ref int width, ref int offsetY, ref int height)
Definition: TileLoader.cs:653
static void DropPalmTreeWood(int type, ref int wood)
Definition: TileLoader.cs:1008
static void SetSpriteEffects(int i, int j, int type, ref SpriteEffects spriteEffects)
Definition: TileLoader.cs:644
static int AutoSelect(int i, int j, Player player)
Definition: TileLoader.cs:844
delegate void DelegateDropCritterChance(int i, int j, int type, ref int wormChance, ref int grassHopperChance, ref int jungleGrubChance)
static DelegateModifyLight[] HookModifyLight
Definition: TileLoader.cs:58
static Func< int, int, int, bool >[] HookSlope
Definition: TileLoader.cs:79
static Action< int, int, int, SpriteBatch >[] HookSpecialDraw
Definition: TileLoader.cs:67
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 void DropCritterChance(int i, int j, int type, ref int wormChance, ref int grassHopperChance, ref int jungleGrubChance)
Definition: TileLoader.cs:543
static Texture2D GetTreeTexture(Tile tile)
Definition: TileLoader.cs:978
delegate void DelegateDrawEffects(int i, int j, int type, SpriteBatch spriteBatch, ref Color drawColor, ref int nextSpecialDrawIndex)
static bool Drop(int i, int j, int type)
Definition: TileLoader.cs:553
static bool HasWalkDust(int type)
Definition: TileLoader.cs:905
static bool CanDropAcorn(int type)
Definition: TileLoader.cs:968
static bool CreateDust(int i, int j, int type, ref int dustType)
Definition: TileLoader.cs:533
static bool CanGrowModTree(int type)
Definition: TileLoader.cs:952
static Action[] HookAnimateTile
Definition: TileLoader.cs:62
static Func< int, int, int, Player, bool >[] HookDangersense
Definition: TileLoader.cs:59
delegate void DelegateModifyLight(int i, int j, int type, ref float r, ref float g, ref float b)
static void KillTile(int i, int j, int type, ref bool fail, ref bool effectOnly, ref bool noItem)
Definition: TileLoader.cs:583
static int OpenDoorID(Tile tile)
Definition: TileLoader.cs:389
static void AdjTiles(Player player, int type)
Definition: TileLoader.cs:796
static DelegateDrawEffects[] HookDrawEffects
Definition: TileLoader.cs:65
delegate void DelegateKillTile(int i, int j, int type, ref bool fail, ref bool effectOnly, ref bool noItem)
static bool Dangersense(int i, int j, int type, Player player)
Definition: TileLoader.cs:630
static void Resize2DArray< T >(ref T[,] array, int newSize)
Definition: TileLoader.cs:106
static void RandomUpdate(int i, int j, int type)
Definition: TileLoader.cs:744
delegate bool DelegateCanKillTile(int i, int j, int type, ref bool blockDamaged)
static void SetAnimationFrame(int type, int i, int j, ref int frameXOffset, ref int frameYOffset)
Sets the animation frame. Sets frameYOffset = modTile.animationFrameHeight * Main....
Definition: TileLoader.cs:694
static Action< int, int, int, bool >[] HookNearbyEffects
Definition: TileLoader.cs:56
delegate bool DelegateCreateDust(int i, int j, int type, ref int dustType)
static bool IsModBed(int type)
Definition: TileLoader.cs:444
delegate int DelegateSaplingGrowthType(int type, ref int style)
static void MineDamage(int minePower, ref int damage)
Definition: TileLoader.cs:771
static int CloseDoorID(Tile tile)
Definition: TileLoader.cs:403
static void CheckModTile(int i, int j, int type)
Definition: TileLoader.cs:297
static bool KillSound(int i, int j, int type)
Definition: TileLoader.cs:506
static void PlaceInWorld(int i, int j, Item item)
Definition: TileLoader.cs:1030
static bool IsClosedDoor(Tile tile)
Definition: TileLoader.cs:413
static bool Slope(int i, int j, int type)
Definition: TileLoader.cs:896
static void NearbyEffects(int i, int j, int type, bool closer)
Definition: TileLoader.cs:610
static bool CanGrowModCactus(int type)
Definition: TileLoader.cs:1022
static void ModifyLight(int i, int j, int type, ref float r, ref float g, ref float b)
Definition: TileLoader.cs:619
static bool HasSmartInteract(int type)
Definition: TileLoader.cs:489
static Action< int, int, int >[] HookHitWire
Definition: TileLoader.cs:78
static bool PreHitWire(int i, int j, int type)
Definition: TileLoader.cs:867
static Func< int, int, int, bool >[] HookPreHitWire
Definition: TileLoader.cs:77
delegate void DelegateNumDust(int i, int j, int type, bool fail, ref int num)
static DelegateSetSpriteEffects[] HookSetSpriteEffects
Definition: TileLoader.cs:61
static void PickPowerCheck(Tile target, int pickPower, ref int damage)
Definition: TileLoader.cs:778
static DelegateKillTile[] HookKillTile
Definition: TileLoader.cs:54
static readonly int vanillaTableCount
Definition: TileLoader.cs:39
static void DisableSmartCursor(Tile tile, ref bool disable)
Definition: TileLoader.cs:369
static void PostDraw(int i, int j, int type, SpriteBatch spriteBatch)
Definition: TileLoader.cs:722
static bool CanKillTile(int i, int j, int type, ref bool blockDamaged)
Definition: TileLoader.cs:573
static Func< int, int, int, Item, bool >[] HookAutoSelect
Definition: TileLoader.cs:76
static bool TileFrame(int i, int j, int type, ref bool resetFrame, ref bool noBreak)
Definition: TileLoader.cs:756
static DelegateChangeWaterfallStyle[] HookChangeWaterfallStyle
Definition: TileLoader.cs:82
static DelegateCreateDust[] HookCreateDust
Definition: TileLoader.cs:47
static DelegateSaplingGrowthType[] HookSaplingGrowthType
Definition: TileLoader.cs:84
static Action< int, Player >[] HookFloorVisuals
Definition: TileLoader.cs:80
static Action< int, int, int >[] HookRandomUpdate
Definition: TileLoader.cs:68
static bool RightClick(int i, int j)
Definition: TileLoader.cs:812
static Func< int, int, int, bool >[] HookCanExplode
Definition: TileLoader.cs:55
delegate void DelegateChangeWaterfallStyle(int type, ref int style)
static readonly int vanillaDoorCount
Definition: TileLoader.cs:41
static void ChangeWaterfallStyle(int type, ref int style)
Definition: TileLoader.cs:913
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 void DrawEffects(int i, int j, int type, SpriteBatch spriteBatch, ref Color drawColor, ref int nextSpecialDrawIndex)
Definition: TileLoader.cs:714
static void DisableSmartInteract(Tile tile, ref bool disable)
Definition: TileLoader.cs:378
static bool CanGrowModPalmTree(int type)
Definition: TileLoader.cs:992
static bool CanExplode(int i, int j)
Definition: TileLoader.cs:595
static bool IsSapling(int type)
Definition: TileLoader.cs:460
delegate bool DelegateTileFrame(int i, int j, int type, ref bool resetFrame, ref bool noBreak)
static Func< int, int, int, bool >[] HookCanPlace
Definition: TileLoader.cs:71