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

c:\Users\Computer\Documents\My Games\Terraria\ModLoader\Mod Sources\DipzMOD\NPC\Boss\Boss.cs(4,7) : error CS0246: The type or namespace name 'TAPI' could not be found (are you missing a using directive or an assembly reference?)

c:\Users\Computer\Documents\My Games\Terraria\ModLoader\Mod Sources\DipzMOD\NPC\Boss\Boss.cs(8,26) : error CS0246: The type or namespace name 'ModNPC' could not be found (are you missing a using directive or an assembly reference?)

c:\Users\Computer\Documents\My Games\Terraria\ModLoader\Mod Sources\DipzMOD\NPC\Boss\Boss.cs(50,45) : error CS0118: 'DipzMOD.NPC' is a 'namespace' but is used like a 'type'


What did I do wrong?
 
I've tried using "npc.TargetClosest(true);", but the npc doesn't actually look at the player. Is there something wrong with this or is there some code I'm missing?
If you want to see the full script:
 

Attachments

  • OpticSpirit.cs
    22.9 KB · Views: 308
I've tried using "npc.TargetClosest(true);", but the npc doesn't actually look at the player. Is there something wrong with this or is there some code I'm missing?
If you want to see the full script:
I can't spot anything particularly wrong, but the code is long so I somewhat ignored most of it only focusing on the targeting part.

By "doesn't actually look at the player" do you mean the AI does not target them at all? Or do you mean the NPC's sprite does not face the player or rotate towards it depending on what kind of graphics you're working with.

In the first case, I would suggest to slap down a bunch of NewText printing your targetPosition's coordinates right after a value is assigned to it. So you can be really sure the targeting is working as it should, which would point the problem somewhere else (say, the AI movements for instance).
In the second case, you need to adjust the NPC's sprite to behave the way you want it to behave. I personally do it in the FindFrame hook, unless it has changed in recent ModLoader and I'm an old fart (which I am). Simple examples would include changing npc.rotation to face the targeted player, or flipping the sprite with npc.spriteDirection to face towards the target. This is also where you'd normally code the NPC's animation.
 
I can't spot anything particularly wrong, but the code is long so I somewhat ignored most of it only focusing on the targeting part.

By "doesn't actually look at the player" do you mean the AI does not target them at all? Or do you mean the NPC's sprite does not face the player or rotate towards it depending on what kind of graphics you're working with.

In the first case, I would suggest to slap down a bunch of NewText printing your targetPosition's coordinates right after a value is assigned to it. So you can be really sure the targeting is working as it should, which would point the problem somewhere else (say, the AI movements for instance).
In the second case, you need to adjust the NPC's sprite to behave the way you want it to behave. I personally do it in the FindFrame hook, unless it has changed in recent ModLoader and I'm an old fart (which I am). Simple examples would include changing npc.rotation to face the targeted player, or flipping the sprite with npc.spriteDirection to face towards the target. This is also where you'd normally code the NPC's animation.

The boss actually targets the player and shoots at him properly (not sure how it will react to multiplayer), but it will always face down.
 
does this work for tmodloader
A good chunk of tMod is based off of old tAPI but there's been a bunch of name and format changing. Most of it still holds true but you might need to look around on the tMod documentation/example mod for the correct names of methods and such.
 
A good chunk of tMod is based off of old tAPI but there's been a bunch of name and format changing. Most of it still holds true but you might need to look around on the tMod documentation/example mod for the correct names of methods and such.

Thanks!
 
Im making a mod but stuck on the boss, always getting the same error
c:\Users\user\Documents\My Games\Terraria\ModLoader\Mod Sources\ShaanGuns\NPCs\Jords\BossName.cs(40,30) : error CS0115: 'ShaanGuns.NPCs.Boss.Jords.AutoloadHead(ref string, ref string)': no suitable method found to override


Do you know how to fix it
 
You need a png file named (Boss name)_Head_Boss.png

Otherwise remove the "AutoLoadBossHead" at the top of the cs file.

(The head is the image that appears on the map)
 
Last edited:
Wow, I Really Need Boss Parts, My Mod(Reborn Mod) Have Some Cool Stuff planned, But i Want To Focus In The Basics Frist. :)
 
i dont understand any of this all i need left for my boss is the code but i dont understand how it would go because im new to making mods, help please? it would be great ;)
 
Hey, is there a way to make your bosses dash at your player? I can't find any up-to-date ways to make my boss dash at me. Can anyone help?

Here is the code, if anyone wanted to re-make my situation. Here, my boss only shoots projectiles, and doesn't charge. I know I haven't added the charge code yet, but that's because I don't know how.
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Terraria;
using Terraria.ModLoader;
using Terraria.ID;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace BetterExploringMod.NPCs.Boss
{
    [AutoloadBossHead]
    public class TutorialBoss : ModNPC
    {
        private Player player;
        private float speed;

        public override void SetStaticDefaults()
        {
            DisplayName.SetDefault("Icicle Guardian");
            Main.npcFrameCount[npc.type] = 3;
        }

        public override void SetDefaults()
        {
            npc.aiStyle = -1; // Will not have any AI from any existing AI styles.
            npc.lifeMax = 2500; // The Max HP the boss has on Normal
            npc.damage = 15; // The base damage value the boss has on Normal
            npc.defense = 3; // The base defense on Normal
            npc.knockBackResist = 0f; // No knockback
            npc.width = 100;
            npc.height = 100;
            npc.value = 10000;
            npc.npcSlots = 1f; // The higher the number, the more NPC slots this NPC takes.
            npc.boss = true; // Is a boss
            npc.lavaImmune = true; // Not hurt by lava
            npc.noGravity = true; // Not affected by gravity
            npc.noTileCollide = true; // Will not collide with the tiles.
            npc.HitSound = SoundID.NPCHit4;
            npc.DeathSound = SoundID.NPCDeath1;
            music = mod.GetSoundSlot(SoundType.Music, "Sounds/Music/FrozenEyeMusic");
            bossBag = mod.ItemType("TutorialBossBag"); // Needed for the NPC to drop loot bag.
        }

        public override void ScaleExpertStats(int numPlayers, float bossLifeScale)
        {
            npc.lifeMax = (int)(npc.lifeMax * 0.625f * bossLifeScale);
            npc.damage = (int)(npc.damage * 0.6f);
            npc.defense = (int)(npc.defense + numPlayers);
        }

        public override void AI()
        {
            if(Main.expertMode)
            {
                Target(); // Sets the Player Target

                DespawnHandler(); // Handles if the NPC should despawn.

                Move(new Vector2(-(Main.rand.Next(299)), -300f)); // Calls the Move Method
                                                                //Attacking
                npc.ai[1] -= 1f; // Subtracts 1 from the ai.
                if (npc.ai[1] == 0f)
                {
                    Shoot();
                }
                if (npc.ai[1] == -15f)
                {
                    Shoot();
                }
                if (npc.ai[1] == -30f)
                {
                    Shoot();
                }
                if (npc.ai[1] == -45f)
                {
                    Shoot();
                }
                if (npc.ai[1] == -60f)
                {
                    Shoot();
                    npc.ai[1] = 180f;
                }
            }
            else
            {
                Target(); // Sets the Player Target

                DespawnHandler(); // Handles if the NPC should despawn.

                Move(new Vector2((Main.rand.Next(299)), -300f)); // Calls the Move Method
                                                                //Attacking
                npc.ai[1] -= 1f; // Subtracts 1 from the ai.
                if (npc.ai[1] == 0f)
                {
                    Shoot();
                }
                if (npc.ai[1] == -15f)
                {
                    Shoot();
                }
                if (npc.ai[1] == -30f)
                {
                    Shoot();
                    npc.ai[1] = 300f;
                }
            }
        }
        private void Target()
        {
            player = Main.player[npc.target]; // This will get the player target.
        }

        private void Move(Vector2 offset)
        {
            speed = 5f; // Sets the max speed of the npc.
            Vector2 moveTo = player.Center + offset; // Gets the point that the npc will be moving to.
            Vector2 move = moveTo - npc.Center;
            float magnitude = Magnitude(move);
            if(magnitude > speed)
            {
                move *= speed / magnitude;
            }
            float turnResistance = 60f; // The larget the number the slower the npc will turn.
            move = (npc.velocity * turnResistance + move) / (turnResistance + 1f);
            magnitude = Magnitude(move);
            if(magnitude > speed)
            {
                move *= speed / magnitude;
            }
            npc.velocity = move;
        }
        private void DespawnHandler()
        {
            if(!player.active || player.dead)
            {
                npc.TargetClosest(false);
                player = Main.player[npc.target];
                if(!player.active || player.dead)
                {
                    npc.velocity = new Vector2(0f, -10f);
                    if(npc.timeLeft > 10)
                    {
                        npc.timeLeft = 10;
                    }
                    return;
                }
            }
        }

        private void Shoot()
        {
            int type = mod.ProjectileType("PearlwoodsBane");
            Vector2 velocity = player.Center - npc.Center; // Get the distance between target and npc.
            float magnitude = Magnitude(velocity);
            if(magnitude > 0) {
                velocity *= 5f / magnitude;
            } else
            {
                velocity = new Vector2(0f, 5f);
            }
            Projectile.NewProjectile(npc.Center, velocity, type, npc.damage, 2f);
        }

        private float Magnitude(Vector2 mag)
        {
            return (float)Math.Sqrt(mag.X * mag.X + mag.Y * mag.Y);
        }

        public override void FindFrame(int frameHeight)
        {
            npc.frameCounter += 1;
            npc.frameCounter %= 20;
            int frame = (int)(npc.frameCounter / 2.0);
            if (frame >= Main.npcFrameCount[npc.type]) frame = 0;
            npc.frame.Y = frame * frameHeight;

            RotateNPCToTarget();
        }

        private void RotateNPCToTarget()
        {
            if (player == null) return;
            Vector2 direction = npc.Center - player.Center;
            float rotation = (float)Math.Atan2(direction.Y, direction.X);
            npc.rotation = rotation + ((float)Math.PI * 0.5f);
        }
        public override void NPCLoot()
        {
            if (Main.expertMode)
            {
                npc.DropBossBags();
            } else
            {
                if (Main.rand.Next(3) == 0) // For items that you want to have a chance to drop
                {
                    Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, ItemID.SuspiciousLookingEye);
                }
                Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("Starpowder"), (Main.rand.Next(3))); // For Items that you want to always drop
            }
        }

        public override bool? DrawHealthBar(byte hbPosition, ref float scale, ref Vector2 position)
        {
            scale = 1.5f;
            return null;
        }
        
    }
}
 
Back
Top Bottom