tModLoader modded NPCs not dropping anything

Gugavo :]

CelebrationMK10
I was playing a multiplayer world with my mod with a few of my friends, and certain NPCs from my mod aren't dropping anything, including coins.
other mods enabled:
Magic storage (and the utility mod it depends on)
recipe browser
ore excavator
 
I did a test, and the problem seems to be multiplayer. I made a world on journey with the exact same mods, and in singleplayer the drops worked but not in multiplayer.
 
after another test of disabling all mods except mine, the problem is definitely multiplayer and not other mods. How do I fix this? Another odd thing is that one specific enemy drops items as normal.
 
Post the code of one of your NPCs that doesn't drop anything in multiplayer
 
C#:
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.GameContent.Bestiary;
using Terraria.GameContent.ItemDropRules;
using Terraria.ModLoader.Utilities;
using Terraria.DataStructures;
using Microsoft.Xna.Framework;
using System;
using TWillyHsepicmod.Items.Placeable.Banners;

namespace TWillyHsepicmod.NPCs
{
    public class Sticky : ModNPC
    {
        public override void SetStaticDefaults()
        {
            Main.npcFrameCount[Type] = Main.npcFrameCount[NPCID.Zombie];

            NPCID.Sets.NPCBestiaryDrawModifiers value = new NPCID.Sets.NPCBestiaryDrawModifiers(0)
            {
                Velocity = 1f
            };
            NPCID.Sets.NPCBestiaryDrawOffset.Add(Type, value);
        }

        public override void SetDefaults()
        {
            NPC.width = 18;
            NPC.height = 40;
            NPC.damage = 14;
            NPC.defense = 6;
            NPC.lifeMax = 50;
            NPC.HitSound = SoundID.NPCHit1;
            NPC.DeathSound = SoundID.NPCDeath1;
            NPC.value = 30;
            NPC.knockBackResist = 0.5f;
            NPC.aiStyle = 3;

            AnimationType = NPCID.Zombie;

            Banner = Type;
            BannerItem = ModContent.ItemType<StickyBanner>();
        }

        public override void HitEffect(NPC.HitInfo hit)
        {
            if (NPC.life <= 0)
            {
                Vector2 center = NPC.Center;
                Player player = Main.player[NPC.lastInteraction];
                int direction = Math.Sign(NPC.Center.X - player.Center.X);

                Vector2 headVelocity = new Vector2(
                    Main.rand.NextFloat(1.5f, 3f) * direction,
                    Main.rand.NextFloat(-4f, -1f)
                );
                Gore.NewGore(NPC.GetSource_Death(), center, headVelocity, Mod.Find<ModGore>("StickyHead_Gore").Type);

                for (int i = 0; i < 5; i++)
                {
                    Vector2 body1Velocity = new Vector2(
                        Main.rand.NextFloat(2f, 5f) * direction,
                        Main.rand.NextFloat(-4f, -1f)
                    );
                    Gore.NewGore(NPC.GetSource_Death(), center, body1Velocity, Mod.Find<ModGore>("StickyBody_Gore").Type);
                }

                for (int i = 0; i < 10; i++)
                {
                    Vector2 body1Velocity = new Vector2(
                        Main.rand.NextFloat(2f, 5f) * direction,
                        Main.rand.NextFloat(-4f, -1f)
                    );
                    Gore.NewGore(NPC.GetSource_Death(), center, body1Velocity, Mod.Find<ModGore>("StickyGore").Type);
                }
            }
        }

        public override void ModifyNPCLoot(NPCLoot npcLoot)
        {
            npcLoot.Add(ItemDropRule.Common(ModContent.ItemType<Items.Weapons.YeetStick>(), 25));
            npcLoot.Add(ItemDropRule.Common(ModContent.ItemType<Items.Pets.Swinub.FamiliarOrb>(), 100));
            npcLoot.Add(ItemDropRule.Common(ModContent.ItemType<Items.ScribliumOre>(), 1));

        }
        public override float SpawnChance(NPCSpawnInfo spawnInfo)
        {
            return SpawnCondition.Overworld.Chance;
        }

        public override void SetBestiary(BestiaryDatabase database, BestiaryEntry bestiaryEntry)
        {
            bestiaryEntry.Info.AddRange(new IBestiaryInfoElement[]
            {
               BestiaryDatabaseNPCsPopulator.CommonTags.SpawnConditions.Times.DayTime,
               BestiaryDatabaseNPCsPopulator.CommonTags.SpawnConditions.Biomes.Surface,

               new FlavorTextBestiaryInfoElement("A poorly drawn stickman brought forth into this world by unknown means. most of their kind mindlessly attack anything near them due to their monster-like nature, but some might have conscience. They seem to like hoarding scriblium."),

            });
        }
    }
}
This one doesn't drop anything, just spawns gores, while the one here drops loot properly.
C#:
using TWillyHsepicmod.Systems;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.GameContent.Bestiary;
using Terraria.GameContent.ItemDropRules;
using Terraria.ModLoader.Utilities;
using Terraria.DataStructures;
using TWillyHsepicmod.Items.Placeable.Banners;

namespace TWillyHsepicmod.NPCs
{
    public class Mistransport : ModNPC
    {
        public override void SetStaticDefaults()
        {
            Main.npcFrameCount[Type] = Main.npcFrameCount[NPCID.Zombie];

            NPCID.Sets.NPCBestiaryDrawModifiers value = new NPCID.Sets.NPCBestiaryDrawModifiers(0)
            {
                Velocity = 1f
            };
            NPCID.Sets.NPCBestiaryDrawOffset.Add(Type, value);
        }

        public override void SetDefaults()
        {
            NPC.width = 18;
            NPC.height = 40;
            NPC.damage = 14;
            NPC.defense = 10;
            NPC.lifeMax = 75;
            NPC.HitSound = SoundID.NPCHit1;
            NPC.DeathSound = SoundID.NPCDeath1;
            NPC.value = 69;
            NPC.knockBackResist = 0.8f;
            NPC.aiStyle = 3;

            AnimationType = NPCID.Zombie;

            Banner = Type;
            BannerItem = ModContent.ItemType<MistransportBanner>();
        }

        public override void ModifyNPCLoot(NPCLoot npcLoot)
        {
            npcLoot.Add(ItemDropRule.Common(ModContent.ItemType<Items.Placeable.FelinjellyBlock>(), 1, 5, 50));
            npcLoot.Add(ItemDropRule.Common(ModContent.ItemType<Items.Pets.Swinub.FamiliarOrb>(), 100));
            npcLoot.Add(ItemDropRule.Common(ModContent.ItemType<Items.Weapons.Nicholas>(), 5));

        }
        public override float SpawnChance(NPCSpawnInfo spawnInfo)
        {
            return SpawnCondition.Overworld.Chance * 0.8f;
        }

        public override void SetBestiary(BestiaryDatabase database, BestiaryEntry bestiaryEntry)
        {
            bestiaryEntry.Info.AddRange(new IBestiaryInfoElement[]
            {

               BestiaryDatabaseNPCsPopulator.CommonTags.SpawnConditions.Times.DayTime,
               BestiaryDatabaseNPCsPopulator.CommonTags.SpawnConditions.Biomes.Surface,

               new FlavorTextBestiaryInfoElement("Feline creatures from the doodle world whose genetic code caused them to melt into a gelatinous form when they tried to cross into this world."),

            });
        }

        public override void HitEffect(NPC.HitInfo hit)
        {
            for (int i = 0; i < 10; i++)
            {
                int dustType = ModContent.DustType<Dusts.White>();
                var dust = Dust.NewDustDirect(NPC.position, NPC.width, NPC.height, dustType);

                dust.velocity.X += Main.rand.NextFloat(-0.05f, 0.05f);
                dust.velocity.Y += Main.rand.NextFloat(-0.05f, 0.05f);

                dust.scale *= 1f + Main.rand.NextFloat(-0.03f, 0.03f);
            }
        }
    }
}
It's definitely not the useless using twillyhsepicmod.systems that I must have accidentally put in there and forgot to take out, as another enemy without the using statement also drops loot properly.
The only similarity I can think of between the 2 enemies that do drop loot is that they both explode into dust instead of using gores.
 
Nothing in your code seems off, the best thing you can do is see if any issues come up in your server.log file. Start a multiplayer game, kill the enemies who don't drop loot, then check the log for exceptions.
 
I'm not exactly sure what this means, but I found this after killing an enemy that I know never drops loot in multiplayer.
Code:
[13:28:53.861] [Main Thread/ERROR] [Network]: [0][127.0.0.1:62860 (fseddssd)] DamageNPC(28)
System.Collections.Generic.KeyNotFoundException: The given key 'TWillyHsepicmod' was not present in the dictionary.
   at TWillyHsepicmod.NPCs.CaveThing.HitEffect(HitInfo hit) in TWillyHsepicmod/NPCs/CaveThing.cs:line 47
   at Terraria.ModLoader.NPCLoader.HitEffect(NPC npc, HitInfo& hit) in tModLoader\Terraria\ModLoader\NPCLoader.cs:line 449
   at Terraria.NPC.HitEffect(HitInfo hit) in tModLoader\Terraria\NPC.cs:line 66011
   at Terraria.NPC.StrikeNPC(HitInfo hit, Boolean fromNet, Boolean noPlayerInteraction) in tModLoader\Terraria\NPC.cs:line 65902
   at Terraria.MessageBuffer.GetData(Int32 start, Int32 length, Int32& messageType) in tModLoader\Terraria\MessageBuffer.cs:line 1640
   at Terraria.NetMessage.CheckBytes(Int32 bufferIndex) in tModLoader\Terraria\NetMessage.cs:line 2359
[13:28:57.864] [Server Loop Thread/INFO] [Network]: [0][127.0.0.1:62860 (fseddssd)] Terminating: Connection lost
[13:28:57.886] [Server Loop Thread/INFO] [Terraria]: fseddssd has left.
[13:28:57.893] [Server Loop Thread/INFO] [Terraria]: Local player left. Autoshutdown starting.
 
Can you post the code for TWillyHsepicmod/NPCs/CaveThing
 
C#:
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.GameContent.Bestiary;
using Terraria.GameContent.ItemDropRules;
using Terraria.ModLoader.Utilities;
using Terraria.DataStructures;
using Microsoft.Xna.Framework;
using Terraria.DataStructures;
using System;
using TWillyHsepicmod.Items.Placeable.Banners;

namespace TWillyHsepicmod.NPCs
{
    public class CaveThing : ModNPC
    {
        public override void SetStaticDefaults()
        {
            Main.npcFrameCount[Type] = 1;

            NPCID.Sets.NPCBestiaryDrawModifiers value = new NPCID.Sets.NPCBestiaryDrawModifiers(0)
            {
                Velocity = 1f
            };
            NPCID.Sets.NPCBestiaryDrawOffset.Add(Type, value);
        }

        public override void SetDefaults()
        {
            NPC.width = 39;
            NPC.height = 39;
            NPC.damage = 15;
            NPC.defense = 8;
            NPC.lifeMax = 169;
            NPC.HitSound = SoundID.NPCHit1;
            NPC.DeathSound = SoundID.NPCDeath1;
            NPC.value = 169;
            NPC.knockBackResist = 0f;
            NPC.aiStyle = 2;

            Banner = Type;
            BannerItem = ModContent.ItemType<CaveThingBanner>();
        }

        public override void HitEffect(NPC.HitInfo hit)
        {
            if (NPC.life <= 0)
            {
                Vector2 center = NPC.Center;

                Player player = Main.player[NPC.lastInteraction];
                int direction = Math.Sign(NPC.Center.X - player.Center.X);

                for (int i = 0; i < 4; i++)
                {
                    Vector2 velocity = new Vector2(
                        Main.rand.NextFloat(2f, 5f) * direction,
                        Main.rand.NextFloat(-4f, -1f)
                    );

                    Gore.NewGore(NPC.GetSource_Death(), center, velocity, Mod.Find<ModGore>("CaveThingTentacle_Gore").Type);
                }

                Vector2 bodyVelocity = new Vector2(
                    Main.rand.NextFloat(1f, 3f) * direction,
                    Main.rand.NextFloat(-3f, -1f)
                );

                Gore.NewGore(NPC.GetSource_Death(), center, bodyVelocity, Mod.Find<ModGore>("CaveThingBody_Gore").Type);
            }
        }

        public override void ModifyNPCLoot(NPCLoot npcLoot)
        {
            npcLoot.Add(ItemDropRule.Common(ModContent.ItemType<Items.MythiteShards>(), 2, 1, 4));
            npcLoot.Add(ItemDropRule.Common(ModContent.ItemType<Items.Weapons.Scythe>(), 10));
            npcLoot.Add(ItemDropRule.Common(ModContent.ItemType<Items.Pets.Swinub.FamiliarOrb>(), 100));
        }
        public override float SpawnChance(NPCSpawnInfo spawnInfo)
        {
            return SpawnCondition.Cavern.Chance * 0.2f;
        }

        public override void SetBestiary(BestiaryDatabase database, BestiaryEntry bestiaryEntry)
        {
            bestiaryEntry.Info.AddRange(new IBestiaryInfoElement[]
            {
               BestiaryDatabaseNPCsPopulator.CommonTags.SpawnConditions.Biomes.Caverns,

               new FlavorTextBestiaryInfoElement("A strange floating eye from the depths of the doodle world that favors deep dark places."),

            });
        }
    }
}
 
Oh I see the issue, you can't let gore spawn on the server, it's a client side visual effect only. Change your check in HitEffect to

if (Main.netMode != NetmodeID.Server && NPC.life <= 0)
 
Oh I see the issue, you can't let gore spawn on the server, it's a client side visual effect only. Change your check in HitEffect to

if (Main.netMode != NetmodeID.Server && NPC.life <= 0)
that explains the pattern of NPCs that use dusts as gores dropped loot normally, but why does the dust work? Is dust handled differently that gore so that if (NPC.life <= 0) works normally?
Should I replace the line in those too just in case?
 
Dusts work because when you call Dust.NewDust(), the NewDust function actually checks the netmode within itself and exits if it's running on a server.
 
Back
Top Bottom