• Journey's End on PC - Find info here and here. Please report bugs and issues for PC 1.4 and 1.4.1 to Re-Logic here.
  • Journey's End on Mobile - Find info here. Report bugs for Mobile 1.4 to DR Studios at this link and give as much detail as possible.
  • 1.4 will bring many changes to the PC version. We strongly advise making plans to back up your worlds and players prior to updating your game. More details here.
  • Console and Switch - The latest news can be found here. To report a bug, please use this link.

Standalone [1.3] tModLoader - A Modding API

xRaiizy

Official Terrarian
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?
 

sfraczak33

Steampunker
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;
}
}
}
 

Airarret

Terrarian
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.
 

LexiTrax

Terrarian
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.
 

IceTheGuy

Skeletron
@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.
 

Clockwork Alpha

Skeletron Prime
@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
 

charda-so

Terrarian
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.
 

DRKV

Golem
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
 

O.S Gaming

Terrarian
Also, im trying to make a weapon that every 5 projectile hits spawns a flamethrower. I have made a seperate variable in which I use to keep track of how many projectile hits. The script compiles without issue, but it just isnt working in-game
 

Airarret

Terrarian
Copyright holders don't police for violations such as mods all that stringently. Once they are made aware of such content though, they will move to take it down. By US copyright laws they have to or they risk losing the IP to public domain. It doesn't matter if it's a mod. It doesn't matter if no one is making money from it. All that matters is if you are using their intellectual property.
Not exactly.

There are three different kinds of intellectual properties: copyright, trademark, and patent. Copyright is automatically granted at creation, and lasts for a long, long time. For a personal creation, it's 70 years after the author's death; for a corporate creation it's 120 years after creation or 95 years after publication. Once copyright expires, a work falls in the public domain; however because of the very long time it lasts, do not expect to see anything created in your lifetime to ever become public domain. No video game will ever become public domain by expiration of their copyright term while most of us are alive. However, it is possible for a copyright holder to voluntarily release something in the public domain, or to make it available under a permissive license (e.g. Creative Content stuff).

Trademark is what you can lose if you do not defend it. While copyright concerns a creative work, the trademark concerns "product identity", that is to say, basically branding. Contrarily to copyright, trademark is not automatic, you need to declare it to the concerned authorities and describe precisely the elements that make up your trademark (titles, logos, mascot characters, special glyphs, etc.) and you also need to define in what domain your trademark applies (e.g., a "Terraria" brand of fertilizers would not infringe on Re-Logic's trademark because it wouldn't be a video game). A recent example of trademark dispute in video game is Voidpoint and 3D Realms getting sued by Iron Maiden (yeah, the band) over their game Ion Maiden (note the lack of 'r'), as they find the title far too close. Notice that here, there is no copyright infringement involved, nobody is accusing Ion Maiden of containing Iron Maiden content, they're accusing it of having a name and some other superficial elements that could cause Iron Maiden fans to believe it's an official Iron Maiden game.
 
Last edited:
Top Bottom