Standalone [1.3] tModLoader - A Modding API

How can you make an NPC be able to be affected by a debuff? And can I make the debuff spawn a new NPC in place of the old one? (Like what if I want to make a debuff that 'zombifies' mobs?)
 
I've been using that to see how other mods are doing compared to mine. Also, it lets me check my download count away from my home PC.
What really annoys me is this bit:
http://javid.ddns.net/tModLoader/private/
What is in it that is so private?
Files that if accessed could break things. Logs.
jopojelly

so far i can only use banners to make recipes show or not

how can i use like buffs on player
biome around player
or a item in the players inv

public class clyablock : ModRecipe
{
int GreenSlime = Item.NPCtoBanner(NPCID.GreenSlime);
public clyablock(Mod mod) : base(mod)
{
}
public override bool RecipeAvailable()
{
return NPC.killCount[GreenSlime] >= 10;
}
Start with:
Player player = Main.player[Main.myPlayer];

Followed by:
// has a buff?
if(player.HasBuff(BuffID.TwinEyesMinion) > -1){return true}

// in a Zone/Biome?
if(player.ZoneCorrupt){return true}

// Has a particular item?
if(player.HasItem(mod.ItemType("SpectreGun"))){return true}
 
Files that if accessed could break things. Logs.
You mean files that if edited could break things.
Is it stuff like the online code behind the Mod Browser?

Also, my mod browser has been taking a long time to reload mods, much longer than usual, even though I recently got a better wifi connection for my PC. Just wondering if there was a problem causing that.[/QUOTE]
 
You mean files that if edited could break things.
Is it stuff like the online code behind the Mod Browser?

Also, my mod browser has been taking a long time to reload mods, much longer than usual, even though I recently got a better wifi connection for my PC. Just wondering if there was a problem causing that.
[/QUOTE]
No, they can't be edited. There are some scripts that propagate changes to the file host, scripts that I wrote while trying different things out, logs from the publish script.

There are some scripts that take arguments that I haven't proofed against browser users stumbling upon them. To be honest, they might not break anything.


The Mod Browser is super busy today, don't know why. It actually makes it hard for me to browse the internet since I share the same bandwidth.
 
Files that if accessed could break things. Logs.

Start with:
Player player = Main.player[Main.myPlayer];

Followed by:
// has a buff?
if(player.HasBuff(BuffID.TwinEyesMinion) > -1){return true}

// in a Zone/Biome?
if(player.ZoneCorrupt){return true}

// Has a particular item?
if(player.HasItem(mod.ItemType("SpectreGun"))){return true}


so where do i put the line

Player player = Main.player[Main.myPlayer];


as the one in wisp looks like this

return Main.player[Main.myPlayer].HasItem(mod.ItemType("SpectreGun"));
 
so where do i put the line

Player player = Main.player[Main.myPlayer];


as the one in wisp looks like this

return Main.player[Main.myPlayer].HasItem(mod.ItemType("SpectreGun"));
You could do it on one line or 2, doesn't matter.
return Main.player[Main.myPlayer].HasItem(mod.ItemType("SpectreGun")));
or
Player player = Main.player[Main.myPlayer];
return player.HasItem(mod.ItemType("SpectreGun")));
 
You could do it on one line or 2, doesn't matter.
return Main.player[Main.myPlayer].HasItem(mod.ItemType("SpectreGun")));
or
Player player = Main.player[Main.myPlayer];
return player.HasItem(mod.ItemType("SpectreGun")));

so how can i use && with 2 of em when they look like this?

Player player = Main.player[Main.myPlayer];
if(player.HasBuff(BuffID.TwinEyesMinion) > -1){return true}
Player player = Main.player[Main.myPlayer];
if(player.ZoneCorrupt){return true}
 
so how can i use && with 2 of em when they look like this?

Player player = Main.player[Main.myPlayer];
if(player.HasBuff(BuffID.TwinEyesMinion) > -1){return true}
Player player = Main.player[Main.myPlayer];
if(player.ZoneCorrupt){return true}
Player player = Main.player[Main.myPlayer];
return player.ZoneCorrupt && (player.HasBuff(BuffID.TwinEyesMinion) > -1);
 
Do you mean that you want to give it a max speed, or have it move at a consistent speed?

If you want to give it a max speed, look at this example which is an extension of an earlier example. Note, I'm still using the code that makes it follow the mouse.
Code:
int maxSpeed = 8; //best keep this below 16

public override void AI()
{
Vector2 acceleration = Vector2.Normalize(Main.MouseWorld - projectile.Center); //convert the distance from this projectile to the mouse to a unit-vector
projectile.velocity += acceleration * 1.5f; //add one and a half of my acceleration to my velocity
projectile.velocity *= 0.95f; //slow down slightly, i.e. apply drag
if (projectile.velocity.Length() > maxSpeed)//if going too fast
{
projectile.velocity.Normalize();//normalise
projectile.velocity *= maxSpeed;//and multiply by my max speed
}
projectile.rotation = projectile.velocity.ToRotation(); //calculate the direction that this projectile is going and rotate to face that way.
}
If you simply want it to move at a fixed rate, the following will do, but the movement will be very abrupt.
Code:
int maxSpeed = 8; //best keep this below 16

public override void AI()
{
projectile.velocity = Vector2.Normalize(Main.MouseWorld - projectile.Center) * maxSpeed; //normalise the difference between my position and multiply by my desired speed.
projectile.rotation = projectile.velocity.ToRotation(); //calculate the direction that this projectile is going and rotate to face that way.
}
Also, I think my findNearest function could be more efficient. Replace the first three 'if' statements inside the 'for' loop with the following:
Code:
if (!Terraria.Main.npc[i].CanBeChasedBy(projectile))//Don't target anything it shouldn't
continue;

I have a big problem now :(
the projectile just goes out a little distance and then stops until there is something to home in on. then it homes.
EDIT: Then it just sits there and never homes
Code:
using System;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Microsoft.Xna.Framework;

namespace Pack.Projectiles
{
    public class TS : ModProjectile
    {
        public override void SetDefaults()
        {
            projectile.name = "Templite Spell";
            projectile.width = 8;
            projectile.height = 8;
            projectile.friendly = true;
            projectile.penetrate = 10;
            projectile.aiStyle = 0;
            projectile.magic = true;
            projectile.tileCollide = true;
            projectile.timeLeft = 60000;
            projectile.light = 10f;
        }
        public NPC FindNearest(Vector2 pos)
        {
            NPC nearest = null;
            float oldDist = 1001;
            float newDist = 1000;
            for (int i = 0; i < Terraria.Main.npc.Length - 1; i++)
            {
                if (!Collision.CanHit(pos, 1, 1, Main.npc[i].position, Main.npc[i].width, Main.npc[i].height))
                    continue;
                if (!Terraria.Main.npc[i].CanBeChasedBy(projectile))
                    continue;
                if (nearest == null)
                    nearest = Terraria.Main.npc[i];
                else
                {
                    oldDist = Vector2.Distance(pos, nearest.position);
                    newDist = Vector2.Distance(pos, Terraria.Main.npc[i].position);
                    if (newDist < oldDist)
                        nearest = Terraria.Main.npc[i];
                }
            }
            return nearest;
        }
        int maxSpeed = 10;
        public override void AI()
        {
            NPC nearest = this.FindNearest(projectile.Center);
            Vector2 acceleration = Vector2.Zero;
            projectile.velocity += acceleration * 1.5f;
            projectile.velocity *= 0.95f;
            if (projectile.velocity.Length() > maxSpeed)
            {
                projectile.velocity.Normalize();
                projectile.velocity *= maxSpeed;
            }
            projectile.rotation = projectile.velocity.ToRotation();
        }
    }
}

where's the mistake in my code?
please help
 
Does anyone know what the method to damage an NPC is? Thank you in advance,

DreamOfNightmares
 
For some odd reason, I have these files called twld and tsw as well as my wld and wld.bak files, but whenever I try to go on a world, I delete the twld and tsw files, but whenever I go on it deletes my backup and when I make a new world, when I use CheatSheet, it just crashes.

-Spectrum

someone plz help im sad
 
Sorry, i know this is a stupid question, but how does one fix this :/
Items/Armour/ChestguardOfMight_Body
at Terraria.ModLoader.Mod.GetTexture(String name)
at Terraria.ModLoader.ModLoader.GetTexture(String name)
at Terraria.ModLoader.Mod.AddEquipTexture(EquipTexture equipTexture, ModItem item, EquipType type, String name, String texture, String armTexture, String femaleTexture)
at Terraria.ModLoader.Mod.AddEquipTexture(ModItem item, EquipType type, String name, String texture, String armTexture, String femaleTexture)
at Terraria.ModLoader.Mod.AutoloadItem(Type type)
at Terraria.ModLoader.Mod.Autoload()
at Terraria.ModLoader.ModLoader.do_Load(Object threadContext)
 
You haven't put the movement animation sprite for your chestplate.
[doublepost=1466754750,1466754576][/doublepost]Look at the ExampleMod, if you want to create a piece of armour you have to create additional .png with the animation (in this case the body)
 
You haven't put the movement animation sprite for your chestplate.
[doublepost=1466754750,1466754576][/doublepost]Look at the ExampleMod, if you want to create a piece of armour you have to create additional .png with the animation (in this case the body)
I have, I have the animations there, arms, body and female.

EDIT: Ok, on third look there was a typo in the name. Swear i checked it earlier, but all good. fixed now ^^
 
How can I make an Item to be either crafted with an iron bar or a lead bar, like the craftinggroup method?
I don't want to add two recipes, and since crafting group method was removed, I am confused what to do.
Terraria has a built in craft group for iron or lead. Just do the following.
recipe1.AddRecipeGroup("IronBar", 3); //vanilla recipe group - adds 3
A custom craft group looks like the following.
Code:
public override void AddRecipeGroups()
{
    //Add the silver ranked group
    RecipeGroup group = new RecipeGroup(() => Lang.misc[37] + " Silver", new int[]
    {
        ItemID.SilverBar,
        ItemID.TungstenBar
    });
    RecipeGroup.RegisterGroup("rankSilver", group); //creates a group called "rankSilver". Use recipe.AddRecipeGroup("rankSilver", 1); to use this group in a recipe
}

I have a big problem now :(
the projectile just goes out a little distance and then stops until there is something to home in on. then it homes.
EDIT: Then it just sits there and never homes
Code:
using System;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Microsoft.Xna.Framework;

namespace Pack.Projectiles
{
    public class TS : ModProjectile
    {
        public override void SetDefaults()
        {
            projectile.name = "Templite Spell";
            projectile.width = 8;
            projectile.height = 8;
            projectile.friendly = true;
            projectile.penetrate = 10;
            projectile.aiStyle = 0;
            projectile.magic = true;
            projectile.tileCollide = true;
            projectile.timeLeft = 60000;
            projectile.light = 10f;
        }
        public NPC FindNearest(Vector2 pos)
        {
            NPC nearest = null;
            float oldDist = 1001;
            float newDist = 1000;
            for (int i = 0; i < Terraria.Main.npc.Length - 1; i++)
            {
                if (!Collision.CanHit(pos, 1, 1, Main.npc[i].position, Main.npc[i].width, Main.npc[i].height))
                    continue;
                if (!Terraria.Main.npc[i].CanBeChasedBy(projectile))
                    continue;
                if (nearest == null)
                    nearest = Terraria.Main.npc[i];
                else
                {
                    oldDist = Vector2.Distance(pos, nearest.position);
                    newDist = Vector2.Distance(pos, Terraria.Main.npc[i].position);
                    if (newDist < oldDist)
                        nearest = Terraria.Main.npc[i];
                }
            }
            return nearest;
        }
        int maxSpeed = 10;
        public override void AI()
        {
            NPC nearest = this.FindNearest(projectile.Center);
            Vector2 acceleration = Vector2.Zero;
            projectile.velocity += acceleration * 1.5f;
            projectile.velocity *= 0.95f;
            if (projectile.velocity.Length() > maxSpeed)
            {
                projectile.velocity.Normalize();
                projectile.velocity *= maxSpeed;
            }
            projectile.rotation = projectile.velocity.ToRotation();
        }
    }
}

where's the mistake in my code?
please help
Well first, I found the problem that was causing the slow down. You need to swap the two if conditions inside the findNearest function so that your projectile isn't checking collision with all 200 non-existent NPC's in the world. And your projectile wasn't homing because you had removed the position of its target from the equation, so that it never knew where to home to. Also, you forgot to check if your 'nearest' NPC was null, which would cause the projectile to disappear. I've fixed your AI for you.
Code:
public override void AI()
{
    NPC nearest = this.FindNearest(projectile.Center);
    Vector2 acceleration;
    if (nearest != null) //this is really important
    {
        acceleration = (nearest.position - projectile.position);
    } else
    {
        acceleration = Vector2.Zero; //maintain speed -- or whatever else you want to do here
    }
    projectile.velocity += acceleration * 1.5f;
    projectile.velocity *= 0.99f;
    if (projectile.velocity.Length() > maxSpeed)
    {
        projectile.velocity.Normalize();
        projectile.velocity *= maxSpeed;
    }
    projectile.rotation = projectile.velocity.ToRotation();
}
Also, it looks like you've been removing my comments from the code. It's a good idea to leave those there so that the code is easier to interpret.
 
Ok, so when I tried to use the LoadCustomData I got the "Unable to read beyond the end of the stream" error.
Here's the code
Code:
 public override void LoadCustomData(BinaryReader reader)
{
            int loadVersion = reader.ReadInt32();
            item.pick = reader.ReadInt32();
            item.damage = reader.ReadInt32();
            item.useTime = reader.ReadInt32();
        }
 
Terraria has a built in craft group for iron or lead. Just do the following.
recipe1.AddRecipeGroup("IronBar", 3); //vanilla recipe group - adds 3
A custom craft group looks like the following.
Code:
public override void AddRecipeGroups()
{
    //Add the silver ranked group
    RecipeGroup group = new RecipeGroup(() => Lang.misc[37] + " Silver", new int[]
    {
        ItemID.SilverBar,
        ItemID.TungstenBar
    });
    RecipeGroup.RegisterGroup("rankSilver", group); //creates a group called "rankSilver". Use recipe.AddRecipeGroup("rankSilver", 1); to use this group in a recipe
}


Well first, I found the problem that was causing the slow down. You need to swap the two if conditions inside the findNearest function so that your projectile isn't checking collision with all 200 non-existent NPC's in the world. And your projectile wasn't homing because you had removed the position of its target from the equation, so that it never knew where to home to. Also, you forgot to check if your 'nearest' NPC was null, which would cause the projectile to disappear. I've fixed your AI for you.
Code:
public override void AI()
{
    NPC nearest = this.FindNearest(projectile.Center);
    Vector2 acceleration;
    if (nearest != null) //this is really important
    {
        acceleration = (nearest.position - projectile.position);
    } else
    {
        acceleration = Vector2.Zero; //maintain speed -- or whatever else you want to do here
    }
    projectile.velocity += acceleration * 1.5f;
    projectile.velocity *= 0.99f;
    if (projectile.velocity.Length() > maxSpeed)
    {
        projectile.velocity.Normalize();
        projectile.velocity *= maxSpeed;
    }
    projectile.rotation = projectile.velocity.ToRotation();
}
Also, it looks like you've been removing my comments from the code. It's a good idea to leave those there so that the code is easier to interpret.
Ok, thanks I got it to work now.
I was even able to make two custom crafting groups.
But how can I give a tile the Ability to work like a Mythril Anvil or an Adamantite Forge?
 
Ok, thanks I got it to work now.
I was even able to make two custom crafting groups.
But how can I give a tile the Ability to work like a Mythril Anvil or an Adamantite Forge?
In the class where is your block just add this line of code in the SetDefults
Code:
adjTiles = new int[] { TileID.Anvils };
you should find both mythril anvil and the forge there.
 
Well first, I found the problem that was causing the slow down. You need to swap the two if conditions inside the findNearest function so that your projectile isn't checking collision with all 200 non-existent NPC's in the world. And your projectile wasn't homing because you had removed the position of its target from the equation, so that it never knew where to home to. Also, you forgot to check if your 'nearest' NPC was null, which would cause the projectile to disappear. I've fixed your AI for you.
Code:
public override void AI()
{
NPC nearest = this.FindNearest(projectile.Center);
Vector2 acceleration;
if (nearest != null) //this is really important
{
acceleration = (nearest.position - projectile.position);
} else
{
acceleration = Vector2.Zero; //maintain speed -- or whatever else you want to do here
}
projectile.velocity += acceleration * 1.5f;
projectile.velocity *= 0.99f;
if (projectile.velocity.Length() > maxSpeed)
{
projectile.velocity.Normalize();
projectile.velocity *= maxSpeed;
}
projectile.rotation = projectile.velocity.ToRotation();
}
Also, it looks like you've been removing my comments from the code. It's a good idea to leave those there so that the code is easier to interpret.

less of a problem now :)

all it does now is go out a small distance and the stops and then homes when there is something to home on.
but it still is stopping when there is nothing to home on.

Code:
public NPC FindNearest(Vector2 pos)
        {
         
            NPC nearest = null;
            float oldDist = 1001;
            float newDist = 1000;
            for (int i = 0; i < Terraria.Main.npc.Length - 1; i++)
            {
                if (!Collision.CanHit(pos, 1, 1, Main.npc[i].position, Main.npc[i].width, Main.npc[i].height))
                    continue;
                if (!Terraria.Main.npc[i].CanBeChasedBy(projectile))
                    continue;
                if (nearest == null)
                    nearest = Terraria.Main.npc[i];
                else
                {
                    oldDist = Vector2.Distance(pos, nearest.position);
                    newDist = Vector2.Distance(pos, Terraria.Main.npc[i].position);
                    if (newDist < oldDist)
                        nearest = Terraria.Main.npc[i];
                }
            }
            return nearest;
        }
        int maxSpeed = 10;
        public override void AI()
        {
            NPC nearest = this.FindNearest(projectile.Center);
            Vector2 acceleration;
            if (nearest != null) // extremely important
            {
                acceleration = (nearest.position - projectile.position);
            } else
            {
                acceleration = Vector2.Zero; // maintain speed -- or whatever else you want to do here
            }
            projectile.velocity += acceleration * 1.5f;
            projectile.velocity *= 0.95f;
            if (projectile.velocity.Length() > maxSpeed)
            {
                projectile.velocity.Normalize();
                projectile.velocity *= maxSpeed;
            }
            projectile.rotation = projectile.velocity.ToRotation();
        }

also, since this homing is almost complete, how might I make an arkhalis type weapon. I have tried, but the projectile for the blade doesn't even show up!

Weapon Code defaults:
Code:
 public override void SetDefaults()
        {
            item.name = "Solarius";
            item.damage = 75;
            item.melee = true;
            item.width = 48;
            item.height = 48;
            item.useTime = 1;
            item.useAnimation = 1;
            item.useStyle = 1;
            item.noMelee = true;
            item.knockBack = 2;
            item.noUseGraphic = true;
            item.channel = true;
            item.value = 100000;
            item.rare = 9;
            item.useSound = 1;
            item.autoReuse = true;
            item.shoot = mod.ProjectileType("SolarisP");
            item.shootSpeed = 20;
        }

Projectile Code defaults:
Code:
public class SolarisP : ModProjectile
    {
        public override void SetDefaults()
        {
            projectile.name = "Solarius";
            projectile.width = 36;
            projectile.height = 20;
            projectile.friendly = true;
            projectile.penetrate = -1;
            projectile.aiStyle = 20;
            projectile.melee = true;
            projectile.tileCollide = false;
            projectile.light = 2f;
        }
the class is shown so you know why the weapon is refering to that name for the projectile.
pls help me
I am so lost :(
 
Last edited:
How would you change the rotation speed of a Yoyo projectile? thanks :)
 
Back
Top Bottom