Standalone [1.3] tModLoader - A Modding API

Hi @bluemagic123, I think I've found a bug, but I'm not sure. I was using the globalNPC hook CanBeHitByProjectile, and found that it wasn't being called in the way I'd expect. It sounds like it should only be called when a projectile hits a NPC, but when I used it, it was being called every frame. I just thought I'd see what's up with that. Thanks.

Edit: Also, is there a way to add a custom field to each vanilla NPC? I tried putting one in globalNPC, but there's only one instance of that for all NPCs.
 
Last edited:
could someone help me?? for some reason my NPC wont spawn and when i spawned him in using the HERO mod and gave him a home, he despawned after relogging.

heres da code:

Code:
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
namespace SacredTools.NPCs
{
    public class PandolarTrader : ModNPC
    {
        public override bool Autoload(ref string name, ref string texture)
        {
            name = "PandolarTrader";
            return mod.Properties.Autoload;
        }
        public override void SetDefaults()
        {
            npc.name = "Pandolar Trader";
            npc.townNPC = true;
            npc.friendly = true;
            npc.width = 18;
            npc.height = 40;
            npc.aiStyle = 7;
            npc.damage = 30;
            npc.defense = 50;
            npc.lifeMax = 500;
            npc.soundHit = 1;
            npc.soundKilled = 1;
            npc.knockBackResist = 0.5f;
            Main.npcFrameCount[npc.type] = 25;           
            animationType = NPCID.Guide;
        }
        public override bool CanTownNPCSpawn(int numTownNPCs, int money)
        {
          
            return false;// this make that he will spawn when a house is available
        }
        public override string TownNPCName()
        {                                       //NPC names
            switch (WorldGen.genRand.Next(4))
            {
                case 0:
                    return "Mural";
                case 1:
                    return "Reggie";
                case 2:
                    return "Waglington";
                default:
                    return "Tucker";
            }
        }
        public override string GetChat()
        {                                           //npc chat
        
            switch (Main.rand.Next(10))
            {
                case 0:
                    return "its a beautiful day outside...";
                case 1:
                    return "all hail Pandolar.";
                case 2:
                    return "you got some spare ice blocks maybe?? its really hot right now.";
                case 3:
                    return "my old home looked way better than this";
                case 4:
                    return "sometimes i think about licking ice cubes...";
                case 5:
                    return "you wanna buy something??";
                case 6:
                    return "you want something??";
                case 7:
                    return "my race was very powerful a long time ago, but now we are almost extinct";
                case 8:
                    return "Eseduh ohuht edahyay emecuh elyay eruhahl ah es et";
                default:
                    return "sup scrub";
            }
        }
        public override void SetChatButtons(ref string button, ref string button2)
        {
            button = Lang.inter[28];
        }
        public override void OnChatButtonClicked(bool firstButton, ref bool shop)
        {
            if (firstButton)
            {
                shop = true;
            }
        }
        public override void SetupShop(Chest shop, ref int nextSlot)
        {
            shop.item[nextSlot].SetDefaults(mod.ItemType("PandolarBow")); //items that he sells
            nextSlot++;
            shop.item[nextSlot].SetDefaults(mod.ItemType("Pandolance"));
            nextSlot++;
            shop.item[nextSlot].SetDefaults (ItemID.Snowball);
            nextSlot++;
        }
    }
}




and another question: how can i make him use a special weapon and make him drop it when he dies??
 
i cant load my self-made mod because of an error:

An unexpected error has occurred.
at Microsoft.Xna.Framework.Graphics.Texture2D..ctor(GraphicsDevice graphicsDevice, Stream stream, Int32 width, Int32 height, XnaImageOperation operation)
at Terraria.ModLoader.Mod.Autoload()
at Terraria.ModLoader.ModLoader.do_Load(Object threadContext)

can someone help me?
 
Hi @bluemagic123, I think I've found a bug, but I'm not sure. I was using the globalNPC hook CanBeHitByProjectile, and found that it wasn't being called in the way I'd expect. It sounds like it should only be called when a projectile hits a NPC, but when I used it, it was being called every frame. I just thought I'd see what's up with that. Thanks.

Edit: Also, is there a way to add a custom field to each vanilla NPC? I tried putting one in globalNPC, but there's only one instance of that for all NPCs.
You have to use NPCInfo for that (on the tML wiki it's called "EntityInfo").
 
please i need help, my Town NPC wont spawn naturally and he despawns when i relog, also i want to make an enemy that spawns ONLY on hardmode in the underworld
 
please i need help, my Town NPC wont spawn naturally and he despawns when i relog, also i want to make an enemy that spawns ONLY on hardmode in the underworld
ExampleMod have all example ^^'. I have use ExampleMod, and my town NPC is 100% functionnal.

For the ennemy, go look examplemod, it have many example after, you need just check if this is a world on hardmode or not.
 
i made my NPC based on that one, i have almost all the same code, but he wont spawn and he keeps despawning, heres the code:
Code:
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
namespace SacredTools.NPCs
{
    public class PandolarTrader : ModNPC
    {
        public override bool Autoload(ref string name, ref string texture)
        {
            name = "PandolarTrader";
            return mod.Properties.Autoload;
        }
        public override void SetDefaults()
        {
            npc.name = "Pandolar Trader";
            npc.townNPC = true;
            npc.friendly = true;
            npc.width = 18;
            npc.height = 40;
            npc.aiStyle = 7;
            npc.damage = 30;
            npc.defense = 50;
            npc.lifeMax = 500;
            npc.soundHit = 1;
            npc.soundKilled = 1;
            npc.knockBackResist = 0.5f;
            Main.npcFrameCount[npc.type] = 25;           
            animationType = NPCID.Guide;
        }
        public override bool CanTownNPCSpawn(int numTownNPCs, int money)
        {
          
            return false;// this make that he will spawn when a house is available
        }
        public override string TownNPCName()
        {                                       //NPC names
            switch (WorldGen.genRand.Next(4))
            {
                case 0:
                    return "Mural";
                case 1:
                    return "Reggie";
                case 2:
                    return "Waglington";
                default:
                    return "Tucker";
            }
        }
        public override string GetChat()
        {                                           //npc chat
        
            switch (Main.rand.Next(10))
            {
                case 0:
                    return "its a beautiful day outside...";
                case 1:
                    return "all hail Pandolar.";
                case 2:
                    return "you got some spare ice blocks maybe?? its really hot right now.";
                case 3:
                    return "my old home looked way better than this";
                case 4:
                    return "sometimes i think about licking ice cubes...";
                case 5:
                    return "you wanna buy something??";
                case 6:
                    return "you want something??";
                case 7:
                    return "my race was very powerful a long time ago, but now we are almost extinct";
                case 8:
                    return "Eseduh ohuht edahyay emecuh elyay eruhahl ah es et";
                default:
                    return "sup scrub";
            }
        }
        public override void SetChatButtons(ref string button, ref string button2)
        {
            button = Lang.inter[28];
        }
        public override void OnChatButtonClicked(bool firstButton, ref bool shop)
        {
            if (firstButton)
            {
                shop = true;
            }
        }
        public override void SetupShop(Chest shop, ref int nextSlot)
        {
            shop.item[nextSlot].SetDefaults(mod.ItemType("PandolarBow")); //items that he sells
            nextSlot++;
            shop.item[nextSlot].SetDefaults(mod.ItemType("Pandolance"));
            nextSlot++;
            shop.item[nextSlot].SetDefaults (ItemID.Snowball);
            nextSlot++;
        }
       
        public override void TownNPCAttackStrength(ref int damage, ref float knockback)
        {
            damage = 20;
            knockback = 4f;
        }

        public override void TownNPCAttackCooldown(ref int cooldown, ref int randExtraCooldown)
        {
            cooldown = 30;
            randExtraCooldown = 30;
        }

        public override void TownNPCAttackProj(ref int projType, ref int attackDelay)
        {
            projType = mod.ProjectileType("FrostBeamProjectile");
            attackDelay = 1;
        }

        public override void TownNPCAttackProjSpeed(ref float multiplier, ref float gravityCorrection, ref float randomOffset)
        {
            multiplier = 12f;
            randomOffset = 2f;
        }
    }
}
 
You have forgot check others files... for spawn a town NPC, you need also go to ExampleWorld. Yes, you do not search good ^^.
 
Hi @bluemagic123, I think I've found a bug, but I'm not sure. I was using the globalNPC hook CanBeHitByProjectile, and found that it wasn't being called in the way I'd expect. It sounds like it should only be called when a projectile hits a NPC, but when I used it, it was being called every frame. I just thought I'd see what's up with that. Thanks.

Edit: Also, is there a way to add a custom field to each vanilla NPC? I tried putting one in globalNPC, but there's only one instance of that for all NPCs.
It looks like the CanHit checks occur before the collision checks for projectiles against NPCs.

could someone help me?? for some reason my NPC wont spawn and when i spawned him in using the HERO mod and gave him a home, he despawned after relogging.

heres da code:

Code:
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
namespace SacredTools.NPCs
{
    public class PandolarTrader : ModNPC
    {
        public override bool Autoload(ref string name, ref string texture)
        {
            name = "PandolarTrader";
            return mod.Properties.Autoload;
        }
        public override void SetDefaults()
        {
            npc.name = "Pandolar Trader";
            npc.townNPC = true;
            npc.friendly = true;
            npc.width = 18;
            npc.height = 40;
            npc.aiStyle = 7;
            npc.damage = 30;
            npc.defense = 50;
            npc.lifeMax = 500;
            npc.soundHit = 1;
            npc.soundKilled = 1;
            npc.knockBackResist = 0.5f;
            Main.npcFrameCount[npc.type] = 25;          
            animationType = NPCID.Guide;
        }
        public override bool CanTownNPCSpawn(int numTownNPCs, int money)
        {
         
            return false;// this make that he will spawn when a house is available
        }
        public override string TownNPCName()
        {                                       //NPC names
            switch (WorldGen.genRand.Next(4))
            {
                case 0:
                    return "Mural";
                case 1:
                    return "Reggie";
                case 2:
                    return "Waglington";
                default:
                    return "Tucker";
            }
        }
        public override string GetChat()
        {                                           //npc chat
       
            switch (Main.rand.Next(10))
            {
                case 0:
                    return "its a beautiful day outside...";
                case 1:
                    return "all hail Pandolar.";
                case 2:
                    return "you got some spare ice blocks maybe?? its really hot right now.";
                case 3:
                    return "my old home looked way better than this";
                case 4:
                    return "sometimes i think about licking ice cubes...";
                case 5:
                    return "you wanna buy something??";
                case 6:
                    return "you want something??";
                case 7:
                    return "my race was very powerful a long time ago, but now we are almost extinct";
                case 8:
                    return "Eseduh ohuht edahyay emecuh elyay eruhahl ah es et";
                default:
                    return "sup scrub";
            }
        }
        public override void SetChatButtons(ref string button, ref string button2)
        {
            button = Lang.inter[28];
        }
        public override void OnChatButtonClicked(bool firstButton, ref bool shop)
        {
            if (firstButton)
            {
                shop = true;
            }
        }
        public override void SetupShop(Chest shop, ref int nextSlot)
        {
            shop.item[nextSlot].SetDefaults(mod.ItemType("PandolarBow")); //items that he sells
            nextSlot++;
            shop.item[nextSlot].SetDefaults(mod.ItemType("Pandolance"));
            nextSlot++;
            shop.item[nextSlot].SetDefaults (ItemID.Snowball);
            nextSlot++;
        }
    }
}




and another question: how can i make him use a special weapon and make him drop it when he dies??
The internal name and npc.name need to be the same.
 
hey blue, could you pls add me on skype?? i have some questions to ask, and to ask here will take long for someone to answer and, well.. u created the Tmodloader ^-^

my name is daniel_bossert_001
 
i need help again... ._.
for some reason my boss vanishes as soon as you hit him, if u dont attack, he will stay there.

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

namespace SacredTools.NPCs.Boss
{
    public class ShadowWrath : ModNPC
    {
        public override void SetDefaults()
        {
            npc.name = "ShadowWrath";
            npc.displayName = " Erazor the Shadow Wrath";
            npc.aiStyle = 5;  //5 is the flying AI
            npc.lifeMax = 80000;   //boss life
            npc.damage = 50;  //boss damage
            npc.defense = 42;    //boss defense
            npc.knockBackResist = 100f;
            npc.width = 100;
            npc.height = 100;
            animationType = NPCID.DemonEye;   //this boss will behavior like the DemonEye
            Main.npcFrameCount[npc.type] = 2;    //boss frame/animation
            npc.value = Item.buyPrice(0, 40, 75, 45);
            npc.npcSlots = 1f;
            npc.boss = true;
            npc.lavaImmune = true;
            npc.noGravity = true;
            npc.noTileCollide = true;
            npc.soundHit = 8;
            npc.soundKilled = 14;
            npc.buffImmune[24] = true;
            music = MusicID.Boss4;
            npc.netAlways = true;
        }
        public override void AutoloadHead(ref string headTexture, ref string bossHeadTexture)
        {
            bossHeadTexture = "SacredTools/NPCs/Boss/ShadowWrath_Head_Boss"; //the boss head texture
        }
        public override void BossLoot(ref string name, ref int potionType)
        {
            potionType = ItemID.GreaterHealingPotion;   //boss drops
            Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("TrueOblivionBar"), 30);
        }
        public override void ScaleExpertStats(int numPlayers, float bossLifeScale)
        {
            npc.lifeMax = (int)(npc.lifeMax * 0.579f * bossLifeScale);  //boss life scale in expertmode
            npc.damage = (int)(npc.damage * 0.6f);  //boss damage increase in expermode
        }
        public override void AI()
        {
            npc.ai[0]++;
            Player P = Main.player[npc.target];
            if (npc.target < 0 || npc.target == 255 || Main.player[npc.target].dead || !Main.player[npc.target].active)
            {
                npc.TargetClosest(true);
            }
            npc.netUpdate = true;

            npc.ai[1]++;
            if (npc.ai[1] >= 230)  // 230 is projectile fire rate
            {
                float Speed = 20f;  //projectile speed
                Vector2 vector8 = new Vector2(npc.position.X + (npc.width / 2), npc.position.Y + (npc.height / 2));
                int damage = 10;  //projectile damage
                int type = mod.ProjectileType("WrathSpell");  //put your projectile
                Main.PlaySound(21, (int)npc.position.X, (int)npc.position.Y, 17);
                float rotation = (float)Math.Atan2(vector8.Y - (P.position.Y + (P.height * 0.5f)), vector8.X - (P.position.X + (P.width * 0.5f)));
                int num54 = Projectile.NewProjectile(vector8.X, vector8.Y, (float)((Math.Cos(rotation) * Speed) * -1), (float)((Math.Sin(rotation) * Speed) * -1), type, damage, 0f, 0);
                npc.ai[1] = 0;
            }
        }
    }
}
 
ok, i did some more testing and i found out that magic weapons wont cause this effect. anyone got an idea why this happens??
[doublepost=1468111049,1468110898][/doublepost]here is the new code:

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

namespace SacredTools.NPCs.Boss
{
    public class ShadowWrath : ModNPC
    {
        public override void SetDefaults()
        {
            npc.name = "ShadowWrath";
            npc.displayName = "Dan Yami";
            npc.aiStyle = 5;  //5 is the flying AI
            npc.lifeMax = 80000;   //boss life
            npc.damage = 70;  //boss damage
            npc.defense = 42;    //boss defense
            npc.knockBackResist = 100f;
            npc.width = 100;
            npc.height = 100;
            animationType = NPCID.Wraith;   //this boss will behavior like the DemonEye
            Main.npcFrameCount[npc.type] = 4;    //boss frame/animation
            npc.value = Item.buyPrice(0, 40, 75, 45);
            npc.npcSlots = 1f;
            npc.boss = true;
            npc.lavaImmune = true;
            npc.noGravity = true;
            npc.noTileCollide = true;
            npc.soundHit = 8;
            npc.soundKilled = 14;
            npc.buffImmune[24] = true;
            music = MusicID.Boss4;
            npc.netAlways = true;
        }
        public override void AutoloadHead(ref string headTexture, ref string bossHeadTexture)
        {
            bossHeadTexture = "SacredTools/NPCs/Boss/ShadowWrath_Head_Boss"; //the boss head texture
        }
        public override void BossLoot(ref string name, ref int potionType)
        {
            potionType = ItemID.GreaterHealingPotion;   //boss drops
            Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("TrueOblivionBar"), 30);
        }
        public override void ScaleExpertStats(int numPlayers, float bossLifeScale)
        {
            npc.lifeMax = (int)(npc.lifeMax * 0.579f * bossLifeScale);  //boss life scale in expertmode
            npc.damage = (int)(npc.damage * 0.6f);  //boss damage increase in expermode
        }
        public override void AI()
        {
            npc.ai[0]++;
            Player P = Main.player[npc.target];
            if (npc.target < 0 || npc.target == 255 || Main.player[npc.target].dead || !Main.player[npc.target].active)
            {
                npc.TargetClosest(true);
            }
            npc.netUpdate = true;

            npc.ai[1]++;
            if (npc.ai[1] >= 230)  // 230 is projectile fire rate
            {
                float Speed = 20f;  //projectile speed
                Vector2 vector8 = new Vector2(npc.position.X + (npc.width / 2), npc.position.Y + (npc.height / 2));
                int damage = 80;  //projectile damage
                int type = mod.ProjectileType("WrathSpell");  //put your projectile
                Main.PlaySound(21, (int)npc.position.X, (int)npc.position.Y, 17);
                float rotation = (float)Math.Atan2(vector8.Y - (P.position.Y + (P.height * 0.5f)), vector8.X - (P.position.X + (P.width * 0.5f)));
                int num54 = Projectile.NewProjectile(vector8.X, vector8.Y, (float)((Math.Cos(rotation) * Speed) * -1), (float)((Math.Sin(rotation) * Speed) * -1), type, damage, 0f, 0);
                npc.ai[1] = 0;
            }
        }
       
       
       
       
    }
}
[doublepost=1468111207][/doublepost]and how do i make him display dust without being hit, just by itself (like the Skeleton Mages, they have these cool particle things on them)
 
well, after even more testing...

i now know...

that he can only be attacked using the Nebula Blaze.

halp me pleasseee
 
Back
Top Bottom