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

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.
Tanks... So you'll try to help me on the Black hole boss?
P.S. Your mod is great!
 
I have some questions... (2)
1.How can i make a boss take no damage if a certain npc is active?
2.How can i make a npc like a worm?
1. There are two ways you can do this. The first way will make no damage numbers appear at all, and the second way will make a bunch of 0's appear but is more risky depending on what other mods do.
For the first method, you'll have to override the ModPlayer class, then override CanHitNPC(NPC npc) and CanHitNPC(Projectile projectile, NPC npc). The two methods would go something like this:
Code:
public override bool? CanHitNPC(NPC npc)
{
    if(npc.type == /*Insert your boss's type here*/)
    {
        bool flag = true;
        for(int k = 0; k < 200; k++)
        {
            if(Main.npc[k].active && Main.npc[k].type == /*Insert the type you're looking for here*/)
            {
                flag = false;
                break;
            }
        }
        if(!flag)
        {
            return false;
        }
    }
    return null;
}

public override bool? CanHitNPC(Projectile projectile, NPC npc)
{
    if(npc.type == /*Insert your boss's type here*/)
    {
        return CanHitNPC(npc);
    }
    return null;
}
For the second (riskier) method, you'll add some method overrides to your ModNPC class instead. Specifically, DamageNPC(Player player, int hitDir, ref int damage, ref float knockback, ref bool crit, ref float critMult) and DamageNPC(Projectile projectile, int hitDir, ref int damage, ref float knockback, ref bool crit, ref float critMult). That will go something like this:
Code:
public override void DamageNPC(Player player, int hitDir, ref int damage, ref float knockback, ref bool crit, ref float critMult)
{
    for(int k = 0; k < 200; k++)
    {
        if(Main.npc[k].active && Main.npc[k].type == /*Insert the type you're looking for here*/)
        {
            damage = 1;
            crit = true;
            critMult = 0f;
            return;
        }
    }
}

public override void DamageNPC(Projectile projectile, int hitDir, ref int damage, ref float knockback, ref bool crit, ref float critMult)
{
    DamageNPC(Main.player[projectile.owner], hitDir, ref damage, ref knockback, ref crit, ref critMult);
}

2. I haven't actually done this myself yet, so I have no idea :p
However, I would assume that first you need to make 3 different NPCs (for the head, body parts, and tail), then copy/paste a bunch of vanilla code and replace the IDs with your own.
 
1. There are two ways you can do this. The first way will make no damage numbers appear at all, and the second way will make a bunch of 0's appear but is more risky depending on what other mods do.
For the first method, you'll have to override the ModPlayer class, then override CanHitNPC(NPC npc) and CanHitNPC(Projectile projectile, NPC npc). The two methods would go something like this:
Code:
public override bool? CanHitNPC(NPC npc)
{
    if(npc.type == /*Insert your boss's type here*/)
    {
        bool flag = true;
        for(int k = 0; k < 200; k++)
        {
            if(Main.npc[k].active && Main.npc[k].type == /*Insert the type you're looking for here*/)
            {
                flag = false;
                break;
            }
        }
        if(!flag)
        {
            return false;
        }
    }
    return null;
}

public override bool? CanHitNPC(Projectile projectile, NPC npc)
{
    if(npc.type == /*Insert your boss's type here*/)
    {
        return CanHitNPC(npc);
    }
    return null;
}
For the second (riskier) method, you'll add some method overrides to your ModNPC class instead. Specifically, DamageNPC(Player player, int hitDir, ref int damage, ref float knockback, ref bool crit, ref float critMult) and DamageNPC(Projectile projectile, int hitDir, ref int damage, ref float knockback, ref bool crit, ref float critMult). That will go something like this:
Code:
public override void DamageNPC(Player player, int hitDir, ref int damage, ref float knockback, ref bool crit, ref float critMult)
{
    for(int k = 0; k < 200; k++)
    {
        if(Main.npc[k].active && Main.npc[k].type == /*Insert the type you're looking for here*/)
        {
            damage = 1;
            crit = true;
            critMult = 0f;
            return;
        }
    }
}

public override void DamageNPC(Projectile projectile, int hitDir, ref int damage, ref float knockback, ref bool crit, ref float critMult)
{
    DamageNPC(Main.player[projectile.owner], hitDir, ref damage, ref knockback, ref crit, ref critMult);
}

2. I haven't actually done this myself yet, so I have no idea :p
However, I would assume that first you need to make 3 different NPCs (for the head, body parts, and tail), then copy/paste a bunch of vanilla code and replace the IDs with your own.
Can you give me an example of what "/*Insert the type you're looking for here*/" is?
 
Making a worm is tricky. You need to link each specific part by AI, assigning each NPC's ID to a specific ai var for the previous npc in the "tail", all the NPCs also must have the worm AI for it to work. The game will not spawn them all by default, so you need to either spawn em all and link em in the first AI cycle or in the spawn code.
 
Is there any way to make a Tmod loader version of this? Because I dont know any simple stuff, like what method, and how to activate the hook.
 
Is there any way to make a Tmod loader version of this? Because I dont know any simple stuff, like what method, and how to activate the hook.
The procedures by themselves should be roughly the same, tmodloader was built in tAPI's image, if anything you might run into slightly differently structured .cs files, renamed methods and a few missing features (such as multiplayer syncing which might be lacking as servers are currently not supported, specifically the ModNet class, but the vanilla methods should otherwise still work even tho proper syncing might take a tad bit more effort). Lack of multiplayer sync aside, it's nothing landing an eye on the documentation/example mod/other mods cannot fix.
 
The procedures by themselves should be roughly the same, tmodloader was built in tAPI's image, if anything you might run into slightly differently structured .cs files, renamed methods and a few missing features (such as multiplayer syncing which might be lacking as servers are currently not supported, specifically the ModNet class, but the vanilla methods should otherwise still work even tho proper syncing might take a tad bit more effort). Lack of multiplayer sync aside, it's nothing landing an eye on the documentation/example mod/other mods cannot fix.
The main issue is that I have NO IDEA where to put the ai, since I only ever used custom AI from copy pasting from someone else.
 
The main issue is that I have NO IDEA where to put the ai, since I only ever used custom AI from copy pasting from someone else.
This is the most bare-bone custom AI boss .cs I can think of.
Code:
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace ExampleMod.NPCs
{
    //ported from my tAPI mod because I'm lazy
    public class TestNPC : ModNPC
    {
        public override void SetDefaults()
        {
            npc.displayName = "Test NPC";
            npc.aiStyle = -1;
            npc.lifeMax = 1000;
            npc.damage = 10;
            npc.defense = 10;
            npc.knockBackResist = 0f; //Immune to knockback
            npc.width = 20;
            npc.height = 20;
            Main.npcFrameCount[npc.type] = 3; //Change to number of images in the sprite
            npc.value = Item.buyPrice(0, 2, 0, 0);
            npc.boss = true;
            npc.lavaImmune = true;
            npc.noGravity = true;
            npc.noTileCollide = true;
            npc.soundHit = 1;
            npc.soundKilled = 1;
            music = MusicID.Boss2;
        }

        public override void AI()
        {
            //AI stuffs
        }
    }
}
Don't forget to change the namespace to your mod's internal name.
 
This is the most bare-bone custom AI boss .cs I can think of.
Code:
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace ExampleMod.NPCs
{
    //ported from my tAPI mod because I'm lazy
    public class TestNPC : ModNPC
    {
        public override void SetDefaults()
        {
            npc.displayName = "Test NPC";
            npc.aiStyle = -1;
            npc.lifeMax = 1000;
            npc.damage = 10;
            npc.defense = 10;
            npc.knockBackResist = 0f; //Immune to knockback
            npc.width = 20;
            npc.height = 20;
            Main.npcFrameCount[npc.type] = 3; //Change to number of images in the sprite
            npc.value = Item.buyPrice(0, 2, 0, 0);
            npc.boss = true;
            npc.lavaImmune = true;
            npc.noGravity = true;
            npc.noTileCollide = true;
            npc.soundHit = 1;
            npc.soundKilled = 1;
            music = MusicID.Boss2;
        }

        public override void AI()
        {
            //AI stuffs
        }
    }
}
Don't forget to change the namespace to your mod's internal name.
Thanks.
[DOUBLEPOST=1453823124,1453822782][/DOUBLEPOST]
Code:
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace Enderuim.NPCs
{
    //ported from my tAPI mod because I'm lazy
    public class Codex : ModNPC
    {
        public override void SetDefaults()
        {
            npc.displayName = "Phantom Codex";
            npc.aiStyle = -1;
            npc.lifeMax = 1000;
            npc.damage = 10;
            npc.defense = 10;
            npc.knockBackResist = 0f; //Immune to knockback
            npc.width = 20;
            npc.height = 20;
            Main.npcFrameCount[npc.type] = 4; //Change to number of images in the sprite
            npc.value = Item.buyPrice(0, 2, 0, 0);
            npc.boss = true;
            npc.lavaImmune = true;
            npc.noGravity = true;
            npc.noTileCollide = true;
            npc.soundHit = 1;
            npc.soundKilled = 1;
            music = MusicID.Boss2;
        }

        public override void AI()
        {
            npc.TargetClosest(faceTarget);
            Player player = Main.player[npc.target];
        }
    }
}
Why doesnt this simple crap not work
 
Thanks.
[DOUBLEPOST=1453823124,1453822782][/DOUBLEPOST]
Code:
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace Enderuim.NPCs
{
    //ported from my tAPI mod because I'm lazy
    public class Codex : ModNPC
    {
        public override void SetDefaults()
        {
            npc.displayName = "Phantom Codex";
            npc.aiStyle = -1;
            npc.lifeMax = 1000;
            npc.damage = 10;
            npc.defense = 10;
            npc.knockBackResist = 0f; //Immune to knockback
            npc.width = 20;
            npc.height = 20;
            Main.npcFrameCount[npc.type] = 4; //Change to number of images in the sprite
            npc.value = Item.buyPrice(0, 2, 0, 0);
            npc.boss = true;
            npc.lavaImmune = true;
            npc.noGravity = true;
            npc.noTileCollide = true;
            npc.soundHit = 1;
            npc.soundKilled = 1;
            music = MusicID.Boss2;
        }

        public override void AI()
        {
            npc.TargetClosest(faceTarget);
            Player player = Main.player[npc.target];
        }
    }
}
Why doesnt this simple crap not work
You know, just saying it doesn't work doesn't really help anybody understand the problem, so you should include what you find wrong with it, the behavior of the object, etc. So what is wrong with it?
 
You know, just saying it doesn't work doesn't really help anybody understand the problem, so you should include what you find wrong with it, the behavior of the object, etc. So what is wrong with it?
Error log:
c:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\Items\CircutBoard.cs(26,45) : error CS1002: ; expected

c:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\NPCs\Codex.cs(35,22) : error CS0103: The name 'faceTarget' does not exist in the current context
 
Error log:
c:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\Items\CircutBoard.cs(26,45) : error CS1002: ; expected

c:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\NPCs\Codex.cs(35,22) : error CS0103: The name 'faceTarget' does not exist in the current context
Ok, what it is trying to tell you for your NPC one is that there is no decleration of a variable called "faceTarget". How to fix is that what's supposed to be in there is a variable of type boolean, meaning either true or false. So all you have to say is whether you want the npc to target closest, true being yes and false being no. Make sure to put it in the parenthesis. I can't really help you with your first error, since this thread is about npcs and you didn't post anything about it.
 
Ok, what it is trying to tell you for your NPC one is that there is no decleration of a variable called "faceTarget". How to fix is that what's supposed to be in there is a variable of type boolean, meaning either true or false. So all you have to say is whether you want the npc to target closest, true being yes and false being no. Make sure to put it in the parenthesis. I can't really help you with your first error, since this thread is about npcs and you didn't post anything about it.
So what do I type? I'm confused
 
Thanks. Im probaly gonna need alot more help later so...
[DOUBLEPOST=1453827720,1453827452][/DOUBLEPOST]crap,,, another error
Code:
    using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace Enderuim.NPCs
{
    //ported from my tAPI mod because I'm lazy
    public class Codex : ModNPC
    {
        public override void SetDefaults()
        {
            npc.displayName = "Phantom Codex";
            npc.aiStyle = -1;
            npc.lifeMax = 1000;
            npc.damage = 10;
            npc.defense = 10;
            npc.knockBackResist = 0f; //Immune to knockback
            npc.width = 20;
            npc.height = 20;
            Main.npcFrameCount[npc.type] = 4; //Change to number of images in the sprite
            npc.value = Item.buyPrice(0, 2, 0, 0);
            npc.boss = true;
            npc.lavaImmune = true;
            npc.noGravity = true;
            npc.noTileCollide = true;
            npc.soundHit = 1;
            npc.soundKilled = 1;
            music = MusicID.Boss2;
        }

        public override void AI()
        {
            npc.TargetClosest(true);
            Player player = Main.player[npc.target];
            Vector2 moveTo = player.Center + new Vector2(0f, -200f);
            float speed = 5f; //make this whatever you want
            Vector2 move = moveTo - npc.Center; //this is how much your boss wants to move
            float magnitude = Math.Sqrt(move.X * move.X + move.Y * move.Y); //fun with the Pythagorean Theorem
            move *= speed / magnitude; //this adjusts your boss's speed so that its speed is always constant
            npc.velocity = move;
        }
    }
}
:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\NPCs\Codex.cs(40,19) : error CS0266: Cannot implicitly convert type 'double' to 'float'. An explicit conversion exists (are you missing a cast?)
 
Back
Top Bottom