Standalone [1.3] tModLoader - A Modding API

My guess would be to just make the setDefaults() [Set the minion stuff and the frames, set aiStyle to the slime ai]. Then after that just implement OnHitNPC() method to the thing with the debuff and that should handle it.

i want to make an enemy that acts like a salamander. any advice on how to make it shoot stuff?
This may be some old code, but it may be useful. This code was put on an NPC that is set to another aiStyle that did not fire. I borrowed some of the code from Bluemagic's original mod on tAPI, but I can try to explain it to you.

Code:
        public override void AI()
        {
            //Code for targeting players and make AI flying around
            Player player = Main.player[npc.target];
            npc.TargetClosest(true);
            npc.noGravity = true;
           
            if (npc.localAI[0] > 0f) //Yeah just counter stuff for next attack, countdown to 0, which is when it will spawn the projectile
            {
                npc.localAI[0] -= 1f;
            }

            //Targetting!
            Vector2 center = new Vector2(npc.position.X + (float)npc.width * 0.5f, npc.position.Y + (float)npc.height * 0.5f); //Getting the position of where to shoot
            float shootToX = player.position.X + (float)player.width * 0.5f - center.X; //x distance to shoot
            float shootToY = player.position.Y - center.Y; //y distance to shoot
            float distance = (float)System.Math.Sqrt((double)(shootToX * shootToX + shootToY * shootToY)); //actually distance in terms of both x and y

            //Checks if the distance is less than the range indicated (480f) and if whether it is able to hit the player
            if (distance < 480f && Collision.CanHit(npc.position, npc.width, npc.height, player.position, player.width, player.height))
            {
                //This chunk of code was just to make the npc to stop moving don't worry about this
                npc.velocity.X = 0f; 
                npc.velocity.Y = 0f;

                //Allowing the npc to shoot whenever the counter is 0, you can ignore the netMode thing, that's only for client/server relations
                if (Main.netMode != 1 && npc.localAI[0] == 0f)
                {
                    distance = 3f / distance; //
                    shootToX *= distance * 2; //Velocity X
                    shootToY *= distance * 2; //Velocity Y
                    npc.localAI[0] = 60f; //Set counter back to a second
                    int ProjID = Projectile.NewProjectile(center.X, center.Y, shootToX, shootToY, 14, 40, 0f, Main.myPlayer, 0f, 0f); //spawning the projectile
                    
                    //Overriding the projectile's defaults to make it not friendly and make it hostile, since 14 is bullet projectile
                    Main.projectile[ProjID].friendly = false;
                    Main.projectile[ProjID].hostile = true;
                }
            }
        }
 
My guess would be to just make the setDefaults() [Set the minion stuff and the frames, set aiStyle to the slime ai]. Then after that just implement OnHitNPC() method to the thing with the debuff and that should handle it.

This is what I use:
Code:
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace TrueEternity.Items.Weapons.Summon
{
    class FleshBabySlime : ModProjectile
    {
        public virtual void SetDefaults()
        {
            projectile.CloneDefaults(ProjectileID.BabySlime);
            projectile.name = "Flesh Baby Slime";
            projectile.width = 12;
            projectile.height = 12;
            projectile.friendly = true;
            projectile.minion = true;
            aiType = ProjectileID.BabySlime;
            Main.projFrames[projectile.type] = 6;
        }

        public virtual void OnHitNPC(NPC target, int damage, float knockback, bool crit)
        {
            target.AddBuff(24, 5);
        }
    }
}

And it doesn't work. :(
 
Can you please tell me how to edit AI to shoot stuff? I want this mob to shoot 2 different projectiles (Fairly fast) AngelicOrb and AngelicShard
[DOUBLEPOST=1453493567,1453493546][/DOUBLEPOST]
Code:
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using System;

namespace Enderuim.NPCs
{
    public class Angelic : ModNPC
    {
        public override void SetDefaults()
        {
            npc.name = "AngelicBeing";
            npc.displayName = "Angelic Being";
            npc.width = 250;
            npc.height = 208;
            npc.damage = 120;
            npc.defense = 20;
            npc.lifeMax = 30000;
            npc.soundHit = 1;
            npc.soundKilled = 2;
            npc.value = 60f;
            npc.knockBackResist = 0f;
        }
                                            public override bool PreAI()
{
    npc.noGravity = true;
    // The following handles the collision: 
 
    npc.TargetClosest(true);
   
    float num1 = 4f;
    float num2 = 1.5f;
    float num3 = num1 * (float) (1.0 + (1.0 - (double) npc.scale));
    float num4 = num2 * (float) (1.0 + (1.0 - (double) npc.scale));
    if (npc.direction == -1 && (double) npc.velocity.X > -(double) num3)
    {
        npc.velocity.X = npc.velocity.X - 0.1f;
        if ((double) npc.velocity.X > (double) num3)
            npc.velocity.X = npc.velocity.X - 0.1f;
        else if ((double) npc.velocity.X > 0.0)
            npc.velocity.X = npc.velocity.X + 0.05f;
        if ((double) npc.velocity.X < -(double) num3)
         npc.velocity.X = -num3;
    }
    else if (npc.direction == 1 && (double) npc.velocity.X < (double) num3)
    {
        npc.velocity.X = npc.velocity.X + 0.1f;
        if ((double) npc.velocity.X < -(double) num3)
            npc.velocity.X = npc.velocity.X + 0.1f;
        else if ((double) npc.velocity.X < 0.0)
            npc.velocity.X = npc.velocity.X - 0.05f;
        if ((double) npc.velocity.X > (double) num3)
            npc.velocity.X = num3;
    }
    if (npc.directionY == -1 && (double) npc.velocity.Y > -(double) num4)
    {
        npc.velocity.Y = npc.velocity.Y - 0.04f;
        if ((double) npc.velocity.Y > (double) num4)
            npc.velocity.Y = npc.velocity.Y - 0.05f;
        else if ((double) npc.velocity.Y > 0.0)
            npc.velocity.Y = npc.velocity.Y + 0.03f;
        if ((double) npc.velocity.Y < -(double) num4)
            npc.velocity.Y = -num4;
    }
    else if (npc.directionY == 1 && (double) npc.velocity.Y < (double) num4)
    {
        npc.velocity.Y = npc.velocity.Y + 0.04f;
        if ((double) npc.velocity.Y < -(double) num4)
            npc.velocity.Y = npc.velocity.Y + 0.05f;
        else if ((double) npc.velocity.Y < 0.0)
            npc.velocity.Y = npc.velocity.Y - 0.03f;
        if ((double) npc.velocity.Y > (double) num4)
            npc.velocity.Y = num4;
    }
 
    if(!npc.wet)
        return false;
 
    if ((double) npc.velocity.Y > 0.0)
        npc.velocity.Y = npc.velocity.Y * 0.95f;
    npc.velocity.Y = npc.velocity.Y - 0.5f;
    if ((double) npc.velocity.Y < -4.0)
        npc.velocity.Y = -4f;
    npc.TargetClosest(true);
 
    return false;
}
        public override void NPCLoot()
        {   
            Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("ShatteredHalo"));
        }
    }
}
 
This is what I use:
Code:
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace TrueEternity.Items.Weapons.Summon
{
    class FleshBabySlime : ModProjectile
    {
        public virtual void SetDefaults()
        {
            projectile.CloneDefaults(ProjectileID.BabySlime);
            projectile.name = "Flesh Baby Slime";
            projectile.width = 12;
            projectile.height = 12;
            projectile.friendly = true;
            projectile.minion = true;
            aiType = ProjectileID.BabySlime;
            Main.projFrames[projectile.type] = 6;
        }

        public virtual void OnHitNPC(NPC target, int damage, float knockback, bool crit)
        {
            target.AddBuff(24, 5);
        }
    }
}

And it doesn't work. :(
Can you explain what and how it doesn't work? Also I'm curious about the placement of your slime projectile in your source.

Edit: I don't know if you need to anymore but try switching "virtual" to "override".
 
Last edited:
It'd help if you can show us the error?

Chances are, it's the same error I was recieving on Linux. If this is the case, it proves that not only does tmodloader not work with Linux, but with any Unix machines. But, I can't know unless he posts logs.

If anybody has any issues with linux/mac and mods not loading, please post logs and mention that you are on Unix.
 
Chances are, it's the same error I was recieving on Linux. If this is the case, it proves that not only does tmodloader not work with Linux, but with any Unix machines. But, I can't know unless he posts logs.

If anybody has any issues with linux/mac and mods not loading, please post logs and mention that you are on Unix.
It's not that tModLoader doesn't work, it's that music doesn't work.

Is everyone ignoring me? I asked this question about 5 times and only got one answer.
What's stopping you from calling Projectile.NewProjectile as usual?
 
Could you just edit my code and put the new projectile in there? its a AngelicOrb and AngelicBolt
Code:
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using System;

namespace Enderuim.NPCs
{
    public class Angelic : ModNPC
    {
        public override void SetDefaults()
        {
            npc.name = "AngelicBeing";
            npc.displayName = "Angelic Being";
            npc.width = 250;
            npc.height = 208;
            npc.damage = 120;
            npc.defense = 20;
            npc.lifeMax = 30000;
            npc.soundHit = 1;
            npc.soundKilled = 2;
            npc.value = 60f;
            npc.knockBackResist = 0f;
        }
                                            public override bool PreAI()
{
    npc.noGravity = true;
    // The following handles the collision: 
 
    npc.TargetClosest(true);
   
    float num1 = 4f;
    float num2 = 1.5f;
    float num3 = num1 * (float) (1.0 + (1.0 - (double) npc.scale));
    float num4 = num2 * (float) (1.0 + (1.0 - (double) npc.scale));
    if (npc.direction == -1 && (double) npc.velocity.X > -(double) num3)
    {
        npc.velocity.X = npc.velocity.X - 0.1f;
        if ((double) npc.velocity.X > (double) num3)
            npc.velocity.X = npc.velocity.X - 0.1f;
        else if ((double) npc.velocity.X > 0.0)
            npc.velocity.X = npc.velocity.X + 0.05f;
        if ((double) npc.velocity.X < -(double) num3)
         npc.velocity.X = -num3;
    }
    else if (npc.direction == 1 && (double) npc.velocity.X < (double) num3)
    {
        npc.velocity.X = npc.velocity.X + 0.1f;
        if ((double) npc.velocity.X < -(double) num3)
            npc.velocity.X = npc.velocity.X + 0.1f;
        else if ((double) npc.velocity.X < 0.0)
            npc.velocity.X = npc.velocity.X - 0.05f;
        if ((double) npc.velocity.X > (double) num3)
            npc.velocity.X = num3;
    }
    if (npc.directionY == -1 && (double) npc.velocity.Y > -(double) num4)
    {
        npc.velocity.Y = npc.velocity.Y - 0.04f;
        if ((double) npc.velocity.Y > (double) num4)
            npc.velocity.Y = npc.velocity.Y - 0.05f;
        else if ((double) npc.velocity.Y > 0.0)
            npc.velocity.Y = npc.velocity.Y + 0.03f;
        if ((double) npc.velocity.Y < -(double) num4)
            npc.velocity.Y = -num4;
    }
    else if (npc.directionY == 1 && (double) npc.velocity.Y < (double) num4)
    {
        npc.velocity.Y = npc.velocity.Y + 0.04f;
        if ((double) npc.velocity.Y < -(double) num4)
            npc.velocity.Y = npc.velocity.Y + 0.05f;
        else if ((double) npc.velocity.Y < 0.0)
            npc.velocity.Y = npc.velocity.Y - 0.03f;
        if ((double) npc.velocity.Y > (double) num4)
            npc.velocity.Y = num4;
    }
 
    if(!npc.wet)
        return false;
 
    if ((double) npc.velocity.Y > 0.0)
        npc.velocity.Y = npc.velocity.Y * 0.95f;
    npc.velocity.Y = npc.velocity.Y - 0.5f;
    if ((double) npc.velocity.Y < -4.0)
        npc.velocity.Y = -4f;
    npc.TargetClosest(true);
 
    return false;
}
        public override void NPCLoot()
        {   
            Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("ShatteredHalo"));
        }
    }
}
 
So now let me throw the spear problem away 'cause I have some ambitious ideas.
I dunno whether they're practicable, but important to me anyway.
1. How can I change the contents of chests generated along with the world?
I mean changing the nature-generated chests. I guess this will compel me to engage with the world generation, which I got totally no idea.
2. Will there be able to modify the price rate?
Sell rate more aptly. Vanilla game holds a rate of 20%. Anything you buy with 100 ends up selling 20, no exception. I want to change certain item's price. For instance, it will need 200 to buy, but when you sell it still get 20.
 
Could you just edit my code and put the new projectile in there? its a AngelicOrb and AngelicBolt

It's hard find motivation to answer a question when it seems like you want us to code for you rather than you asking questions to help yourself understand how to code up the functionality you want.......but, I'll show you this on the condition that you read through it and understand what it does.

(Haven't tested, but the syntax is correct. Place after FindTarget.)
Code:
            npc.ai[0]++;
            if (npc.ai[0] > 80)
            {
                if (npc.HasValidTarget && Main.player[npc.target].Distance(npc.Center) < 500f)
                {
                    Vector2 direction = Main.player[npc.target].Center - npc.Center;
                    direction.Normalize();
                    if (Main.rand.Next(2) == 0)
                    {
                        Projectile.NewProjectile(npc.Center.X, npc.Center.Y, direction.X * 5f, direction.Y * 5f, mod.ProjectileType("AngelicOrb"), 10, 1, Main.myPlayer, 0, 0);
                    }
                    else
                    {
                        Projectile.NewProjectile(npc.Center.X, npc.Center.Y, direction.X * 5f, direction.Y * 5f, mod.ProjectileType("AngelicBolt"), 10, 1, Main.myPlayer, 0, 0);
                    }
                    npc.ai[0] = 0;
                }
            }
[DOUBLEPOST=1453508418,1453508284][/DOUBLEPOST]
So now let me throw the spear problem away 'cause I have some ambitious ideas.
I dunno whether they're practicable, but important to me anyway.
1. How can I change the contents of chests generated along with the world?
I mean changing the nature-generated chests. I guess this will compel me to engage with the world generation, which I got totally no idea.
2. Will there be able to modify the price rate?
Sell rate more aptly. Vanilla game holds a rate of 20%. Anything you buy with 100 ends up selling 20, no exception. I want to change certain item's price. For instance, it will need 200 to buy, but when you sell it still get 20.
1. Next update will have access to this.
2. No.
[DOUBLEPOST=1453508446][/DOUBLEPOST]
How do I get rid of my minion when I right click the buff?
If you follow ExampleMod, it should work.
 
It's hard find motivation to answer a question when it seems like you want us to code for you rather than you asking questions to help yourself understand how to code up the functionality you want.......but, I'll show you this on the condition that you read through it and understand what it does.

(Haven't tested, but the syntax is correct. Place after FindTarget.)
Code:
            npc.ai[0]++;
            if (npc.ai[0] > 80)
            {
                if (npc.HasValidTarget && Main.player[npc.target].Distance(npc.Center) < 500f)
                {
                    Vector2 direction = Main.player[npc.target].Center - npc.Center;
                    direction.Normalize();
                    if (Main.rand.Next(2) == 0)
                    {
                        Projectile.NewProjectile(npc.Center.X, npc.Center.Y, direction.X * 5f, direction.Y * 5f, mod.ProjectileType("AngelicOrb"), 10, 1, Main.myPlayer, 0, 0);
                    }
                    else
                    {
                        Projectile.NewProjectile(npc.Center.X, npc.Center.Y, direction.X * 5f, direction.Y * 5f, mod.ProjectileType("AngelicBolt"), 10, 1, Main.myPlayer, 0, 0);
                    }
                    npc.ai[0] = 0;
                }
            }
[DOUBLEPOST=1453508418,1453508284][/DOUBLEPOST]
1. Next update will have access to this.
2. No.
[DOUBLEPOST=1453508446][/DOUBLEPOST]
If you follow ExampleMod, it should work.
sorry to annoy but i cannot seem to find FindTarget
 
1. Next update will have access to this.
2. No.
Well, that's quiet disappointing.
Now you are here, I got to ask about that projectile problem - how to make a projectile spin?
More specifically, it will whirl while it flies, since most of the projectiles are dead, they won't spin, so is default one.
 
Im sorry for being a pain in the arse, but it isnt working. Truly sorry.
Code:
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using System;

namespace Enderuim.NPCs
{
    public class Angelic : ModNPC
    {
        public override void SetDefaults()
        {
            npc.name = "AngelicBeing";
            npc.displayName = "Angelic Being";
            npc.width = 250;
            npc.height = 208;
            npc.damage = 120;
            npc.defense = 20;
            npc.lifeMax = 30000;
            npc.soundHit = 1;
            npc.soundKilled = 2;
            npc.value = 60f;
            npc.knockBackResist = 0f;
        }
                                            public override bool PreAI()
{
    npc.noGravity = true;
    // The following handles the collision: 
 
    npc.TargetClosest(true);
   
    float num1 = 4f;
    float num2 = 1.5f;
    float num3 = num1 * (float) (1.0 + (1.0 - (double) npc.scale));
    float num4 = num2 * (float) (1.0 + (1.0 - (double) npc.scale));
    if (npc.direction == -1 && (double) npc.velocity.X > -(double) num3)
    {
        npc.velocity.X = npc.velocity.X - 0.1f;
        if ((double) npc.velocity.X > (double) num3)
            npc.velocity.X = npc.velocity.X - 0.1f;
        else if ((double) npc.velocity.X > 0.0)
            npc.velocity.X = npc.velocity.X + 0.05f;
        if ((double) npc.velocity.X < -(double) num3)
         npc.velocity.X = -num3;
    }
    else if (npc.direction == 1 && (double) npc.velocity.X < (double) num3)
    {
        npc.velocity.X = npc.velocity.X + 0.1f;
        if ((double) npc.velocity.X < -(double) num3)
            npc.velocity.X = npc.velocity.X + 0.1f;
        else if ((double) npc.velocity.X < 0.0)
            npc.velocity.X = npc.velocity.X - 0.05f;
        if ((double) npc.velocity.X > (double) num3)
            npc.velocity.X = num3;
    }
    if (npc.directionY == -1 && (double) npc.velocity.Y > -(double) num4)
    {
        npc.velocity.Y = npc.velocity.Y - 0.04f;
        if ((double) npc.velocity.Y > (double) num4)
            npc.velocity.Y = npc.velocity.Y - 0.05f;
        else if ((double) npc.velocity.Y > 0.0)
            npc.velocity.Y = npc.velocity.Y + 0.03f;
        if ((double) npc.velocity.Y < -(double) num4)
            npc.velocity.Y = -num4;
    }
    else if (npc.directionY == 1 && (double) npc.velocity.Y < (double) num4)
    {
        npc.velocity.Y = npc.velocity.Y + 0.04f;
        if ((double) npc.velocity.Y < -(double) num4)
            npc.velocity.Y = npc.velocity.Y + 0.05f;
        else if ((double) npc.velocity.Y < 0.0)
            npc.velocity.Y = npc.velocity.Y - 0.03f;
        if ((double) npc.velocity.Y > (double) num4)
            npc.velocity.Y = num4;
    }
 
    if(!npc.wet)
        return false;
 
    if ((double) npc.velocity.Y > 0.0)
        npc.velocity.Y = npc.velocity.Y * 0.95f;
    npc.velocity.Y = npc.velocity.Y - 0.5f;
    if ((double) npc.velocity.Y < -4.0)
        npc.velocity.Y = -4f;
    npc.TargetClosest(true);
    npc.ai[0]++;
            if (npc.ai[0] > 80)
            {
                if (npc.HasValidTarget && Main.player[npc.target].Distance(npc.Center) < 500f)
                {
                    Vector2 direction = Main.player[npc.target].Center - npc.Center;
                    direction.Normalize();
                    if (Main.rand.Next(2) == 0)
                    {
                        Projectile.NewProjectile(npc.Center.X, npc.Center.Y, direction.X * 5f, direction.Y * 5f, mod.ProjectileType("AngelicOrb"), 10, 1, Main.myPlayer, 0, 0);
                    }
                    else
                    {
                        Projectile.NewProjectile(npc.Center.X, npc.Center.Y, direction.X * 5f, direction.Y * 5f, mod.ProjectileType("AngelicBolt"), 10, 1, Main.myPlayer, 0, 0);
                    }
                    npc.ai[0] = 0;
                }
            }
 
    return false;
}
        public override void NPCLoot()
        {   
            Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("ShatteredHalo"));
        }
    }
}
 
Here is what I have for the minion
public override void CheckActive()
{
Player player = Main.player[projectile.owner];
EnergyPlayer modPlayer = (EnergyPlayer)player.GetModPlayer(mod, "EnergyPlayer");
if (player.dead)
{
modPlayer.vampireMinion = false;
}
if (modPlayer.vampireMinion)
{
projectile.timeLeft = 2;
public override void Update(Player player, ref int buffIndex)
{
EnergyPlayer modPlayer = (EnergyPlayer)player.GetModPlayer(mod, "EnergyPlayer");
if (player.ownedProjectileCounts[mod.ProjectileType("VampireSlime")] > 0)
{
modPlayer.vampireMinion = true;
}
if (!modPlayer.vampireMinion)
{
player.DelBuff(buffIndex);
buffIndex--;
}
else
{
player.buffTime[buffIndex] = 18000;
}
}
It does kill the minions when I die.
 
Back
Top Bottom