tModLoader Modding Tutorial 3: Some More Weapons

Oh, consumeAmmoOnLastShotOnly works weirdly wtih CanConsumeAmmo for some reason. My flamethrowers had this problem too, remind me later and I'll send my solution
reminder
 

C#:
public override bool CanConsumeAmmo (Item ammo, Player player)
   => player.itemAnimation <= player.itemTimeMax && Main.rand.Next(101) <= 33;
I hope this is the correct code, I don't remember which version works, so please test it and let me know here if it works or not

Also don't forget to remove consumeAmmoOnLastShotOnly
 
C#:
public override bool CanConsumeAmmo (Item ammo, Player player)
   => player.itemAnimation <= player.itemTimeMax && Main.rand.Next(101) <= 33;
I hope this is the correct code, I don't remember which version works, so please test it and let me know here if it works or not

Also don't forget to remove consumeAmmoOnLastShotOnly
sadly this didn't work, even after removing the consumeAmmoOnLastShotOnly. i have tried setting it to false, but it still didn't work for me.
 
sadly this didn't work, even after removing the consumeAmmoOnLastShotOnly. i have tried setting it to false, but it still didn't work for me.
I'll try to find solution tomorrow, and if I will I'll send it here
 
I was wondering if you could help me troubleshoot for my custom enemy mod. Feel free to use the scripts and stuff for your next tutorial but I've been struggling with getting it to Load properly. it compiles fine but while loading content it says its missing content despite it having everything it needs. I am currently using the examplemod slime sprite as a placeholder till I'm able to locate the blue slime sprite in the game to edit from. Advice is welcome for spawn mechanics or other mechanics if there's a better way of doing so, I may not be able to test any advised changes for a bit because my parents are pretty strict but it'll be within a week.
Link to gdrive

C#:
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.ModLoader.Utilities;
using Terraria.GameContent.ItemDropRules;

namespace OreSlimes.NPCs
{
    public class IronSlime : ModNPC
    {
        public override void SetStaticDefaults()
        {
            // Set display name
          
            Main.npcFrameCount[NPC.type] = Main.npcFrameCount[NPCID.BlueSlime]; // Use Blue Slime frames   
        }

        public override void SetDefaults()
        {
            // Copy the Blue Slime's AI
            NPC.width = 32; // NPC hitbox width
            NPC.height = 24; // NPC hitbox height
            NPC.aiStyle = 1; // Use Blue Slime AI
            AIType = NPCID.BlueSlime; // Blue Slime AI type
            AnimationType = NPCID.BlueSlime; // Blue Slime animations
            NPC.damage = 15; // Damage dealt by NPC
            NPC.defense = 20; // Defense stat of the NPC
            NPC.lifeMax = 50; // Max health
            NPC.HitSound = SoundID.NPCHit1; // Hit sound
            NPC.DeathSound = SoundID.NPCDeath1; // Death sound
            NPC.value = 100f; // Money drop value
            NPC.knockBackResist = 0.05f; // Knockback resistance
        }

        public override float SpawnChance(NPCSpawnInfo spawnInfo)
        {
            // Set spawn conditions based on player zone
            if (spawnInfo.Player.ZoneRockLayerHeight || spawnInfo.Player.ZoneDirtLayerHeight)
            {
                return 0.005f; // Rare spawn in caves
            }

            // Increase spawn chance near iron ore (replace spawnTileX/spawnTileY with NPC.position)
            if (NearIronOre((int)(NPC.position.X / 16), (int)(NPC.position.Y / 16)))
            {
                return 0.1f;
            }

            return 0f;
        }

        // Helper method to detect if iron ore is nearby
        private bool NearIronOre(int tileX, int tileY)
        {
            for (int x = tileX - 5; x <= tileX + 5; x++)
            {
                for (int y = tileY - 5; y <= tileY + 5; y++)
                {
                    Tile tile = Main.tile[x, y];
                    if (tile != null && tile.HasTile && (tile.TileType == TileID.Iron || tile.TileType == TileID.Lead))
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        public override void ModifyNPCLoot(NPCLoot npcLoot)
        {
            // Drop iron ore on death
            npcLoot.Add(ItemDropRule.Common(ItemID.IronOre, 1, 3, 7));
        }

        public override void FindFrame(int frameHeight)
        {
            NPC.spriteDirection = NPC.direction; // Adjust sprite direction based on NPC movement
            NPC.frame.Y = NPC.frame.Y % Main.npcFrameCount[NPC.type] * frameHeight;
        }
    }
}
 

Attachments

I was wondering if you could help me troubleshoot for my custom enemy mod. Feel free to use the scripts and stuff for your next tutorial but I've been struggling with getting it to Load properly. it compiles fine but while loading content it says its missing content despite it having everything it needs. I am currently using the examplemod slime sprite as a placeholder till I'm able to locate the blue slime sprite in the game to edit from. Advice is welcome for spawn mechanics or other mechanics if there's a better way of doing so, I may not be able to test any advised changes for a bit because my parents are pretty strict but it'll be within a week.
Link to gdrive

C#:
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.ModLoader.Utilities;
using Terraria.GameContent.ItemDropRules;

namespace OreSlimes.NPCs
{
    public class IronSlime : ModNPC
    {
        public override void SetStaticDefaults()
        {
            // Set display name
         
            Main.npcFrameCount[NPC.type] = Main.npcFrameCount[NPCID.BlueSlime]; // Use Blue Slime frames  
        }

        public override void SetDefaults()
        {
            // Copy the Blue Slime's AI
            NPC.width = 32; // NPC hitbox width
            NPC.height = 24; // NPC hitbox height
            NPC.aiStyle = 1; // Use Blue Slime AI
            AIType = NPCID.BlueSlime; // Blue Slime AI type
            AnimationType = NPCID.BlueSlime; // Blue Slime animations
            NPC.damage = 15; // Damage dealt by NPC
            NPC.defense = 20; // Defense stat of the NPC
            NPC.lifeMax = 50; // Max health
            NPC.HitSound = SoundID.NPCHit1; // Hit sound
            NPC.DeathSound = SoundID.NPCDeath1; // Death sound
            NPC.value = 100f; // Money drop value
            NPC.knockBackResist = 0.05f; // Knockback resistance
        }

        public override float SpawnChance(NPCSpawnInfo spawnInfo)
        {
            // Set spawn conditions based on player zone
            if (spawnInfo.Player.ZoneRockLayerHeight || spawnInfo.Player.ZoneDirtLayerHeight)
            {
                return 0.005f; // Rare spawn in caves
            }

            // Increase spawn chance near iron ore (replace spawnTileX/spawnTileY with NPC.position)
            if (NearIronOre((int)(NPC.position.X / 16), (int)(NPC.position.Y / 16)))
            {
                return 0.1f;
            }

            return 0f;
        }

        // Helper method to detect if iron ore is nearby
        private bool NearIronOre(int tileX, int tileY)
        {
            for (int x = tileX - 5; x <= tileX + 5; x++)
            {
                for (int y = tileY - 5; y <= tileY + 5; y++)
                {
                    Tile tile = Main.tile[x, y];
                    if (tile != null && tile.HasTile && (tile.TileType == TileID.Iron || tile.TileType == TileID.Lead))
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        public override void ModifyNPCLoot(NPCLoot npcLoot)
        {
            // Drop iron ore on death
            npcLoot.Add(ItemDropRule.Common(ItemID.IronOre, 1, 3, 7));
        }

        public override void FindFrame(int frameHeight)
        {
            NPC.spriteDirection = NPC.direction; // Adjust sprite direction based on NPC movement
            NPC.frame.Y = NPC.frame.Y % Main.npcFrameCount[NPC.type] * frameHeight;
        }
    }
}
Slimes are 2 frames, and iirc examplemod slime is 6 frames, so you might get weird spritesheet. Try changing Main.npcFrameCount[NPC.type] = Main.npcFrameCount[NPCID.BlueSlime] to Main.npcFrameCount[NPC.type] = 2
 
Slimes are 2 frames, and iirc examplemod slime is 6 frames, so you might get weird spritesheet. Try changing Main.npcFrameCount[NPC.type] = Main.npcFrameCount[NPCID.BlueSlime] to Main.npcFrameCount[NPC.type] = 2
This combined with fixing my mods pathing issues and changing sprites worked to get it loading. The slime rarely spawns in caves as wanted but my code for spawning very frequently wasn’t working even with very high numbers. I’ve tried some different stuff that hasn’t worked and even asked chatgpt just in case but no dice. Any suggestions, maybe some weird new spawn mechanic that would be easy to implement would be better but I’d prefer naturally so I can eventually add many more slimes and maybe hybrids?
 
Last edited:
This combined with fixing my mods pathing issues and changing sprites worked to get it loading. The slime rarely spawns in caves as wanted but my code for spawning very frequently wasn’t working even with very high numbers. I’ve tried some different stuff that hasn’t worked and even asked chatgpt just in case but no dice. Any suggestions, maybe some weird new spawn mechanic that would be easy to implement would be better but I’d prefer naturally so I can eventually add many more slimes and maybe hybrids?
I think it is because you are trying to get the position of NPC that not existing in world (if (NearIronOre((int)(NPC.position.X / 16), (int)(NPC.position.Y / 16)))). Maybe try making it so if player is near iron ore and then increase spawn?
 
Hey, are you able to help me with a custom NPC?
I'm getting this error:
CS0115: 'Pyre.SetupShop(Chest, ref int)': no suitable method found to override

Here's the code it's referring to:
public override void SetupShop(Chest shop, ref int nextSlot)
{
// Add various Teleportation Pylons without needing King Slime to be defeated
shop.item[nextSlot].SetDefaults(ItemID.TeleportationPylonPurity);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.TeleportationPylonJungle);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.TeleportationPylonUnderground);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.TeleportationPylonOcean);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.TeleportationPylonDesert);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.TeleportationPylonSnow);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.TeleportationPylonMushroom);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.TeleportationPylonVictory);
nextSlot++;
 
Hey, are you able to help me with a custom NPC?
I'm getting this error:
CS0115: 'Pyre.SetupShop(Chest, ref int)': no suitable method found to override

Here's the code it's referring to:
public override void SetupShop(Chest shop, ref int nextSlot)
{
// Add various Teleportation Pylons without needing King Slime to be defeated
shop.item[nextSlot].SetDefaults(ItemID.TeleportationPylonPurity);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.TeleportationPylonJungle);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.TeleportationPylonUnderground);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.TeleportationPylonOcean);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.TeleportationPylonDesert);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.TeleportationPylonSnow);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.TeleportationPylonMushroom);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.TeleportationPylonVictory);
nextSlot++;
You are using old method, look up in ExamplePerson for the new one
 
I think it is because you are trying to get the position of NPC that not existing in world (if (NearIronOre((int)(NPC.position.X / 16), (int)(NPC.position.Y / 16)))). Maybe try making it so if player is near iron ore and then increase spawn?
Everything fixed all slimes up to platinum of both ore variations added so far with varying stats, gold slime damage stacks with coin count of nearest player, platinum slime life max and life Regen increase based off of coin count. Planning to publish the first version soon. Thanks for the help.
 
Everything fixed all slimes up to platinum of both ore variations added so far with varying stats, gold slime damage stacks with coin count of nearest player, platinum slime life max and life Regen increase based off of coin count. Planning to publish the first version soon. Thanks for the help.
sounds fun
 
What program or website would you recommend me (and other people) to learn C# if I have proficient java knowledge? Thanks!
 
What program or website would you recommend me (and other people) to learn C# if I have proficient java knowledge? Thanks!
I learned it from youtube videos and some pages on microsoft website
 
TYSM for quick reply. Thanks!
 
Is the next tutorial going to be about making armor/vanity items and/or accessories? Im trying to make a mod with just a simple helmet vanity but i cant find a good code base :(
 
Is the next tutorial going to be about making armor/vanity items and/or accessories? Im trying to make a mod with just a simple helmet vanity but i cant find a good code base :guidesad:
I won't do tutorials like this anymore (I think)
A good code base for new modders can be found at ExampleMod
 
my friends and i are all aspiring mod creators,so i highly appreciate this tutorial! even though i barely know anything about code (which is alright,i have temporarily taken the role of concept artist/spriter), it helped the others and i understand a lot about how terraria and the items work。so thank you。 <3
also,are you still available to take questions?
This is amazing and helps so much thank you <3 I am very appreciative of the guides you've made :3
 
How can I make the projectiles release from the barrel of the gun instead of the player? Tried 'position + vector2(x,y)' but it likes adjusting the projectiles spawnpoint, not released correctly from the barrel when rotating the gun.
 
Back
Top Bottom