Standalone [1.3] tModLoader - A Modding API

I bet their gonna make an update like if you got the mods off your character and the new mods on, you click on that ! thing and then it says Turn mods on. Would've been a cool thing if they did add it! :D
 
If this should be posted on another forum, please tell me. I'm trying to play with the NEWEST version of Calamity, as well as Tremor, Thorium, kRPG, and Spirit. When I try to load any world, it gives me this error:

Index was outside the bounds of the array.
at Terraria.ModLoader.GlobalItem.Instance(Item item)
at Terraria.ModLoader.ItemLoader.UpdateEquip(Item item, Player player)
at Terraria.Player.VanillaUpdateEquip(Item item)
at Terraria.Player.UpdateEquips(Int32 i)
at Terraria.Player.Update(Int32 i)
at Terraria.WorldGen.do_playWorldCallBack(Object threadContext)
at Terraria.WorldGen.playWorldCallBack(Object threadContext)

Please note that none of my worlds were loaded with the version of calamity that expanded the world. I went from a very old version straight to the newest.
 
Hi, I downloaded this two days ago, and when I launched Terraria it worked perfectly fine. I downloaded the Calamity Mod (the one w/o music and from the 'Mod Browser' section on the menu) and it was working perfectly when I began to play. Once I launch Terraria up again yesterday it freezes every time it gets to 'Initializing: CalamityMod'. Does anyone here know the solution to this? Because I'm new to this and I don't really know much. I tried taking out all the contents that the tModLoader came with and launched the 'vanilla' copy and it worked normally, then I reinstalled tModLoader and put back into the files but I still won't work. Any solutions that you guys know of? View attachment 222480
This may sound weird, but try clicking and holding on the background sun before it gets to this step and keep holding it until the mods load. It worked for me and honestly I have no idea why.
 
This may sound weird, but try clicking and holding on the background sun before it gets to this step and keep holding it until the mods load. It worked for me and honestly I have no idea why.
i have a question that is even weirder

what if you click and hold the moon instead?
 
cool, it's actually sad that there is no other easter eggs in menu

Wish if andrew added background changing option and moon colour changing. Like what i mean by background changing is like corruption biome on menu can be changed and the corruption can be changed with crimson and mushroom biome. And the forest biome would be able to changed to hallow.

Thats what i would've liked to be added in terraria so bad. With the Terraria sign changing everytime it shows one of these biome. Also the tree boi.
[doublepost=1560971253,1560971105][/doublepost]And yeah its sad there is no other secret in menu. Like, if they added a star falling from the sky in the night time menu. Which could only happen if you clicked the 5 stars in the midnight sky. so the moon would stop and then a star falls.
 
Just been working on a basic cheat npc mod. and i'm trying to add cross mod support. but i keep getting this error


("c:\Users\dylan\Documents\My Games\Terraria\ModLoader\Mod Sources\TheCheatNpc\NPCs\Kimi.cs(345,7) : error CS1513: } expected")



here is the code.


using System.Linq;
using Terraria;
using Terraria.ID;
using Terraria.Localization;
using Terraria.ModLoader;
using Terraria.Utilities;

namespace TheCheatNpc.NPCs
{
[AutoloadHead]
public class Kimi : ModNPC
{
public override string Texture
{
get
{
return "TheCheatNpc/NPCs/Kimi";
}
}

public override bool Autoload(ref string name)
{
name = "Kimi";
return mod.Properties.Autoload;
}

public override void SetStaticDefaults()
{
// DisplayName automatically assigned from .lang files, but the commented line below is the normal approach.
// DisplayName.SetDefault("Example Person");
Main.npcFrameCount[npc.type] = 25;
NPCID.Sets.ExtraFramesCount[npc.type] = 9;
NPCID.Sets.AttackFrameCount[npc.type] = 4;
NPCID.Sets.DangerDetectRange[npc.type] = 700;
NPCID.Sets.AttackType[npc.type] = 0;
NPCID.Sets.AttackTime[npc.type] = 90;
NPCID.Sets.AttackAverageChance[npc.type] = 30;
NPCID.Sets.HatOffsetY[npc.type] = 4;
}

public override void SetDefaults()
{
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.HitSound = SoundID.NPCHit1;
npc.DeathSound = SoundID.NPCDeath1;
npc.knockBackResist = 0.5f;
animationType = NPCID.DyeTrader;
}

public override void HitEffect(int hitDirection, double damage)
{
int num = npc.life > 0 ? 1 : 5;
for (int k = 0; k < num; k++)
{
Dust.NewDust(npc.position, npc.width, npc.height, mod.DustType("Sparkle"));
}
}

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("EssenceOfMadness"))

{
return true;
}
}
}
}
return false;
}

public override string TownNPCName()
{
switch (WorldGen.genRand.Next(4))
{
case 0:
return "Kimi";
case 1:
return "Kimi";
case 2:
return "Kimi";
default:
return "Kimi";
}
}

public override void FindFrame(int frameHeight)
{
/*npc.frame.Width = 40;
if (((int)Main.time / 10) % 2 == 0)
{
npc.frame.X = 40;
}
else
{
npc.frame.X = 0;
}*/
}

public override string GetChat()
{
int dryad = NPC.FindFirstNPC(NPCID.Dryad);
if (dryad >= 0 && Main.rand.Next(4) == 0)
{
return "Can you please tell " + Main.npc[dryad].GivenName + " that i want some plants for my shelves that i totally have?";
}
switch (Main.rand.Next(3))
{
case 0:
return "Sometimes I feel like I'm different from everyone else here.";
case 1:
return "I'll have Two Number Nines, A number 9 large, A number 6 with extra dip. two number 45s. one with cheese. and a large soda.";
default:
return "Well heres some items i guess.";
}
}

/*
// Consider using this alternate approach to choosing a random thing. Very useful for a variety of use cases.
// The WeightedRandom class needs "using Terraria.Utilities;" to use
public override string GetChat()
{
WeightedRandom<string> chat = new WeightedRandom<string>();

int partyGirl = NPC.FindFirstNPC(NPCID.PartyGirl);
if (partyGirl >= 0 && Main.rand.Next(4) == 0)
{
chat.Add("Can you please tell " + Main.npc[partyGirl].GivenName + " to stop decorating my house with colors?");
}
chat.Add("Sometimes I feel like I'm different from everyone else here.");
chat.Add("What's your favorite color? My favorite colors are white and black.");
chat.Add("What? I don't have any arms or legs? Oh, don't be ridiculous!");
chat.Add("This message has a weight of 5, meaning it appears 5 times more often.", 5.0);
chat.Add("This message has a weight of 0.1, meaning it appears 10 times as rare.", 0.1);
return chat; // chat is implicitly cast to a string. You can also do "return chat.Get();" if that makes you feel better
}
*/

public override void SetChatButtons(ref string button, ref string button2)
{
button = Language.GetTextValue("LegacyInterface.28");
}

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

public override void SetupShop(Chest shop, ref int nextSlot)
{
Mod thorium = ModLoader.GetMod("ThoriumMod");
if(thorium != null)
Mod calamity = ModLoader.GetMod("CalamityMod");
if(calamity != null)
Mod tremor = ModLoader.GetMod("Tremor");
if(tremor != null)
Mod spirit = ModLoader.GetMod("SpiritMod");
if(spirit != null)
{
shop.item[nextSlot].SetDefaults(ItemID.JungleYoyo);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.DirtBlock);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.MudBlock);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.TerraBlade);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.MedusaHead);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.HermesBoots);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.ArmorBracing);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Bezoar);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.CountercurseMantra);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.MedicatedBandage);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Megaphone);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.MoonStone);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.ObsidianRose);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.PocketMirror);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.RifleScope);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.SharkToothNecklace);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.ThePlan);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Vitamins);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.NecromanticScroll);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.HerculesBeetle);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.LuckyCoin);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.GoldRing);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.DiscountCard);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.NaturesGift);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.BandofStarpower);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.BandofRegeneration);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Blindfold);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Muramasa);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Starfury);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Arkhalis);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.IceBlade);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.BladedGlove);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Katana);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.FalconBlade);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.TaxCollectorsStickOfDoom);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.PsychoKnife);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Keybrand);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Spear);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Trident);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.DarkLance);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.IceBoomerang);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Flamarang);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.BloodyMachete);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.ChainGuillotines);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.ChainKnife);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Anchor);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Marrow);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.IceBow);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Boomstick);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Handgun);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Revolver);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.GrenadeLauncher);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.ElectrosphereLauncher);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Sandgun);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Harpoon);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Toxikarp);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.MagicMissile);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Flamelash);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Vilethorn);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.CrimsonRod);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.BatScepter);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.ClingerStaff);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.FlowerofFrost);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.LaserRifle);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.GoldenShower);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.CrystalStorm);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.MagnetSphere);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.WaterBolt);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.DemonScythe);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.ToxicFlask);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.ShadowFlameHexDoll);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.MagicDagger);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.UnholyTrident);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.SlimeStaff);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.HornetStaff);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.PirateStaff);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.RavenStaff);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Beenade);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.SpikyBall);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Shuriken);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Snowball);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.MolotovCocktail);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Javelin);
nextSlot++;
shop.item[nextSlot].SetDefaults(ItemID.Wood);
nextSlot++;
}
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 = 30;
randExtraCooldown = 30;
}

public override void TownNPCAttackProj(ref int projType, ref int attackDelay)
{
projType = mod.ProjectileType("SparklingBall");
attackDelay = 1;
}

public override void TownNPCAttackProjSpeed(ref float multiplier, ref float gravityCorrection, ref float randomOffset)
{
multiplier = 12f;
randomOffset = 2f;
}
}
}
 
Please use the code tags so that we keep the formatting. Code displayed as normal text, without preserving the whitespace, is hard to read.

Your problem is that your SetupShop() function is not properly closed, so it "eats" the next few functions (TownNPCAttackStrength, TownNPCAttackCooldown, etc.). You open one brace for the function's content, then you open another brace for the if (spirit != null) conditions, and then you have a loooong list of vanilla items you add (well over 40, so you'll need a shop extender if you want all 84 items I've counted to be actually available, in vanilla merchants have only 40 shop slots, you may want to address that), and then you close one brace, but not two.

Also this looks very wrong to me:
Code:
public override void SetupShop(Chest shop, ref int nextSlot)
{
Mod thorium = ModLoader.GetMod("ThoriumMod");
if(thorium != null)
Mod calamity = ModLoader.GetMod("CalamityMod");
if(calamity != null)
Mod tremor = ModLoader.GetMod("Tremor");
if(tremor != null)
Mod spirit = ModLoader.GetMod("SpiritMod");
if(spirit != null)
{

I'm not a C# coder, but I'm familiar enough with a lot of other C-family language (C, C++, Java, JavaScript, Perl, and a few more obscure scripting languages) and from that experience I'm pretty sure your thing cannot work.

If you don't use curly braces after an if () condition, only the next instruction is run. That means that if you don't have, for example, Thorium loaded, then thorium is null, so the next instruction (which is Mod calamity = ModLoader.GetMod("CalamityMod")) isn't run, so when you check calamity it'll be null too even if Calamity is loaded. Worst case, the calamity variable will not even exist and you'll get a crash.

You should instead do something like
Code:
Mod thorium = ModLoader.GetMod("ThoriumMod");
Mod calamity = ModLoader.GetMod("CalamityMod");
Mod tremor = ModLoader.GetMod("Tremor");
Mod spirit = ModLoader.GetMod("SpiritMod");
No condition checks there. Keep your condition checks only for when you're going to actually reference them. The way you've got that shop set up, the merchant will sell vanilla items if all four mods are loaded, and nothing if any mod is missing. I haven't actually seen any of your mod references being used.

Another thing, not a bug but still worth addressing is this:
Code:
       public override string TownNPCName()
       {
           switch (WorldGen.genRand.Next(4))
           {
           case 0:
               return "Kimi";
           case 1:
               return "Kimi";
           case 2:
               return "Kimi";
           default:
               return "Kimi";
           }
       }
If you're just gonna use Kimi as your NPC name, why bother making it random?
Code:
       public override string TownNPCName()
       {
           return "Kimi";
       }
That's all you need.
 
Hello, i am new at modding in Terraria and i have a question that really bothers me.

Where can i see what the members of SetDefaults(NPC npc) are?
For example, aiStyle, townNPC, damage and so on.

Thank you in advance.
 
@Proto Persona I don't think you understand what a "Mod" means, Why would Nintendo send a cease and desist letter to fans making a mod inspired by their characters in another video game? That never happened to the countless minecraft nintendo mods. And what would re-logic say about it? There is already countless mods made for terraria by the community, and (As far as I know) Re-Logic dosen't seem to mind it? I think you confused a fan made mod with an actual update for the game (much like journey's end for example) That would cause a copyright issue(If it was not allowed by nintendo) But this is a mod. not an update.
 
@Proto Persona I don't think you understand what a "Mod" means, Why would Nintendo send a cease and desist letter to fans making a mod inspired by their characters in another video game? That never happened to the countless minecraft nintendo mods. And what would re-logic say about it? There is already countless mods made for terraria by the community, and (As far as I know) Re-Logic dosen't seem to mind it? I think you confused a fan made mod with an actual update for the game (much like journey's end for example) That would cause a copyright issue(If it was not allowed by nintendo) But this is a mod. not an update.
Pokemon Brick Bronze Taken Down By Roblox | Heavy.com
 
Hello, I'm having a problem and I can't find anyone else having the same issue, or at least no one talks about it online.

I'm trying to create a modded Wings Item, based on Jim's Wing model (6 frames animation instead of the normal 4). I've come accross the WingUpdate() Function which is suppose to allow us to customize the animations and effects of the wings while in flight, but I don't exactly know how to use the player.wingFrameCounter and player.wingFrame to animate said wings.

Is there any example of modded wings that use more (or less) than 4 frames for their animation that I could refere to?

Thanks in advance.
 
Hello, I'm having a problem and I can't find anyone else having the same issue, or at least no one talks about it online.

I'm trying to create a modded Wings Item, based on Jim's Wing model (6 frames animation instead of the normal 4). I've come accross the WingUpdate() Function which is suppose to allow us to customize the animations and effects of the wings while in flight, but I don't exactly know how to use the player.wingFrameCounter and player.wingFrame to animate said wings.

Is there any example of modded wings that use more (or less) than 4 frames for their animation that I could refere to?

Thanks in advance.
I'd imagine it's the same deal as with tile animations. So, wingFrameCounter is just for keeping track of delay between frames, and wingFrame is what actually determines what gets drawn. The commented out section here is how it's done with tiles: tModLoader/tModLoader
 
Back
Top Bottom