Standalone [1.3] tModLoader - A Modding API

hey does some one know how to make this tile have a certain hit sound and Pickaxe Requirement??
Code:
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ModLoader;

namespace Trelamium.Tiles
{
    public class TrelamiumOreTile : ModTile
    {
        public override void SetDefaults()
        {
            Main.tileSolid[Type] = true;
            Main.tileMergeDirt[Type] = true;
            Main.tileBlockLight[Type] = true;  //true for block to emit light
            Main.tileLighted[Type] = true;
            drop = mod.ItemType("TrelamiumOre");   //put your CustomBlock name
            AddMapEntry(new Color(80, 80, 80));
        }
    }
}
 
i
Can you define error in the code? I've only installed and updated mods, but it is definitely a mod causing it
[doublepost=1487606608][/doublepost]
Counterpart as in basic elemental addition
meant like a typo in the code. if i saw your code i could probly help but i mightnot be your #1 option for help because i only worked on a few varies of codes
[doublepost=1487626333,1487626236][/doublepost]i
Can you define error in the code? I've only installed and updated mods, but it is definitely a mod causing it
[doublepost=1487606608][/doublepost]
Counterpart as in basic elemental addition
meant like a typo in the code. if i saw your code i could probly help but i mightnot be your #1 option for help because i only worked on a few varies of codes
 
hey does some one know how to make this tile have a certain hit sound and Pickaxe Requirement??
Code:
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ModLoader;

namespace Trelamium.Tiles
{
    public class TrelamiumOreTile : ModTile
    {
        public override void SetDefaults()
        {
            Main.tileSolid[Type] = true;
            Main.tileMergeDirt[Type] = true;
            Main.tileBlockLight[Type] = true;  //true for block to emit light
            Main.tileLighted[Type] = true;
            drop = mod.ItemType("TrelamiumOre");   //put your CustomBlock name
            AddMapEntry(new Color(80, 80, 80));
        }
    }
}
You would add the minPick = put number here; code to the set defaults. Hope this helps :)
 
Hi Pros.

Can somebody explain me the height and width system? When i create a Modtile.

In the tModLoader gitHub is saw some samples:
Code:
TileObjectData.newTile.CopyFrom(TileObjectData.Style2x2);
What does the 2x2 means in pixel?

When i have for example a 38x42px images. What i need to set as style? Or did i need:
Code:
TileObjectData.newTile.Width = 38;
TileObjectData.newTile.Height = 42;
Nothing works well at the moment.

What is one pixel there? For example i have the extractinator (not animated):
NG6eftm.png


And by the way what i need to set if i wan't to animate that?

THX
 
I dare to ask this as I'm sure it's been asked many times, but to save me looking through 700 odd pages - what is the deal with the bugged mannequins. Is it a fixable issue or a just dead as dead unfixable.
 
as far as i know.
every Sprite in Terraria, a "Pixel" on the Sprite is actually 2x2 Pixels.
so i assume when you set the Size you need the actual File Resolution X and Y.
Not sure if anyone even Follows that other than Vanilla Terraria.
 
Hejo Guys, i am pretty new into this whole Modding Stuff. I tried to create a Worm Boss just like the Eater of worlds. (i used a template)
It all works fine, he spawns, music kicks in, he attacks me...
BUT
After some time parts of him despawn. And if i die the Head stays and keeps following me :O
Halp plz :D
Code:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace MementoMod.NPCs.DimensionWorm
{
    public class WormHead : ModNPC
    {

        public override void SetDefaults()
        {
            npc.name = "The Eater of Dimensions";        //this is the npc Name
            npc.displayName = "The Eater of Dimensions";
            npc.lifeMax = 750000;        //this is the npc health
            npc.damage = 200;    //this is the npc damage
            npc.defense = 100;         //this is the npc defense
            npc.aiStyle = -1;
            npc.knockBackResist = 0f;
            npc.width = 200; //this is where you put the npc sprite width.     important
            npc.height = 318; //this is where you put the npc sprite height.   important
            npc.boss = true;
            npc.lavaImmune = true;       //this make the npc immune to lava
            npc.noGravity = true;           //this make the npc float
            npc.noTileCollide = true;        //this make the npc go tru walls
            npc.behindTiles = true;
            Main.npcFrameCount[npc.type] = 1;
            npc.value = Item.buyPrice(0, 20, 0, 0);
            npc.npcSlots = 5f;
            npc.netAlways = true;
            music = MusicID.Boss2;
            npc.HitSound = SoundID.NPCHit1;
            npc.DeathSound = SoundID.NPCDeath1;
            animationType = NPCID.TheDestroyer;
            NPCID.Sets.MustAlwaysDraw[npc.type] = true;
            npc.behindTiles = true;
            npc.value = 120000f;
            npc.alpha = (int) byte.MaxValue;
        }
       
        public override void AI()
        {
            if (npc.localAI[0] == 0f)
            {
                Main.PlaySound(SoundID.Roar, npc.position, 0);
                npc.localAI[0] = 1f;
            }
            npc.velocity.Y += 1f;
            if (npc.timeLeft > 10)
            {
                npc.timeLeft = 10;
            }
        }
       
        public override bool Autoload(ref string name, ref string texture, ref string[] altTextures)
        {
            texture = "MementoMod/NPCs/DimensionWorm/WormHead";
            return mod.Properties.Autoload;
        }
       
        public virtual bool CheckActive()
        {
            return true;
        }

        public override void BossLoot(ref string name, ref int potionType)
        {
            potionType = ItemID.LesserHealingPotion;   //boss drops
            Item.NewItem((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height, mod.ItemType("DimensionBreaker"));
        }
        public override void ScaleExpertStats(int numPlayers, float bossLifeScale)
        {
            npc.lifeMax = (int)(npc.lifeMax * 0.579f * bossLifeScale);  //boss life scale in expertmode
            npc.damage = (int)(npc.damage * 0.6f);  //boss damage increase in expermode
        }
       
        public override bool PreAI()
        {
            if (Main.netMode != 1)
            {
                // So, we start the AI off by checking if npc.ai[0] is 0.
                // This is practically ALWAYS the case with a freshly spawned NPC, so this means this is the first update.
                // Since this is the first update, we can safely assume we need to spawn the rest of the worm (bodies + tail).
                if (npc.ai[0] == 0)
                {
                    // So, here we assing the npc.realLife value.
                    // The npc.realLife value is mainly used to determine which NPC loses life when we hit this NPC.
                    // We don't want every single piece of the worm to have its own HP pool, so this is a neat way to fix that.
                    npc.realLife = npc.whoAmI;
                    // LatestNPC is going to be used later on and I'll explain it there.
                    int latestNPC = npc.whoAmI;

                    // Here we determine the length of the worm.
                    // In this case the worm will have a length of 10 to 14 body parts.
                    int randomWormLength = Main.rand.Next(40, 40);
                    for (int i = 0; i < randomWormLength; ++i)
                    {
                        // We spawn a new NPC, setting latestNPC to the newer NPC, whilst also using that same variable
                        // to set the parent of this new NPC. The parent of the new NPC (may it be a tail or body part)
                        // will determine the movement of this new NPC.
                        // Under there, we also set the realLife value of the new NPC, because of what is explained above.
                        latestNPC = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, mod.NPCType("WormBody"), npc.whoAmI, 0, latestNPC);
                        Main.npc[(int)latestNPC].realLife = npc.whoAmI;
                        Main.npc[(int)latestNPC].ai[3] = npc.whoAmI;
                    }
                    // When we're out of that loop, we want to 'close' the worm with a tail part!
                    latestNPC = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, mod.NPCType("WormTail"), npc.whoAmI, 0, latestNPC);
                    Main.npc[(int)latestNPC].realLife = npc.whoAmI;
                    Main.npc[(int)latestNPC].ai[3] = npc.whoAmI;

                    // We're setting npc.ai[0] to 1, so that this 'if' is not triggered again.
                    npc.ai[0] = 1;
                    npc.netUpdate = true;
                }
            }

            int minTilePosX = (int)(npc.position.X / 16.0) - 1;
            int maxTilePosX = (int)((npc.position.X + npc.width) / 16.0) + 2;
            int minTilePosY = (int)(npc.position.Y / 16.0) - 1;
            int maxTilePosY = (int)((npc.position.Y + npc.height) / 16.0) + 2;
            if (minTilePosX < 0)
                minTilePosX = 0;
            if (maxTilePosX > Main.maxTilesX)
                maxTilePosX = Main.maxTilesX;
            if (minTilePosY < 0)
                minTilePosY = 0;
            if (maxTilePosY > Main.maxTilesY)
                maxTilePosY = Main.maxTilesY;

            bool collision = false;
            // This is the initial check for collision with tiles.
            for (int i = minTilePosX; i < maxTilePosX; ++i)
            {
                for (int j = minTilePosY; j < maxTilePosY; ++j)
                {
                    if (Main.tile[i, j] != null && (Main.tile[i, j].nactive() && (Main.tileSolid[(int)Main.tile[i, j].type] || Main.tileSolidTop[(int)Main.tile[i, j].type] && (int)Main.tile[i, j].frameY == 0) || (int)Main.tile[i, j].liquid > 64))
                    {
                        Vector2 vector2;
                        vector2.X = (float)(i * 16);
                        vector2.Y = (float)(j * 16);
                        if (npc.position.X + npc.width > vector2.X && npc.position.X < vector2.X + 16.0 && (npc.position.Y + npc.height > (double)vector2.Y && npc.position.Y < vector2.Y + 16.0))
                        {
                            collision = true;
                            if (Main.rand.Next(100) == 0 && Main.tile[i, j].nactive())
                                WorldGen.KillTile(i, j, true, true, false);
                        }
                    }
                }
            }
            // If there is no collision with tiles, we check if the distance between this NPC and its target is too large, so that we can still trigger 'collision'.
            if (!collision)
            {
                Rectangle rectangle1 = new Rectangle((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height);
                int maxDistance = 800;
                bool playerCollision = true;
                for (int index = 0; index < 255; ++index)
                {
                    if (Main.player[index].active)
                    {
                        Rectangle rectangle2 = new Rectangle((int)Main.player[index].position.X - maxDistance, (int)Main.player[index].position.Y - maxDistance, maxDistance * 2, maxDistance * 2);
                        if (rectangle1.Intersects(rectangle2))
                        {
                            playerCollision = false;
                            break;
                        }
                    }
                }
                if (playerCollision)
                    collision = true;
            }

            // speed determines the max speed at which this NPC can move.
            // Higher value = faster speed.
            float speed = 40f;
            // acceleration is exactly what it sounds like. The speed at which this NPC accelerates.
            float acceleration = 0.17f;

            Vector2 npcCenter = new Vector2(npc.position.X + npc.width * 0.5f, npc.position.Y + npc.height * 0.5f);
            float targetXPos = Main.player[npc.target].position.X + (Main.player[npc.target].width / 2);
            float targetYPos = Main.player[npc.target].position.Y + (Main.player[npc.target].height / 2);

            float targetRoundedPosX = (float)((int)(targetXPos / 16.0) * 16);
            float targetRoundedPosY = (float)((int)(targetYPos / 16.0) * 16);
            npcCenter.X = (float)((int)(npcCenter.X / 16.0) * 16);
            npcCenter.Y = (float)((int)(npcCenter.Y / 16.0) * 16);
            float dirX = targetRoundedPosX - npcCenter.X;
            float dirY = targetRoundedPosY - npcCenter.Y;

            float length = (float)Math.Sqrt(dirX * dirX + dirY * dirY);
            // If we do not have any type of collision, we want the NPC to fall down and de-accelerate along the X axis.
            if (!collision)
            {
                npc.TargetClosest(true);
                npc.velocity.Y = npc.velocity.Y + 0.11f;
                if (npc.velocity.Y > speed)
                    npc.velocity.Y = speed;
                if (Math.Abs(npc.velocity.X) + Math.Abs(npc.velocity.Y) < speed * 0.4)
                {
                    if (npc.velocity.X < 0.0)
                        npc.velocity.X = npc.velocity.X - acceleration * 1.1f;
                    else
                        npc.velocity.X = npc.velocity.X + acceleration * 1.1f;
                }
                else if (npc.velocity.Y == speed)
                {
                    if (npc.velocity.X < dirX)
                        npc.velocity.X = npc.velocity.X + acceleration;
                    else if (npc.velocity.X > dirX)
                        npc.velocity.X = npc.velocity.X - acceleration;
                }
                else if (npc.velocity.Y > 4.0)
                {
                    if (npc.velocity.X < 0.0)
                        npc.velocity.X = npc.velocity.X + acceleration * 0.9f;
                    else
                        npc.velocity.X = npc.velocity.X - acceleration * 0.9f;
                }
            }
            // Else we want to play some audio (soundDelay) and move towards our target.
            else
            {
                if (npc.soundDelay == 0)
                {
                    float num1 = length / 40f;
                    if (num1 < 10.0)
                        num1 = 10f;
                    if (num1 > 20.0)
                        num1 = 20f;
                    npc.soundDelay = (int)num1;
                    Main.PlaySound(15, (int)npc.position.X, (int)npc.position.Y, 1);
                }
                float absDirX = Math.Abs(dirX);
                float absDirY = Math.Abs(dirY);
                float newSpeed = speed / length;
                dirX = dirX * newSpeed;
                dirY = dirY * newSpeed;
                if (npc.velocity.X > 0.0 && dirX > 0.0 || npc.velocity.X < 0.0 && dirX < 0.0 || (npc.velocity.Y > 0.0 && dirY > 0.0 || npc.velocity.Y < 0.0 && dirY < 0.0))
                {
                    if (npc.velocity.X < dirX)
                        npc.velocity.X = npc.velocity.X + acceleration;
                    else if (npc.velocity.X > dirX)
                        npc.velocity.X = npc.velocity.X - acceleration;
                    if (npc.velocity.Y < dirY)
                        npc.velocity.Y = npc.velocity.Y + acceleration;
                    else if (npc.velocity.Y > dirY)
                        npc.velocity.Y = npc.velocity.Y - acceleration;
                    if (Math.Abs(dirY) < speed * 0.2 && (npc.velocity.X > 0.0 && dirX < 0.0 || npc.velocity.X < 0.0 && dirX > 0.0))
                    {
                        if (npc.velocity.Y > 0.0)
                            npc.velocity.Y = npc.velocity.Y + acceleration * 2f;
                        else
                            npc.velocity.Y = npc.velocity.Y - acceleration * 2f;
                    }
                    if (Math.Abs(dirX) < speed * 0.2 && (npc.velocity.Y > 0.0 && dirY < 0.0 || npc.velocity.Y < 0.0 && dirY > 0.0))
                    {
                        if (npc.velocity.X > 0.0)
                            npc.velocity.X = npc.velocity.X + acceleration * 2f;
                        else
                            npc.velocity.X = npc.velocity.X - acceleration * 2f;
                    }
                }
                else if (absDirX > absDirY)
                {
                    if (npc.velocity.X < dirX)
                        npc.velocity.X = npc.velocity.X + acceleration * 1.1f;
                    else if (npc.velocity.X > dirX)
                        npc.velocity.X = npc.velocity.X - acceleration * 1.1f;
                    if (Math.Abs(npc.velocity.X) + Math.Abs(npc.velocity.Y) < speed * 0.5)
                    {
                        if (npc.velocity.Y > 0.0)
                            npc.velocity.Y = npc.velocity.Y + acceleration;
                        else
                            npc.velocity.Y = npc.velocity.Y - acceleration;
                    }
                }
                else
                {
                    if (npc.velocity.Y < dirY)
                        npc.velocity.Y = npc.velocity.Y + acceleration * 1.1f;
                    else if (npc.velocity.Y > dirY)
                        npc.velocity.Y = npc.velocity.Y - acceleration * 1.1f;
                    if (Math.Abs(npc.velocity.X) + Math.Abs(npc.velocity.Y) < speed * 0.5)
                    {
                        if (npc.velocity.X > 0.0)
                            npc.velocity.X = npc.velocity.X + acceleration;
                        else
                            npc.velocity.X = npc.velocity.X - acceleration;
                    }
                }
            }
            // Set the correct rotation for this NPC.
            npc.rotation = (float)Math.Atan2(npc.velocity.Y, npc.velocity.X) + 1.57f;
           
            // Some netupdate stuff (multiplayer compatibility).
            if (collision)
            {
                if (npc.localAI[0] != 1)
                    npc.netUpdate = true;
                npc.localAI[0] = 1f;
            }
            else
            {
                if (npc.localAI[0] != 0.0)
                    npc.netUpdate = true;
                npc.localAI[0] = 0.0f;
            }
            if ((npc.velocity.X > 0.0 && npc.oldVelocity.X < 0.0 || npc.velocity.X < 0.0 && npc.oldVelocity.X > 0.0 || (npc.velocity.Y > 0.0 && npc.oldVelocity.Y < 0.0 || npc.velocity.Y < 0.0 && npc.oldVelocity.Y > 0.0)) && !npc.justHit)
                npc.netUpdate = true;

            return false;
        }

        public override bool PreDraw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch, Color drawColor)
        {
            Texture2D texture = Main.npcTexture[npc.type];
            Vector2 origin = new Vector2(texture.Width * 0.5f, texture.Height * 0.5f);
            Main.spriteBatch.Draw(texture, npc.Center - Main.screenPosition, new Rectangle?(), drawColor, npc.rotation, origin, npc.scale, SpriteEffects.None, 0);
            return false;
        }
        public override bool? DrawHealthBar(byte hbPosition, ref float scale, ref Vector2 position)
        {
            scale = 1.9f;   //this make the NPC Health Bar biger
            return null;
        }
    }
}
 
I'm new to modding and need some questions answered, like is there a limit to how many mods I can have, and sometimes I get a log when reloading my mods (it mostly happens when trying to load large mods like thorium and calamity) it says "Insufficient memory to continue execution of the program", is this normal? and how can i fix it?
 
Thought I'd re-post this here in case tMod devs weren't aware of this -- although I assume you likely are. This is taken from the Legends of Terraria 3 mod thread:

Um, not sure if it's this mod or something else, but I keep seeing the error pop up in the chat 'type == SoundLoader.CustomSoundType 0' or some other number instead of zero. I saw it crop up with the sexy succubus laugh from the enemies from this mod, though the sounds still played normally from what I can tell. Is anyone else getting that?

Yes, I got that as well:

View attachment 160322

some very new versions of gabehaswon have the same issues

To be honest, i have to say, i know another mod with the same bug, W1K's mod Lite, with the slugger zombies. They have a special sound that plays when they hit you with a baseball, and it does trigger the same message, however it also does not play the sound.

The reason that this does not happen in most of the mods is because most custom sounds are loaded via set defaults. Some of my sounds are called in not standard places, as in not defined as kill sound, hit sound or use sound. I call them via code, in AI or so. Debug text is, from what i heard, something left out in tml itself, and that means, i cannot do anything about it. The one only thing we can do about it is to wait, until tModloader devs remove the debug text calling when mod calls sounds via PlaySound().


I too have confirmed experiencing this persistent debug message involving custom sounds in various mods. Is there a way to fix this in an upcoming patch so the messages stop appearing in the chat window whenever specific sounds are played? Thanks.
 
Last edited:
Thought I'd re-post this here in case tMod devs weren't aware of this -- although I assume you likely are. This is taken from the Legends of Terraria 3 mod thread:












I too have confirmed experiencing this persistent debug message involving custom sounds in various mods. Is there a way to fix this in an upcoming patch so the messages stop appearing in the chat window whenever specific sounds are played? Thanks.
It's fixed.
 
Back
Top Bottom