Standalone [1.3] tModLoader - A Modding API

What am i doing? It says that Main.animationFrameHeight = 4; does not exist and public override void AnimateTile is missing bunch of brackects...

Code:
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.ObjectData;

namespace ExampleMod.Tiles
{
    public class EnchantingTable : ModTile
    {
        public override void SetDefaults()
        {
            Main.tileSolidTop[Type] = true;
            Main.tileFrameImportant[Type] = true;
            Main.tileNoAttach[Type] = true;
            Main.animationFrameHeight = 4;
            Main.tileTable[Type] = false;
            Main.tileLavaDeath[Type] = true;

public override void AnimateTile(ref int frame, ref int frameCounter)
{
      frameCounter++;
      if (frameCounter >= 10)
      {
          frame = (frame + 1) % 4;
          frameCounter = 0;
      }
}

            TileObjectData.newTile.CopyFrom(TileObjectData.Style2x1);
            TileObjectData.newTile.CoordinateHeights = new int[]{ 18 };
            TileObjectData.addTile(Type);
            AddToArray(ref TileID.Sets.RoomNeeds.CountsAsTable);
            dustType = mod.DustType("Sparkle");
            adjTiles = new int[]{ TileID.WorkBenches };
        }

        public override void NumDust(int i, int j, bool fail, ref int num)
        {
            num = fail ? 1 : 3;
        }

        public override void KillMultiTile(int i, int j, int frameX, int frameY)
        {
            Item.NewItem(i * 16, j * 16, 32, 16, mod.ItemType("EnchantingTable"));
        }
    }
}
Why do you have AnimateTile right in the middle of SetDefaults?

How to make a mount that completely replaces the player sprite, is 2×2 tiles and has infinite flying and takes only one frame to start moving and to stop?
[DOUBLEPOST=1451079144,1451078786][/DOUBLEPOST]Is it possible to create a buff that reduces the maximum health to 1 point but gives a 99% chance of dodging every attack?
I haven't worked much with mounts yet.
And it will be possible to make that buff in the next update.

How to let a projectile spin at the end (Like Vampire knives)
or just let it spin in general

and how to add dust on melee weapons...

I am so dumb ;_;
To make it spin, increment projectile.rotation.
To add dust to melee weapons, I think the ExampleSword and ExamplePickaxe do that.

bluemagic123 can you help me ? I createf laser rifle : shootspeed = 2, extraUpadet = 20, and add dust but the trail is made of many dusts and they are randomly rotated and i want only straight line what should i do ?
Set the dusts' velocity to zero after you make them.

HELP!
my terraria wont go back to normal
i just wanna play with some friends :mad:
You can either click on "Restore Vanilla Terraria" in the installer, or you can rename your Terraria_v1.3.0.8.exe file to Terraria.exe.
 
You need to use Autoload to make the internal name the same as the name (so you need to add a space in the Autoload name). I might try to make this easier to use later.
I see. Thx a lot.
Rarely have I realized this, since the NPCs I made before all don't have a space in their name!
Gald to have you here, then maybe I got another question: would it be possible to delete vanilla recipes, for now or next update?
 
I see. Thx a lot.
Rarely have I realized this, since the NPCs I made before all don't have a space in their name!
Gald to have you here, then maybe I got another question: would it be possible to delete vanilla recipes, for now or next update?
Deleting vanilla recipes has been possible ever since the very first version. However, that's something that you need to know how to program, and need to have an understanding of Terraria's code, in order to be able to do. I think early on someone posted some code for it, but I don't remember where it is.
 
Ok so the mod is building but the tile is not moving

Code:
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.ObjectData;

namespace ExampleMod.Tiles
{
    public class EnchantingTable : ModTile
    {
        public override void SetDefaults()
        {
            Main.tileSolidTop[Type] = true;
            Main.tileFrameImportant[Type] = true;
            Main.tileNoAttach[Type] = true;
            Main.tileTable[Type] = false;
            Main.tileLavaDeath[Type] = true;
            TileObjectData.newTile.CopyFrom(TileObjectData.Style2x1);
            TileObjectData.newTile.CoordinateHeights = new int[] { 18 };
            TileObjectData.addTile(Type);
            AddToArray(ref TileID.Sets.RoomNeeds.CountsAsTable);
            AddMapEntry(new Color(200, 200, 200), "EnchantingTable");
            dustType = mod.DustType("Sparkle");
            adjTiles = new int[] { TileID.WorkBenches };
        }
        public int animationFrameHeight = 72;

        public override void AnimateTile(ref int frame, ref int frameCounter)
        {
            frameCounter++;
            if (frameCounter >= 10)
            {
                frame = (frame + 1) % 4;
                frameCounter = 0;
            }
        }


        public override void NumDust(int i, int j, bool fail, ref int num)
        {
            num = fail ? 1 : 3;
        }

        public override void KillMultiTile(int i, int j, int frameX, int frameY)
        {
            Item.NewItem(i * 16, j * 16, 32, 16, mod.ItemType("EnchantingTable"));
        }
    }
}
 
Last edited:
Deleting vanilla recipes has been possible ever since the very first version. However, that's something that you need to know how to program, and need to have an understanding of Terraria's code, in order to be able to do. I think early on someone posted some code for it, but I don't remember where it is.
Don't quite get you, do you mean I may need to engage with vanilla source coedes to reach this? And there's already someone figuring out this rihgt? I may search in this thread.
 
Deleting vanilla recipes has been possible ever since the very first version. However, that's something that you need to know how to program, and need to have an understanding of Terraria's code, in order to be able to do. I think early on someone posted some code for it, but I don't remember where it is.
This is what you posted in #959 when there are two persons discussing about this problem:
Ok. So are we trying to remove a recipe? What you need to do first is iterate through the entire Main.recipe. You will need to check for the one you want to remove by checking the type of createItem, and iterating through requiredItem to make sure it has all the ingredients of the recipe you're looking for. Once you do this, you need to set this index of Main.recipe to the recipe in the next index. Continue setting the recipes to the next index for the rest of the iteration; when you reach the final index set it to a new Recipe.

Alternately, instead of actually removing the recipe, you can set the type of all its ingredients to 0, then make its only ingredient an unobtainable item like the Red Potion. This is kind of hacky though.
Seems this is an indirect way. Is this the only way? If it is, maybe you can give me an example of how this works.
 
Ok so the mod is building but the tile is not moving

Code:
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.ObjectData;

namespace ExampleMod.Tiles
{
    public class EnchantingTable : ModTile
    {
        public override void SetDefaults()
        {
            Main.tileSolidTop[Type] = true;
            Main.tileFrameImportant[Type] = true;
            Main.tileNoAttach[Type] = true;
            Main.tileTable[Type] = false;
            Main.tileLavaDeath[Type] = true;
            TileObjectData.newTile.CopyFrom(TileObjectData.Style2x1);
            TileObjectData.newTile.CoordinateHeights = new int[] { 18 };
            TileObjectData.addTile(Type);
            AddToArray(ref TileID.Sets.RoomNeeds.CountsAsTable);
            AddMapEntry(new Color(200, 200, 200), "EnchantingTable");
            dustType = mod.DustType("Sparkle");
            adjTiles = new int[] { TileID.WorkBenches };
        }
        public int animationFrameHeight = 72;

        public override void AnimateTile(ref int frame, ref int frameCounter)
        {
            frameCounter++;
            if (frameCounter >= 10)
            {
                frame = (frame + 1) % 4;
                frameCounter = 0;
            }
        }


        public override void NumDust(int i, int j, bool fail, ref int num)
        {
            num = fail ? 1 : 3;
        }

        public override void KillMultiTile(int i, int j, int frameX, int frameY)
        {
            Item.NewItem(i * 16, j * 16, 32, 16, mod.ItemType("EnchantingTable"));
        }
    }
}
You need to set animationFrameHeight in SetDefaults. You're not supposed to create your own animationFrameHeight field.

This is what you posted in #959 when there are two persons discussing about this problem:

Seems this is an indirect way. Is this the only way? If it is, maybe you can give me an example of how this works.
That isn't indirect; in fact it's a very direct way. And yeah, those are the only ways I know of. Unfortunately, I don't have time at the moment to make an example for how it works.
 
That isn't indirect; in fact it's a very direct way. And yeah, those are the only ways I know of. Unfortunately, I don't have time at the moment to make an example for how it works.
Okay, just take your time bro.
As long as I've known this is the only way, I can sink my teeth into it. I don't need to think about there being a better way anymore.
 
That isn't indirect; in fact it's a very direct way. And yeah, those are the only ways I know of. Unfortunately, I don't have time at the moment to make an example for how it works.
I spent a lot of time trying to understand the workd you've posted and the discussion among p47 ~ p49.
It seems it will work by:
Code:
Main.recipe[1346].requiredItem[0].SetDefaults(0);
Question is, it need to access to the recipe number. And I got no idea where it stores in vanilla game.

Someone seems to write a snippest codes to locate the recipe number:
Code:
            for (int i=0; i < Recipe.numRecipes - 1; i++) // Loop through all the recipes
            {
                for (int x = 0; x < Main.recipe[i].requiredItem.Length; x++) // Loop through required items
                {
                    if (Main.recipe[i].requiredItem[x].type == ItemID.BladeofGrass) // If req. item is .. ?
                    {
                        ErrorLogger.Log("Recipe result: " + Main.recipe[i].createItem.ToString());
                        ErrorLogger.Log("Recipe req [" + x + "]: " + Main.recipe[i].requiredItem[x].ToString());
                        ErrorLogger.Log("Req item x=" + x);
                        ErrorLogger.Log("Loop i="+i);
                    }
                }
            }
I also get no idea of this, so I throw it into my Load(), and nothing happens.
If you finish your job, remember to give a quick reply about how to find recipe numbers.

EDIT: Yeah, I've now totally understood these stuff now, and I also find that I can look up recipe numbers in the Vanilla Recipes file you put in wiki. Anyways, no further trouble about this, no need to reply.
 
Last edited:
Hey, I'm wanting to create my own custom AI for an NPC/Critter but reading the original code or the example mod's NPCs' AI gets me confused. Most of all - what's the AI float array for? Even the mod NPCs' AI uses it. Could anyone maybe give me just a quick explanation what that's for? Or, if anyone's feeling it, a quick rundown of important stuff that needs to appear in the AI code?

Thanks
 
Ok so my tile now works but I noticed that it is too small, so i tried to make a 3x3 tile but only left side is showing and is not animating properly.
1u1N4yb.png

Code:
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.ObjectData;

namespace Letack.Tiles
{
    public class EnchantingTable : ModTile
    {
        public override void SetDefaults()
        {
            Main.tileSolidTop[Type] = false;
            Main.tileFrameImportant[Type] = true;
            Main.tileNoAttach[Type] = true;
            Main.tileTable[Type] = false;
            Main.tileLavaDeath[Type] = true;
            TileObjectData.newTile.CopyFrom(TileObjectData.Style3x3);
            TileObjectData.newTile.CoordinateHeights = new int[]{ 48 };
            TileObjectData.addTile(Type);
            animationFrameHeight = 54;
            AddToArray(ref TileID.Sets.RoomNeeds.CountsAsTable);
            AddMapEntry(new Color(200, 200, 200), "EnchantingTable");
            dustType = mod.DustType("Sparkle");
            adjTiles = new int[] { TileID.WorkBenches };
        }
     
        public override void AnimateTile(ref int frame, ref int frameCounter)
        {
            frameCounter++;
            if (frameCounter >= 20)
            {
                frame = (frame + 1) % 4;
                frameCounter = 0;
            }
        }


        public override void NumDust(int i, int j, bool fail, ref int num)
        {
            num = fail ? 3 : 5;
        }

        public override void KillMultiTile(int i, int j, int frameX, int frameY)
        {
            Item.NewItem(i * 16, j * 16, 32, 16, mod.ItemType("EnchantingTable"));
        }
    }
}
 
Hi guys i have a little problem here so i scripted everthing just fine and i cant build it it
says: cant find terrariamacexe and also something about metadata
 
Ok so my tile now works but I noticed that it is too small, so i tried to make a 3x3 tile but only left side is showing and is not animating properly.
1u1N4yb.png

Code:
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.ObjectData;

namespace Letack.Tiles
{
    public class EnchantingTable : ModTile
    {
        public override void SetDefaults()
        {
            Main.tileSolidTop[Type] = false;
            Main.tileFrameImportant[Type] = true;
            Main.tileNoAttach[Type] = true;
            Main.tileTable[Type] = false;
            Main.tileLavaDeath[Type] = true;
            TileObjectData.newTile.CopyFrom(TileObjectData.Style3x3);
            TileObjectData.newTile.CoordinateHeights = new int[]{ 48 };
            TileObjectData.addTile(Type);
            animationFrameHeight = 54;
            AddToArray(ref TileID.Sets.RoomNeeds.CountsAsTable);
            AddMapEntry(new Color(200, 200, 200), "EnchantingTable");
            dustType = mod.DustType("Sparkle");
            adjTiles = new int[] { TileID.WorkBenches };
        }
 
        public override void AnimateTile(ref int frame, ref int frameCounter)
        {
            frameCounter++;
            if (frameCounter >= 20)
            {
                frame = (frame + 1) % 4;
                frameCounter = 0;
            }
        }


        public override void NumDust(int i, int j, bool fail, ref int num)
        {
            num = fail ? 3 : 5;
        }

        public override void KillMultiTile(int i, int j, int frameX, int frameY)
        {
            Item.NewItem(i * 16, j * 16, 32, 16, mod.ItemType("EnchantingTable"));
        }
    }
}

I usually solve those problems by manually adding:
Code:
  TileObjectData.newTile.CoordinateHeights = new int[] {48,48,48};
  TileObjectData.newTile.Width = 3;
  TileObjectData.newTile.Height = 3;
Maybe it's excessive but it usually works for me.
Also if it's not animating properly, check if your animationFrameHeight is set correctly.
 
Last edited:
Ok so i managed to get the table to place but it doesnt animate properly and the placement preview show 3 frames of the table. I did checked the animationFrameHeight and edited the .png file but still it doesnt work...
BOmJtlg.png

Code:
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.ObjectData;

namespace Letack.Tiles
{
    public class EnchantingTable : ModTile
    {
        public override void SetDefaults()
        {
            Main.tileSolidTop[Type] = false;
            Main.tileFrameImportant[Type] = true;
            Main.tileNoAttach[Type] = true;
            Main.tileTable[Type] = false;
            Main.tileLavaDeath[Type] = true;
            TileObjectData.newTile.CopyFrom(TileObjectData.Style3x3);
            TileObjectData.newTile.CoordinateHeights = new int[] { 48, 48, 48 };
            TileObjectData.newTile.Width = 3;
            TileObjectData.newTile.Height = 3;
            TileObjectData.addTile(Type);
            animationFrameHeight = 54;
            AddToArray(ref TileID.Sets.RoomNeeds.CountsAsTable);
            AddMapEntry(new Color(200, 200, 200), "EnchantingTable");
            dustType = mod.DustType("Sparkle");
            adjTiles = new int[] { TileID.WorkBenches };
        }

        public override void AnimateTile(ref int frame, ref int frameCounter)
        {
            frameCounter++;
            if (frameCounter >= 20)
            {
                frame = (frame + 1) % 4;
                frameCounter = 4;
            }
        }


        public override void NumDust(int i, int j, bool fail, ref int num)
        {
            num = fail ? 1 : 3;
        }

        public override void KillMultiTile(int i, int j, int frameX, int frameY)
        {
            Item.NewItem(i * 16, j * 16, 32, 16, mod.ItemType("EnchantingTable"));
        }
    }
}
[DOUBLEPOST=1451139616,1451139508][/DOUBLEPOST]
Sorry that I am still asking but....how to do so?
Thank you for the dust help thought!
public override bool Update(Dust dust)
Try this. you can also change the numbers if you want.

public override bool Update(Dust dust)
{
dust.position += dust.velocity;
dust.rotation += dust.velocity.X * 0.15f;
dust.scale *= 0.99f;
float light = 0.35f * dust.scale;
Lighting.AddLight(dust.position, light, light, light);
if (dust.scale < 0.5f)
{
dust.active = false;
}
return false;
}
 
Ok so i managed to get the table to place but it doesnt animate properly and the placement preview show 3 frames of the table. I did checked the animationFrameHeight and edited the .png file but still it doesnt work...
BOmJtlg.png

Code:
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.ObjectData;

namespace Letack.Tiles
{
    public class EnchantingTable : ModTile
    {
        public override void SetDefaults()
        {
            Main.tileSolidTop[Type] = false;
            Main.tileFrameImportant[Type] = true;
            Main.tileNoAttach[Type] = true;
            Main.tileTable[Type] = false;
            Main.tileLavaDeath[Type] = true;
            TileObjectData.newTile.CopyFrom(TileObjectData.Style3x3);
            TileObjectData.newTile.CoordinateHeights = new int[] { 48, 48, 48 };
            TileObjectData.newTile.Width = 3;
            TileObjectData.newTile.Height = 3;
            TileObjectData.addTile(Type);
            animationFrameHeight = 54;
            AddToArray(ref TileID.Sets.RoomNeeds.CountsAsTable);
            AddMapEntry(new Color(200, 200, 200), "EnchantingTable");
            dustType = mod.DustType("Sparkle");
            adjTiles = new int[] { TileID.WorkBenches };
        }

        public override void AnimateTile(ref int frame, ref int frameCounter)
        {
            frameCounter++;
            if (frameCounter >= 20)
            {
                frame = (frame + 1) % 4;
                frameCounter = 4;
            }
        }


        public override void NumDust(int i, int j, bool fail, ref int num)
        {
            num = fail ? 1 : 3;
        }

        public override void KillMultiTile(int i, int j, int frameX, int frameY)
        {
            Item.NewItem(i * 16, j * 16, 32, 16, mod.ItemType("EnchantingTable"));
        }
    }
}

Your CoordinateHeights are off. Make them so:
Code:
TileObjectData.newTile.CoordinateHeights = new int[] { 16,16,16 };
Then see what happens.
 
Ok so i managed to get the table to place but it doesnt animate properly and the placement preview show 3 frames of the table. I did checked the animationFrameHeight and edited the .png file but still it doesnt work...
BOmJtlg.png

Code:
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.ObjectData;

namespace Letack.Tiles
{
    public class EnchantingTable : ModTile
    {
        public override void SetDefaults()
        {
            Main.tileSolidTop[Type] = false;
            Main.tileFrameImportant[Type] = true;
            Main.tileNoAttach[Type] = true;
            Main.tileTable[Type] = false;
            Main.tileLavaDeath[Type] = true;
            TileObjectData.newTile.CopyFrom(TileObjectData.Style3x3);
            TileObjectData.newTile.CoordinateHeights = new int[] { 48, 48, 48 };
            TileObjectData.newTile.Width = 3;
            TileObjectData.newTile.Height = 3;
            TileObjectData.addTile(Type);
            animationFrameHeight = 54;
            AddToArray(ref TileID.Sets.RoomNeeds.CountsAsTable);
            AddMapEntry(new Color(200, 200, 200), "EnchantingTable");
            dustType = mod.DustType("Sparkle");
            adjTiles = new int[] { TileID.WorkBenches };
        }

        public override void AnimateTile(ref int frame, ref int frameCounter)
        {
            frameCounter++;
            if (frameCounter >= 20)
            {
                frame = (frame + 1) % 4;
                frameCounter = 4;
            }
        }


        public override void NumDust(int i, int j, bool fail, ref int num)
        {
            num = fail ? 1 : 3;
        }

        public override void KillMultiTile(int i, int j, int frameX, int frameY)
        {
            Item.NewItem(i * 16, j * 16, 32, 16, mod.ItemType("EnchantingTable"));
        }
    }
}
[DOUBLEPOST=1451139616,1451139508][/DOUBLEPOST]
public override bool Update(Dust dust)
Try this. you can also change the numbers if you want.

public override bool Update(Dust dust)
{
dust.position += dust.velocity;
dust.rotation += dust.velocity.X * 0.15f;
dust.scale *= 0.99f;
float light = 0.35f * dust.scale;
Lighting.AddLight(dust.position, light, light, light);
if (dust.scale < 0.5f)
{
dust.active = false;
}
return false;
}
Uh I think you misunderstood

I know how to let dust rotate, but I have problems with letting my projectile rotate

But still thank you!
 
I know how to let dust rotate, but I have problems with letting my projectile rotate

You do it the same way except instead of

Code:
dust.rotation += dust.velocity.X * 0.15f;
you do:
Code:
projectile.rotation += [placeholder for a number of your choice];
in the projectile's code.
 
You do it the same way except instead of

Code:
dust.rotation += dust.velocity.X * 0.15f;
you do:
Code:
projectile.rotation += [placeholder for a number of your choice];
in the projectile's code.
Oh it does work the same? I didn't try that lol

Thank you!

So, next question...how to maipulate the gravityy of projectiles

I feel so dumb for asking, but yeah
 
Back
Top Bottom