tModLoader Official tModLoader Help Thread

When I borrowed from ExampleDualUseWeapon, I just wanted it to play a sound on right click. To that end, I found everything from line 68 on to be unnecessary. If you look then, I think your second "return" value might need to be changed.

Also, in my use of it, that line still has "override" instead of "virtual", and works like a charm.
 
Okay... I've been beating my head against this for a day and a half. I've been searching ExampleMod, decompiled Terraria code, stepping through the Terraria-Specific C# Crash Course trying to get a handle on how this works, trying all manner of ideas based on what I've seen, and nothing.

The idea is simple: In my mod's GlobalNPC, I need resetEffects to call the npc's npc.damage from Terraria.NPC. Then, when the npc is affected by my debuff, I want to set npc.damage = 0. HOWEVER, when the debuff wears off and it comes back around to ResetEffects, I need npc.damage to recall its value from Terraria.NPC and return to normal.

I can set npc.damage to 0, but that npc's damage remains 0 when the debuff wears off. I have the logic worked out, but I apparently just suck at syntax and don't know how to get this to work. It's my last hurdle to a silly themed weapon that has already taught me a LOT. Any input would be appreciated.
 
Okay... I've been beating my head against this for a day and a half. I've been searching ExampleMod, decompiled Terraria code, stepping through the Terraria-Specific C# Crash Course trying to get a handle on how this works, trying all manner of ideas based on what I've seen, and nothing.

The idea is simple: In my mod's GlobalNPC, I need resetEffects to call the npc's npc.damage from Terraria.NPC. Then, when the npc is affected by my debuff, I want to set npc.damage = 0. HOWEVER, when the debuff wears off and it comes back around to ResetEffects, I need npc.damage to recall its value from Terraria.NPC and return to normal.

I can set npc.damage to 0, but that npc's damage remains 0 when the debuff wears off. I have the logic worked out, but I apparently just suck at syntax and don't know how to get this to work. It's my last hurdle to a silly themed weapon that has already taught me a LOT. Any input would be appreciated.
hmm, maybe when you are applying debuff, you should save the damagr that the npc has, and after it wears off return the value to it? i dont really know, just a poor theory
 
hmm, maybe when you are applying debuff, you should save the damagr that the npc has, and after it wears off return the value to it? i dont really know, just a poor theory
I've tried, but I don't grasp the syntax well enough to know how. If I can just get npc.damage to call its value from Terraria.NPC in ResetEffects, I think it'd work. Otherwise, yeah, I need to define a way to save the original value, set the current npc.damage to 0, and then return it to the original value when it evaluates buff status as false.

Edit: Thought I'd just go ahead and include my GlobalNPC code. It's short at this point. It's kind of a mess, but where I put the current processes is working, so I've left it until I know better. Insight on general structure and my damage problem is deeply appreciated; I've learned a lot this last week!
Code:
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ModLoader;

namespace FarLandsMod.NPCs
{
    public class FarLandsGlobalNPC : GlobalNPC
    {
        public override bool InstancePerEntity
        {
            get
            {
                return true;
            }
        }

        public bool HedgePetrify = false;

        public override void ResetEffects(NPC npc)
        {
            HedgePetrify = false;
        }
     
        public override bool PreAI(NPC npc)
        {
            if (HedgePetrify)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
//Not sure where to put the X/Y/damage effects of the debuff. Putting them in UpdateLifeRegen has worked.
        public override void UpdateLifeRegen(NPC npc, ref int damage)
        {
            if (HedgePetrify)
            {
                //THIS is where I CAN set the npc's damage to 0, but it never reverts back if I do
                //npc.damage = 0;

                //The following stops lateral movement fine; however, while it does bring airborne targets to the ground, npcs still tend to "shake". I'm not sure how to clean that up, but it works for now so I leave it. I'm suspecting some kind of Y = 10 until tile collision then Y = 0 code might resolve it, but I'm having trouble getting anything else to work. Movement resumes on fade, I think because preAI returns to true and reassigns X and Y values
                npc.velocity.X = 0;
                if (npc.velocity.Y == 0)
                    {
                        npc.velocity.Y = 0;
                    }
                else
                    {
                        npc.velocity.Y = 10;
                    }

                if (npc.lifeRegen > 0)
                    {
                        npc.lifeRegen = 0;
                    }
            }
        }

//The following draws a small amount of dust while they're debuffed. Hoping to replace it with something that changes their palette to greyish until fade. When I get there.
        public override void DrawEffects(NPC npc, ref Color drawColor)
        {
            if (HedgePetrify)
            {
                if (Main.rand.Next(4) < 3)
                {
                    int dust = Dust.NewDust(npc.position - new Vector2(1f, 1f), npc.width + 1, npc.height + 1, mod.DustType("Smoke"), npc.velocity.X * 0.1f, npc.velocity.Y * 0.1f, 10, default(Color), 1f);
                    Main.dust[dust].noGravity = true;
                    Main.dust[dust].velocity *= 1f;
                    Main.dust[dust].velocity.Y -= 0.1f;
                    if (Main.rand.Next(4) == 0)
                    {
                        Main.dust[dust].noGravity = false;
                        Main.dust[dust].scale *= 0.1f;
                    }
                }
            }
        }
    }
}
 
Last edited:
I've tried, but I don't grasp the syntax well enough to know how. If I can just get npc.damage to call its value from Terraria.NPC in ResetEffects, I think it'd work. Otherwise, yeah, I need to define a way to save the original value, set the current npc.damage to 0, and then return it to the original value when it evaluates buff status as false.

Edit: Thought I'd just go ahead and include my GlobalNPC code. It's short at this point. It's kind of a mess, but where I put the current processes is working, so I've left it until I know better. Insight on general structure and my damage problem is deeply appreciated; I've learned a lot this last week!
Code:
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ModLoader;

namespace FarLandsMod.NPCs
{
    public class FarLandsGlobalNPC : GlobalNPC
    {
        public override bool InstancePerEntity
        {
            get
            {
                return true;
            }
        }

        public bool HedgePetrify = false;

        public override void ResetEffects(NPC npc)
        {
            HedgePetrify = false;
        }
    
        public override bool PreAI(NPC npc)
        {
            if (HedgePetrify)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
//Not sure where to put the X/Y/damage effects of the debuff. Putting them in UpdateLifeRegen has worked.
        public override void UpdateLifeRegen(NPC npc, ref int damage)
        {
            if (HedgePetrify)
            {
                //THIS is where I CAN set the npc's damage to 0, but it never reverts back if I do
                //npc.damage = 0;

                //The following stops lateral movement fine; however, while it does bring airborne targets to the ground, npcs still tend to "shake". I'm not sure how to clean that up, but it works for now so I leave it. I'm suspecting some kind of Y = 10 until tile collision then Y = 0 code might resolve it, but I'm having trouble getting anything else to work. Movement resumes on fade, I think because preAI returns to true and reassigns X and Y values
                npc.velocity.X = 0;
                if (npc.velocity.Y == 0)
                    {
                        npc.velocity.Y = 0;
                    }
                else
                    {
                        npc.velocity.Y = 10;
                    }

                if (npc.lifeRegen > 0)
                    {
                        npc.lifeRegen = 0;
                    }
            }
        }

//The following draws a small amount of dust while they're debuffed. Hoping to replace it with something that changes their palette to greyish until fade. When I get there.
        public override void DrawEffects(NPC npc, ref Color drawColor)
        {
            if (HedgePetrify)
            {
                if (Main.rand.Next(4) < 3)
                {
                    int dust = Dust.NewDust(npc.position - new Vector2(1f, 1f), npc.width + 1, npc.height + 1, mod.DustType("Smoke"), npc.velocity.X * 0.1f, npc.velocity.Y * 0.1f, 10, default(Color), 1f);
                    Main.dust[dust].noGravity = true;
                    Main.dust[dust].velocity *= 1f;
                    Main.dust[dust].velocity.Y -= 0.1f;
                    if (Main.rand.Next(4) == 0)
                    {
                        Main.dust[dust].noGravity = false;
                        Main.dust[dust].scale *= 0.1f;
                    }
                }
            }
        }
    }
}
you can create public int NPCdamage = npc.damage i think
 
here, try this. havent tested yet but might work.

if it doesnt work, try removing const in NPCDamage, if it still doesnt work, just declare public int NPCDamage, and give it the value before it applies debuff in if(hedgepetrify) { }

Code:
[CODE]
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ModLoader;

namespace FarLandsMod.NPCs
{
public class FarLandsGlobalNPC : GlobalNPC
{
public override bool InstancePerEntity
{
get
{
return true;
}
}

public bool HedgePetrify = false;

public const int NPCDamage = npc.damage;

public override void ResetEffects(NPC npc)
{
HedgePetrify = false;
npc.damage = NPCDamage;
}

public override bool PreAI(NPC npc)
{
if (HedgePetrify)
{
return false;
}
else
{
return true;
}
}
//Not sure where to put the X/Y/damage effects of the debuff. Putting them in UpdateLifeRegen has worked.
public override void UpdateLifeRegen(NPC npc, ref int damage)
{
if (HedgePetrify)
{
//THIS is where I CAN set the npc's damage to 0, but it never reverts back if I do
npc.damage = 0;

//The following stops lateral movement fine; however, while it does bring airborne targets to the ground, npcs still tend to "shake". I'm not sure how to clean that up, but it works for now so I leave it. I'm suspecting some kind of Y = 10 until tile collision then Y = 0 code might resolve it, but I'm having trouble getting anything else to work. Movement resumes on fade, I think because preAI returns to true and reassigns X and Y values
npc.velocity.X = 0;
if (npc.velocity.Y == 0)
{
npc.velocity.Y = 0;
}
else
{
npc.velocity.Y = 10;
}

if (npc.lifeRegen > 0)
{
npc.lifeRegen = 0;
}
}
}

//The following draws a small amount of dust while they're debuffed. Hoping to replace it with something that changes their palette to greyish until fade. When I get there.
public override void DrawEffects(NPC npc, ref Color drawColor)
{
if (HedgePetrify)
{
if (Main.rand.Next(4) < 3)
{
int dust = Dust.NewDust(npc.position - new Vector2(1f, 1f), npc.width + 1, npc.height + 1, mod.DustType("Smoke"), npc.velocity.X * 0.1f, npc.velocity.Y * 0.1f, 10, default(Color), 1f);
Main.dust[dust].noGravity = true;
Main.dust[dust].velocity *= 1f;
Main.dust[dust].velocity.Y -= 0.1f;
if (Main.rand.Next(4) == 0)
{
Main.dust[dust].noGravity = false;
Main.dust[dust].scale *= 0.1f;
}
}
}
}
}
}
[code][CODE]
 
Last edited:
I've tried, but I don't grasp the syntax well enough to know how. If I can just get npc.damage to call its value from Terraria.NPC in ResetEffects, I think it'd work. Otherwise, yeah, I need to define a way to save the original value, set the current npc.damage to 0, and then return it to the original value when it evaluates buff status as false.

Edit: Thought I'd just go ahead and include my GlobalNPC code. It's short at this point. It's kind of a mess, but where I put the current processes is working, so I've left it until I know better. Insight on general structure and my damage problem is deeply appreciated; I've learned a lot this last week!
Code:
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ModLoader;

namespace FarLandsMod.NPCs
{
    public class FarLandsGlobalNPC : GlobalNPC
    {
        public override bool InstancePerEntity
        {
            get
            {
                return true;
            }
        }

        public bool HedgePetrify = false;

        public override void ResetEffects(NPC npc)
        {
            HedgePetrify = false;
        }
    
        public override bool PreAI(NPC npc)
        {
            if (HedgePetrify)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
//Not sure where to put the X/Y/damage effects of the debuff. Putting them in UpdateLifeRegen has worked.
        public override void UpdateLifeRegen(NPC npc, ref int damage)
        {
            if (HedgePetrify)
            {
                //THIS is where I CAN set the npc's damage to 0, but it never reverts back if I do
                //npc.damage = 0;

                //The following stops lateral movement fine; however, while it does bring airborne targets to the ground, npcs still tend to "shake". I'm not sure how to clean that up, but it works for now so I leave it. I'm suspecting some kind of Y = 10 until tile collision then Y = 0 code might resolve it, but I'm having trouble getting anything else to work. Movement resumes on fade, I think because preAI returns to true and reassigns X and Y values
                npc.velocity.X = 0;
                if (npc.velocity.Y == 0)
                    {
                        npc.velocity.Y = 0;
                    }
                else
                    {
                        npc.velocity.Y = 10;
                    }

                if (npc.lifeRegen > 0)
                    {
                        npc.lifeRegen = 0;
                    }
            }
        }

//The following draws a small amount of dust while they're debuffed. Hoping to replace it with something that changes their palette to greyish until fade. When I get there.
        public override void DrawEffects(NPC npc, ref Color drawColor)
        {
            if (HedgePetrify)
            {
                if (Main.rand.Next(4) < 3)
                {
                    int dust = Dust.NewDust(npc.position - new Vector2(1f, 1f), npc.width + 1, npc.height + 1, mod.DustType("Smoke"), npc.velocity.X * 0.1f, npc.velocity.Y * 0.1f, 10, default(Color), 1f);
                    Main.dust[dust].noGravity = true;
                    Main.dust[dust].velocity *= 1f;
                    Main.dust[dust].velocity.Y -= 0.1f;
                    if (Main.rand.Next(4) == 0)
                    {
                        Main.dust[dust].noGravity = false;
                        Main.dust[dust].scale *= 0.1f;
                    }
                }
            }
        }
    }
}
Have you tried using the hook OnHitPlayer in your GlobalNPC Class to check if your buff is active and set that hooks damage (not NPC.damage) to 0? That's probably the way to go because OnHitPlayer is called each time the enemy hits a player, and the values in the hook only affect that one hit.
 
Oh dang. OH DANG. It works!!! @jopojelly (bless his heart) pointed me at "CanHitPlayer" for a completely inert NPC. That makes it unable to touch the player. Interrupting preAI keeps the NPC from deciding to shoot or cast. Velocity values keep it still. And it all wears off when HedgePetrify returns false! Here's the code I was able to use:
Code:
        public override bool CanHitPlayer(NPC npc, Player target, ref int cooldownSlot)
        {
            if (HedgePetrify)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
I removed all other damage references.
Also, I know the practiced modders will laugh, but I learned from this that if you're gonna set something only under certain conditions (like this returns "false" IF Hedgepetrify is "true"), then be sure to also add an else for when the the conditions return to normal (this returns "true" when the NPC is NOT HedgePetrify'd, so the NPC can hit a player normally)!

By the way... @Solo-Ion and @kipo26, you both gave me stuff to work with to try to address other things I want to do. Thank you!
 
Oh dang. OH DANG. It works!!! @jopojelly (bless his heart) pointed me at "CanHitPlayer" for a completely inert NPC. That makes it unable to touch the player. Interrupting preAI keeps the NPC from deciding to shoot or cast. Velocity values keep it still. And it all wears off when HedgePetrify returns false! Here's the code I was able to use:
Code:
        public override bool CanHitPlayer(NPC npc, Player target, ref int cooldownSlot)
        {
            if (HedgePetrify)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
I removed all other damage references.
Also, I know the practiced modders will laugh, but I learned from this that if you're gonna set something only under certain conditions (like this returns "false" IF Hedgepetrify is "true"), then be sure to also add an else for when the the conditions return to normal (this returns "true" when the NPC is NOT HedgePetrify'd, so the NPC can hit a player normally)!

By the way... @Solo-Ion and @kipo26, you both gave me stuff to work with to try to address other things I want to do. Thank you!
You can also just "return !HedgePetrify;"
 
I've probably missed this on the Thread, but how do i change the Particle color, I want to make a Beam Weapon which fires purple/pink beam, but i can't figure out how to change the Particle color, its the default White-Blue color. Help?
 
Is it possible to make my mod generate custom structures similar to underground cabins or jungle shrines? If so how would I go about doing that?
 
is it possible to change the color of cloned projectile? i cloned NebulaBlaze1 and want to change its dust color
 
Tile questions, hurrah.

1) Is it possible to make a tile act as another mod's tile? Ex: Make TileA of ModA act like TileB of ModB when ModB is enabled. Found out how to do this.
2) How do you make a tile act as Lava and Honey for crafting purposes?
 
Last edited:
Okay, if I can just work out how to apply an Ichor-like debuff coloring to the NPCs instead of the current , that debuff will be great AND I'll be able to use effects like it for many other ideas I have. That's just cosmetic, though...but if someone has material I could look through to help me understand how, I'd appreciate it. I suspect it has to do with PostDraw.
 
Last edited:
Can anyone give me the code of gravitation potion? My laptop is not powerful enough to decompile Terraria and I want to use it as a permanent armour effect :/
 
Can anyone give me the code of gravitation potion? My laptop is not powerful enough to decompile Terraria and I want to use it as a permanent armour effect :/
I don't think that the moderators like it if you share a large amount of the source code, so I had a quick look myself and it looks like you just need to set player.gravControl to True to get the gravitation buff effect.
 
Back
Top Bottom