tAPI tAPI Community Resources - Development assistance for developers, by developers.

What does a DamageNPC hook look like?

public override void DamageNPC(NPC npc, int hitDir, ref int damage, ref float knockback, ref bool crit, ref float critMult)

It's similar to DealtNPC, but is called before the damage actually goes through, so you can use it to modify the damage dealt by the weapon, if it crits or not, etc. Here, you just want to do the same thing as you were doing, except referring to "damage" instead of "dmgDealt." The issue is that you'll have to define "player" since it isn't defined in the hook. Use the line: Player player = Main.player[projectile.owner] before the rest of your code.

An alternative that might work better is to spawn a vampire heal projectile on hit instead of directly giving the player health:

Projectile.NewProjectile(npc.position, new Vector2(0, 0), 305, 0, 0, Main.myPlayer, projectile.owner, (int) (dmgDealt / 8));

This is set up to work with the DealtNPC hook.
 
-get snipped-
With solutions come more problems, it seems.
Code:
public class MProjectile : ModProjectile
    {
        Player player = Main.player[projectile.owner];
        public override void DamageNPC(NPC npc, int hitDir, ref int damage, ref float knockback, ref bool crit, ref float critMult)
        {
            for (int i = 3; i < 8; i++)
            {
                if (player.armor[i].type == ItemDef.byName["Rektmod:VampiricEmblem"].type)
                {
                    player.statLife += (int)(damage / 8);
                }
            }
        }
    }
Right now i have that going on, and the builder says this:
Compiling code...
MProjectile.cs (31,16)
An object reference is required for the non-static field, method, or property 'TAPI.ModProjectile.projectile.get'
Player player = Main.player[projectile.owner];
 
With solutions come more problems, it seems.
Code:
public class MProjectile : ModProjectile
    {
        Player player = Main.player[projectile.owner];
        public override void DamageNPC(NPC npc, int hitDir, ref int damage, ref float knockback, ref bool crit, ref float critMult)
        {
            for (int i = 3; i < 8; i++)
            {
                if (player.armor[i].type == ItemDef.byName["Rektmod:VampiricEmblem"].type)
                {
                    player.statLife += (int)(damage / 8);
                }
            }
        }
    }
Right now i have that going on, and the builder says this:

Try placing the Player definition after the hook, just before the for() loop.
 
How would i implement the same for melee?
It worked, then?

Melee is easier, no need for global mods. Just place the same code in the item's .cs file under this hook:

public override void DamageNPC(Player player, NPC npc, int hitDir, ref int damage, ref float knockback, ref bool crit, ref float critMult)

You don't need the player definition, since it's in the hook.
 
It worked, then?

Melee is easier, no need for global mods. Just place the same code in the item's .cs file under this hook:

public override void DamageNPC(Player player, NPC npc, int hitDir, ref int damage, ref float knockback, ref bool crit, ref float critMult)

You don't need the player definition, since it's in the hook.
One more thing that would be swood would be some green numbers telling you how much health you stole from whatever poor sob you managed to hit.
So is that hard to do?
 
One more thing that would be swood would be some green numbers telling you how much health you stole from whatever poor sob you managed to hit.
So is that hard to do?
Pretty easy, actually.

CombatText.NewText(new Rectangle((int)npc.position.X, (int)npc.position.Y - 75, npc.width, npc.height), new Color(10, 110, 10, 255), "" + ((int)(damage / 8)), false, false);

I don't know the RGB values for the green you want, but you can tweak the first 3 ints in new Color() to find the right balance. Just tack this line on right next to the player.statLife line.
 
So i'm trying to make an accessory that spawns projectiles around you when you get damaged.
Code:
public class MPlayer : ModPlayer
    {   
        public void PostHurt(bool pvp, bool quiet, int hitDirection, string deathText, bool crit, float critMultiplier, ref double parsedDamage)
        {
            for (int i = 3; i < 8; i++)
            {
                if (player.armor[i].type == ItemDef.byName["Rektmod:VengeanceEmblem"].type)
                {
                    Projectile.NewProjectile(projectile.position.X, projectile.position.Y, 0, 0, "Rektmod:AlienBlast", projectile.damage, projectile.knockBack, Main.myPlayer);
                }
            }
        }
    }
And it's giving me this
Validating Jsons...
Compiling code...
MPlayer.cs (15,14)
'Rektmod.MPlayer.PostHurt(bool, bool, int, string, bool, float, ref double)' hides inherited member 'TAPI.ModPlayer.PostHurt(bool, bool, int, string, bool, float, ref double)'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
public void PostHurt(bool pvp, bool quiet, int hitDirection, string deathText, bool crit, float critMultiplier, ref double parsedDamage)
^
MPlayer.cs (31,20)
The name 'projectile' does not exist in the current context
Projectile.NewProjectile(projectile.position.X, projectile.position.Y, 0, 0, "Rektmod:AlienBlast", projectile.damage, projectile.knockBack, Main.myPlayer);
^
MPlayer.cs (54,20)
The name 'projectile' does not exist in the current context
Projectile.NewProjectile(projectile.position.X, projectile.position.Y, 0, 0, "Rektmod:AlienBlast", projectile.damage, projectile.knockBack, Main.myPlayer);
^
MPlayer.cs (105,20)
The name 'projectile' does not exist in the current context
Projectile.NewProjectile(projectile.position.X, projectile.position.Y, 0, 0, "Rektmod:AlienBlast", projectile.damage, projectile.knockBack, Main.myPlayer);
^
MPlayer.cs (124,20)
The name 'projectile' does not exist in the current context
Projectile.NewProjectile(projectile.position.X, projectile.position.Y, 0, 0, "Rektmod:AlienBlast", projectile.damage, projectile.knockBack, Main.myPlayer);
 
Last edited:
So i'm trying to make an accessory that spawns projectiles around you when you get damaged.
Code:
    public override void PostHurt(bool pvp, bool quiet, int hitDirection, string deathText, bool crit, float critMultiplier, ref double parsedDamage)
    {
        for (int i = 3; i < 8; i++)
        {
            if (player.armor[i].type == ItemDef.byName["Rektmod:VengeanceEmblem"].type)
            {
                Projectile.NewProjectile(projectile.position.X, projectile.position.Y, 0, 0, "Rektmod:AlienBlast", projectile.damage, projectile.knockBack, Main.myPlayer);
            }
        }
    }
And it's giving me this

I'm not sure exactly what's happening here - the problems I see in the code are not the ones coming up in the error report, so the builder probably isn't getting past the hook (might be out of date/broken). An alternative to using ModPlayer is to just put the effects into the accessory .cs file under a DealtPlayer hook. As for the issues with your code, the new projectile is trying to reference some other projectile for its position, damage, and knockback, while there is no such projectile to reference. It also has no velocity, which is probably unintended.
 
So i'm trying to make an accessory that spawns projectiles around you when you get damaged.
Code:
public class MPlayer : ModPlayer
    {   
        public void PostHurt(bool pvp, bool quiet, int hitDirection, string deathText, bool crit, float critMultiplier, ref double parsedDamage)
        {
            for (int i = 3; i < 8; i++)
            {
                if (player.armor[i].type == ItemDef.byName["Rektmod:VengeanceEmblem"].type)
                {
                    Projectile.NewProjectile(projectile.position.X, projectile.position.Y, 0, 0, "Rektmod:AlienBlast", projectile.damage, projectile.knockBack, Main.myPlayer);
                }
            }
        }
    }
And it's giving me this
You might need to take a step back from modding for a moment. Try unpacking some of the more popular mods found in the forums and look through the code they use. Try to understand what each line is doing and how it effects things in the game. You also might want to visit some sites that review the basics of C# coding to familiarize yourself with coding. When errors pop up, try searching for the error message using Google.

Your most recent problem looks to be happening because you forgot to use the word 'override' in your method declaration. (Which the first error says, "Otherwise add the new keyword.") And the other errors may be happening because you didn't make your CS class extend the ModProjectile class. That's why it's not finding a variable named 'projectile'.

Edit: Rereading your code looks like you might be reusing projectile code in the ModPlayer class, but need to create the projectile differently in this context. Such as making the spawn position coordinates be based on the players position. (Using player.position.X instead of projectile.position.X)
 
Is it possible to modify the values stored in .json via a .cs file for the same item? I'm looking to mess with autoReuse for a gun that will autofire 6 shots, then flip off autoReuse, forcing you to click again. That next shot turns autoReuse back on, and then you have this new kind of weapon that isn't painful/difficult to use like the Venus Magnum, but isn't quite as mindless as the megashark, and is distinct from burst-fire weapons like the clockwork assault rifle.
 
Is it possible to modify the values stored in .json via a .cs file for the same item? I'm looking to mess with autoReuse for a gun that will autofire 6 shots, then flip off autoReuse, forcing you to click again. That next shot turns autoReuse back on, and then you have this new kind of weapon that isn't painful/difficult to use like the Venus Magnum, but isn't quite as mindless as the megashark, and is distinct from burst-fire weapons like the clockwork assault rifle.
I'm not at a computer right now, but it should be something like -
ItemDef.byName["InternalName:ItemName"].autoReuse = false;
 
I'm not at a computer right now, but it should be something like -
ItemDef.byName["InternalName:ItemName"].autoReuse = false;

It seems weird to have to define the item within its own .cs file, but it compiles fine. I'll test it out in game once all the other assets are done.
 
I think you're right. You might try -
item.autoReuse = false;

Thanks, that compiles fine and looks much less prone to modifying other people's items - if I ever decide to get multiplayer working.

Edit: It works wonderfully. I added an additional 10 frame delay after the last shot via reuseDelay in the same fashion, and the effect is exactly as I imagined.
 
Last edited:
Back
Top Bottom