Standalone [1.3] tModLoader - A Modding API

I've had this problem - first make sure you have the latest tModLoader and then go to your ModLoader/Players folder and remove the .tplr files of the faulty characters. (that will probably somewhat hurt their inventory, but the characters should work afterwards).

You can try just moving the files to your desktop or somewhere, if you don't want to delete them. But if the characters work afterwards, they will create new .tplr files for themselves, so the old files will be useless for you.
? is there a file location dor this?
 
Oh and can we make Minecarts yet. There is no example. Im guessing its some kind of mount.
Maybe, but no one has tried yet.

2 things: How do you edit the loottables of randomly generated chests (like pyridmid chests) and 2: how to do ore generation (on world creation)
1. In probably postworldgen, iterate through chests, find a spot in the item array that is empty, call Setdefaults on the item.

Code:
    for (int i = 0; i < 1000; i++)
            {
                Chest chest = Main.chest[i];
                                other code....

2. Like this:
Code:
        public override void ModifyWorldGenTasks(List<GenPass> tasks, ref float totalWeight)
        {
            int ShiniesIndex = tasks.FindIndex(genpass => genpass.Name.Equals("Shinies"));

            tasks.Insert(ShiniesIndex + 1, new PassLegacy("Crazy Ore", delegate (GenerationProgress progress)
            {
                progress.Message = "Example Mod Ores";

                for (int k = 0; k < (int)((double)(Main.maxTilesX * Main.maxTilesY) * 6E-05); k++)
                {
                    WorldGen.TileRunner(WorldGen.genRand.Next(0, Main.maxTilesX), WorldGen.genRand.Next((int)WorldGen.worldSurfaceLow, Main.maxTilesY), (double)WorldGen.genRand.Next(3, 6), WorldGen.genRand.Next(2, 6), mod.TileType("ExampleBlock"), false, 0f, 0f, false, true);
                }
            }));
        }
 
Maybe, but no one has tried yet.


1. In probably postworldgen, iterate through chests, find a spot in the item array that is empty, call Setdefaults on the item.

Code:
    for (int i = 0; i < 1000; i++)
            {
                Chest chest = Main.chest[i];
                                other code....

2. Like this:
Code:
        public override void ModifyWorldGenTasks(List<GenPass> tasks, ref float totalWeight)
        {
            int ShiniesIndex = tasks.FindIndex(genpass => genpass.Name.Equals("Shinies"));

            tasks.Insert(ShiniesIndex + 1, new PassLegacy("Crazy Ore", delegate (GenerationProgress progress)
            {
                progress.Message = "Example Mod Ores";

                for (int k = 0; k < (int)((double)(Main.maxTilesX * Main.maxTilesY) * 6E-05); k++)
                {
                    WorldGen.TileRunner(WorldGen.genRand.Next(0, Main.maxTilesX), WorldGen.genRand.Next((int)WorldGen.worldSurfaceLow, Main.maxTilesY), (double)WorldGen.genRand.Next(3, 6), WorldGen.genRand.Next(2, 6), mod.TileType("ExampleBlock"), false, 0f, 0f, false, true);
                }
            }));
        }
what do I have to edit to make it work with EnderuimOre? And where (Im assuming the ore cs). Im sorry im new to world genning
 
Maybe, but no one has tried yet.


1. In probably postworldgen, iterate through chests, find a spot in the item array that is empty, call Setdefaults on the item.

Code:
    for (int i = 0; i < 1000; i++)
            {
                Chest chest = Main.chest[i];
                                other code....

2. Like this:
Code:
        public override void ModifyWorldGenTasks(List<GenPass> tasks, ref float totalWeight)
        {
            int ShiniesIndex = tasks.FindIndex(genpass => genpass.Name.Equals("Shinies"));

            tasks.Insert(ShiniesIndex + 1, new PassLegacy("Crazy Ore", delegate (GenerationProgress progress)
            {
                progress.Message = "Example Mod Ores";

                for (int k = 0; k < (int)((double)(Main.maxTilesX * Main.maxTilesY) * 6E-05); k++)
                {
                    WorldGen.TileRunner(WorldGen.genRand.Next(0, Main.maxTilesX), WorldGen.genRand.Next((int)WorldGen.worldSurfaceLow, Main.maxTilesY), (double)WorldGen.genRand.Next(3, 6), WorldGen.genRand.Next(2, 6), mod.TileType("ExampleBlock"), false, 0f, 0f, false, true);
                }
            }));
        }
tremor has tried the mounts and made 1 (i think only one by now) so minecrats are possible i think
 
what do I have to edit to make it work with EnderuimOre? And where (Im assuming the ore cs). Im sorry im new to world genning
Change mod.TileType("ExampleBlock")
[DOUBLEPOST=1457298568,1457298505][/DOUBLEPOST]
tremor has tried the mounts and made 1 (i think only one by now) so minecrats are possible i think
I know mounts are possible, just not sure how to specifically make a Minecraft mount.
 
Do I change the numbers to define the rarity?
 
How would I go about making vanilla enemies immune to modded debuffs?

Edit - Welp, never mind. I think I figured it out... :sigh:
 
Last edited:
So as it turns out, it was a Missing Texture exception... needless to say, it was caused by my dumb mistake :/

Anyway it draws now. After some time of trial of error it even draws in the right place but:
  1. It seems that the sprite isn't affected by light, so at night it's much brighter than the rest of the clothes, even though it's the same color
  2. When my character (for example) jumps, the sprite sometimes "doesn't keep up" and is drawn elsewhere than the character...
(The border of the sleeve is [supposed to be] the same color as the rest of the borders)

Code:
        public override void PostDraw(SpriteBatch spriteBatch, Color drawColor)
        {
            if (winter)
            {
                try
                {
                    if (npc.direction == -1)
                    {
                        spriteBatch.Draw(mod.GetTexture("NPCs/Enthusiast_Shirt"), npc.Center - Main.screenPosition, new Rectangle(0, npc.frame.Y, 40, 60), Color.White, 0f, new Vector2(20, 30), 1f, SpriteEffects.None, 0f);
                    }
                    else
                    {
                        spriteBatch.Draw(mod.GetTexture("NPCs/Enthusiast_Shirt"), npc.Center - Main.screenPosition, new Rectangle(0, npc.frame.Y, 40, 60), Color.White, 0f, new Vector2(20, 30), 1f, SpriteEffects.FlipHorizontally, 0f);
                    }
                }
                catch (Exception e)
                {
                    Main.NewText(e + "");
                }
            }
        }

Is there a way to completely change which texture is used for the NPC itself? Like - instead of drawing a collar in front of it, I'd make it draw from a spritesheet that already has the shirt. I tried to figure it out, but didn't succeed.
The only way to conditionally change the texture reliably would be to manually draw the NPC in the PreDraw hook. However, if lighting is the only problem then you can use the drawColor parameter instead of Color.White.

Do I change the numbers to define the rarity?
...SetDefaults...
 
The only way to conditionally change the texture reliably would be to manually draw the NPC in the PreDraw hook. However, if lighting is the only problem then you can use the drawColor parameter instead of Color.White.


...SetDefaults...
rarity as in spawning
 
c:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\Tiles\ExampleBlock.cs(32,57) : error CS0246: The type or namespace name 'GenPass' could not be found (are you missing a using directive or an assembly reference?)

c:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\Tiles\ExampleBlock.cs(32,52) : error CS0246: The type or namespace name 'List' could not be found (are you missing a using directive or an assembly reference?)


Code that I edited
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace ExampleMod.Tiles
{
public class ExampleBlock : ModTile
{
public override void SetDefaults()
{
Main.tileSolid[Type] = true;
Main.tileMergeDirt[Type] = true;
Main.tileBlockLight[Type] = true;
Main.tileLighted[Type] = true;
dustType = mod.DustType("Sparkle");
AddMapEntry(new Color(200, 200, 200));
}

public override void NumDust(int i, int j, bool fail, ref int num)
{
num = fail ? 1 : 3;
}

public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b)
{
r = 0.5f;
g = 0.5f;
b = 0.5f;
}
public override void ModifyWorldGenTasks(List<GenPass> tasks, ref float totalWeight)
{
int ShiniesIndex = tasks.FindIndex(genpass => genpass.Name.Equals("Shinies"));

tasks.Insert(ShiniesIndex + 1, new PassLegacy("Crazy Ore", delegate (GenerationProgress progress)
{
progress.Message = "Growing Enderuim Crystals...";

for (int k = 0; k < (int)((double)(Main.maxTilesX * Main.maxTilesY) * 6E-05); k++)
{
WorldGen.TileRunner(WorldGen.genRand.Next(0, Main.maxTilesX), WorldGen.genRand.Next((int)WorldGen.worldSurfaceLow, Main.maxTilesY), (double)WorldGen.genRand.Next(3, 6), WorldGen.genRand.Next(2, 6), mod.TileType("ExampleBlock"), false, 0f, 0f, false, true);
}
}));
}
}
}
 
How would i go about Generating Ore onto new maps ?
 
So as it turns out, it was a Missing Texture exception... needless to say, it was caused by my dumb mistake :/

Anyway it draws now. After some time of trial of error it even draws in the right place but:
  1. It seems that the sprite isn't affected by light, so at night it's much brighter than the rest of the clothes, even though it's the same color
  2. When my character (for example) jumps, the sprite sometimes "doesn't keep up" and is drawn elsewhere than the character...
(The border of the sleeve is [supposed to be] the same color as the rest of the borders)

Code:
        public override void PostDraw(SpriteBatch spriteBatch, Color drawColor)
        {
            if (winter)
            {
                try
                {
                    if (npc.direction == -1)
                    {
                        spriteBatch.Draw(mod.GetTexture("NPCs/Enthusiast_Shirt"), npc.Center - Main.screenPosition, new Rectangle(0, npc.frame.Y, 40, 60), Color.White, 0f, new Vector2(20, 30), 1f, SpriteEffects.None, 0f);
                    }
                    else
                    {
                        spriteBatch.Draw(mod.GetTexture("NPCs/Enthusiast_Shirt"), npc.Center - Main.screenPosition, new Rectangle(0, npc.frame.Y, 40, 60), Color.White, 0f, new Vector2(20, 30), 1f, SpriteEffects.FlipHorizontally, 0f);
                    }
                }
                catch (Exception e)
                {
                    Main.NewText(e + "");
                }
            }
        }

Is there a way to completely change which texture is used for the NPC itself? Like - instead of drawing a collar in front of it, I'd make it draw from a spritesheet that already has the shirt. I tried to figure it out, but didn't succeed.

Like BlueMagic said, you simply need to replace Color.White with the colour at the location of your NPC. To save you some time, this is what you use 'Lighting.GetColor((int)npc.Center.X / 16, (int)npc.Center.Y / 16)'.

You could also simplify your code by doing away with the npc.direction check and instead use 'npc.spriteDirection > 0 ? SpriteEffects.None : SpriteEffects.FlipHorizontally' for the sprite direction.
 
c:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\Tiles\ExampleBlock.cs(32,57) : error CS0246: The type or namespace name 'GenPass' could not be found (are you missing a using directive or an assembly reference?)

c:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\Tiles\ExampleBlock.cs(32,52) : error CS0246: The type or namespace name 'List' could not be found (are you missing a using directive or an assembly reference?)


Code that I edited
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace ExampleMod.Tiles
{
public class ExampleBlock : ModTile
{
public override void SetDefaults()
{
Main.tileSolid[Type] = true;
Main.tileMergeDirt[Type] = true;
Main.tileBlockLight[Type] = true;
Main.tileLighted[Type] = true;
dustType = mod.DustType("Sparkle");
AddMapEntry(new Color(200, 200, 200));
}

public override void NumDust(int i, int j, bool fail, ref int num)
{
num = fail ? 1 : 3;
}

public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b)
{
r = 0.5f;
g = 0.5f;
b = 0.5f;
}
public override void ModifyWorldGenTasks(List<GenPass> tasks, ref float totalWeight)
{
int ShiniesIndex = tasks.FindIndex(genpass => genpass.Name.Equals("Shinies"));

tasks.Insert(ShiniesIndex + 1, new PassLegacy("Crazy Ore", delegate (GenerationProgress progress)
{
progress.Message = "Growing Enderuim Crystals...";

for (int k = 0; k < (int)((double)(Main.maxTilesX * Main.maxTilesY) * 6E-05); k++)
{
WorldGen.TileRunner(WorldGen.genRand.Next(0, Main.maxTilesX), WorldGen.genRand.Next((int)WorldGen.worldSurfaceLow, Main.maxTilesY), (double)WorldGen.genRand.Next(3, 6), WorldGen.genRand.Next(2, 6), mod.TileType("ExampleBlock"), false, 0f, 0f, false, true);
}
}));
}
}
}

Add
Code:
using System.Collections.Generic;
using Terraria.World.Generation;
to the list at the top of your code.
 
How would i go about Generating Ore onto new maps ?
There is an example one post above your post, the ModifyWorldGenTasks portion.
[DOUBLEPOST=1457339147,1457338972][/DOUBLEPOST]
Do I change the numbers to define the rarity?
This part:
for (int k = 0; k < (int)((double)(Main.maxTilesX * Main.maxTilesY) * 6E-05); k++)
is how many splotches, ant the other variables relate to how big the splotches are.
public static void TileRunner(int i, int j, double strength, int steps, int type, bool addTile = false, float speedX = 0f, float speedY = 0f, bool noYChange = false, bool overRide = true)
 
How do you edit the loottables of randomly generated chests (like pyridmid chests)
I've made an example:

Code:
        public override void PostWorldGen()
        {
            // Place some items in Ice Chests
            int[] itemsToPlaceInWaterChests = new int[] { mod.ItemType("CarKey"), mod.ItemType("ExampleLightPet"), ItemID.PinkJellyfishJar };
            int itemsToPlaceInWaterChestsChoice = 0;
            for (int chestIndex = 0; chestIndex < 1000; chestIndex++)
            {
                Chest chest = Main.chest[chestIndex];
                if (chest != null && Main.tile[chest.x, chest.y].frameX == 11 * 36)
                {
                    for (int inventoryIndex = 0; inventoryIndex < 40; inventoryIndex++)
                    {
                        if (chest.item[inventoryIndex].type == 0)
                        {
                            chest.item[inventoryIndex].SetDefaults(itemsToPlaceInWaterChests[itemsToPlaceInWaterChestsChoice]);
                            itemsToPlaceInWaterChestsChoice = (itemsToPlaceInWaterChestsChoice + 1) % itemsToPlaceInWaterChests.Length;
                            break;
                        }
                    }
                }
            }
        }
 
Code:
c:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\Tiles\ExampleBlock.cs(33,32) : error CS0115: 'ExampleMod.Tiles.ExampleBlock.ModifyWorldGenTasks(System.Collections.Generic.List<Terraria.World.Generation.GenPass>, ref float)': no suitable method found to override


using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using System.Collections.Generic;
using Terraria.World.Generation;
namespace ExampleMod.Tiles
{
    public class ExampleBlock : ModTile
    {
        public override void SetDefaults()
        {
            Main.tileSolid[Type] = true;
            Main.tileMergeDirt[Type] = true;
            Main.tileBlockLight[Type] = true;
            Main.tileLighted[Type] = true;
            dustType = mod.DustType("Sparkle");
            AddMapEntry(new Color(200, 200, 200));
        }

        public override void NumDust(int i, int j, bool fail, ref int num)
        {
            num = fail ? 1 : 3;
        }

        public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b)
        {
            r = 0.5f;
            g = 0.5f;
            b = 0.5f;
        }
                public override void ModifyWorldGenTasks(List<GenPass> tasks, ref float totalWeight)
        {
            int ShiniesIndex = tasks.FindIndex(genpass => genpass.Name.Equals("Shinies"));

            tasks.Insert(ShiniesIndex + 1, new PassLegacy("Crazy Ore", delegate (GenerationProgress progress)
            {
                progress.Message = "Growing Enderuim Crystals...";

                for (int k = 0; k < (int)((double)(Main.maxTilesX * Main.maxTilesY) * 6E-05); k++)
                {
                    WorldGen.TileRunner(WorldGen.genRand.Next(0, Main.maxTilesX), WorldGen.genRand.Next((int)WorldGen.worldSurfaceLow, Main.maxTilesY), (double)WorldGen.genRand.Next(3, 6), WorldGen.genRand.Next(2, 6), mod.TileType("ExampleBlock"), false, 0f, 0f, false, true);
                }
            }));
        }
    }
}
 
Code:
c:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\Tiles\ExampleBlock.cs(33,32) : error CS0115: 'ExampleMod.Tiles.ExampleBlock.ModifyWorldGenTasks(System.Collections.Generic.List<Terraria.World.Generation.GenPass>, ref float)': no suitable method found to override


using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using System.Collections.Generic;
using Terraria.World.Generation;
namespace ExampleMod.Tiles
{
    public class ExampleBlock : ModTile
    {
        public override void SetDefaults()
        {
            Main.tileSolid[Type] = true;
            Main.tileMergeDirt[Type] = true;
            Main.tileBlockLight[Type] = true;
            Main.tileLighted[Type] = true;
            dustType = mod.DustType("Sparkle");
            AddMapEntry(new Color(200, 200, 200));
        }

        public override void NumDust(int i, int j, bool fail, ref int num)
        {
            num = fail ? 1 : 3;
        }

        public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b)
        {
            r = 0.5f;
            g = 0.5f;
            b = 0.5f;
        }
                public override void ModifyWorldGenTasks(List<GenPass> tasks, ref float totalWeight)
        {
            int ShiniesIndex = tasks.FindIndex(genpass => genpass.Name.Equals("Shinies"));

            tasks.Insert(ShiniesIndex + 1, new PassLegacy("Crazy Ore", delegate (GenerationProgress progress)
            {
                progress.Message = "Growing Enderuim Crystals...";

                for (int k = 0; k < (int)((double)(Main.maxTilesX * Main.maxTilesY) * 6E-05); k++)
                {
                    WorldGen.TileRunner(WorldGen.genRand.Next(0, Main.maxTilesX), WorldGen.genRand.Next((int)WorldGen.worldSurfaceLow, Main.maxTilesY), (double)WorldGen.genRand.Next(3, 6), WorldGen.genRand.Next(2, 6), mod.TileType("ExampleBlock"), false, 0f, 0f, false, true);
                }
            }));
        }
    }
}
You do not want to put the ModifyWorldGenTasks in a ModTile class.
Instead, create a class that derives from ModWorld and put it in there.
 
Code:
c:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\Tiles\ExampleBlock.cs(33,32) : error CS0115: 'ExampleMod.Tiles.ExampleBlock.ModifyWorldGenTasks(System.Collections.Generic.List<Terraria.World.Generation.GenPass>, ref float)': no suitable method found to override


using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using System.Collections.Generic;
using Terraria.World.Generation;
namespace ExampleMod.Tiles
{
    public class ExampleBlock : ModTile
    {
        public override void SetDefaults()
        {
            Main.tileSolid[Type] = true;
            Main.tileMergeDirt[Type] = true;
            Main.tileBlockLight[Type] = true;
            Main.tileLighted[Type] = true;
            dustType = mod.DustType("Sparkle");
            AddMapEntry(new Color(200, 200, 200));
        }

        public override void NumDust(int i, int j, bool fail, ref int num)
        {
            num = fail ? 1 : 3;
        }

        public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b)
        {
            r = 0.5f;
            g = 0.5f;
            b = 0.5f;
        }
                public override void ModifyWorldGenTasks(List<GenPass> tasks, ref float totalWeight)
        {
            int ShiniesIndex = tasks.FindIndex(genpass => genpass.Name.Equals("Shinies"));

            tasks.Insert(ShiniesIndex + 1, new PassLegacy("Crazy Ore", delegate (GenerationProgress progress)
            {
                progress.Message = "Growing Enderuim Crystals...";

                for (int k = 0; k < (int)((double)(Main.maxTilesX * Main.maxTilesY) * 6E-05); k++)
                {
                    WorldGen.TileRunner(WorldGen.genRand.Next(0, Main.maxTilesX), WorldGen.genRand.Next((int)WorldGen.worldSurfaceLow, Main.maxTilesY), (double)WorldGen.genRand.Next(3, 6), WorldGen.genRand.Next(2, 6), mod.TileType("ExampleBlock"), false, 0f, 0f, false, true);
                }
            }));
        }
    }
}
Well, it's a ModWorld method not a ModTile method.
 
Code:
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using System.Collections.Generic;
using Terraria.World.Generation;
{
namespace ExampleMod.Tiles   
    {
            public override void ModifyWorldGenTasks(List<GenPass> tasks, ref float totalWeight)
        {
            int ShiniesIndex = tasks.FindIndex(genpass => genpass.Name.Equals("Shinies"));

            tasks.Insert(ShiniesIndex + 1, new PassLegacy("Crazy Ore", delegate (GenerationProgress progress)
            {
                progress.Message = "Growing Enderuim Crystals...";

                for (int k = 0; k < (int)((double)(Main.maxTilesX * Main.maxTilesY) * 6E-05); k++)
                {
                    WorldGen.TileRunner(WorldGen.genRand.Next(0, Main.maxTilesX), WorldGen.genRand.Next((int)WorldGen.worldSurfaceLow, Main.maxTilesY), (double)WorldGen.genRand.Next(3, 6), WorldGen.genRand.Next(2, 6), mod.TileType("ExampleBlock"), false, 0f, 0f, false, true);
                }
            }));
        }
    }
}
c:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\Tiles\ExampleBlockGen.cs(8,1) : error CS0116: A namespace cannot directly contain members such as fields or methods

c:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\Tiles\ExampleBlockGen.cs(11,26) : error CS1518: Expected class, delegate, enum, interface, or struct

c:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\Tiles\ExampleBlockGen.cs(15,48) : error CS1518: Expected class, delegate, enum, interface, or struct

c:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\Tiles\ExampleBlockGen.cs(15,81) : error CS1031: Type expected

c:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\Tiles\ExampleBlockGen.cs(15,110) : error CS1002: ; expected

c:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\Tiles\ExampleBlockGen.cs(16,13) : error CS0116: A namespace cannot directly contain members such as fields or methods

c:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\Tiles\ExampleBlockGen.cs(23,14) : error CS0116: A namespace cannot directly contain members such as fields or methods

c:\Users\Devin\Documents\My Games\Terraria\ModLoader\Mod Sources\Enderuim\Tiles\ExampleBlockGen.cs(24,9) : error CS1022: Type or namespace definition, or end-of-file expected
 
Back
Top Bottom