Standalone [1.3] tModLoader - A Modding API

Well, this is acutally irrlevant. This is just a custom name.
Anyway thanks for the reply! I have settled this problem after I posted. I just misplaced some files.
By the way do u have some ideas about the sound problem?
No clue, I only mess with tAPI at the moment. I will migrate to tModLoader if they ever add .json support though.
Maybe try using:
Main.PlaySound("Your Sound", *insert player variable*.position.X, *insert player variable*.position.Y, true, null);
 
No clue, I only mess with tAPI at the moment. I will migrate to tModLoader if they ever add .json support though.
Maybe try using:
Main.PlaySound("Your Sound", *insert player variable*.position.X, *insert player variable*.position.Y, true, null);
Em... all right then. I don't think I'm gonna need to use Main.PlaySound. Cause sound has been defined in SetDefault. I only need to link the file I've put into the game manaully.
Let's just wait for other guys to answer.
 
Em... all right then. I don't think I'm gonna need to use Main.PlaySound. Cause sound has been defined in SetDefault. I only need to link the file I've put into the game manaully.
Let's just wait for other guys to answer.
Call mod.addsound in mod.load. the code you posted does nothing and will never be called. Note that it wasn't a virtual method, but a method available for you to use.
 
Call mod.addsound in mod.load. the code you posted does nothing and will never be called. Note that it wasn't a virtual method, but a method available for you to use.
:confused:Should I adjsut what I've set in main cs file or item cs file?
Code:
        public void AddSound(SoundType type, string soundPath, ModSound modSound = null)
        {
            type = SoundType.Item;
            soundPath = "Sounds/SG550";
        }
Code:
            item.useSound = mod.GetSoundSlot(SoundType.Item, "Sounds/SG550");
 
:confused:Should I adjsut what I've set in main cs file or item cs file?
Code:
        public void AddSound(SoundType type, string soundPath, ModSound modSound = null)
        {
            type = SoundType.Item;
            soundPath = "Sounds/SG550";
        }
Code:
            item.useSound = mod.GetSoundSlot(SoundType.Item, "Sounds/SG550");
Delete that AddSound method you wrote, keep the item.useSound line.

Add this line somewhere in your mod.load method (that place you swapped out textures.)

AddSound(SoundType.Item, "Sounds/SG550");

Delete this line since you are doing things manually (I think it will load it twice if you keep it, since its not where it is expected. Not a problem, but it's nice to be organized.):

properties.AutoloadSounds = true;
 
Delete that AddSound method you wrote, keep the item.useSound line.

Add this line somewhere in your mod.load method (that place you swapped out textures.)

AddSound(SoundType.Item, "Sounds/SG550");

Delete this line since you are doing things manually (I think it will load it twice if you keep it, since its not where it is expected. Not a problem, but it's nice to be organized.):

properties.AutoloadSounds = true;
Code:
        public override void SetModInfo(out string name, ref ModProperties properties)
        {
            name = "wch";
            properties.Autoload = true;
            properties.AutoloadGores = true;
        }

        public override void Load()
        {
            vanillaCobaltShieldTexture = Main.itemTexture[ItemID.CobaltShield];
            Main.itemTexture[ItemID.CobaltShield] = ModLoader.GetTexture("wch/VanillaRedesign/CobaltShieldRedesign");
            vanillaCrystalBulletProjectileTexture = Main.projectileTexture[ProjectileID.CrystalBullet];
            Main.projectileTexture[ProjectileID.CrystalBullet] = ModLoader.GetTexture("wch/VanillaRedesign/CrystalBulletProjectileRedesign");
            AddSound(SoundType.Item, "Sounds/SG550");
            AddSound(SoundType.Item, "Sounds/AK47");
        }
So I write it like this.
And now, it will crash whatever, once I click the "Build + Reload". What's going on?
 
Apparently, I'm doing it wrong.


: error CS0115: 'SvardMod.Items.ArcaneGlove.OnHitNPCWithProj(Terraria.Projectile, Terraria.NPC, int, float, bool)': no suitable method found to override

Code:
   public class ArcaneGlove : ModItem
   {
     public override void SetDefaults()
     {
       item.name = "Arcane Glove";
       item.width = 28;
       item.height = 24;
       item.value = 100000;
       item.toolTip = "Enemies sometimes drop mana stars";
       item.accessory = true;
       item.rare = 8;
     }

     public override void OnHitNPCWithProj(Projectile proj, NPC target, int damage, float knockback, bool crit)
     {
       Random chance;
       if (Projectile.magic == true)
       {
         if (chance.Next(14) == 0)
         {
           Item.NewItem((int)target.position.X, (int)target.position.Y, target.width, target.height, ItemID.Star));
         }
       }
     }

     public override void AddRecipes()
     {
       ModRecipe recipe = new ModRecipe(mod);
       recipe.AddIngredient(ItemID.FallenStar);
       recipe.AddTile(114);
       recipe.SetResult(this);
       recipe.AddRecipe();
     }
   }
 
Last edited:
Apparently, I'm doing it wrong.


: error CS0115: 'SvardMod.Items.ArcaneGlove.OnHitNPCWithProj(Terraria.Projectile, Terraria.NPC, int, float, bool)': no suitable method found to override

Code:
   public class ArcaneGlove : ModItem
   {
     public override void SetDefaults()
     {
       item.name = "Arcane Glove";
       item.width = 28;
       item.height = 24;
       item.value = 100000;
       item.toolTip = "Enemies sometimes drop mana stars";
       item.accessory = true;
       item.rare = 8;
     }

     public override void OnHitNPCWithProj(Projectile proj, NPC target, int damage, float knockback, bool crit)
     {
       Random chance;
       if (Projectile.magic == true)
       {
         if (chance.Next(14) == 0)
         {
           Item.NewItem((int)target.position.X, (int)target.position.Y, target.width, target.height, ItemID.Star));
         }
       }
     }

     public override void AddRecipes()
     {
       ModRecipe recipe = new ModRecipe(mod);
       recipe.AddIngredient(ItemID.FallenStar);
       recipe.AddTile(114);
       recipe.SetResult(this);
       recipe.AddRecipe();
     }
   }
That method isn't part of ModItem. The hook you'll want to use is in ModPlayer (In the end, ModItem.UpdateAccessory will set a Boolean in ModPlayer, and the OnHitNPCWithProj will check that Boolean) , but we haven't released tmodloader v0.7 yet, so you'll have to wait maybe a week or so to do that.

So I write it like this.
And now, it will crash whatever, once I click the "Build + Reload". What's going on?
The code looks right now. When you say crash, do you mran no error message pops up and the whole program disappears? If so, that is troubling. If there was a message, it would help to see it, but as long as its a typical wav file, it shouldn't cause any issues. You could try just any other wav file replacing the two you have there to see if the wav files themselves are to blame. If they are in a weird format, something like audacity can help. Here are the wav file requirements:

must be a valid PCM wave file. Also, this wave file must be in the RIFF bitstream format.

The audio format has the following restrictions:
  • Must be a PCM wave file
  • Can only be mono or stereo
  • Must be 8 or 16 bit
  • Sample rate must be between 8,000 Hz and 48,000 Hz

So there is some leway.

Let me know if you don't know how to check the wav file for these things. You can attach the wav file to a post if you like.
 
Glad to know such a feature is coming soon. It seems that a lot of the stuff I want to do in my mod relies on hooks that won't be available until future builds.
 
The code looks right now. When you say crash, do you mran no error message pops up and the whole program disappears? If so, that is troubling. If there was a message, it would help to see it, but as long as its a typical wav file, it shouldn't cause any issues. You could try just any other wav file replacing the two you have there to see if the wav files themselves are to blame. If they are in a weird format, something like audacity can help. Here are the wav file requirements:
OK, and yeah, there's no error message. When I tried to "Build + Reload" as usual, the game simply went dead with "Terraria have encountered a problem, and needs to be closed.".
Besides, I think it has nothing to do with my wav files. For a reason that if I conform to "Autoload", if I put the sound files in Sounds/Item, it will work. I guess it may be an issue with the "AddSound"? It seems that it will crash once I add this line.
 
OK, and yeah, there's no error message. When I tried to "Build + Reload" as usual, the game simply went dead with "Terraria have encountered a problem, and needs to be closed.".
Besides, I think it has nothing to do with my wav files. For a reason that if I conform to "Autoload", if I put the sound files in Sounds/Item, it will work. I guess it may be an issue with the "AddSound"? It seems that it will crash once I add this line.
OK, maybe there's a problem.

You know what, I think when manually adding, the path might need to start with the mod folder name. (I don't usually not autoload, so I had forgotten about that. The wiki was confusing me too for some reason.)

Try it with "modname/sounds/sg550" if you'd like to keep your original file structure.

Glad to know such a feature is coming soon. It seems that a lot of the stuff I want to do in my mod relies on hooks that won't be available until future builds.
Yeah, every time we finish one thing, it seems like people need the next thing.

If you are feeling adventurous, you could setup the current build off github and get started using the hooks you need.
 
Try it with "modname/sounds/sg550" if you'd like to keep your original file structure.
Oh, after I changed the path... it crashed again...
Well, let's just forget about this annoying problem. Maybe I should use sound autoload since it's not a big deal to put my sounds file in sounds/file.
I'm wondering about another thing, though. How should I create a dot buff? Dot Buff like Burning or FrostBurn, I don't find their codes.
 
Oh, after I changed the path... it crashed again...
Well, let's just forget about this annoying problem. Maybe I should use sound autoload since it's not a big deal to put my sounds file in sounds/file.
I'm wondering about another thing, though. How should I create a dot buff? Dot Buff like Burning or FrostBurn, I don't find their codes.
You mean debuff, right? You want to make a new buff? There is limited support right now for buffs, we're adding more hooks next update. For now, there is a single update hook that will let a buff affect a player each tick. The example mod on github has good examples of how the setup looks, and the wiki can help as well. https://github.com/bluemagic123/tModLoader/wiki/ModBuff

Unfortunately, some things will be impossible until next update. I can guide you if you tell me what kind of buff you are hoping to make.

Vanilla buffids are also on wiki if you want them.
 
You mean debuff, right? You want to make a new buff? There is limited support right now for buffs, we're adding more hooks next update. For now, there is a single update hook that will let a buff affect a player each tick. The example mod on github has good examples of how the setup looks, and the wiki can help as well. https://github.com/bluemagic123/tModLoader/wiki/ModBuff

Unfortunately, some things will be impossible until next update. I can guide you if you tell me what kind of buff you are hoping to make.

Vanilla buffids are also on wiki if you want them.
Okay. I know how to make basical buffs, only having a hard time on these dot buffs - I want to make some debuffs like burning ,frostburning or cursed inferno. Any luck about this?
 
Okay. I know how to make basical buffs, only having a hard time on these dot buffs - I want to make some debuffs like burning ,frostburning or cursed inferno. Any luck about this?
Hmm. I'll have to wait until I have my computer tomorrow, but the update method passes in a player object, so you can do whatever you want with that. I don't remember off the top of my head, but you can decrement player.statlife to lose health.

Cursed inferno and frostburn are both just life loss and prevent regen. Not sure how to do the prevent regen portion.
 
Hmm. I'll have to wait until I have my computer tomorrow, but the update method passes in a player object, so you can do whatever you want with that. I don't remember off the top of my head, but you can decrement player.statlife to lose health.

Cursed inferno and frostburn are both just life loss and prevent regen. Not sure how to do the prevent regen portion.
Seems complicated, maybe I'm supposed to wait till next update.

Now I got another super wired issue - my NPC disappears!
This is how I design this NPC:
Code:
using System;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace wch.NPCs
{
    public class UnicornPony : ModNPC
    {
        public override bool Autoload(ref string name, ref string texture)
        {
            name = "UnicornPony";
            return mod.Properties.Autoload;
        }

        public override void SetDefaults()
        {
            npc.name = "Unicorn Pony";
            npc.townNPC = true;
            npc.friendly = true;
            npc.width = 18;
            npc.height = 40;
            npc.aiStyle = 7;
            npc.damage = 10;
            npc.defense = 15;
            npc.lifeMax = 250;
            npc.soundHit = 1;
            npc.soundKilled = 1;
            npc.knockBackResist = 0.5f;
            Main.npcFrameCount[npc.type] = 26;
            NPCID.Sets.ExtraFramesCount[npc.type] = 9;
            NPCID.Sets.AttackFrameCount[npc.type] = 4;
            NPCID.Sets.DangerDetectRange[npc.type] = 200;
            NPCID.Sets.AttackType[npc.type] = 1;
            NPCID.Sets.AttackTime[npc.type] = 20;
            NPCID.Sets.AttackAverageChance[npc.type] = 25;
            animationType = NPCID.Guide;
        }

        public override void DrawTownAttackGun(ref float scale, ref int item, ref int closeness)
        {
            scale = 1f;
            item = ItemID.PlatinumBow;
            closeness = 12;
        }


        public override bool CanTownNPCSpawn(int numTownNPCs, int money)
        {
            for (int k = 0; k < 255; k++)
            {
                Player player = Main.player[k];
                if (player.active)
                {
                    for (int j = 0; j < player.inventory.Length; j++)
                    {
                        if (player.inventory[j].type == mod.ItemType("TestItem"))
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }


        public override string TownNPCName()
        {
            switch (WorldGen.genRand.Next(3))
            {
                case 0:
                    return "EnergySway";
                default:
                    return "CresentSpark";
            }
        }

        public override string GetChat()
        {
            switch (Main.rand.Next(3))
            {
                case 0:
                    return "What? You never seen a talking unicorn before?";
                default:
                    return "For the last time, I'm a PONY! Not a HORSE! Somebody just can't figure out the difference.";
            }
        }

        public override void SetChatButtons(ref string button, ref string button2)
        {
            button = Lang.inter[28];
        }

        public override void OnChatButtonClicked(bool firstButton, ref bool shop)
        {
            if (firstButton)
            {
                shop = true;
            }
        }

        public override void SetupShop(Chest shop, ref int nextSlot)
        {
            shop.item[nextSlot].SetDefaults(ItemID.WoodenArrow);
            nextSlot++;
            if (Main.moonPhase < 2)
            {
                shop.item[nextSlot].SetDefaults(mod.ItemType("WoodSheild"));
                nextSlot++;
            }
            else if (Main.moonPhase < 6)
            {
                shop.item[nextSlot].SetDefaults(mod.ItemType("LavaSheild"));
                nextSlot++;
            }
            else
            {
            }
        }

        public override void TownNPCAttackStrength(ref int damage, ref float knockback)
        {
            damage = 20;
            knockback = 4f;
        }

        public override void TownNPCAttackCooldown(ref int cooldown, ref int randExtraCooldown)
        {
            cooldown = 10;
            randExtraCooldown = 40;
        }

        public override void TownNPCAttackProj(ref int projType, ref int attackDelay)
        {
            projType = ProjectileID.JestersArrow;
            attackDelay = 5;
        }

        public override void TownNPCAttackProjSpeed(ref float multiplier, ref float gravityCorrection, ref float randomOffset)
        {
            multiplier = 12f;
            randomOffset = 2f;
        }
    }
}
Every time I log out the game, it will disappear. By "disappear", it's not delete. The NPC is still well loaded, but it needs to reappear every time I restart the game. Seems the game can't save the status of this NPC, what's wrong? This is pretty wired.
 
Hey, I looked at the example mod and found out pretty much every mod item requires the Example Item to be crafted and it's crafting recipe is a dirt block(and also the item itself?)

I can't craft it. Or do I need 999 dirt blocks? Can someone help?
 
Hey, I looked at the example mod and found out pretty much every mod item requires the Example Item to be crafted and it's crafting recipe is a dirt block(and also the item itself?)

I can't craft it. Or do I need 999 dirt blocks? Can someone help?

it should be craftable with dirt block
or did you change anythink in codes ?
 
Back
Top Bottom