• 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

I can't get useItem to agree with me. I want the tile to consume an item upon right clicking it and getting another item.
I am using tAPI but if anybody knows the solution, I would greatly appreciate it.

Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using TAPI;
using Terraria;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Dinosauria.Tiles
{
public class Excavator : ModTileType
{
public override bool RightClick(int f, int r)
{
base.RightClick(f , r);

{
int oa = 0;
int fr = 0;
for (int ii = 0; ii < Main.localPlayer.inventory.Length; ii++)
for (int iii = 0; iii < Main.localPlayer.inventory.Length; iii++)

if (Main.localPlayer.HasItem(iii) == true)
{
if (Main.localPlayer.inventory[ii].displayName == "Old Amber") oa++;
if (Main.localPlayer.inventory[iii].displayName == "Fossil Rock") fr++;
if (iii >= 0)
{
Main.timeOut = (int) 10;
Main.localPlayer.inventory[iii].uniqueStack = (Main.localPlayer.inventory[iii].displayName == "Fossil Rock");
Main.localPlayer.inventory[iii].stack -= 1;
Main.localPlayer.inventory[iii].consumeItem = ("Fossil Rock", "Fossil Rock");

int rand = Main.rand.Next(9);
if(rand == 0)
Item.NewItem((int)Main.localPlayer.position.X, (int)Main.localPlayer.position.Y, Main.localPlayer.width, Main.localPlayer.height, "Dinosauria:OldAmber", 1, false, 0, false);
else if (rand == 1)
Item.NewItem((int)Main.localPlayer.position.X, (int)Main.localPlayer.position.Y, Main.localPlayer.width, Main.localPlayer.height, "Dinosauria:OldClaw", 1, false, 0, false);
else if (rand == 2)
Item.NewItem((int)Main.localPlayer.position.X, (int)Main.localPlayer.position.Y, Main.localPlayer.width, Main.localPlayer.height, "Dinosauria:BoneFossil", 1, false, 0, false);

}


}

return true;
}



}

public static Color lightColor = new Color(100, 180, 100);


}
}
 

jopojelly

Retinazer
tModLoader
Guide: A Visual Guide to the Confusing World of ModTile.
For this guide, all code and visuals will refer to this texture:
LearnTile.png


Everything is bits of code you'll want to include in "SetDefaults()" before you call "TileObjectData.addTile(Type);"

Main.tileSolid[Type] = true;
Main.tileSolid[Type] = false; // default

Main.tileSolidTop[Type] = true;

Main.tileNoAttach[Type] = true;
Main.tileNoAttach[Type] = false; // default

Main.tileTable[Type] = true;
Main.tileTable[Type] = false; // default

TileObjectData.newTile.LavaDeath = true; or Main.tileLavaDeath[Type] = true; (if not using TileObjectData)
Set to True if you'd like your tile to die if hit by lava.

Use this to utilize an existing template. This is typically useful for tiles that are more than a simple 1x1 tile. The names are self explanatory usually.
Here they are:
StyleSwitch;
StyleTorch;
Style4x2;
Style2x2;
Style1x2;
Style1x1;
StyleAlch;
StyleDye;
Style2x1;
Style6x3;
StyleSmallCage;
StyleOnTable1x1; // placeable on tables only, like bottles
Style1x2Top; // "Hangs" from attaching to tiles above.
Style1xX;
Style2xX;
Style3x2;
Style3x3;
Style3x4;
Style3x3Wall;

Typically, you'll want to start out by copying a template, and modifying it as needed.
For example, "MonsterBanner.cs" in ExampleMod first does:
TileObjectData.newTile.CopyFrom(TileObjectData.Style1x2Top);
....and then it makes adjustments such as:
TileObjectData.newTile.Height = 3; // because the template is for 1x2 not 1x3
TileObjectData.newTile.CoordinateHeights = new int[]{ 16, 16, 16 }; // because height changed
....and finally calls:
TileObjectData.addTile(Type);

TileObjectData.newTile.Width = 3;
ZjvSjOV.png

TileObjectData.newTile.Width = 2;
4Qqx0mC.png

TileObjectData.newTile.Width = 1;
8dudSXH.png

TileObjectData.newTile.Height = 3;
ZjvSjOV.png

TileObjectData.newTile.Height = 2;
IqzM18z.png

TileObjectData.newTile.Height = 1;
ypcuohX.png

TileObjectData.newTile.Origin = new Point16(0, 0); // default
Link to gif

TileObjectData.newTile.Origin = new Point16(2, 0); // note how the cursor is placing the tile using the area marked "3" which is 2 to the right

TileObjectData.newTile.Origin = new Point16(1, 2); // Here we see the cursor hovering over the "8" area, which is 2 down and 1 to the right.

There should be TileObjectData.newTile.Height elements in the array. Basically, all should be 16 in most cases. Use 18 on the bottom so that the texture can extend a little into the ground below. Here is a closeup of the texture, note how there is white there, this is to illustrate why we use 18 on a bottom tile sometimes.
XMHqvfy.png

TileObjectData.newTile.CoordinateHeights = new int[] { 16, 16, 18 }; // Here we see the white pixels. Correctly doing this will help the tile look like it's actually there and sitting in the soil, obviously we need to draw the sprite correctly and not with white. (note that it seems solid must be false for this.)
CDzrin7.png

TileObjectData.newTile.CoordinateHeights = new int[] { 16, 16, 16 }; // notice how the grass doesn't completely cover it's area, so our tile seems to float a little.
PMBuMum.png

TileObjectData.newTile.UsesCustomCanPlace = true;
Should be set already to true if you copied a template, but set to true if you use anchors or else the Terraria code won't honor your tile code.

TileObjectData.newTile.CoordinateWidth = 16; // Just do this.
TileObjectData.newTile.CoordinatePadding = 2; // And a padding of 2 pixels to left and bottom of each area in the spritesheet. Do this or weird artifacts will appear.
rzuUkYw.png

The most common anchor is AnchorBottom, so I will explain it here
TileObjectData.newTile.AnchorBottom = new AnchorData(AnchorType.SolidTile, TileObjectData.newTile.Width - 1, 0);
// the 2nd variable is the width and the 3rd is the start of the tiles that require the anchor. If the 1st or 2nd block under this is broken, the tile will break as well, but if the 3rd block is broken it will not break. The 1st Variable is a BitMask describing the types or tiles valid for the anchor.
Gif of this code in action.

This will be at the end if the TileObjectData.newTile portion if you use it.
TileObjectData.addTile(Type);

Used to make a ModTile act as a vanilla tile for the purposes of crafting.
adjTiles = new int[]{ TileID.WorkBenches }; // Causes this tile to be counted as a WorkBench.

Determines the drop when this tile is mined. If it is a 1x1 block tile, "drop = " in setDefaults is used, other wise, override the KillMultiTile hook.
Code:
               public override void KillMultiTile(int i, int j, int frameX, int frameY)
        {
            // the 3rd and 4th numbers should be 16*width blocks and 16 * height blocks respectively.
            Item.NewItem(i * 16, j * 16, 16, 32, mod.ItemType("ExampleChair"));
        }

Used to make a ModTile act as a lightsource, chair or table for the purposes of housing.
AddToArray(ref TileID.Sets.RoomNeeds.CountsAsTable);
AddToArray(ref TileID.Sets.RoomNeeds.CountsAsDoor);
AddToArray(ref TileID.Sets.RoomNeeds.CountsAsTorch);
AddToArray(ref TileID.Sets.RoomNeeds.CountsAsChair);

"TileObjectData.newSubTile" is used to give different properties to different "styles" of the original tile. For example, the Obsidian Lantern is lava proof because of this:
TileObjectData.newSubTile.CopyFrom(TileObjectData.newTile);
TileObjectData.newSubTile.LavaDeath = false;
TileObjectData.newSubTile.LavaPlacement = LiquidPlacement.Allowed;
TileObjectData.addSubTile(32);

"TileObjectData.newAlternate" is to give a single "style" different placements and anchoring options. For example, Torches have a left and right alternative in addition to the normal. Subtiles and Alternates are use together to allow Underwater torches that can be placed point left, right, and up.

More to come. Contact me if something needs explaining.[/spoiler]
 
Last edited:

ikillzombies

Skeletron Prime
The problem is, people won't actually read it. I mean, making an error message pop up for loading the mod telling what exactly is going wrong didn't even help.

I know for certain that some people don't even read the installation instructions, or a file called README.
unfortunately, you right :(
 

Eldrazi

Eater of Worlds
anyone know how to make a projectile fall like star wrath's projectile.
last one i used didn't work
The following is the code that is used to spawn the 'stars' (this is a modified version of the source version):
Code:
Vector2 value7 = Main.screenPosition + new Vector2((float)Main.mouseX, (float)Main.mouseY);
float num115 = value7.Y;
if (num115 > player.Center.Y - 200f)
{
    num115 = player.Center.Y - 200f;
}
for (int num116 = 0; num116 < 3; num116++)
{
    Vector2 vector2 = player.Center + new Vector2(-(float)Main.rand.Next(0, 401) * (float)player.direction, -600f);
    vector2.Y -= (float)(100 * num116);
    Vector2 value8 = value7 - vector2;
    if (value8.Y < 0f)
    {
        value8.Y *= -1f;
    }
    if (value8.Y < 20f)
    {
        value8.Y = 20f;
    }
    value8.Normalize();
    value8 *= yourProjectileSpeed;
    num78 = value8.X;
    num79 = value8.Y;
    float speedX5 = num78;
    float speedY6 = num79 + (float)Main.rand.Next(-40, 41) * 0.02f;
    Projectile.NewProjectile(vector2.X, vector2.Y, speedX5, speedY6, 503, 50, 0, player.whoAmI, 0f, num115);
}
The AI of the projectile is basically used to check if the projectile has gotten above a certain Y coordinate (projectile.ai[1] is used for that) to check if the projectile should collide.
Note that this code is not tested.
 

Darkninja

Spazmatism
The following is the code that is used to spawn the 'stars' (this is a modified version of the source version):
Code:
Vector2 value7 = Main.screenPosition + new Vector2((float)Main.mouseX, (float)Main.mouseY);
float num115 = value7.Y;
if (num115 > player.Center.Y - 200f)
{
    num115 = player.Center.Y - 200f;
}
for (int num116 = 0; num116 < 3; num116++)
{
    Vector2 vector2 = player.Center + new Vector2(-(float)Main.rand.Next(0, 401) * (float)player.direction, -600f);
    vector2.Y -= (float)(100 * num116);
    Vector2 value8 = value7 - vector2;
    if (value8.Y < 0f)
    {
        value8.Y *= -1f;
    }
    if (value8.Y < 20f)
    {
        value8.Y = 20f;
    }
    value8.Normalize();
    value8 *= yourProjectileSpeed;
    num78 = value8.X;
    num79 = value8.Y;
    float speedX5 = num78;
    float speedY6 = num79 + (float)Main.rand.Next(-40, 41) * 0.02f;
    Projectile.NewProjectile(vector2.X, vector2.Y, speedX5, speedY6, 503, 50, 0, player.whoAmI, 0f, num115);
}
The AI of the projectile is basically used to check if the projectile has gotten above a certain Y coordinate (projectile.ai[1] is used for that) to check if the projectile should collide.
Note that this code is not tested.
do i put this code in the projectile(.cs) or Weapon(.cs)
 

Darkninja

Spazmatism
This is the code you'd put on your weapon, since this is the code that spawns the projectiles (or stars, whichever naming you prefer).
so i used this code (
Code:
namespace Sword.Items.Weapons
{
    public class NaturesWrath : ModItem
    {
        public override void SetDefaults()
        {
            item.name = "Natures Wrath";
            item.damage = 110;
            item.melee = true;
            item.autoReuse = true;
            item.width = 68;
            item.height = 76;
            item.useTime = 16;
            item.useAnimation = 16;
            item.useStyle = 1;
            item.scale = 1.1f;
            item.knockBack = 6.5f;
            item.value = 200000;
            item.rare = 9;
            item.useSound = 105;
            item.shoot = 503;
            item.shootSpeed = 8f;
        }              

        public override bool Shoot(Player player, ref Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack)
        {
            int projNum = 3;
            for (int index = 0; index < projNum; ++index)
            {
                Vector2 vector2_1 = new Vector2((float) ((double) player.position.X + (double) player.width * 0.5 + (double) (Main.rand.Next(201) * -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));
                vector2_1.X = (float) (((double) vector2_1.X + (double) player.Center.X) / 2.0) + (float) Main.rand.Next(-200, 201);
                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(-40, 41) * 0.02f;
                float SpeedY = num17 + (float) Main.rand.Next(-40, 41) * 0.02f;
                Projectile.NewProjectile(vector2_1.X, vector2_1.Y, SpeedX, SpeedY, type, damage, knockBack, Main.myPlayer, 0.0f, (float) Main.rand.Next(5));
            }
            return false;
        }

}}
) and i got this error:
Missing texture Sword/Items/Weapons/NaturesWrath
at Terraria.ModLoader.ModLoader.GetTexture(String name)
at Terraria.ModLoader.Mod.SetupContent()
at Terraria.ModLoader.ModLoader.do_Load(Object threadContext)

can u help pleez
 

Eldrazi

Eater of Worlds
so i used this code (
Code:
namespace Sword.Items.Weapons
{
    public class NaturesWrath : ModItem
    {
        public override void SetDefaults()
        {
            item.name = "Natures Wrath";
            item.damage = 110;
            item.melee = true;
            item.autoReuse = true;
            item.width = 68;
            item.height = 76;
            item.useTime = 16;
            item.useAnimation = 16;
            item.useStyle = 1;
            item.scale = 1.1f;
            item.knockBack = 6.5f;
            item.value = 200000;
            item.rare = 9;
            item.useSound = 105;
            item.shoot = 503;
            item.shootSpeed = 8f;
        }             

        public override bool Shoot(Player player, ref Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack)
        {
            int projNum = 3;
            for (int index = 0; index < projNum; ++index)
            {
                Vector2 vector2_1 = new Vector2((float) ((double) player.position.X + (double) player.width * 0.5 + (double) (Main.rand.Next(201) * -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));
                vector2_1.X = (float) (((double) vector2_1.X + (double) player.Center.X) / 2.0) + (float) Main.rand.Next(-200, 201);
                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(-40, 41) * 0.02f;
                float SpeedY = num17 + (float) Main.rand.Next(-40, 41) * 0.02f;
                Projectile.NewProjectile(vector2_1.X, vector2_1.Y, SpeedX, SpeedY, type, damage, knockBack, Main.myPlayer, 0.0f, (float) Main.rand.Next(5));
            }
            return false;
        }

}}
) and i got this error:
Missing texture Sword/Items/Weapons/NaturesWrath
at Terraria.ModLoader.ModLoader.GetTexture(String name)
at Terraria.ModLoader.Mod.SetupContent()
at Terraria.ModLoader.ModLoader.do_Load(Object threadContext)

can u help pleez
Your texture is not placed correctly (or named wrong), it's exactly what the error says ;)
 

Darkninja

Spazmatism
Wait whut?
No, I mean check if the names of your class and texture are the same, since this IS a texture that is placed/named wrong.
well that's goood ,mean ok
[DOUBLEPOST=1450752451,1450752436][/DOUBLEPOST]awww soo confused
[DOUBLEPOST=1450752966][/DOUBLEPOST]yes, yes, yes!!!!!!!!!!!!!!!!
Thank you so much i love this and it works perfectly>
 

Eldrazi

Eater of Worlds
sorry to bother you guys again
but what does this (projectile.alpha) do?
Do you know what alpha is? Alpha determines the transparancy of an image (more specifically a pixel, but...).
Now normally an alpha of 0 would result in total transparancy and an alpha of 255 would be no transparancy at all, but it's quite the other way around when you're modding Terraria.
 

Darkninja

Spazmatism
Do you know what alpha is? Alpha determines the transparancy of an image (more specifically a pixel, but...).
Now normally an alpha of 0 would result in total transparancy and an alpha of 255 would be no transparancy at all, but it's quite the other way around when you're modding Terraria.
i see now. tnx
[DOUBLEPOST=1450754706,1450754208][/DOUBLEPOST]also what determines how fast the projectile falls
i tried decreasing the item.shootSpeed but didn't work
 

Eldrazi

Eater of Worlds
i see now. tnx
[DOUBLEPOST=1450754706,1450754208][/DOUBLEPOST]also what determines how fast the projectile falls
i tried decreasing the item.shootSpeed but didn't work
This line:
Code:
float SpeedY = num17 + (float) Main.rand.Next(-40, 41) * 0.02f;
You'll want to change the '0.02f' value for a different falling speed (the higher the value, the faster it'll fall).
 
Top Bottom