tModLoader Official tModLoader Help Thread

Hi, I wanted to ask, does anyone know how to add a cooldowns ?
I have a custom code that allows to prevent insta hit kills, but I want it to have a cooldown, does anyone know how to do this ?
If needed I can provide the code ( if possible I don't want to use any buffs for the cooldown ).
 
Last edited:
It's not all that hard.
There's a method for projectiles that's called when the projectile hits an NPC (look it up on the GitHub tModLoader wiki, I'm sure you can find it).
Then you just want to up the life of the player that owns the boomerang projectile in question. Example:
Code:
public override void OnHitNPC(NPC target, int damage, float knockback, bool crit)
{
    Player player = Main.player[projectile.owner];

    // Get a correct heal amount.
    // What this code basically does is it checks if the player is missing life and if it is set a correct heal amount, which cannot exceed 10.
    // So if statLifeMax2 is 200 and the player has 100 health healAmount gets set to 10, but when it's 195 healAmount gets set to 5.   
    int healAmount = MathHelper.Clamp(player.statLifeMax2 - player.statLife, 0, 10);

    player.statLife += healAmount; // Up the life of the player by the healAmount value.
    player.HealEffect(healAmount); // Displays the heal text
}
Off the top of my head; that should work.
thank you
 
Hi, I wanted to ask, does anyone know how to add a cooldowns ?
I have a custom code that allows to prevent insta hit kills, but I want it to have a cooldown, does anyone know how to do this ?
If needed I can provide the code ( if possible I don't want to use any buffs for the cooldown ).
What exactly do you mean by cooldown and what is this cooldown for? You can just create a timer like you would with any AI, but with a custom variable instead?
 
Code:
        public override bool PreHurt(bool pvp, bool quiet, ref int damage, ref int hitDirection, ref bool crit, ref bool customDamage, ref bool playSound, ref bool genGore, ref string deathText)
        {
            if (this.damageReduction && damage > 350)
                damage = 350;

            return true;
        }
Basically, I want to know if there is a way to create a flag that checks if damage reduction was already used in the last 1200 ticks, if yes then damage reduction won't work, but if no, then return true, so it would be !something_timer > 0 and if true, then add 1800 ticks to that timer.
( this code is in myPlayer.cs in case you wonder )
 
The mod browser is in beta and not entirely reliable, it's down more often than you might think. Usually this is due to high traffic

Thanks. I just let it sit there then went AFK. It actually wasn't locked up. It took 5-10 minutes, but finally came up. It was coming up immediately before, which is why I thought it crashed the game.
 
Can anyone share scripts for a basic healing potion(that gives potion sickness on use) and a Chlorophyte Shotbow script?

Found something related to the potion, just looking for some help with the shotbow script.
 
Last edited:
Thanks that fixed it.

EDIT: Okay, I'm having a difficult time with my candles' tile. I tried to fix the problems the best I can, but now I'm stuck. This is my codes:

Code:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.DataStructures;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.ObjectData;

namespace CorruptionCandles.Tiles
{
    public class CursedCandle : ModTile
    {
        public override void SetDefaults()
        {
            Main.tileFrameImportant[Type] = true;
            TileObjectData.newTile.CopyFrom(TileObjectData.Style1xX);
            TileObjectData.newTile.UsesCustomCanPlace = true;
            TileObjectData.newTile.Height = 1;
            TileObjectData.newTile.Width = 1;
            TileObjectData.newTile.Origin = new Point16(0, 0);
            TileObjectData.newTile.CoordinateHeights = new int[]{ 16, 16, 22 };
            TileObjectData.addTile(Type);
            AddMapEntry(new Color(0, 255, 0));
            dustType = 1;
            animationFrameHeight = 20;
            disableSmartCursor = true;
            drop = mod.ItemType("CursedCandle");
            AddMapEntry(new Color(0, 255, 0), "Torch");
            dustType = mod.DustType("Sparkle");
            torch = true;
        }

        public override void NumDust(int i, int j, bool fail, ref int num)
        {
            num = Main.rand.Next(1, 3);
        }

        public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b)
        {
            Tile tile = Main.tile[i, j];
            if (tile.frameX < 66)
            {
                r = 0.0f;
                g = 1.0f;
                b = 0.0f;
            }
        }

        public override void NearbyEffects(int i, int j, bool closer)
        {
            if(closer)
            {
                Main.player[Main.myPlayer].AddBuff(mod.BuffType("CursedCandle"), 2);
            }
        }

        public override void AnimateTile(ref int frame, ref int frameCounter)
        {
            frame = Main.tileFrame[TileID.WaterCandle];
            frameCounter = Main.tileFrameCounter[TileID.WaterCandle];
        }

        public override void PostDraw(int i, int j, SpriteBatch spriteBatch)
        {
            ulong randSeed = Main.TileFrameSeed ^ (ulong)((long)j << 32 | (long)((ulong)i));
            Color color = new Color(100, 100, 100, 0);
            int frameX = Main.tile[i, j].frameX;
            int frameY = Main.tile[i, j].frameY;
            int width = 16;
            int offsetY = 0;
            int height = 20;
            if (WorldGen.SolidTile(i, j - 1))
            {
                offsetY = 2;
                if (WorldGen.SolidTile(i - 1, j + 1) || WorldGen.SolidTile(i + 1, j + 1))
                {
                    offsetY = 4;
                }
            }
            Vector2 zero = new Vector2(Main.offScreenRange, Main.offScreenRange);
            if (Main.drawToScreen)
            {
                zero = Vector2.Zero;
            }
            for (int k = 0; k < 7; k++)
            {
                float x = (float)Utils.RandomInt(ref randSeed, -10, 11) * 0.15f;
                float y = (float)Utils.RandomInt(ref randSeed, -10, 1) * 0.35f;
                Main.spriteBatch.Draw(mod.GetTexture("Tiles/CursedCandle_Flame"), new Vector2((float)(i * 16 - (int)Main.screenPosition.X) - (width - 16f) / 2f + x, (float)(j * 16 - (int)Main.screenPosition.Y + offsetY) + y) + zero, new Rectangle(frameX, frameY, width, height), color, 0f, default(Vector2), 1f, SpriteEffects.None, 0f);
            }
        }

    }
}

Code:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.DataStructures;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.ObjectData;

namespace CorruptionCandles.Tiles
{
    public class CrimsonCandle : ModTile
    {
        public override void SetDefaults()
        {
            Main.tileFrameImportant[Type] = true;
            TileObjectData.newTile.CopyFrom(TileObjectData.Style1xX);
            TileObjectData.newTile.UsesCustomCanPlace = true;
            TileObjectData.newTile.Height = 1;
            TileObjectData.newTile.Width = 1;
            TileObjectData.newTile.Origin = new Point16(0, 0);
            TileObjectData.newTile.CoordinateHeights = new int[]{ 16, 16, 22 };
            TileObjectData.addTile(Type);
            AddMapEntry(new Color(0, 255, 0));
            dustType = 1;
            animationFrameHeight = 20;
            disableSmartCursor = true;
            drop = mod.ItemType("CrimsonCandle");
            AddMapEntry(new Color(0, 255, 0), "Torch");
            dustType = mod.DustType("Sparkle");
            torch = true;
        }

        public override void NumDust(int i, int j, bool fail, ref int num)
        {
            num = Main.rand.Next(1, 3);
        }

        public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b)
        {
            Tile tile = Main.tile[i, j];
            if (tile.frameX < 66)
            {
                r = 0.0f;
                g = 1.0f;
                b = 0.0f;
            }
        }

        public override void NearbyEffects(int i, int j, bool closer)
        {
            if(closer)
            {
                Main.player[Main.myPlayer].AddBuff(mod.BuffType("CrimsonCandle"), 2);
            }
        }

        public override void AnimateTile(ref int frame, ref int frameCounter)
        {
            frame = Main.tileFrame[TileID.WaterCandle];
            frameCounter = Main.tileFrameCounter[TileID.WaterCandle];
        }

        public override void PostDraw(int i, int j, SpriteBatch spriteBatch)
        {
            ulong randSeed = Main.TileFrameSeed ^ (ulong)((long)j << 32 | (long)((ulong)i));
            Color color = new Color(100, 100, 100, 0);
            int frameX = Main.tile[i, j].frameX;
            int frameY = Main.tile[i, j].frameY;
            int width = 16;
            int offsetY = 0;
            int height = 20;
            if (WorldGen.SolidTile(i, j - 1))
            {
                offsetY = 2;
                if (WorldGen.SolidTile(i - 1, j + 1) || WorldGen.SolidTile(i + 1, j + 1))
                {
                    offsetY = 4;
                }
            }
            Vector2 zero = new Vector2(Main.offScreenRange, Main.offScreenRange);
            if (Main.drawToScreen)
            {
                zero = Vector2.Zero;
            }
            for (int k = 0; k < 7; k++)
            {
                float x = (float)Utils.RandomInt(ref randSeed, -10, 11) * 0.15f;
                float y = (float)Utils.RandomInt(ref randSeed, -10, 1) * 0.35f;
                Main.spriteBatch.Draw(mod.GetTexture("Tiles/CrimsonCandle_Flame"), new Vector2((float)(i * 16 - (int)Main.screenPosition.X) - (width - 16f) / 2f + x, (float)(j * 16 - (int)Main.screenPosition.Y + offsetY) + y) + zero, new Rectangle(frameX, frameY, width, height), color, 0f, default(Vector2), 1f, SpriteEffects.None, 0f);
            }
        }

    }
}

I'm having a lot of issues, so I don't know if this is too much for one post, so I'm not expecting help for all of this at once:

The 2 biggest problems:

  • The buff is added for a couple of seconds then it disappears.
  • The CrimsonCandle.cs is very similar to CursedCandle.cs, yet unlike the Cursed Candle, when I place the Crimson Candle down it has no animation and all background furniture and leaves becomes invisible.

My other problems are:

  • Neither of the torches are giving off light.
  • How do I make it so that the candle is only placed on surfaces like crafting tables, and platforms?
  • I also seem to be getting the animation wrong. I used the "public override void PostDraw" from ExampleTorch.cs as a reference, but I don't understand the whole thing. I attached the Cursed Candle image files. As the animation moves, I see the pink line on the right of the candle fluctuate between in different sizes between being drawn in a little bit and not being drawn at all.
If someone could give me a example of a candle (one that can be opened with tModReader v0.8) that might solve all the problems I'm having.
 
Code:
        public override bool PreHurt(bool pvp, bool quiet, ref int damage, ref int hitDirection, ref bool crit, ref bool customDamage, ref bool playSound, ref bool genGore, ref string deathText)
        {
            if (this.damageReduction && damage > 350)
                damage = 350;

            return true;
        }
Basically, I want to know if there is a way to create a flag that checks if damage reduction was already used in the last 1200 ticks, if yes then damage reduction won't work, but if no, then return true, so it would be !something_timer > 0 and if true, then add 1800 ticks to that timer.
( this code is in myPlayer.cs in case you wonder )
Fairly easy. I pressume this is in a ModPlayer class. Create a variable ( `int myCooldownTimer` ?). In that update you posted, check if it's <= 0 and if it is, set it to 1800. Then in PostUpdateEquips, just do `myCooldownTimer--;`. Easy as that.
Can anyone share scripts for a basic healing potion(that gives potion sickness on use) and a Chlorophyte Shotbow script?

Found something related to the potion, just looking for some help with the shotbow script.
What exactly do you mean by the shotbow script?
If someone could give me a example of a candle (one that can be opened with tModReader v0.8) that might solve all the problems I'm having.
You're adding the buff for 2 ticks (1/30th of a second) every time, so you may want to look into that.
 
What exactly do you mean by the shotbow script?

I mean when the shotbow sometimes fires more then one arrow every time you shoot it.
But I got a feeling now that it may just be a standard shotgun script that does that.

EDIT: Would this shotgun script make a bow function like the chlorophyte shotbow?
Code:
}
     public override bool Shoot(Player player, ref Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack)
     {
       int numberProjectiles = 1 + Main.rand.Next(3);
       for (int i = 0; i < numberProjectiles; i++)
       {
         Vector2 perturbedSpeed = new Vector2(speedX, speedY).RotatedByRandom(MathHelper.ToRadians(3));
         Projectile.NewProjectile(position.X, position.Y, perturbedSpeed.X, perturbedSpeed.Y, type, damage, knockBack, player.whoAmI);
       }
       return false;
     }
 
Last edited:
my minion decides to fly off to the sky. What am i missing?
Code:
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace LegendOfTerraria3.Projectiles.Minion
{
    public class MedusaHead : ModProjectile
    {
        public override void SetDefaults()
        {
            projectile.CloneDefaults(ProjectileID.Raven);
            projectile.name = "Medusa Head";
            projectile.width = 18;
            projectile.height = 26;
            projectile.aiStyle = 26;
            aiType = ProjectileID.Raven;
            Main.projFrames[projectile.type] = 8;
            projectile.damage = 15;
        }
    }
}
 
my minion decides to fly off to the sky. What am i missing?
Code:
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace LegendOfTerraria3.Projectiles.Minion
{
    public class MedusaHead : ModProjectile
    {
        public override void SetDefaults()
        {
            projectile.CloneDefaults(ProjectileID.Raven);
            projectile.name = "Medusa Head";
            projectile.width = 18;
            projectile.height = 26;
            projectile.aiStyle = 26;
            aiType = ProjectileID.Raven;
            Main.projFrames[projectile.type] = 8;
            projectile.damage = 15;
        }
    }
}
What happens if you change the aiStyle and aiType?
[doublepost=1476090090,1476090019][/doublepost]
I mean when the shotbow sometimes fires more then one arrow every time you shoot it.
But I got a feeling now that it may just be a standard shotgun script that does that.

EDIT: Would this shotgun script make a bow function like the chlorophyte shotbow?
Code:
}
     public override bool Shoot(Player player, ref Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack)
     {
       int numberProjectiles = 1 + Main.rand.Next(3);
       for (int i = 0; i < numberProjectiles; i++)
       {
         Vector2 perturbedSpeed = new Vector2(speedX, speedY).RotatedByRandom(MathHelper.ToRadians(3));
         Projectile.NewProjectile(position.X, position.Y, perturbedSpeed.X, perturbedSpeed.Y, type, damage, knockBack, player.whoAmI);
       }
       return false;
     }
You're shooting 1 + Rand.Next(3) here, so a minimum of 1 up to 3. (random is upper bound exclusive)
It can also be that your useTime is smaller than useAnimation
 
this.useStyle = 1;
this.useAnimation = 8;
this.useTime = 8;
this.useSound = 1;
item.shoot is changing depending on the type:
Code:
this.shoot = 361 + type - 2291;
If you want to try out, here are the checked type for fishing poles:
Code:
type == 2289 || (type >= 2291 && type <= 2296)
Could you maybe explain that a bit more noob friendly? I have like no experience at all with tmodloader modding. :/
 
How do I make NPCs spawn in a certain biome. Or hardmode. Or once you've defeated a boss.
And how do I create a custom structure to generate in the world?
 
Are you using aiStyle/aiType? If so, there's no way to do that (for as far as I know).
If you're using AI code directly, you'll have to show us the code you have.
I dont have the code right now, i have a single .cs file with code like all the other weapons ( swords, bows and that) but just with copy defaults and use channel and projectile shoot. ( btw i didnt understud you so i said all that could maybe help).
 
I dont have the code right now, i have a single .cs file with code like all the other weapons ( swords, bows and that) but just with copy defaults and use channel and projectile shoot. ( btw i didnt understud you so i said all that could maybe help).
Then it (indirectly) uses the method I mentioned first (aiStyle/aiType) and it's thus not possible.
 
Back
Top Bottom