tModLoader How do I detect when a player picks up/drops an item?

Spookmaster

Terrarian
Hi, folks! I'm new to Terraria modding, so I figured I'd start with something fun and small, instead of making a giant project. So, for my first project, I wanted to make a unique accessory that does the following:

unknown.png


I managed to get the stat bonuses and recipe working perfectly, but I'd like some help with the rest of it. In specific, I want to get the money things working before I worry about the snail itself; are there any hooks that detect when a player picks up an item, and, similarly, are there any that detect when a player drops an item? I'd also like to know if there's a way to despawn an item.

Here's a sort of pseudo-code example of what I'm looking for:

Code:
public void PlayerGainedItem(Player player, int ItemIndex, int Amount)
{
    if (player.HasSnailRing && ItemIsCoin(ItemIndex))
    {
        Amount *= 2;
    }
}

public void PlayerDroppedItem(Player player, int ItemIndex)
{
    if (player.HasSnailRing && ItemIsCoin(ItemIndex))
    {
        DespawnItem(ItemIndex);
    }
}

public bool ItemIsCoin(int ItemIndex)
{
    return (ItemIndex == ItemID.CopperCoin || ItemIndex == ItemID.SilverCoin || ItemIndex == ItemID.GoldCoin || ItemIndex == ItemID.PlatinumCoin);
}
 
Update: I did some digging around and found OnPickup, which is about the closest thing I could find to what I'm looking for. The problem is that there seems to be two different versions of OnPickup. One of them just contains the Player that picked up the item, while the other contains both the Player and the Item. I want to use the latter, but I keep getting errors when I try. I'm assuming I'm doing something wrong; any help?

This is the Mod file:

Code:
using Terraria.ModLoader;

namespace TestMod_SnailRing
{
    public class TestMod_SnailRing : Mod
    {
        public TestMod_SnailRing()
        {
            Properties = new ModProperties()
            {
                Autoload = true,
                AutoloadGores = true,
                AutoloadSounds = true
            };
        }

        public override void Load()
        {
            GlobalItem globalthing = new GlobalItem();
            AddGlobalItem(Name, globalthing);
        }
    }
}
And this is the accessory itself:
Code:
using System;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace TestMod_SnailRing.Items.Accessories
{
    public class SnailRing : ModItem
    {
        const int ExtraTime = 5;
        const float StatMods = 0.2F;

        public override void SetStaticDefaults()
        {
            DisplayName.SetDefault("Snail Ring"); // By default, capitalization in classnames will add spaces to the display name. You can customize the display name here by uncommenting this line.
            Tooltip.SetDefault($@"While equipped, you gain a {(int)Math.Round(100.0F * StatMods)}% bonus to most stats, and any money you pick up is doubled.
However, a snail will follow you. If you touch the snail, you will instantly die.
The snail can fly, and travels through blocks. You cannot kill the snail.
The snail will teleport to your screen if it is too far away.
The snail will continue to follow you for {ExtraTime} minutes after this accessory is unequipped.
When you die, regardless of whether or not the snail killed you, any money you were carrying will vanish.");
        }

        public override void SetDefaults()
        {
            item.CloneDefaults(ItemID.BandofRegeneration);
            item.maxStack = 1;
            item.value = Item.sellPrice(gold: 50);
            item.rare = 6;
        }

        public override bool OnPickup(Player player) //This is the only version of OnPickup I can get to work, and it doesn't suit my needs.
        {
            return true; //Placeholder return value
        }

        /*public override bool OnPickup(Player player, Item item) This is what I want to use, but it's not working.
        {
            Logic and such goes here.
        }*/

        public override void UpdateAccessory(Player player, bool hideVisual)
        {
            player.allDamage += StatMods;
            player.accRunSpeed += StatMods;
            player.moveSpeed += StatMods;
            player.endurance += StatMods;
            player.meleeCrit += (int)Math.Round((float)player.meleeCrit * StatMods);
            player.magicCrit += (int)Math.Round((float)player.magicCrit * StatMods);
            player.rangedCrit += (int)Math.Round((float)player.rangedCrit * StatMods);
            player.thrownCrit += (int)Math.Round((float)player.thrownCrit * StatMods);
            player.lifeRegen += (int)Math.Round((float)player.lifeRegen * StatMods);
            player.manaRegen += (int)Math.Round((float)player.manaRegen * StatMods);
            player.statLifeMax2 += (int)Math.Round((float)player.statLifeMax2 * StatMods);
            player.statManaMax2 += (int)Math.Round((float)player.statManaMax2 * StatMods);
            player.statDefense += (int)Math.Round((float)player.statDefense * StatMods);
            player.toolTime -= (int)Math.Round((float)player.toolTime * StatMods);

            /*NPC snail = new NPC();
            snail.friendly = false;
            snail.scale = 2.0F;
            snail.aiStyle = 0;


            TODO: Spawn the dreaded snail.*/
        }

        public override void AddRecipes()
        {
            ModRecipe recipe = new ModRecipe(mod);
            recipe.AddIngredient(ItemID.SoulofFright, 15);
            recipe.AddIngredient(ItemID.SoulofMight, 15);
            recipe.AddIngredient(ItemID.SoulofSight, 15);
            recipe.AddIngredient(ItemID.SoulofNight, 30);
            recipe.AddIngredient(ItemID.PlatinumCoin, 1);
            recipe.AddIngredient(ItemID.Snail, 1);
            recipe.AddTile(TileID.DemonAltar);
            recipe.SetResult(this);
            recipe.AddRecipe();
        }
    }
}
 
Back
Top Bottom