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

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

namespace KahanMod.NPCs.Bosses
{
    public class Yama : ModNPC
    {
        public override void SetDefaults()
        {
            npc.name = "Yama";
            npc.displayName = "Yama";
            npc.aiStyle = 0;
            npc.lifeMax = 9000; 
            npc.damage = 40;
            npc.defense = 25; 
            npc.knockBackResist = 0f;
            npc.width = 60;
            npc.height = 30;
            animationType = NPCID.BoundGoblin;
            Main.npcFrameCount[npc.type] = 2;  
            npc.value = Item.buyPrice(0, 0, 10, 0);
            npc.npcSlots = 1f;
            npc.boss = true;
            npc.lavaImmune = true;
            npc.noGravity = true;
            npc.noTileCollide = true;
            npc.HitSound = SoundID.NPCHit1;
            npc.DeathSound = SoundID.NPCDeath17;
            npc.buffImmune[24] = false;
            music = MusicID.Boss2;
            npc.netAlways = true;
        }
        public override void AutoloadHead(ref string headTexture, ref string bossHeadTexture)
        {
            bossHeadTexture = "KahanMod/NPCs/Bosses/Yama_Head_Boss";
        }
        public override void BossLoot(ref string name, ref int potionType)
        {
            potionType = ItemID.HealingPotion; 
             if (Main.expertMode)
            {
                Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("YamaTreasureBag"));
            }
            else
          {                          
            int choice = Main.rand.Next(3);
            if (choice == 0)
            {
                  Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("YoyoMold"));
            }
            if (choice == 1)
            {
                 Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("FlailMold"));
            }
            if (choice == 2)
            {
                 Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("KatanaMold"));
            }
            Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("RedFragment"), Main.rand.Next(5, 10));
          }
      
        }
        public override void ScaleExpertStats(int numPlayers, float bossLifeScale)
        {
            npc.lifeMax = (int)(npc.lifeMax * 0.8f * bossLifeScale);
            npc.damage = (int)(npc.damage * 0.6f);
        }
        public override void AI()
        {
         Player player = Main.player[npc.target];
         Vector2 moveTo = player.Center + new Vector2(0f, -200f);
         float speed = 3f;
         Vector2 move = moveTo - npc.Center;
         float magnitude = (float) Math.Sqrt(move.X * move.X + move.Y * move.Y);
         move *= speed / magnitude;
         npc.velocity = move;
      
         if (npc.ai[0] % 600 == 3)
            {
                NPC.NewNPC((int)npc.position.X, (int)npc.position.Y, mod.NPCType("TorturedSoul"));
            }
            npc.ai[1] += 0;
        }
    }
}
Thanks again
 
Ok, so basically, what you are doing is trying to spawn an NPC when the counter divided by 600 gets a remainder of 3. The only problem is that you never set up the counter at all, meaning you can just add "npc.ai[0] += 1" anywhere inside the AI. Instead of checking if the remainder is 3, just switch the 3 to 0. You can remove the "npc.ai[1] += 0" since you never use that counter.
How I can make that he will spawn 5 npc every 20 seconds
 
How I can make that he will spawn 5 npc every 20 seconds
Terraria runs at around 60 ticks per 1 second, meaning you will need to make the counter check if the remainder is 0 when the counter is a multiple of (60 * 20). So it should have a semblance of:

Code:
npc.ai[0] += 1;
if(npc.ai[0] %(60 * 20) == 0)
{
   for(int i = 0; i < 5; i++)
   {
      //NPC spawning code
   }
}
 
Terraria runs at around 60 ticks per 1 second, meaning you will need to make the counter check if the remainder is 0 when the counter is a multiple of (60 * 20). So it should have a semblance of:

Code:
npc.ai[0] += 1;
if(npc.ai[0] %(60 * 20) == 0)
{
   for(int i = 0; i < 5; i++)
   {
      //NPC spawning code
   }
}
Thanks for third time :)
 
Terraria runs at around 60 ticks per 1 second, meaning you will need to make the counter check if the remainder is 0 when the counter is a multiple of (60 * 20). So it should have a semblance of:

Code:
npc.ai[0] += 1;
if(npc.ai[0] %(60 * 20) == 0)
{
   for(int i = 0; i < 5; i++)
   {
      //NPC spawning code
   }
}
and how to make boss spawns 1 npc when at 50% life
 
Am I doing it right?
using System;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;


namespace YourModName.NPCs.Boss
{
public class StormElemental : ModNPC
{
public override void SetDefaults()
{
npc.name = "Storm Elemental";
npc.displayName = "Storm Elemental";
npc.width = 98;
npc.height = 84;
npc.damage = 12;
npc.defense = 5;
npc.lifeMax = 2000;
npc.HitSound = SoundID.NPCHit3;
npc.DeathSound = SoundID.NPCDeath6;
npc.value = 60f;
npc.knockBackResist = 0.9f;
npc.aiStyle = 49;
Main.npcFrameCount[npc.type] = 1;
aiType = NPCID.AngryNimbus; //npc behavior
animationType = NPCID.AngryNimbus;
npc.npcSlots = 1f;
npc.boss = true;
music = MusicID.Boss1;
npc.netAlways = true;
}
public override void FindFrame(int frameHeight)
{
npc.frameCounter -= 0.5F; // Determines the animation speed. Higher value = faster animation.
npc.frameCounter %= Main.npcFrameCount[npc.type];
int frame = (int)npc.frameCounter;
npc.frame.Y = frame * frameHeight;

npc.spriteDirection = npc.direction;

}
public override void AutoloadHead(ref string headTexture, ref string bossHeadTexture)
{
bossHeadTexture = "YourModName/NPCs/Boss/BossName_Head_Boss1"; //the boss head texture
}
public override void BossLoot(ref string name, ref int potionType)
{
potionType = ItemID.LesserHealingPotion; //boss drops
Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("CrabHand"));
}
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] >= 100) // 230 is projectile fire rate
{
float Speed = 15f; //projectile speed
Vector2 vector8 = new Vector2(npc.position.X + (npc.width / 2), npc.position.Y + (npc.height / 2));
int damage = 15; //projectile damage
int type = mod.ProjectileType("Storm"); //put your projectile
Main.PlaySound(25, (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;

npc.ai[1]++;
if (npc.ai[1] >= 50) // 230 is projectile fire rate
{
Projectile.NewProjectile(projectile.position.X, projectile.position.Y, 0, 0, 291, (int) (projectile.damage * 1.5), projectile.knockBack, Main.myPlayer); // 296 is the explosion from the Inferno Fork
}
}
}
}

(it's the last part that I added the counter for)
 
Am I doing it right?
using System;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;


namespace YourModName.NPCs.Boss
{
public class StormElemental : ModNPC
{
public override void SetDefaults()
{
npc.name = "Storm Elemental";
npc.displayName = "Storm Elemental";
npc.width = 98;
npc.height = 84;
npc.damage = 12;
npc.defense = 5;
npc.lifeMax = 2000;
npc.HitSound = SoundID.NPCHit3;
npc.DeathSound = SoundID.NPCDeath6;
npc.value = 60f;
npc.knockBackResist = 0.9f;
npc.aiStyle = 49;
Main.npcFrameCount[npc.type] = 1;
aiType = NPCID.AngryNimbus; //npc behavior
animationType = NPCID.AngryNimbus;
npc.npcSlots = 1f;
npc.boss = true;
music = MusicID.Boss1;
npc.netAlways = true;
}
public override void FindFrame(int frameHeight)
{
npc.frameCounter -= 0.5F; // Determines the animation speed. Higher value = faster animation.
npc.frameCounter %= Main.npcFrameCount[npc.type];
int frame = (int)npc.frameCounter;
npc.frame.Y = frame * frameHeight;

npc.spriteDirection = npc.direction;

}
public override void AutoloadHead(ref string headTexture, ref string bossHeadTexture)
{
bossHeadTexture = "YourModName/NPCs/Boss/BossName_Head_Boss1"; //the boss head texture
}
public override void BossLoot(ref string name, ref int potionType)
{
potionType = ItemID.LesserHealingPotion; //boss drops
Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("CrabHand"));
}
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] >= 100) // 230 is projectile fire rate
{
float Speed = 15f; //projectile speed
Vector2 vector8 = new Vector2(npc.position.X + (npc.width / 2), npc.position.Y + (npc.height / 2));
int damage = 15; //projectile damage
int type = mod.ProjectileType("Storm"); //put your projectile
Main.PlaySound(25, (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;

npc.ai[1]++;
if (npc.ai[1] >= 50) // 230 is projectile fire rate
{
Projectile.NewProjectile(projectile.position.X, projectile.position.Y, 0, 0, 291, (int) (projectile.damage * 1.5), projectile.knockBack, Main.myPlayer); // 296 is the explosion from the Inferno Fork
}
}
}
}

(it's the last part that I added the counter for)
That's not a good idea, it will never get called. Also, the projectile you spawn in the new thing is friendly, so you need to make it hostile.
 
ok so I need the projectile id but what should I position the counter and the projectile? What am I doing wrong?
No need for a new ID, just save the value from Projectile.NewProjectile into an "int", and use the int as an index for "Main.projectiles[index]" and set that to hostile. You only need one counter. You can probably figure out how to use a counter.
 
like this?
Code:
            if (npc.ai[1] >= 50)  // 230 is projectile fire rate
            {
             int Projectile.NewProjectile(projectile.position.X, projectile.position.Y, 0, 0, 291, (int) (projectile.damage * 1.5), projectile.knockBack, Main.myPlayer); // 296 is the explosion from the Inferno Fork
            }
        }
    }
}
 
like this?
Code:
            if (npc.ai[1] >= 50)  // 230 is projectile fire rate
            {
             int Projectile.NewProjectile(projectile.position.X, projectile.position.Y, 0, 0, 291, (int) (projectile.damage * 1.5), projectile.knockBack, Main.myPlayer); // 296 is the explosion from the Inferno Fork
            }
        }
    }
}
So, uhh, just as a recommendation, you should probably look up a coding guide/tutorial. It will benefit you greatly. There are great guides in the Official tModLoader Help Thread.
 
Okay, Am I right?
Code:
          npc.ai[0] += 1;
          if(npc.ai[0] %(60 * 5) == 0)
          {
             for(int i = 0; i < 5; i++)
             {
               
             }
          } 

            int rand = Main.rand.Next(5);
            int num = mod.ProjectileType("Gust"); 
            }
        }
    }
}
 
Or maybe this?
Code:
          npc.ai[0] += 1;
          if (npc.ai[1] >= 100)  // 230 is projectile fire rate
          {
             for(int i = 0; i < 255; i++)
             {
               
             }
          } 

            int rand = Main.rand.Next(5);
            int num = mod.ProjectileType("Gust"); 
            }
        }
    }
}
 
error: in class declaration, structure or member interface exist incorrect token if
Code:
using System;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace KahanMod.NPCs.Bosses
{
    public class Yama : ModNPC
    {
        public override void SetDefaults()
        {
            npc.name = "Yama";
            npc.displayName = "Yama";
            npc.aiStyle = 0; 
            npc.lifeMax = 9000;  
            npc.damage = 40; 
            npc.defense = 25;  
            npc.knockBackResist = 0f;
            npc.width = 60;
            npc.height = 30;
            animationType = NPCID.BoundGoblin; 
            Main.npcFrameCount[npc.type] = 2;   
            npc.value = Item.buyPrice(0, 0, 10, 0);
            npc.npcSlots = 1f;
            npc.boss = true; 
            npc.lavaImmune = true;
            npc.noGravity = true;
            npc.noTileCollide = true;
            npc.HitSound = SoundID.NPCHit1;
            npc.DeathSound = SoundID.NPCDeath17;
            npc.buffImmune[24] = false;
            music = MusicID.Boss2;
            npc.netAlways = true;
        }
        public override void AutoloadHead(ref string headTexture, ref string bossHeadTexture)
        {
            bossHeadTexture = "KahanMod/NPCs/Bosses/Yama_Head_Boss";
        }
        public override void BossLoot(ref string name, ref int potionType)
        {
            potionType = ItemID.HealingPotion;  
             if (Main.expertMode)
            {
                Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("YamaTreasureBag"));
            }
            else
          {                           
            int choice = Main.rand.Next(3);
            if (choice == 0)
            {
                  Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("YoyoMold"));
            }
            if (choice == 1)
            {
                 Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("FlailMold"));
            }
            if (choice == 2)
            {
                 Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("KatanaMold"));
            }
            Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("RedFragment"), Main.rand.Next(5, 10));
          }
       
        }
        public override void ScaleExpertStats(int numPlayers, float bossLifeScale)
        {
            npc.lifeMax = (int)(npc.lifeMax * 0.8f * bossLifeScale); 
            npc.damage = (int)(npc.damage * 0.6f); 
        }
        public override void AI()
        {
         Player player = Main.player[npc.target];
         Vector2 moveTo = player.Center + new Vector2(0f, -200f);
         float speed = 3f;
         Vector2 move = moveTo - npc.Center;
         float magnitude = (float) Math.Sqrt(move.X * move.X + move.Y * move.Y);
         move *= speed / magnitude;
         npc.velocity = move;
       
        npc.ai[0] += 1;
        if(npc.ai[0] %(60 * 10) == 0)
        {
            for(int i = 0; i < 5; i++)
            {

               if (npc.ai[0] % 600 == 0)
        
               {
                 NPC.NewNPC((int)npc.position.X, (int)npc.position.Y, mod.NPCType("TorturedSoul"));  //NPC name
               }

              }
            }
        }
         if (npc.life <= npc.lifeMax * 0.5f)
         {
             for(int i = 0; i < 1; i++)
            {

               if (npc.ai[0] % 600 == 0)
        
               {
                 NPC.NewNPC((int)npc.position.X, (int)npc.position.Y, mod.NPCType("HorseFace"));  //NPC name
               }

              }
            }
         }
    }
}
what I did wrong
 
Back
Top Bottom