1using Microsoft.Xna.Framework;
 
    2using Microsoft.Xna.Framework.Graphics;
 
    4using System.Collections.Generic;
 
    6using Terraria.ObjectData;
 
   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>();
 
   41        private static readonly 
int vanillaDoorCount = TileID.Sets.RoomNeeds.CountsAsDoor.Length;
 
   44        private delegate 
void DelegateNumDust(
int i, 
int j, 
int type, 
bool fail, ref 
int num);
 
   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;
 
   53        private delegate 
void DelegateKillTile(
int i, 
int j, 
int type, ref 
bool fail, ref 
bool effectOnly, ref 
bool noItem);
 
   57        private delegate 
void DelegateModifyLight(
int i, 
int j, 
int type, ref 
float r, ref 
float g, ref 
float b);
 
   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);
 
   69        private delegate 
bool DelegateTileFrame(
int i, 
int j, 
int type, ref 
bool resetFrame, ref 
bool noBreak);
 
   79        private static Func<int, int, int, bool>[] 
HookSlope;
 
   87        internal static int ReserveTileID() {
 
  103            return type >= TileID.Count && type < 
TileCount ? tiles[type - TileID.Count] : 
null;
 
  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];
 
  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;
 
  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);
 
  164                Array.Resize(ref Main.tileMerge[k], 
nextTile);
 
  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;
 
  235            while (TileObjectData._data.Count < 
nextTile) {
 
  236                TileObjectData._data.Add(
null);
 
  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);
 
  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);
 
  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);
 
  270            ModLoader.BuildGlobalHook(ref 
HookPlaceInWorld, globalTiles, g => g.PlaceInWorld);
 
  277        internal static void Unload() {
 
  289            while (TileObjectData._data.Count > TileID.Count) {
 
  290                TileObjectData._data.RemoveAt(TileObjectData._data.Count - 1);
 
  298            if (WorldGen.destroyObject) {
 
  301            TileObjectData tileData = TileObjectData.GetTileData(type, 0, 0);
 
  302            if (tileData == 
null) {
 
  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;
 
  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) {
 
  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);
 
  327            int remainingFrameY = partFrameY;
 
  328            while (remainingFrameY > 0) {
 
  329                remainingFrameY -= tileData.CoordinateHeights[partY] + tileData.CoordinatePadding;
 
  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;
 
  345                if (partiallyDestroyed) {
 
  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);
 
  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);
 
  366            TileObject.objectPreview.Active = 
false;
 
  372                if (modTile != 
null) {
 
  381                if (modTile != 
null) {
 
  391            if (modTile != 
null) {
 
  394            if (tile.type == TileID.ClosedDoor && (tile.frameY < 594 || tile.frameY > 646 || tile.frameX >= 54)) {
 
  395                return TileID.OpenDoor;
 
  405            if (modTile != 
null) {
 
  408            if (tile.type == TileID.OpenDoor) {
 
  409                return TileID.ClosedDoor;
 
  415            if (modTile != 
null) {
 
  416                return modTile.openDoorID > -1;
 
  418            return tile.type == TileID.ClosedDoor;
 
  423            if (modTile != 
null) {
 
  424                return modTile.
chest;
 
  430            if (type == TileID.Dressers) {
 
  438            if (modTile != 
null) {
 
  446            if (modTile == 
null) {
 
  454            if (modTile == 
null) {
 
  455                return type == TileID.Torches;
 
  457            return modTile.
torch;
 
  462            if (modTile == 
null) {
 
  463                return type == TileID.Saplings;
 
  469            return SoundLoader.tileToMusic.ContainsKey(tile.type)
 
  470            && 
SoundLoader.tileToMusic[tile.type].ContainsKey(tile.frameY / 36 * 36);
 
  474        internal static void SetDefaults(
ModTile tile) {
 
  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" };
 
  480            if (Main.tileLavaDeath[tile.
Type]) {
 
  481                Main.tileObsidianKill[tile.
Type] = 
true;
 
  483            if (Main.tileSolid[tile.
Type]) {
 
  484                Main.tileNoSunLight[tile.
Type] = 
true;
 
  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) {
 
  495            if (modTile != 
null) {
 
  496                TileObjectData data = TileObjectData.GetTileData(type, 0);
 
  498                height = data.Height;
 
  499                frameWidth = data.CoordinateWidth + data.CoordinatePadding;
 
  500                frameHeight = data.CoordinateHeights[0] + data.CoordinatePadding;
 
  501                extraY = data.CoordinateFullHeight % frameHeight;
 
  508                if (!hook(i, j, type)) {
 
  513            if (modTile != 
null) {
 
  524        public static void NumDust(
int i, 
int j, 
int type, 
bool fail, ref 
int numDust) {
 
  528                hook(i, j, type, fail, ref numDust);
 
  533        public static bool CreateDust(
int i, 
int j, 
int type, ref 
int dustType) {
 
  535                if (!hook(i, j, type, ref dustType)) {
 
  543        public static void DropCritterChance(
int i, 
int j, 
int type, ref 
int wormChance, ref 
int grassHopperChance, ref 
int jungleGrubChance) {
 
  547                hook(i, j, type, ref wormChance, ref grassHopperChance, ref jungleGrubChance);
 
  553        public static bool Drop(
int i, 
int j, 
int type) {
 
  555                if (!hook(i, j, type)) {
 
  560            if (modTile != 
null) {
 
  561                if (!modTile.
Drop(i, j)) {
 
  564                if (modTile.
drop > 0) {
 
  565                    Item.NewItem(i * 16, j * 16, 16, 16, modTile.
drop, 1, 
false, -1);
 
  573        public static bool CanKillTile(
int i, 
int j, 
int type, ref 
bool blockDamaged) {
 
  575                if (!hook(i, j, type, ref blockDamaged)) {
 
  583        public static void KillTile(
int i, 
int j, 
int type, ref 
bool fail, ref 
bool effectOnly, ref 
bool noItem) {
 
  587                hook(i, j, type, ref fail, ref effectOnly, ref noItem);
 
  591        public static void KillMultiTile(
int i, 
int j, 
int frameX, 
int frameY, 
int type) {
 
  596            int type = Main.tile[i, j].type;
 
  598            if (modTile != 
null && !modTile.
CanExplode(i, j)) {
 
  602                if (!hook(i, j, type)) {
 
  614                hook(i, j, type, closer);
 
  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]) {
 
  626                hook(i, j, type, ref r, ref g, ref b);
 
  630        public static bool Dangersense(
int i, 
int j, 
int type, Player player) {
 
  632            if (modTile != 
null && modTile.
Dangersense(i, j, player)) {
 
  636                if (hook(i, j, type, player)) {
 
  644        public static void SetSpriteEffects(
int i, 
int j, 
int type, ref SpriteEffects spriteEffects) {
 
  648                hook(i, j, type, ref spriteEffects);
 
  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;
 
  660                    while (partFrameY > 0) {
 
  661                        partFrameY -= tileData.CoordinateHeights[partY] + tileData.CoordinatePadding;
 
  664                    width = tileData.CoordinateWidth;
 
  665                    offsetY = tileData.DrawYOffset;
 
  666                    height = tileData.CoordinateHeights[partY];
 
  674                for (
int i = 0; i < tiles.Count; i++) {
 
  676                    modTile.
AnimateTile(ref Main.tileFrame[modTile.
Type], ref Main.tileFrameCounter[modTile.
Type]);
 
  694        public static void SetAnimationFrame(
int type, 
int i, 
int j, ref 
int frameXOffset, ref 
int frameYOffset) {
 
  696            if (modTile != 
null) {
 
  697                frameYOffset = modTile.animationFrameHeight * Main.tileFrame[type];
 
  705        public static bool PreDraw(
int i, 
int j, 
int type, SpriteBatch spriteBatch) {
 
  707                if (!hook(i, j, type, spriteBatch)) {
 
  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);
 
  717                hook(i, j, type, spriteBatch, ref drawColor, ref nextSpecialDrawIndex);
 
  722        public static void PostDraw(
int i, 
int j, 
int type, SpriteBatch spriteBatch) {
 
  726                hook(i, j, type, spriteBatch);
 
  733        public static void SpecialDraw(
int type, 
int specX, 
int specY, SpriteBatch spriteBatch) {
 
  737                hook(specX, specY, type, spriteBatch);
 
  745            if (!Main.tile[i, j].active()) {
 
  756        public static bool TileFrame(
int i, 
int j, 
int type, ref 
bool resetFrame, ref 
bool noBreak) {
 
  759            if (modTile != 
null) {
 
  760                flag = modTile.
TileFrame(i, j, ref resetFrame, ref noBreak);
 
  763                flag &= hook(i, j, type, ref resetFrame, ref noBreak);
 
  771        public static void MineDamage(
int minePower, ref 
int damage) {
 
  772            Tile target = Main.tile[Player.tileTargetX, Player.tileTargetY];
 
  774            damage += modTile != 
null ? (int)(minePower / modTile.
mineResist) : minePower;
 
  780            if (modTile != 
null && pickPower < modTile.
minPick) {
 
  786        public static bool CanPlace(
int i, 
int j, 
int type) {
 
  788                if (!hook(i, j, type)) {
 
  796        public static void AdjTiles(Player player, 
int type) {
 
  798            if (modTile != 
null) {
 
  799                foreach (
int k 
in modTile.
adjTiles) {
 
  800                    player.adjTile[k] = 
true;
 
  804                int[] adjTiles = hook(type);
 
  805                foreach (
int k 
in adjTiles) {
 
  806                    player.adjTile[k] = 
true;
 
  813            bool returnValue = 
false;
 
  814            int type = Main.tile[i, j].type;
 
  816            if (
GetTile(type)?.NewRightClick(i, j) ?? 
false)
 
  827            int type = Main.tile[i, j].type;
 
  836            int type = Main.tile[i, j].type;
 
  845            if (!Main.tile[i, j].active()) {
 
  848            int type = Main.tile[i, j].type;
 
  850            for (
int k = 0; k < 50; k++) {
 
  851                Item item = player.inventory[k];
 
  852                if (item.type == 0 || item.stack == 0) {
 
  855                if (modTile != 
null && modTile.
AutoSelect(i, j, item)) {
 
  859                    if (hook(i, j, type, item)) {
 
  869                if (!hook(i, j, type)) {
 
  879        public static void HitWire(
int i, 
int j, 
int type) {
 
  896        public static bool Slope(
int i, 
int j, 
int type) {
 
  898                if (!hook(i, j, type)) {
 
  909        public static void WalkDust(
int type, ref 
int dustType, ref 
bool makeDust, ref Color color) {
 
  916                hook(type, ref style);
 
  921            int originalType = saplingType;
 
  922            int originalStyle = style;
 
  925            if (modTile != 
null) {
 
  928                    originalType = saplingType;
 
  929                    originalStyle = style;
 
  933                    saplingType = originalType;
 
  934                    style = originalStyle;
 
  938                saplingType = hook(type, ref style);
 
  940                    originalType = saplingType;
 
  941                    originalStyle = style;
 
  945                    saplingType = originalType;
 
  946                    style = originalStyle;
 
  953            return trees.ContainsKey(type);
 
  956        public static void TreeDust(Tile tile, ref 
int dust) {
 
  957            if (tile.active() && trees.ContainsKey(tile.type)) {
 
  958                dust = trees[tile.type].CreateDust();
 
  963            if (trees.ContainsKey(type)) {
 
  964                gore = trees[type].GrowthFXGore();
 
  969            return trees.ContainsKey(type) ? trees[type].CanDropAcorn() : 
false;
 
  973            if (trees.ContainsKey(type)) {
 
  974                wood = trees[type].DropWood();
 
  979            return tile.active() && trees.ContainsKey(tile.type) ? trees[tile.type].GetTexture() : 
null;
 
  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;
 
  989            return trees.ContainsKey(type) ? trees[type].GetBranchTextures(i, j, trunkOffset, ref frame) : 
null;
 
  993            return palmTrees.ContainsKey(type);
 
  997            if (tile.active() && palmTrees.ContainsKey(tile.type)) {
 
  998                dust = palmTrees[tile.type].CreateDust();
 
 1003            if (palmTrees.ContainsKey(type)) {
 
 1004                gore = palmTrees[type].GrowthFXGore();
 
 1009            if (palmTrees.ContainsKey(type)) {
 
 1010                wood = palmTrees[type].DropWood();
 
 1015            return tile.active() && palmTrees.ContainsKey(tile.type) ? palmTrees[tile.type].GetTexture() : 
null;
 
 1019            return palmTrees.ContainsKey(type) ? palmTrees[type].GetTopTextures() : 
null;
 
 1023            return cacti.ContainsKey(type);
 
 1027            return cacti.ContainsKey(type) ? cacti[type].GetTexture() : 
null;
 
 1031            int type = item.createTile;
 
 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;
 
static bool AllowVanillaClients
 
This class represents a type of tile that can be added by a mod. Only one instance of this class will...
 
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...
 
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...
 
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...
 
virtual void SetDefaults()
Allows you to set the properties of this tile. Many properties are stored as arrays throughout Terrar...
 
bool disableSmartCursor
Whether or not the smart cursor function is disabled when the cursor hovers above this tile....
 
int soundType
The default type of sound made when this tile is hit. Defaults to 0.
 
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...
 
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).
 
ushort Type
The internal ID of this type of tile.
 
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...
 
bool bed
Whether or not this tile is a valid spawn point. Defaults to false. If you set this to true,...
 
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 ...
 
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.
 
bool sapling
Whether or not this tile is a sapling, which can grow into a modded tree or palm tree.
 
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...
 
int drop
The default type of item dropped when this tile is killed. Defaults to 0, which means no item.
 
int[] adjTiles
An array of the IDs of tiles that this tile can be considered as when looking for crafting stations.
 
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...
 
virtual void HitWire(int i, int j)
Allows you to make something happen when a wire current passes through this tile.
 
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....
 
virtual bool Drop(int i, int j)
Allows you to customize which items the tile at the given coordinates drops. Remember that the x,...
 
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...
 
int openDoorID
The ID of the tile that this door transforms into when it is opened. Defaults to -1,...
 
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...
 
int closeDoorID
The ID of the tile that this door transforms into when it is closed. Defaults to -1,...
 
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...
 
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....
 
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.
 
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...
 
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....
 
int soundStyle
The default style of sound made when this tile is hit. Defaults to 1.
 
virtual bool HasSmartInteract()
Whether or not the smart interact function can select this tile. Useful for things like chests....
 
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...
 
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...
 
virtual void RightClick(int i, int j)
Allows you to make something happen when this tile is right-clicked by the player.
 
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....
 
virtual void PostSetDefaults()
Allows you to override some default properties of this tile, such as Main.tileNoSunLight and Main....
 
virtual bool HasWalkDust()
Whether or not this tile creates dust when the player walks on it. Returns false by default.
 
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...
 
virtual void SpecialDraw(int i, int j, SpriteBatch spriteBatch)
Special Draw. Only called if coordinates are placed in Main.specX/Y during DrawEffects....
 
virtual void FloorVisuals(Player player)
Allows you to make something happen when a player stands on this type of tile. For example,...
 
float mineResist
A multiplier describing how much this block resists harvesting. Higher values will make it take longe...
 
virtual bool CanExplode(int i, int j)
Whether or not the tile at the given coordinates can be killed by an explosion (ie....
 
bool disableSmartInteract
Whether or not the smart tile interaction function is disabled when the cursor hovers above this tile...
 
int minPick
The minimum pickaxe power required for pickaxes to mine this block. Defaults to 0.
 
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 ...
 
string chest
The default name of this chest that is displayed when this 2x2 chest is open. Defaults to the empty s...
 
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.
 
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....
 
virtual bool Slope(int i, int j)
Allows you to control how hammers slope this tile. Return true to allow it to slope normally....
 
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...
 
virtual void ChangeWaterfallStyle(ref int style)
Allows you to change the style of waterfall that passes through or over this type of tile.
 
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....
 
bool torch
Whether or not this tile behaves like a torch. If you are making a torch tile, then setting this to t...
 
This class is used to keep track of and support the existence of custom sounds that have been added t...
 
This serves as the central class from which tile-related functions are supported and carried out.
 
static void PalmTreeGrowthFXGore(int type, ref int gore)
 
static ModTile GetTile(int type)
Gets the ModTile instance with the given type. If no ModTile with the given type exists,...
 
static Action< int, int, int >[] HookMouseOverFar
 
static bool UnlockChest(int i, int j, int type, ref short frameXAdjustment, ref int dustType, ref bool manual)
 
static void TreeGrowthFXGore(int type, ref int gore)
 
static void HitWire(int i, int j, int type)
 
static readonly int vanillaChairCount
 
static void DropTreeWood(int type, ref int wood)
 
static void WalkDust(int type, ref int dustType, ref bool makeDust, ref Color color)
 
static Action< int, int, int, SpriteBatch >[] HookPostDraw
 
static DelegateTileFrame[] HookTileFrame
 
static Texture2D GetPalmTreeTopTextures(int type)
 
static DelegateCanKillTile[] HookCanKillTile
 
static Func< int, int, int, SpriteBatch, bool >[] HookPreDraw
 
static bool CanPlace(int i, int j, int type)
 
static bool IsLockedChest(int i, int j, int type)
 
static Func< int, int, int, bool >[] HookDrop
 
static Func< int, int[]>[] HookAdjTiles
 
static Action< int, int, int >[] HookMouseOver
 
static void TreeDust(Tile tile, ref int dust)
 
static bool IsDresser(int type)
 
static bool SaplingGrowthType(int type, ref int saplingType, ref int style)
 
static readonly int vanillaTorchCount
 
static Texture2D GetCactusTexture(int type)
 
static void MouseOverFar(int i, int j)
 
static Action< int, int, Item >[] HookPlaceInWorld
 
delegate void DelegateSetSpriteEffects(int i, int j, int type, ref SpriteEffects spriteEffects)
 
static void MouseOver(int i, int j)
 
static DelegateNumDust[] HookNumDust
 
static Texture2D GetTreeTopTextures(int type, int i, int j, ref int frame, ref int frameWidth, ref int frameHeight, ref int xOffsetLeft, ref int yOffset)
 
static void NumDust(int i, int j, int type, bool fail, ref int numDust)
 
static void PalmTreeDust(Tile tile, ref int dust)
 
static Action< int, int, int >[] HookRightClick
 
static string ModChestName(int type)
 
static DelegateDropCritterChance[] HookDropCritterChance
 
static void KillMultiTile(int i, int j, int frameX, int frameY, int type)
 
static string ModDresserName(int type)
 
static bool IsTorch(int type)
 
static void FloorVisuals(int type, Player player)
 
static Texture2D GetPalmTreeTexture(Tile tile)
 
static Func< int, int, int, bool >[] HookKillSound
 
static Texture2D GetTreeBranchTextures(int type, int i, int j, int trunkOffset, ref int frame)
 
static bool IsModMusicBox(Tile tile)
 
static bool PreDraw(int i, int j, int type, SpriteBatch spriteBatch)
 
static void SetDrawPositions(int i, int j, ref int width, ref int offsetY, ref int height)
 
static void DropPalmTreeWood(int type, ref int wood)
 
static void SetSpriteEffects(int i, int j, int type, ref SpriteEffects spriteEffects)
 
static int AutoSelect(int i, int j, Player player)
 
delegate void DelegateDropCritterChance(int i, int j, int type, ref int wormChance, ref int grassHopperChance, ref int jungleGrubChance)
 
static DelegateModifyLight[] HookModifyLight
 
static Func< int, int, int, bool >[] HookSlope
 
static Action< int, int, int, SpriteBatch >[] HookSpecialDraw
 
static void FixSmartInteractCoords(int type, ref int width, ref int height, ref int frameWidth, ref int frameHeight, ref int extraX, ref int extraY)
 
static void DropCritterChance(int i, int j, int type, ref int wormChance, ref int grassHopperChance, ref int jungleGrubChance)
 
static Texture2D GetTreeTexture(Tile tile)
 
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)
 
static bool HasWalkDust(int type)
 
static bool CanDropAcorn(int type)
 
static bool CreateDust(int i, int j, int type, ref int dustType)
 
static bool CanGrowModTree(int type)
 
static Action[] HookAnimateTile
 
static Func< int, int, int, Player, bool >[] HookDangersense
 
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)
 
static int OpenDoorID(Tile tile)
 
static void AdjTiles(Player player, int type)
 
static DelegateDrawEffects[] HookDrawEffects
 
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)
 
static void Resize2DArray< T >(ref T[,] array, int newSize)
 
static void RandomUpdate(int i, int j, int type)
 
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....
 
static Action< int, int, int, bool >[] HookNearbyEffects
 
delegate bool DelegateCreateDust(int i, int j, int type, ref int dustType)
 
static bool IsModBed(int type)
 
delegate int DelegateSaplingGrowthType(int type, ref int style)
 
static void MineDamage(int minePower, ref int damage)
 
static int CloseDoorID(Tile tile)
 
static void CheckModTile(int i, int j, int type)
 
static bool KillSound(int i, int j, int type)
 
static void PlaceInWorld(int i, int j, Item item)
 
static bool IsClosedDoor(Tile tile)
 
static bool Slope(int i, int j, int type)
 
static void NearbyEffects(int i, int j, int type, bool closer)
 
static bool CanGrowModCactus(int type)
 
static void ModifyLight(int i, int j, int type, ref float r, ref float g, ref float b)
 
static bool HasSmartInteract(int type)
 
static Action< int, int, int >[] HookHitWire
 
static bool PreHitWire(int i, int j, int type)
 
static Func< int, int, int, bool >[] HookPreHitWire
 
delegate void DelegateNumDust(int i, int j, int type, bool fail, ref int num)
 
static DelegateSetSpriteEffects[] HookSetSpriteEffects
 
static void PickPowerCheck(Tile target, int pickPower, ref int damage)
 
static DelegateKillTile[] HookKillTile
 
static readonly int vanillaTableCount
 
static void DisableSmartCursor(Tile tile, ref bool disable)
 
static void PostDraw(int i, int j, int type, SpriteBatch spriteBatch)
 
static bool CanKillTile(int i, int j, int type, ref bool blockDamaged)
 
static Func< int, int, int, Item, bool >[] HookAutoSelect
 
static bool TileFrame(int i, int j, int type, ref bool resetFrame, ref bool noBreak)
 
static DelegateChangeWaterfallStyle[] HookChangeWaterfallStyle
 
static DelegateCreateDust[] HookCreateDust
 
static DelegateSaplingGrowthType[] HookSaplingGrowthType
 
static Action< int, Player >[] HookFloorVisuals
 
static Action< int, int, int >[] HookRandomUpdate
 
static bool RightClick(int i, int j)
 
static Func< int, int, int, bool >[] HookCanExplode
 
static void AnimateTiles()
 
delegate void DelegateChangeWaterfallStyle(int type, ref int style)
 
static readonly int vanillaDoorCount
 
static void ChangeWaterfallStyle(int type, ref int style)
 
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 ...
 
static void DrawEffects(int i, int j, int type, SpriteBatch spriteBatch, ref Color drawColor, ref int nextSpecialDrawIndex)
 
static void DisableSmartInteract(Tile tile, ref bool disable)
 
static bool CanGrowModPalmTree(int type)
 
static bool CanExplode(int i, int j)
 
static bool IsSapling(int type)
 
delegate bool DelegateTileFrame(int i, int j, int type, ref bool resetFrame, ref bool noBreak)
 
static Func< int, int, int, bool >[] HookCanPlace