tAPI [Tutorial] Custom Bosses - NPC AI and Server Syncing

I should have updated this long ago, but as of r15 of tAPI, the "music" property of NPCs' .json files now works. So you don't need any C# code to make music play anymore.
 
Cool to see the json working without having to throw extra stuffs in the AI.
Any clue whether custom music is supported yet tho?

They Should Add A Json Property For Dust :)
I don't think this is necessary considering all dust act differently based on their parameters, type and the NPC's AI itself. Also the more json properties there are (used and unused properties), the more time it will take for the system to parse them.
 
Cool to see the json working without having to throw extra stuffs in the AI.
Any clue whether custom music is supported yet tho?


I don't think this is necessary considering all dust act differently based on their parameters, type and the NPC's AI itself. Also the more json properties there are (used and unused properties), the more time it will take for the system to parse them.
Looking through the source code, it looks like custom music involves things like a Wavebanks folder, files with a .xsb or .xwb extension, and a Wavebanks/Wavebanks.json file with a "tracks" array that lists custom music. The part with if(text == "Wavebanks.json") seems kind of funny to me though (since text is with the extension removed), so I'm not sure whether or not it works. And this is just the code that loads everything; haven't looked at the part that plays the music yet.
 
I formatted it so its much clearer to see, and here you can see the multitude of problems...
Code:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

using TAPI;
using Terraria;

namespace ZItemsMod.NPCs
{
    public class ElectrumElemental : ModNPC
    {
        public override void HitEffect(int hitDirection, double damage, bool isDead)
        {
            if (Main.netMode != 2)
            {
            for (int m = 0; m < (isDead ? 20 : 5); m++)
            {
            int dustID = Dust.NewDust(npc.position, npc.width, npc.height, 5, npc.velocity.X * 0.2f, npc.velocity.Y * 0.2f, 100, Color.Red, isDead && m % 2 == 0 ? 3f : 1f);
            if (isDead && m % 2 == 0) { Main.dust[dustID].noGravity = true; }
            }
            if (isDead)
            {
            Gore.NewGore(npc.position, npc.velocity, GoreDef.gores["ZItemsMod:ElectrumElemental"], 1f);
            Gore.NewGore(npc.position, npc.velocity, GoreDef.gores["ZItemsMod:ElectrumElemental2"], 1f);
            Gore.NewGore(npc.position, npc.velocity, GoreDef.gores["ZItemsMod:GoresPlate_2"], 1f);
            Gore.NewGore(npc.position, npc.velocity, GoreDef.gores["ZItemsMod:GoresPlate_2"], 1f);
            }
        }
        if (Main.netMode != 1)
        {
            Projectile.NewProjectile(1, 1, 1, 1, 44, 16, 2, Main.myPlayer, 0, 0);
        }
    }
}

That if statement isn't within a function, rather outside into the open sea where it won't be read. I'm guessing that you want your NPC to shoot at the player so you should probably stick it inside the AI() function. Also the parameters for your Projectile production is wrong.

Here's an example of how you do NPC projectiles, the code made by Bluemagic.

Code:
using System;
using Microsoft.Xna.Framework;
using Terraria;
using TAPI;

namespace COFP.NPCs
{
    public class FlyingFrog : ModNPC
    {
        public override void AI()
        {
            Player player = Main.player[npc.target]; //Setting the target
            npc.ai[0] += 2f;
            if (npc.localAI[0] > 0f)
            {
                npc.localAI[0] -= 1f;
            }
           
            //Setting Shoot Vector
            Vector2 center = new Vector2(npc.position.X + (float)npc.width * 0.5f, npc.position.Y + (float)npc.height * 0.5f);
            float shootToX = player.position.X + (float)player.width * 0.5f - center.X;
            float shootToY = player.position.Y - center.Y;
            float distance = (float)System.Math.Sqrt((double)(shootToX * shootToX + shootToY * shootToY));

            //Fire the projectile if the player's distance is less than 480 pixels and if there is nothing blocking the pathway to the player
            if (distance < 480f && Collision.CanHit(npc.position, npc.width, npc.height, player.position, player.width, player.height))
            {
                if (npc.velocity.Y == 0f)
                {
                    npc.velocity.X *= 0.9f;
                }
                if (Main.netMode != 1 && npc.localAI[0] == 0f)
                {
                   //I think this is right, not so certain.
                    distance = 3f / distance;
                    shootToX *= distance * 2;
                    if(shootToY > 0)
                    {
                        shootToY *= (float) distance - 0.25f;
                    }
                    else
                    {
                        shootToY *= (float) distance + 0.25f;
                    }
                    npc.localAI[0] = 30f;
                    Projectile.NewProjectile(center.X, center.Y, shootToX, shootToY, "COFP:NPCInferno", 35, 0f, Main.myPlayer, 0f, 0f);
                }
            }

        }
        public override void SelectFrame(int frameSize)
        {
            Player player = Main.player[npc.target];
            Vector2 center = new Vector2(npc.position.X + (float)npc.width * 0.5f, npc.position.Y + (float)npc.height * 0.5f);
            float shootToX = player.position.X + (float)player.width * 0.5f - center.X;
            float shootToY = player.position.Y - center.Y;
            float distance = (float)System.Math.Sqrt((double)(shootToX * shootToX + shootToY * shootToY));
            npc.spriteDirection = npc.direction;
            npc.rotation = npc.velocity.X * 0.1f;
            npc.frameCounter += 1.0;
            if (distance < 480f && Collision.CanHit(npc.position, npc.width, npc.height, player.position, player.width, player.height))             
            {
                if (npc.frameCounter <= 5)
                {
                    npc.frame.Y = 2 * frameSize;
                }
                else if(npc.frameCounter <= 10)
                {
                    npc.frame.Y = 3 * frameSize;
                }
                else if(npc.frameCounter >= 11)
                {
                    npc.frameCounter = 0;
                }
            }
            else if(npc.velocity.X != 0)
            {
                if (npc.frameCounter < 6.0)
                {
                    npc.frame.Y = 0;
                }
                else
                {
                    npc.frame.Y = frameSize;
                    if (npc.frameCounter >= 11.0)
                    {
                        npc.frameCounter = 0.0;
                    }
                }
            }
        }
    }
}
Man thanks a lot, this helped me so much!
 
Is there any way to make a message than only shows up when the Boss HP gets lower of 50% of it's Max Hp? But only one time
 
And how can i enter a message if the npc hp is under 50% of its max?
Make a global bool stat and set it to false, then in AI, check whether the NPC's life var reaches below maxLife*0.5f AND the bool is set to false, if it proves true, you call Main.NewText and set the bool to true.
 
Make a global bool stat and set it to false, then in AI, check whether the NPC's life var reaches below maxLife*0.5f AND the bool is set to false, if it proves true, you call Main.NewText and set the bool to true.
Well... i'am a little noob on these things... I can't really wonderstand anything without seeing an example of a code...
But thanks anyway
 
Well... i'am a little noob on these things... I can't really wonderstand anything without seeing an example of a code...
But thanks anyway
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using TAPI;

namespace internalName.NPCs
{
    public class npcName : ModNPC
    {
        public bool oneTimeText = false;
        public override void Initialize()
        {
            oneTimeText = false;
        }
        public override void AI()
        {
            if (npc.life <= npc.lifeMax * 0.5f && !oneTimeText)
            {
                Main.NewText("Texty text");
                oneTimeText = true;
            }
        }
    }
}
 
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using TAPI;

namespace internalName.NPCs
{
    public class npcName : ModNPC
    {
        public bool oneTimeText = false;
        public override void Initialize()
        {
            oneTimeText = false;
        }
        public override void AI()
        {
            if (npc.life <= npc.lifeMax * 0.5f && !oneTimeText)
            {
                Main.NewText("Texty text");
                oneTimeText = true;
            }
        }
    }
}
Thanks a lot for this! I don't no how can i tank you...
 
Something bad is going on here...
When i summon my custom Boss the game crashes after deliver him the final blow...
the .cs file of the custom boss:
Code:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

using TAPI;
using Terraria;

namespace ZItemsMod.NPCs
{
    public class Zeromus : ModNPC
    {
        public override void HitEffect(int hitDirection, double damage, bool isDead)
        {
            if (Main.netMode != 2)
            {
                if (isDead)
                {
                    Gore.NewGore(npc.position, npc.velocity, GoreDef.gores["ZItemsMod:Zeromus1"], 1f);
                    Gore.NewGore(npc.position, npc.velocity, GoreDef.gores["ZItemsMod:Zeromus2"], 1f);
                    Gore.NewGore(npc.position, npc.velocity, GoreDef.gores["ZItemsMod:Zeromus3"], 1f);
                    Gore.NewGore(npc.position, npc.velocity, GoreDef.gores["ZItemsMod:Zeromus4"], 1f);
                    Main.NewText(npc.displayName + " was thrown into the rift.");
                }
            }          
        }
        public bool oneTimeText = false;
        public override void Initialize()
        {
            oneTimeText = false;
        }
        public override void AI()
        {
            Player player = Main.player[npc.target];
            npc.ai[0] += 2f;
            if (npc.localAI[0] > 0f)
            {
                npc.localAI[0] -= 1f;
            }

            Vector2 center = new Vector2(npc.position.X + (float)npc.width * 0.5f, npc.position.Y + (float)npc.height * 0.5f);
            float shootToX = player.position.X + (float)player.width * 0.5f - center.X;
            float shootToY = player.position.Y - center.Y;
            float distance = (float)System.Math.Sqrt((double)(shootToX * shootToX + shootToY * shootToY));

            if (distance < 200f && Collision.CanHit(npc.position, npc.width, npc.height, player.position, player.width, player.height))
            {
                if (npc.velocity.Y == 0f)
                {
                    npc.velocity.X *= 0.9f;
                }
                if (Main.netMode != 1 && npc.localAI[0] == 0f)
                {
                    distance = 3f / distance;
                    shootToX *= distance * 2;
                    if(shootToY > 0)
                    {
                        shootToY *= (float) distance - 0.25f;
                    }
                    else
                    {
                        shootToY *= (float) distance + 0.25f;
                    }
                    npc.localAI[0] = 30f;
                    Projectile.NewProjectile(center.X, center.Y, shootToX, shootToY, "ZItemsMod:Flare", 200, 0f, Main.myPlayer, 0f, 0f);
                }
            }
            if (npc.life <= npc.lifeMax * 0.3f && !oneTimeText)
            {
                Main.NewText("Zeromus: I see... I must use my true power from now on!!");
                oneTimeText = true;
                if (distance > 800f)
                {
                    if (npc.velocity.Y == 0f)
                    {
                    npc.velocity.X *= 0.1f;
                    }
                    if (Main.netMode != 1 && npc.localAI[0] == 0f)
                    {
                        distance = 3f / distance;
                        shootToX *= distance * 2;
                        if(shootToY > 0)
                        {
                            shootToY *= (float) distance - 0.25f;
                        }
                        else
                        {
                            shootToY *= (float) distance + 0.25f;
                        }
                        npc.localAI[0] = 30f;
                        Projectile.NewProjectile(center.X, center.Y, shootToX, shootToY, "ZItemsMod:Bigbang", 200, 0f, Main.myPlayer, 0f, 0f);
                    }
                }
            }
        }
        public override void SelectFrame(int frameSize)
        {
            Player player = Main.player[npc.target];
            Vector2 center = new Vector2(npc.position.X + (float)npc.width * 0.5f, npc.position.Y + (float)npc.height * 0.5f);
            float shootToX = player.position.X + (float)player.width * 0.5f - center.X;
            float shootToY = player.position.Y - center.Y;
            float distance = (float)System.Math.Sqrt((double)(shootToX * shootToX + shootToY * shootToY));
            npc.spriteDirection = npc.direction;
            npc.rotation = npc.velocity.X * 0.1f;
            npc.frameCounter += 1.0;
            if (distance < 200f && Collision.CanHit(npc.position, npc.width, npc.height, player.position, player.width, player.height))          
            {
                if (npc.frameCounter <= 5)
                {
                    npc.frame.Y = 2 * frameSize;
                }
                else if(npc.frameCounter <= 10)
                {
                    npc.frame.Y = 3 * frameSize;
                }
                else if(npc.frameCounter >= 11)
                {
                    npc.frameCounter = 0;
                }
            }
            else if(npc.velocity.X != 0)
            {
                if (npc.frameCounter < 6.0)
                {
                    npc.frame.Y = 0;
                }
                else
                {
                    npc.frame.Y = frameSize;
                    if (npc.frameCounter >= 11.0)
                    {
                        npc.frameCounter = 0.0;
                    }
                }
            }
        }
        public override void OnSpawn()
        {
            if(Main.netMode == 0)
            {
                Main.NewText("From the rift, Zeromus have been summoned!");
            }
            else if(Main.netMode == 2)
            {
                NetMessage.SendData(25, -1, -1, "From the rift, Zeromus have been summoned!");
            }
        }
    }
}
Everything is working right (including projectiles, Etc...) What can i do to fix this bug?
 
Something bad is going on here...
When i summon my custom Boss the game crashes after deliver him the final blow...
the .cs file of the custom boss:
Code:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

using TAPI;
using Terraria;

namespace ZItemsMod.NPCs
{
    public class Zeromus : ModNPC
    {
        public override void HitEffect(int hitDirection, double damage, bool isDead)
        {
            if (Main.netMode != 2)
            {
                if (isDead)
                {
                    Gore.NewGore(npc.position, npc.velocity, GoreDef.gores["ZItemsMod:Zeromus1"], 1f);
                    Gore.NewGore(npc.position, npc.velocity, GoreDef.gores["ZItemsMod:Zeromus2"], 1f);
                    Gore.NewGore(npc.position, npc.velocity, GoreDef.gores["ZItemsMod:Zeromus3"], 1f);
                    Gore.NewGore(npc.position, npc.velocity, GoreDef.gores["ZItemsMod:Zeromus4"], 1f);
                    Main.NewText(npc.displayName + " was thrown into the rift.");
                }
            }        
        }
        public bool oneTimeText = false;
        public override void Initialize()
        {
            oneTimeText = false;
        }
        public override void AI()
        {
            Player player = Main.player[npc.target];
            npc.ai[0] += 2f;
            if (npc.localAI[0] > 0f)
            {
                npc.localAI[0] -= 1f;
            }

            Vector2 center = new Vector2(npc.position.X + (float)npc.width * 0.5f, npc.position.Y + (float)npc.height * 0.5f);
            float shootToX = player.position.X + (float)player.width * 0.5f - center.X;
            float shootToY = player.position.Y - center.Y;
            float distance = (float)System.Math.Sqrt((double)(shootToX * shootToX + shootToY * shootToY));

            if (distance < 200f && Collision.CanHit(npc.position, npc.width, npc.height, player.position, player.width, player.height))
            {
                if (npc.velocity.Y == 0f)
                {
                    npc.velocity.X *= 0.9f;
                }
                if (Main.netMode != 1 && npc.localAI[0] == 0f)
                {
                    distance = 3f / distance;
                    shootToX *= distance * 2;
                    if(shootToY > 0)
                    {
                        shootToY *= (float) distance - 0.25f;
                    }
                    else
                    {
                        shootToY *= (float) distance + 0.25f;
                    }
                    npc.localAI[0] = 30f;
                    Projectile.NewProjectile(center.X, center.Y, shootToX, shootToY, "ZItemsMod:Flare", 200, 0f, Main.myPlayer, 0f, 0f);
                }
            }
            if (npc.life <= npc.lifeMax * 0.3f && !oneTimeText)
            {
                Main.NewText("Zeromus: I see... I must use my true power from now on!!");
                oneTimeText = true;
                if (distance > 800f)
                {
                    if (npc.velocity.Y == 0f)
                    {
                    npc.velocity.X *= 0.1f;
                    }
                    if (Main.netMode != 1 && npc.localAI[0] == 0f)
                    {
                        distance = 3f / distance;
                        shootToX *= distance * 2;
                        if(shootToY > 0)
                        {
                            shootToY *= (float) distance - 0.25f;
                        }
                        else
                        {
                            shootToY *= (float) distance + 0.25f;
                        }
                        npc.localAI[0] = 30f;
                        Projectile.NewProjectile(center.X, center.Y, shootToX, shootToY, "ZItemsMod:Bigbang", 200, 0f, Main.myPlayer, 0f, 0f);
                    }
                }
            }
        }
        public override void SelectFrame(int frameSize)
        {
            Player player = Main.player[npc.target];
            Vector2 center = new Vector2(npc.position.X + (float)npc.width * 0.5f, npc.position.Y + (float)npc.height * 0.5f);
            float shootToX = player.position.X + (float)player.width * 0.5f - center.X;
            float shootToY = player.position.Y - center.Y;
            float distance = (float)System.Math.Sqrt((double)(shootToX * shootToX + shootToY * shootToY));
            npc.spriteDirection = npc.direction;
            npc.rotation = npc.velocity.X * 0.1f;
            npc.frameCounter += 1.0;
            if (distance < 200f && Collision.CanHit(npc.position, npc.width, npc.height, player.position, player.width, player.height))        
            {
                if (npc.frameCounter <= 5)
                {
                    npc.frame.Y = 2 * frameSize;
                }
                else if(npc.frameCounter <= 10)
                {
                    npc.frame.Y = 3 * frameSize;
                }
                else if(npc.frameCounter >= 11)
                {
                    npc.frameCounter = 0;
                }
            }
            else if(npc.velocity.X != 0)
            {
                if (npc.frameCounter < 6.0)
                {
                    npc.frame.Y = 0;
                }
                else
                {
                    npc.frame.Y = frameSize;
                    if (npc.frameCounter >= 11.0)
                    {
                        npc.frameCounter = 0.0;
                    }
                }
            }
        }
        public override void OnSpawn()
        {
            if(Main.netMode == 0)
            {
                Main.NewText("From the rift, Zeromus have been summoned!");
            }
            else if(Main.netMode == 2)
            {
                NetMessage.SendData(25, -1, -1, "From the rift, Zeromus have been summoned!");
            }
        }
    }
}
Everything is working right (including projectiles, Etc...) What can i do to fix this bug?
Could I see your .json file for him too?
Also, the error message would be nice, if possible
 
Something bad is going on here...
When i summon my custom Boss the game crashes after deliver him the final blow...
the .cs file of the custom boss:
Code:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

using TAPI;
using Terraria;

namespace ZItemsMod.NPCs
{
    public class Zeromus : ModNPC
    {
        public override void HitEffect(int hitDirection, double damage, bool isDead)
        {
            if (Main.netMode != 2)
            {
                if (isDead)
                {
                    Gore.NewGore(npc.position, npc.velocity, GoreDef.gores["ZItemsMod:Zeromus1"], 1f);
                    Gore.NewGore(npc.position, npc.velocity, GoreDef.gores["ZItemsMod:Zeromus2"], 1f);
                    Gore.NewGore(npc.position, npc.velocity, GoreDef.gores["ZItemsMod:Zeromus3"], 1f);
                    Gore.NewGore(npc.position, npc.velocity, GoreDef.gores["ZItemsMod:Zeromus4"], 1f);
                    Main.NewText(npc.displayName + " was thrown into the rift.");
                }
            }         
        }
        public bool oneTimeText = false;
        public override void Initialize()
        {
            oneTimeText = false;
        }
        public override void AI()
        {
            Player player = Main.player[npc.target];
            npc.ai[0] += 2f;
            if (npc.localAI[0] > 0f)
            {
                npc.localAI[0] -= 1f;
            }

            Vector2 center = new Vector2(npc.position.X + (float)npc.width * 0.5f, npc.position.Y + (float)npc.height * 0.5f);
            float shootToX = player.position.X + (float)player.width * 0.5f - center.X;
            float shootToY = player.position.Y - center.Y;
            float distance = (float)System.Math.Sqrt((double)(shootToX * shootToX + shootToY * shootToY));

            if (distance < 200f && Collision.CanHit(npc.position, npc.width, npc.height, player.position, player.width, player.height))
            {
                if (npc.velocity.Y == 0f)
                {
                    npc.velocity.X *= 0.9f;
                }
                if (Main.netMode != 1 && npc.localAI[0] == 0f)
                {
                    distance = 3f / distance;
                    shootToX *= distance * 2;
                    if(shootToY > 0)
                    {
                        shootToY *= (float) distance - 0.25f;
                    }
                    else
                    {
                        shootToY *= (float) distance + 0.25f;
                    }
                    npc.localAI[0] = 30f;
                    Projectile.NewProjectile(center.X, center.Y, shootToX, shootToY, "ZItemsMod:Flare", 200, 0f, Main.myPlayer, 0f, 0f);
                }
            }
            if (npc.life <= npc.lifeMax * 0.3f && !oneTimeText)
            {
                Main.NewText("Zeromus: I see... I must use my true power from now on!!");
                oneTimeText = true;
                if (distance > 800f)
                {
                    if (npc.velocity.Y == 0f)
                    {
                    npc.velocity.X *= 0.1f;
                    }
                    if (Main.netMode != 1 && npc.localAI[0] == 0f)
                    {
                        distance = 3f / distance;
                        shootToX *= distance * 2;
                        if(shootToY > 0)
                        {
                            shootToY *= (float) distance - 0.25f;
                        }
                        else
                        {
                            shootToY *= (float) distance + 0.25f;
                        }
                        npc.localAI[0] = 30f;
                        Projectile.NewProjectile(center.X, center.Y, shootToX, shootToY, "ZItemsMod:Bigbang", 200, 0f, Main.myPlayer, 0f, 0f);
                    }
                }
            }
        }
        public override void SelectFrame(int frameSize)
        {
            Player player = Main.player[npc.target];
            Vector2 center = new Vector2(npc.position.X + (float)npc.width * 0.5f, npc.position.Y + (float)npc.height * 0.5f);
            float shootToX = player.position.X + (float)player.width * 0.5f - center.X;
            float shootToY = player.position.Y - center.Y;
            float distance = (float)System.Math.Sqrt((double)(shootToX * shootToX + shootToY * shootToY));
            npc.spriteDirection = npc.direction;
            npc.rotation = npc.velocity.X * 0.1f;
            npc.frameCounter += 1.0;
            if (distance < 200f && Collision.CanHit(npc.position, npc.width, npc.height, player.position, player.width, player.height))         
            {
                if (npc.frameCounter <= 5)
                {
                    npc.frame.Y = 2 * frameSize;
                }
                else if(npc.frameCounter <= 10)
                {
                    npc.frame.Y = 3 * frameSize;
                }
                else if(npc.frameCounter >= 11)
                {
                    npc.frameCounter = 0;
                }
            }
            else if(npc.velocity.X != 0)
            {
                if (npc.frameCounter < 6.0)
                {
                    npc.frame.Y = 0;
                }
                else
                {
                    npc.frame.Y = frameSize;
                    if (npc.frameCounter >= 11.0)
                    {
                        npc.frameCounter = 0.0;
                    }
                }
            }
        }
        public override void OnSpawn()
        {
            if(Main.netMode == 0)
            {
                Main.NewText("From the rift, Zeromus have been summoned!");
            }
            else if(Main.netMode == 2)
            {
                NetMessage.SendData(25, -1, -1, "From the rift, Zeromus have been summoned!");
            }
        }
    }
}
Everything is working right (including projectiles, Etc...) What can i do to fix this bug?
If it crashes when it dies, then most likely the problem is with your gores or your drops. It doesn't seem really likely that it's the gores, but an easy way to find out is to comment out the gore part and see if it still crashes. For the drops, I don't see any LootRules, so I assume your using a .json file for them; in which case, like the above person said, we'd also need to see the .json file.
 
I am making a miniboss. It is going to circle around the player and sometimes charge and sometimes shoot a projectile. I think i know how to make it charge and shoot. How am I going to make it circle around the player at a constant distance?
 
I am making a miniboss. It is going to circle around the player and sometimes charge and sometimes shoot a projectile. I think i know how to make it charge and shoot. How am I going to make it circle around the player at a constant distance?
For that, you need to use trigonometry. There will be two factors here: the distance and the angle. So, your friends will be Math.Sin and Math.Cos. Since the distance will be constant, you can just remember that when you type your code. The angle will be changing at a constant rate for the circling, so you will need to store it in the ai array. The code will go something like this:
Code:
float distance = 160f; //change this
int angleSlot = 0; //change this to whatever slot you use in the ai array
float rotateSpeed = 0.01f; //change this
npc.ai[angleSlot] += rotateSpeed;
npc.ai[angleSlot] %= 2f * (float)Math.PI;
float xUnitOffset = (float)Math.Cos(npc.ai[angleSlot]);
float yUnitOffset = (float)Math.Sin(npc.ai[angleSlot]);
Vector2 offset = distance * new Vector2(xUnitOffset, yUnitOffset);
npc.Center = player.Center + offset;
 
If it crashes when it dies, then most likely the problem is with your gores or your drops. It doesn't seem really likely that it's the gores, but an easy way to find out is to comment out the gore part and see if it still crashes. For the drops, I don't see any LootRules, so I assume your using a .json file for them; in which case, like the above person said, we'd also need to see the .json file.
There is the .json of my boss:
Code:
{
    "displayName": "Zeromus",
    "size": [250,200],
    "value": [0,0,500,0],
    "npcSlots": 1,
    "aiStyle": 14,
    "animationType": 252,
    "scale": 1.4,
    "frameCount": 5,
    "lifeMax": 100000,
    "boss": true,
    "defense": 200,
    "damage": 50,
    "soundHit" : 1,
    "soundKilled" : 1,
    "noTileCollide": true,
    "knockbackResist": 0,
    "buffImmunity": [24, 39, 30, 36, 44, 47, 32, 33, 23, 69, 70, 20],
    "noGravity": true,
    "lavaImmune": true,
    "music": "FinalFantasyIVFb",

    "drops": [
        {
            "item": "ZItemsMod:VoidPower",
            "stack": 10,
            "chance": 1
        },
        {
            "item": "ZItemsMod:ZephyrBadge",
            "stack": 1,
            "chance": 1
        }
    ]
}
But i think there's nothing wrong with it...
Also the error message is simply: tAPI has stopped working

Edit: Already solved... I simply deleted the folder "Gores" without even know about it...
 
Last edited:
Hi again, i have a little question... Is it possible to create a boss like a Black hole that makes the player be forced to approach him?
Also how can i make a NPC that won't move?
 
Hi again, i have a little question... Is it possible to create a boss like a Black hole that makes the player be forced to approach him?
Also how can i make a NPC that won't move?
For your Black hole boss, I would try changing the velocity of nearby players to move more towards the NPC. If that doesn't work, then I would try changing their positions instead.
For an NPC that doesn't move... just, keep its velocity at 0 and don't change its position.
 
Back
Top Bottom