tModLoader Official tModLoader Help Thread

Im sorry if im boring to you, but how to do that, and can i do it with tModLoader
( and where to find the Terraria source ( i have been searching for the source all day ))
 
You're adding the buff for 2 ticks (1/30th of a second) every time, so you may want to look into that.
Okay, so I changed the 2 to 300, so the effect is being added to long to allow it to disappear (unless the player is too far from the candle), but there's still a timer. This works, but I'd prefer it if the buff was like the water candle buff, where it would be there without a timer, until the player is too far away, and it would go away instantly when the player does.
 
Im sorry if im boring to you, but how to do that, and can i do it with tModLoader
( and where to find the Terraria source ( i have been searching for the source all day ))
Yes, you can do that with tModLoader (really, cloning vanilla items only gets you so far. You'll eventually have to venture into the world of 'real' programming).
There are multiple methods you can use to implement AI, but I recommend using PreAI:
Code:
public override bool PreAI()
{
    // AI stuff.
    return false;
}
Terraria's source cannot be found online, since we're not permitted to distribute it in any way.
Heck, even me telling you how to decompile it could get me into trouble, but I've done so in the past so I pay that little mind.
I'd recommend you download a program called 'IlSpy'. Once downloaded, you can drag+drop your Terraria executable file into the program and it'll decompile it for you. Simple as that.
Okay, so I changed the 2 to 300, so the effect is being added to long to allow it to disappear (unless the player is too far from the candle), but there's still a timer. This works, but I'd prefer it if the buff was like the water candle buff, where it would be there without a timer, until the player is too far away, and it would go away instantly when the player does.
The I recommend using 10 instead of 300.
 
Terraria's source cannot be found online, since we're not permitted to distribute it in any way.
Heck, even me telling you how to decompile it could get me into trouble, but I've done so in the past so I pay that little mind.
I'd recommend you download a program called 'IlSpy'. Once downloaded, you can drag+drop your Terraria executable file into the program and it'll decompile it for you. Simple as that.
Decompiling is fine, as long as no source or unprotected .exe are distributed.
 
Yes, you can do that with tModLoajustcloning vanilla items only gets you so far. You'll eventually have to venture into the world of 'real' programming).
There are multiple methods you can use to implement AI, but I recommend using PreAI:
Code:
public override bool PreAI()
{
    // AI stuff.
    return false;
}
Terraria's source cannot be found online, since we're not permitted to distribute it in any way.
Heck, even me telling you how to decompile it could get me into trouble, but I've done so in the past so I pay that little mind.
I'd recommend you download a program called 'IlSpy'. Once downloaded, you can drag+drop your Terraria executable file into the program and it'll decompile it for you. Simple as that.

The I recommend using 10 instead of 300.
Thanks, btw i already tryed the ILSpy, but it just cracks up my computer and it just doesn't work with Terraria 1.3 and up ( i really hoped for having a great mod, but i dont know anything about programming, i just understand what the code does, and it sucks that all my yoyos are the same range )
 
Thanks, btw i already tryed the ILSpy, but it just cracks up my computer and it just doesn't work with Terraria 1.3 and up ( i really hoped for having a great mod, but i dont know anything about programming, i just understand what the code does, and it sucks that all my yoyos are the same range )

You need to wait for the decompiler to finish. Terraria's source code is huge, so it takes a bit.
Also, don't decompile the whole code, look for a specific file or function and decompile only it.
 
You need to wait for the decompiler to finish. Terraria's source code is huge, so it takes a bit.
Also, don't decompile the whole code, look for a specific file or function and decompile only it.
I decompiled it but there were just some useless files with ID like Item.ID and Projectile.ID , but no item or any other .cs file than that. :'(
 
I decompiled it but there were just some useless files with ID like Item.ID and Projectile.ID , but no item or any other .cs file than that. :'(
If you see a lot of IDs then you're probably in the wrong namespace.
Simply the Terraria namespace should contain all needed classes and Funktions used for Items,Enemys,Projectiles e.t.c
 
Last edited:
I'm going to make my mod Multiplayer compatible soon, So i had to ask before any errors come up. Cause i can't really test any multiplayer features.
Is Main.myPlayer used for the ID of the Player that your Client handles?
 
I'm going to make my mod Multiplayer compatible soon, So i had to ask before any errors come up. Cause i can't really test any multiplayer features.
Is Main.myPlayer used for the ID of the Player that your Client handles?
That is correct. Another important field is Main.NetMode. It will be 0 when playing in single-player, 1 when playing in multiplayer and 2 on the server running the game.
 
The I recommend using 10 instead of 300.
Thanks. I set it to 60, it didn't constantly disappear, and gave it only 1 second to disappear, when going out of range. I guess I'll try 30 when I'm sure the buff is working.

Okay, so here are my codes now:

Code:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.DataStructures;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.ObjectData;

namespace CorruptionCandles.Tiles
{
    public class CursedCandle : ModTile
    {
        public override void SetDefaults()
        {
            Main.tileFrameImportant[Type] = true;
            TileObjectData.newTile.CopyFrom(TileObjectData.Style1xX);
            TileObjectData.newTile.UsesCustomCanPlace = true;
            TileObjectData.newTile.Height = 1;
            TileObjectData.newTile.Width = 1;
            TileObjectData.newTile.Origin = new Point16(0, 0);
            TileObjectData.newTile.CoordinateHeights = new int[]{ 16, 16, 22 };
            TileObjectData.addTile(Type);
            AddMapEntry(new Color(0, 255, 0));
            dustType = 1;
            animationFrameHeight = 20;
            disableSmartCursor = true;
            drop = mod.ItemType("CursedCandle");
            AddMapEntry(new Color(0, 255, 0), "Torch");
            dustType = mod.DustType("Sparkle");
            torch = true;
        }

        public override void NumDust(int i, int j, bool fail, ref int num)
        {
            num = Main.rand.Next(1, 3);
        }

        public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b)
        {
            Tile tile = Main.tile[i, j];
            if (tile.frameX < 66)
            {
                r = 0.0f;
                g = 1.0f;
                b = 0.0f;
            }
        }

        public override void NearbyEffects(int i, int j, bool closer)
        {
            if(closer)
            {
                Main.player[Main.myPlayer].AddBuff(mod.BuffType("CursedCandle"), 60);
            }
        }

        public override void AnimateTile(ref int frame, ref int frameCounter)
        {
            frame = Main.tileFrame[TileID.WaterCandle];
            frameCounter = Main.tileFrameCounter[TileID.WaterCandle];
        }

        public override void PostDraw(int i, int j, SpriteBatch spriteBatch)
        {
            ulong randSeed = Main.TileFrameSeed ^ (ulong)((long)j << 32 | (long)((ulong)i));
            Color color = new Color(100, 100, 100, 0);
            int frameX = Main.tile[i, j].frameX;
            int frameY = Main.tile[i, j].frameY;
            int width = 16;
            int offsetY = 0;
            int height = 20;
            if (WorldGen.SolidTile(i, j - 1))
            {
                offsetY = 2;
                if (WorldGen.SolidTile(i - 1, j + 1) || WorldGen.SolidTile(i + 1, j + 1))
                {
                    offsetY = 4;
                }
            }
            Vector2 zero = new Vector2(Main.offScreenRange, Main.offScreenRange);
            if (Main.drawToScreen)
            {
                zero = Vector2.Zero;
            }
            for (int k = 0; k < 7; k++)
            {
                float x = (float)Utils.RandomInt(ref randSeed, -10, 11) * 0.15f;
                float y = (float)Utils.RandomInt(ref randSeed, -10, 1) * 0.35f;
                Main.spriteBatch.Draw(mod.GetTexture("Tiles/CursedCandle_Flame"), new Vector2((float)(i * 16 - (int)Main.screenPosition.X) - (width - 16f) / 2f + x, (float)(j * 16 - (int)Main.screenPosition.Y + offsetY) + y) + zero, new Rectangle(frameX, frameY, width, height), color, 0f, default(Vector2), 1f, SpriteEffects.None, 0f);
            }
        }

    }
}

Code:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.DataStructures;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.ObjectData;

namespace CorruptionCandles.Tiles
{
    public class CrimsonCandle : ModTile
    {
        public override void SetDefaults()
        {
            Main.tileFrameImportant[Type] = true;
            TileObjectData.newTile.CopyFrom(TileObjectData.Style1xX);
            TileObjectData.newTile.UsesCustomCanPlace = true;
            TileObjectData.newTile.Height = 1;
            TileObjectData.newTile.Width = 1;
            TileObjectData.newTile.Origin = new Point16(0, 0);
            TileObjectData.newTile.CoordinateHeights = new int[]{ 16, 16, 22 };
            TileObjectData.addTile(Type);
            AddMapEntry(new Color(0, 255, 0));
            dustType = 1;
            animationFrameHeight = 20;
            disableSmartCursor = true;
            drop = mod.ItemType("CrimsonCandle");
            AddMapEntry(new Color(0, 255, 0), "Torch");
            dustType = mod.DustType("Sparkle");
            torch = true;
        }

        public override void NumDust(int i, int j, bool fail, ref int num)
        {
            num = Main.rand.Next(1, 3);
        }

        public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b)
        {
            Tile tile = Main.tile[i, j];
            if (tile.frameX < 66)
            {
                r = 0.0f;
                g = 1.0f;
                b = 0.0f;
            }
        }

        public override void NearbyEffects(int i, int j, bool closer)
        {
            if(closer)
            {
                Main.player[Main.myPlayer].AddBuff(mod.BuffType("CrimsonCandle"), 60);
            }
        }

        public override void AnimateTile(ref int frame, ref int frameCounter)
        {
            frame = Main.tileFrame[TileID.WaterCandle];
            frameCounter = Main.tileFrameCounter[TileID.WaterCandle];
        }

        public override void PostDraw(int i, int j, SpriteBatch spriteBatch)
        {
            ulong randSeed = Main.TileFrameSeed ^ (ulong)((long)j << 32 | (long)((ulong)i));
            Color color = new Color(100, 100, 100, 0);
            int frameX = Main.tile[i, j].frameX;
            int frameY = Main.tile[i, j].frameY;
            int width = 16;
            int offsetY = 0;
            int height = 20;
            if (WorldGen.SolidTile(i, j - 1))
            {
                offsetY = 2;
                if (WorldGen.SolidTile(i - 1, j + 1) || WorldGen.SolidTile(i + 1, j + 1))
                {
                    offsetY = 4;
                }
            }
            Vector2 zero = new Vector2(Main.offScreenRange, Main.offScreenRange);
            if (Main.drawToScreen)
            {
                zero = Vector2.Zero;
            }
            for (int k = 0; k < 7; k++)
            {
                float x = (float)Utils.RandomInt(ref randSeed, -10, 11) * 0.15f;
                float y = (float)Utils.RandomInt(ref randSeed, -10, 1) * 0.35f;
                Main.spriteBatch.Draw(mod.GetTexture("Tiles/CrimsonCandle_Flame"), new Vector2((float)(i * 16 - (int)Main.screenPosition.X) - (width - 16f) / 2f + x, (float)(j * 16 - (int)Main.screenPosition.Y + offsetY) + y) + zero, new Rectangle(frameX, frameY, width, height), color, 0f, default(Vector2), 1f, SpriteEffects.None, 0f);
            }
        }

    }
}

If someone could give me a example of a candle (one that can be opened with tModReader v0.8) that might solve all the problems I'm having.

I'm not expecting help for all of this at once:

My biggest problem:
  • The CrimsonCandle.cs is very similar to CursedCandle.cs, yet unlike the Cursed Candle, when I place the Crimson Candle down it has no animation and all background furniture and leaves becomes invisible.

My other problems are:

  • Neither of the torches are giving off light.
  • How do I make it so that the candle is only placed on surfaces like crafting tables, and platforms?
  • I also seem to be getting the animation wrong. I used the "public override void PostDraw" from ExampleTorch.cs as a reference, but I don't understand the whole thing. I attached the Cursed Candle image files. As the animation moves, I see the pink line on the right of the candle fluctuate between in different sizes between being drawn in a little bit and not being drawn at all.
 

Attachments

  • CursedCandle.png
    CursedCandle.png
    356 bytes · Views: 159
  • CursedCandle_Flame.png
    CursedCandle_Flame.png
    358 bytes · Views: 497
That is correct. Another important field is Main.NetMode. It will be 0 when playing in single-player, 1 when playing in multiplayer and 2 on the server running the game.
Another question. On servers, what clients run the NPCLoot function from GlobalNPC.
If only on the host client, then how can you see which player the NPC was killed by?
 
Another question. On servers, what clients run the NPCLoot function from GlobalNPC.
If only on the host client, then how can you see which player the NPC was killed by?
I haven't really messed around with NPCLoot much so I can't really give you much of an answer, but whenever I want to find out where and when a hook is called, I put something like the following into it.
Code:
Main.NewText("NPCLoot, someVaraible: " + npc.someVaraible); //this will output text to the chat box ingame
Console.WriteLine("NPCLoot, someVaraible: " + npc.someVaraible); //this will output text to the server's console window
I hope this is useful.
 
How do you make it that a mobs spawns biome specific and an item has a randomized sprite(like gel) and how do I do I make a world gen tile like the enchanted sword
 
Hey guys! I'm quite new here and i ran into a massive problem, when i try to open my character on my world it gives me a error code:
Unable to read beyond the end of the stream.

at System.IO.BinaryReader.FillBuffer(Int32 numBytes)
at System.IO.BinaryReader.ReadUInt16()
at Terraria.ModLoader.IO.ItemIO.GetCustomData(Int32 type, BinaryReader reader, Boolean hasGlobalSaving)
at Terraria.ModLoader.Default.MysteryItem.LoadCustomData(BinaryReader reader)
at Terraria.ModLoader.IO.ItemIO.ReadCustomData(Item item, Byte[] data, Boolean hasGlobalSaving)

Anyone that can give me any information on this would be a great help, thanks. (p.s. im still in 1.3.3.2 and tmodloader version v0.8.3.4 if that helps.)`:sigh:
 
Hey guys! I'm quite new here and i ran into a massive problem, when i try to open my character on my world it gives me a error code:
Unable to read beyond the end of the stream.

at System.IO.BinaryReader.FillBuffer(Int32 numBytes)
at System.IO.BinaryReader.ReadUInt16()
at Terraria.ModLoader.IO.ItemIO.GetCustomData(Int32 type, BinaryReader reader, Boolean hasGlobalSaving)
at Terraria.ModLoader.Default.MysteryItem.LoadCustomData(BinaryReader reader)
at Terraria.ModLoader.IO.ItemIO.ReadCustomData(Item item, Byte[] data, Boolean hasGlobalSaving)

Anyone that can give me any information on this would be a great help, thanks. (p.s. im still in 1.3.3.2 and tmodloader version v0.8.3.4 if that helps.)`:sigh:
Yeah I am having the exact same crash report, but with my world file and not my character. I could use an explanation as well.
 
Back
Top Bottom