Standalone [1.3] tModLoader - A Modding API

N o clu but what I believe that I did was delete my character manually and gave him all his stuff back...
[doublepost=1498107265,1498106718][/doublepost]I will be back in the morning. If someone can reply to both our ?'s that would be awesome.
 
I keep getting this message when I load up terraria and it goes through my mods.
Field not found: 'Terraria.Item.toolTip2'.
at TrueEater.GlobalTrueItem.SetDefaults(Item item)
at Terraria.ModLoader.ItemLoader.SetDefaults(Item item, Boolean createModItem)
at Terraria.ModLoader.Mod.SetupContent()
at Terraria.ModLoader.ModLoader.do_Load(Object threadContext)

And every time I click "Ok" to let it disable the mod. It just does it again. I did it for 10 mins strait once.
disable that mod, it's outdated.
[doublepost=1498109645,1498109615][/doublepost]
hey jopojelly, thx for the help. I got another problem tho
Missing mod: ApocalyplseMOD/Items/BreastplateName_Body
at Terraria.ModLoader.ModLoader.GetTexture(String name)
at Terraria.ModLoader.Mod.AddEquipTexture(EquipTexture equipTexture, ModItem item, EquipType type, String name, String texture, String armTexture, String femaleTexture)
at Terraria.ModLoader.Mod.AddEquipTexture(ModItem item, EquipType type, String name, String texture, String armTexture, String femaleTexture)
at Terraria.ModLoader.Mod.AutoloadItem(Type type)
at Terraria.ModLoader.Mod.Autoload()
at Terraria.ModLoader.ModLoader.do_Load(Object threadContext)

here is code

using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
namespace ApocalyplseMOD.Items
{
[AutoloadEquip(EquipType.Body)]
public class BreastplateName : ModItem
{
public override void SetStaticDefaults()
{
base.SetStaticDefaults();
DisplayName.SetDefault("Solar breastplate");
Tooltip.SetDefault("I wanna be a mage when i grow up!"
+ "\nImmunity to 'On Fire!'"
+ "\n+20 max mana and +1 max minions");
}
public override void SetDefaults()
{
item.width = 18;
item.height = 18;
item.value = 10000;
item.rare = 2;
item.defense = 8;
}
public override void UpdateEquip(Player player)
{
player.buffImmune[BuffID.OnFire] = true;
player.statManaMax2 += 20;
player.maxMinions++;
}
public override void AddRecipes()
{
ModRecipe recipe = new ModRecipe(mod);
recipe.AddIngredient(mod, "StarBar", 20);
recipe.AddTile(TileID.Anvils);
recipe.SetResult(this);
recipe.AddRecipe();
}
}
}
read this: https://github.com/blushiemagic/tModLoader/wiki/Basic-tModLoader-Modding-FAQ
 
I got a projectile (Named "CataclysmicLife") to spawn the "SpiritHeal" projectile upon hitting an NPC, but the SpiritHeal projectile does not heal me, even with the Spectre Hood equipped. Is there something I'm missing?
The mod loads fine, though. Here's the code:
Code:
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace JoshuasMod.Projectiles     //We need this to basically indicate the folder where it is to be read from, so you the texture will load correctly.
{
    public class ValkyrieBlade : ModProjectile
    {
        public override void SetDefaults()
        {
            projectile.width = 80;
            projectile.height = 80;
            projectile.aiStyle = -1;
            projectile.friendly = true;
            projectile.melee = true;
            projectile.penetrate = 3;
            projectile.tileCollide = false;
            projectile.ignoreWater = true;
        }

        // NewTileCollideStyle is the replacement for TileCollideStyle, but we will support the old TileCollideStyle until a new vanilla release, at which time NewTileCollideStyle will become TileCollideStyle
        public override bool TileCollideStyle(ref int width, ref int height, ref bool fallThrough)
        {
            // For going through platforms and such, javelins use a tad smaller size
            width = 20;
            height = 20;
            return true;
        }

        public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox)
        {
            // Inflate some target hitboxes if they are beyond 8,8 size
            if (targetHitbox.Width > 8 && targetHitbox.Height > 8)
            {
                targetHitbox.Inflate(-targetHitbox.Width / 8, -targetHitbox.Height / 8);
            }
            // Return if the hitboxes intersects, which means the javelin collides or not
            return projHitbox.Intersects(targetHitbox);
        }

        public override void Kill(int timeLeft)
        {
            Main.PlaySound(0, (int)projectile.position.X, (int)projectile.position.Y, 1, 1f, 0f); // Play a death sound
        }

        // Here's an example on how you could make your AI even more readable, by giving AI fields more descriptive names
        // These are not used in AI, but it is good practice to apply some form like this to keep things organized
        public float isStickingToTarget
        {
            get { return projectile.ai[0]; }
            set { projectile.ai[0] = value; }
        }

        public float targetWhoAmI
        {
            get { return projectile.ai[1]; }
            set { projectile.ai[1] = value; }
        }

        public override void ModifyHitNPC(NPC target, ref int damage, ref float knockback, ref bool crit, ref int hitDirection)
        {
            // If you'd use the example above, you'd do: isStickingToTarget = 1f;
            // and: targetWhoAmI = (float)target.whoAmI;
            projectile.ai[0] = 1f; // Set ai0 state to 1f
            projectile.ai[1] = (float)target.whoAmI; // Set the target whoAmI
            projectile.velocity = (target.Center - projectile.Center) * 0.75f; // Change velocity based on delta center of targets (difference between entity centers)
            projectile.netUpdate = true; // netUpdate this javelin
            target.AddBuff(BuffID.CursedInferno, 10 * 60, true); // Unsure what this does, but it was in the vanilla code

            projectile.damage = 0; // Makes sure the sticking javelins do not deal damage anymore
            // The following code handles the javelin sticking to the enemy hit.

            int maxStickingJavelins = 6; // This seems to be the maximum amount of javelins being able to attach
            Point[] stickingJavelins = new Point[maxStickingJavelins]; // The point array holding for sticking javelins
            int javelinIndex = 0; // The javelin index
            for (int i = 0; i < Main.maxProjectiles; i++) // Loop all projectiles
            {
                Projectile currentProjectile = Main.projectile[i];
                if (i != projectile.whoAmI  // Make sure the looped projectile is not the current javelin
                    && currentProjectile.active // Make sure the projectile is active
                    && currentProjectile.owner == Main.myPlayer // Make sure the projectile's owner is the client's player
                    && currentProjectile.type == projectile.type // Make sure the projectile is of the same type as this javelin
                    && currentProjectile.ai[0] == 1f // Make sure ai0 state is set to 1f (set earlier in ModifyHitNPC)
                    && currentProjectile.ai[1] == (float)target.whoAmI) // Make sure ai1 is set to the target whoAmI (set earlier in ModifyHitNPC)
                {
                    stickingJavelins[javelinIndex++] = new Point(i, currentProjectile.timeLeft); // Add the current projectile's index and timeleft to the point array
                    if (javelinIndex >= stickingJavelins.Length) // If the javelin's index is bigger than or equal to the point array's length, break
                    {
                        break;
                    }
                }
            }
            // Here we loop the other javelins if new javelin needs to take an older javelin's place.
            if (javelinIndex >= stickingJavelins.Length)
            {
                int oldJavelinIndex = 0;
                // Loop our point array
                for (int i = 1; i < stickingJavelins.Length; i++)
                {
                    // Remove the already existing javelin if it's timeLeft value (which is the Y value in our point array) is smaller than the new javelin's timeLeft
                    if (stickingJavelins[i].Y < stickingJavelins[oldJavelinIndex].Y)
                    {
                        oldJavelinIndex = i; // Remember the index of the removed javelin
                    }
                }
                // Remember that the X value in our point array was equal to the index of that javelin, so it's used here to kill it.
                Main.projectile[stickingJavelins[oldJavelinIndex].X].Kill();
            }
        }
       
        // Added these 2 constant to showcase how you could make AI code cleaner by doing this
        // Change this number if you want to alter how long the javelin can travel at a constant speed
        private const float maxTicks = 56.25f;
        // Change this number if you want to alter how the alpha changes
        private const int alphaReduction = 25;

        public override void AI()
        {
            // Slowly remove alpha as it is present
            if (projectile.alpha > 0)
            {
                projectile.alpha -= alphaReduction;
            }
            // If alpha gets lower than 0, set it to 0
            if (projectile.alpha < 0)
            {
                projectile.alpha = 0;
            }
            // If ai0 is 0f, run this code. This is the 'movement' code for the javelin as long as it isn't sticking to a target
            if (projectile.ai[0] == 0f)
            {
                projectile.ai[1] += 0.85f;
                // For a little while, the javelin will travel with the same speed, but after this, the javelin drops velocity very quickly.
                if (projectile.ai[1] >= maxTicks)
                {
                    // Change these multiplication factors to alter the javelin's movement change after reaching maxTicks
                    float velXmult = 0.99f; // x velocity factor, every AI update the x velocity will be 99% faster than the original speed
                    float velYmult = 0.25f; // y velocity factor, every AI update the y velocity will be be 0.35f bigger of the original speed, causing the javelin to drop to the ground
                    projectile.ai[1] = maxTicks; // set ai1 to maxTicks continuously
                    projectile.velocity.X = projectile.velocity.X * velXmult;
                    projectile.velocity.Y = projectile.velocity.Y + velYmult;
                }
                // Make sure to set the rotation accordingly to the velocity, and add some to work around the sprite's rotation
                projectile.rotation = projectile.velocity.ToRotation() + MathHelper.ToRadians(45f); // Please notice the MathHelper usage, offset the rotation by 90 degrees (to radians because rotation uses radians) because the sprite's rotation is not aligned!
            }
            // This code is ran when the javelin is sticking to a target
            if (projectile.ai[0] == 1f)
            {
                // These 2 could probably be moved to the ModifyNPCHit hook, but in vanilla they are present in the AI
                projectile.ignoreWater = true; // Make sure the projectile ignores water
                projectile.tileCollide = false; // Make sure the projectile doesn't collide with tiles anymore
                int aiFactor = 10; // Change this factor to change the 'lifetime' of this sticking javelin
                bool killProj = false; // if true, kill projectile at the end
                bool hitEffect = true; // if true, perform a hit effect
                projectile.localAI[0] += 1f; 
                // Every 30 ticks, the javelin will perform a hit effect
                hitEffect = projectile.localAI[0] % 30f == 0f;
                int projTargetIndex = (int)projectile.ai[1];
                if (projectile.localAI[0] >= (float)(60 * aiFactor)) // If it's time for this javelin to die, kill it
                {
                    killProj = true;
                }
                else if (projTargetIndex < 0 || projTargetIndex >= 200) // If the index is past its limits, kill the javelin
                {
                    killProj = true;
                }
                else if (Main.npc[projTargetIndex].active && !Main.npc[projTargetIndex].dontTakeDamage) // If the target is active and can take damage
                {
                    // Set the projectile's position relative to the target's center
                    projectile.Center = Main.npc[projTargetIndex].Center - projectile.velocity * 2f;
                    projectile.gfxOffY = Main.npc[projTargetIndex].gfxOffY;
                    if (hitEffect) // Perform a hit effect here
                    {
                        Main.npc[projTargetIndex].HitEffect(0, 1.0);
                    }
                }
                else // Otherwise, kill the projectile
                {
                    killProj = true;
                }

                if (killProj) // Kill the projectile
                {
                    projectile.Kill();
                }
            }
        }
    }
}
}
 
Last edited:
You, sir, helped a ton :D
But one more (very nooby) question:
How do I change the Influx Waver Projectile to a custom/modded projectile?

Here's the code again:
Code:
                Vector2 vector2_1 = new Vector2((float)((double)player.position.X + (double)player.width * 0.5 + (double)(Main.rand.Next(100) * -player.direction) + ((double)Main.mouseX + (double)Main.screenPosition.X - (double)player.position.X)), (float)((double)player.position.Y + (double)player.height * 0.5 - 600.0));   //This defines the projectile width, direction and position.
                vector2_1.X = (float)(((double)vector2_1.X + (double)player.Center.X) / 2.0) + (float)Main.rand.Next(-100, 100);
                vector2_1.Y -= (float)(100 * index);
                float num12 = (float)Main.mouseX + Main.screenPosition.X - vector2_1.X;
                float num13 = (float)Main.mouseY + Main.screenPosition.Y - vector2_1.Y;
                if ((double)num13 < 0.0) num13 *= -1f;
                if ((double)num13 < 20.0) num13 = 20f;
                float num14 = (float)Math.Sqrt((double)num12 * (double)num12 + (double)num13 * (double)num13);
                float num15 = item.shootSpeed / num14;
                float num16 = num12 * num15;
                float num17 = num13 * num15;
                float SpeedX = num16 + (float)Main.rand.Next(-12, 10) * 0.160f;  //This defines the projectile X position speed and randomness.
                float SpeedY = num17 + (float)Main.rand.Next(-12, 10) * 0.160f;  //This defines the projectile Y position speed and randomness.
                Projectile.NewProjectile(vector2_1.X, vector2_1.Y, SpeedX, SpeedY, type, damage, knockBack, Main.myPlayer, 0.0f, (float)Main.rand.Next(5));
                Projectile.NewProjectile(vector2_1.X, vector2_1.Y, SpeedX * 0.5f, SpeedY * 0.5f, ProjectileID.InfluxWaver, damage * 2, knockBack, Main.myPlayer, 0.0f, (float)Main.rand.Next(5));[/SPOILER]
Sure thing, here's how to get the type of a moded projectile:
Code:
mod.ProjectileType("YourProjectile'sClassName")
This goes where you "have ProjectileID.InfluxWaver"

I got a projectile (Named "CataclysmicLife") to spawn the "SpiritHeal" projectile upon hitting an NPC, but the SpiritHeal projectile does not heal me, even with the Spectre Hood equipped. Is there something I'm missing?
The mod loads fine, though. Here's the code:
Code:
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace JoshuasMod.Projectiles
{

    public class CataclysmicLife : ModProjectile
    {
        public override void SetDefaults()
        {
            projectile.width = 60;
            projectile.height = 140;
            projectile.friendly = true;
            projectile.melee = true;
            projectile.tileCollide = false;
            projectile.penetrate = -1;
            projectile.timeLeft = 900;
            projectile.light = 0.75f;
            projectile.extraUpdates = 1;
            projectile.tileCollide = false;
            projectile.ignoreWater = true;
        }
      
        public override void AI()
        {
            projectile.rotation = (float)Math.Atan2((double)projectile.velocity.Y, (double)projectile.velocity.X) + 1.75f; 
        }
      
        public override void OnHitNPC(NPC target, int damage, float knockback, bool crit)
        {
                int ShotAmt = 1;
                int spread = 1;
                float spreadMult = 0.9f;
                for (int i = 0; i < ShotAmt; i++)
                {
                    float vX = projectile.velocity.X + (float)Main.rand.Next(-spread, spread + 1) * spreadMult;
                    float vY = projectile.velocity.Y + (float)Main.rand.Next(-spread, spread + 1) * spreadMult;
                    Projectile.NewProjectile(projectile.position.X, projectile.position.Y, vX / 2, vY / 2, ProjectileID.SpiritHeal, projectile.damage * 5, -10f, 0);
                }
          
            target.AddBuff(BuffID.DryadsWardDebuff, 5 * 60);
        }
    }
}
Looks like you need to set the SpiritHeal projectile's AI[0] to the ID of the player that you want to heal, and the owner of the projectile to the ID of the player who created the projectile. I havn't tested this though, so I don't know if it will work.
 
Sure thing, here's how to get the type of a moded projectile:
Code:
mod.ProjectileType("YourProjectile'sClassName")
This goes where you "have ProjectileID.InfluxWaver"
I personally prefer mod.ProjectileType<YourProjectileClass>(); but to each their own I guess.
 
Help!When i try host/join hosted server by my friend my game crash!What to do?(Steam,Linux)
Mods does not affect because even when I turn off all the mods the game again crash when i host...
And game starting at 2nd-3rd time with tmodloader...
 
disable that mod, it's outdated.



I cant disable the mod. I wont let me get to the menu
[doublepost=1498143414,1498143366][/doublepost]oops lel just move that last part out of the box
[doublepost=1498143749][/doublepost]Field not found: 'Terraria.Item.toolTip2'.
at TrueEater.GlobalTrueItem.SetDefaults(Item item)
at Terraria.ModLoader.ItemLoader.SetDefaults(Item item, Boolean createModItem)
at Terraria.ModLoader.Mod.SetupContent()
at Terraria.ModLoader.ModLoader.do_Load(Object threadContext)


It keeps popping up even after I click "ok" to continue to the menu.
 
[doublepost=1498143414,1498143366][/doublepost]oops lel just move that last part out of the box
[doublepost=1498143749][/doublepost]Field not found: 'Terraria.Item.toolTip2'.
at TrueEater.GlobalTrueItem.SetDefaults(Item item)
at Terraria.ModLoader.ItemLoader.SetDefaults(Item item, Boolean createModItem)
at Terraria.ModLoader.Mod.SetupContent()
at Terraria.ModLoader.ModLoader.do_Load(Object threadContext)


It keeps popping up even after I click "ok" to continue to the menu.
Go to %UserProfile%/Documents/My Games/Terraria/ModLoader/Mods (paste this in your windows explorer path) and remove the TrueEater.enabled file
This should stop the file from loading
 
@blushiemagic You might want to catch some Exceptions during loading mods.
The reason for it is that I managed to get a NullReferenceException during loading one of my mods, which I wanted to update for the current version of tModLoader.
The Exception is not handled, since Terraria itself crashed and I can't identify why it happens since - because of the lack of handling - the application doesn't write it into the log.
I know it's nearly impossible (or isn't possible at all) to identify what code causes this mod-wise at runtime but we don't actually need that. A little hint on what has thrown the exception (in the application itself) would be enough.
 
Okay so I'm working on this mod and I already merged all my items to 0.10, however. whenever I try to reload it the game crashes without a trace... I have no idea how to fix this, any help? thanks in advance!
 
Okay so I'm working on this mod and I already merged all my items to 0.10, however. whenever I try to reload it the game crashes without a trace... I have no idea how to fix this, any help? thanks in advance!

I guess that's what I was talking about in my previous post. It's hard to locate the source of the problem without logging, I'm also having this problem right now.
 
I guess that's what I was talking about in my previous post. It's hard to locate the source of the problem without logging, I'm also having this problem right now.
oh sorry I missed that, and yeah I tried just using a single item as a mod ( no dusts or projectiles or anything ) and it was still crashing... oh well
 
I don't think it's tModLoader itself, but after 10 minutes of playing my game will crash with no reason why. I've since downgraded to the previous version of all my mods and can run it fine. I don't know where my logs are or where/if i can find them, i did a clean wipe of everything. Could it be an unstable mod/bug that's causing my issue?
 
Hi, so I've been playing on a PC for the last couple days and had no problems, but today, I had to switch to my Mac and after installing tModLoader, my game freezes after the Re-Logic splash. I've tried using the .jar file and manually installing on two users and I've gotten the freeze every time except for one, and that was the first launch after installing. Is this just a thing? Please help.
 
upload_2017-6-23_14-5-37.png


How can i solve this ?
 
My game crashed after I talked to the guide, while using a gamepad. I think the fact that I was using a gamepad was the issue, since I saw it is the crash log.

The given key was not present in the dictionary.
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at Terraria.Initializers.UILinksInitializer.<>c__DisplayClass3_0.<Load>b__58()
at Terraria.UI.Gamepad.UILinkPage.Update()
at Terraria.UI.Gamepad.UILinkPointNavigator.Update()
at Terraria.Main.DoUpdate_HandleInput()
at Terraria.Main.DoUpdate(GameTime gameTime)
at Terraria.Main.Update(GameTime gameTime)
 
My game crashed after I talked to the guide, while using a gamepad. I think the fact that I was using a gamepad was the issue, since I saw it is the crash log.

The given key was not present in the dictionary.
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at Terraria.Initializers.UILinksInitializer.<>c__DisplayClass3_0.<Load>b__58()
at Terraria.UI.Gamepad.UILinkPage.Update()
at Terraria.UI.Gamepad.UILinkPointNavigator.Update()
at Terraria.Main.DoUpdate_HandleInput()
at Terraria.Main.DoUpdate(GameTime gameTime)
at Terraria.Main.Update(GameTime gameTime)
I've gotten the same error while reloading mods with a gamepad connected. It's a bug that's been around for a while, though I haven't had it come up while speaking to the guide.
 
Back
Top Bottom