Standalone [1.3] tModLoader - A Modding API

Alright. Thank you.
[doublepost=1458812256,1458811736][/doublepost]Bow works fine, but I think I messed something with the projectile:

using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ModLoader;
using Terraria.ID;

namespace EpicModpack.Projectiles
{
public class Stinger : ModProjectile
{
public override void SetDefaults()
{
projectile.name = "Stinger";
projectile.width = 10;
projectile.height = 18;
projectile.friendly = true;
projectile.ranged = true;
projectile.penetrate = 0;
projectile.timeLeft = 600;
projectile.aiStyle = 55;
}

public override void OnHitNPC(NPC target, int damage, float knockback, bool crit)
{
if (Main.rand.Next(10) == 0)
{
target.AddBuff(BuffID.Poisoned, 180, false);
}
}
}
}

What is wrong? The projectile doesn't even show.
Could you also show your item code?
 
Alright:

using System;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Microsoft.Xna.Framework;

namespace EpicModpack.Items.Weapons
{
public class Stingbow : ModItem
{
public override void SetDefaults()
{
item.name = "Stingbow";
item.damage = 28;
item.ranged = true;
item.width = 18;
item.height = 40;
item.useTime = 24;
item.useAnimation = 20;
item.useStyle = 5;
item.noMelee = true;
item.knockBack = 4;
item.value = 10000;
item.rare = 2;
item.useSound = 5;
item.autoReuse = false;
item.shoot = 10;
item.shootSpeed = 6.7f;
item.useAmmo = 1;
}

public override void AddRecipes()
{
ModRecipe recipe = new ModRecipe(mod);
recipe.AddIngredient(ItemID.Stinger, 12);
recipe.AddIngredient(ItemID.JungleSpores, 8);
recipe.AddTile(TileID.Anvils);
recipe.SetResult(this);
recipe.AddRecipe();
}

public override bool Shoot(Player player, ref Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack)
{
if (type == ProjectileID.WoodenArrowFriendly)
{
type = mod.ProjectileType("Stinger");
}
return true;
}
}
}
 
Allright hang on, it may (probably) be due to the fact you set projectile.penetrate to 0 in the SetDefaults function of your projectile.
If you want it to penetrate infinitely, set projectile.penetrate to -1.
 
Allright hang on, it may (probably) be due to the fact you set projectile.penetrate to 0 in the SetDefaults function of your projectile.
If you want it to penetrate infinitely, set projectile.penetrate to -1.
My idea was that the projectile won't penetrate.
 
Is your current projectile affected by it? Then it's probably something in the vanilla AI.
Probably nothing you can do about it in that case, then.
It is affected. I was looking through vanilla projectile field values, and bullets and arrows have the same AI. If I can't do anything about it, it's ok. Thank you so much for help.
 
It is affected. I was looking through vanilla projectile field values, and bullets and arrows have the same AI. If I can't do anything about it, it's ok. Thank you so much for help.
There is no such thing as for example setting a bool that will stop projectiles being affected by gravity, unfortunately. You'll have to decompile SRC, go to the aiStyle's code and grab whatever code you need from it, and find out how it's programmed. You'll need to look for code changing the X and Y velocities. Realistically speaking, it would make sense that the X velocity reduces over time due to resistance (energy --> heat) and for the Y velocity to go down due to gravity. That means you need to ADD to Y, so it needs to go UP (the other way around). Just remember this: negative X is to the left, negative Y is UP, so positive is the other way around (right, down) This is because it all originates from one starting point: the top left corner of the world.
 
Last edited:
How to add multiple recipes for one item (like Night's Edge, has different recipe for Crimson worlds)?
You just create two recipes, easy as that:
Code:
ModRecipe recipe = new ModRecipe(mod);
// Blabla, recipe stuff.
recipe.AddRecipe();

recipe = new ModRecipe(mod);
// Repeat.
recipe.AddRecipe();
 
Like with any other weapon that shoots a projectile, you just want to assign item.shoot and item.shootSpeed (where shoot should be set to the ID of the projectile and shootSpeed to the speed at which you want to shoot your projectile (try something like 10)).

It's not really an 'animation'. Strange as it may seem, spears are actually projectiles. Luckily the code ain't too long. Take a look at the following:
Code:
public override bool PreAI()
{
    float protractSpeed = 1.5F;
    float retractSpeed = 1.4F;

    Vector2 heldPos = Main.player[projectile.owner].RotatedRelativePoint(Main.player[projectile.owner].MountedCenter, true);
    projectile.direction = Main.player[projectile.owner].direction;
    Main.player[projectile.owner].heldProj = projectile.whoAmI;
    Main.player[projectile.owner].itemTime = Main.player[projectile.owner].itemAnimation;
    projectile.position.X = heldPos.X - (float)(projectile.width / 2);
    projectile.position.Y = heldPos.Y - (float)(projectile.height / 2);
    if (!Main.player[projectile.owner].frozen)
    {
        if (projectile.ai[0] == 0f)
        {
            projectile.ai[0] = 3f;
            projectile.netUpdate = true;
        }
        if (Main.player[projectile.owner].itemAnimation < Main.player[projectile.owner].itemAnimationMax / 3)
        {
            projectile.ai[0] -= retractSpeed;
        }
        else
        {
            projectile.ai[0] += protractSpeed;
        }
    }
    projectile.position += projectile.velocity * projectile.ai[0];
    if (Main.player[projectile.owner].itemAnimation == 0)
    {
        projectile.Kill();
    }
    projectile.rotation = (float)Math.Atan2((double)projectile.velocity.Y, (double)projectile.velocity.X) + 2.355f;
    if (projectile.spriteDirection == -1)
    {
        projectile.rotation -= 1.57f;
    }
    return false;
}
You can change the speed of the spear by modifying the top-most variables. DO NOTE: that spears are drawn different from other projectiles. The 'tip of the spear' should be in the top left corner of your sprite. The following drawing code would make your spear draw properly then:
Code:
public override bool PreDraw()
{
    Vector2 zero = Vector2.Zero;
    SpriteEffects effects1 = SpriteEffects.None;
    if (projectile.spriteDirection == -1)
    {
        zero.X = (float)Main.projectileTexture[projectile.type].Width;
        effects1 = SpriteEffects.FlipHorizontally;
    }
    Main.spriteBatch.Draw(Main.projectileTexture[projectile.type], new Vector2(projectile.position.X - Main.screenPosition.X + (float)(projectile.width / 2), projectile.position.Y - Main.screenPosition.Y + (float)(projectile.height / 2) + projectile.gfxOffY), new Microsoft.Xna.Framework.Rectangle?(new Microsoft.Xna.Framework.Rectangle(0, 0, Main.projectileTexture[projectile.type].Width, Main.projectileTexture[projectile.type].Height)), projectile.GetAlpha(lightColor), projectile.rotation, zero, projectile.scale, effects1, 0.0f);
    return false;
}

The following is how the dusts/gores are spawned:
Code:
for (int i = 0; i < 10; i ++)
{
    Dust.NewDust(projectile.position, projectile.width, projectile.height, 57, projectile.velocity.X * 0.1f, projectile.velocity.Y * 0.1f, 150, default(Color), 1.2f);
}
for (int j = 0; j < 3; j ++)
{
    Gore.NewGore(projectile.position, new Vector2(projectile.velocity.X * 0.05f, projectile.velocity.Y * 0.05f), Main.rand.Next(16, 18), 1f);
}
Thank you, but there is a problem I want to make sword to shoot chaos balls, so how can I make it to shoot NPC?
 
Thank you, but there is a problem I want to make sword to shoot chaos balls, so how can I make it to shoot NPC?
You'll want to override the Shoot function of your ModItem and spawn the NPC manually:
Code:
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 newNPC = NPC.NewNPC(position.X, position.Y, NPCID.ChaosBall);
     Main.npc[newNPC].velocity = new Vector2(speedX, speedY);
    return false;
}
This is untested, so not sure if it will work (since the ChaosBall is originally a hostile NPC).
 
h_1458821102_2557074_e8803da539.png

:c
Code:
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace NopeMod.Items.Weapons.Melee
{
    public class ChaosSword : ModItem
    {
        public override void SetDefaults()
        {
            item.name = "Chaos Sword";
            item.damage = 15;
            item.melee = true;
            item.width = 52;
            item.height = 52;
            item.toolTip = "Sword of chaos.";
            item.useTime = 40;
            item.useAnimation = 40;
            item.useStyle = 1;
            item.knockBack = 4;
            item.value = 00001000;
            item.rare = 2;
            item.useSound = 1;
            item.autoReuse = false;
            item.shoot = 14;
            item.shootSpeed = 10;
        }
               
            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 newNPC = NPC.NewNPC(position.X, position.Y, NPCID.ChaosBall);
                    Main.npc[newNPC].velocity = new Vector2(speedX, speedY);
                    return false;
                }


        public override void AddRecipes()
        {
            ModRecipe recipe = new ModRecipe(mod);
            recipe.AddIngredient(ItemID.DirtBlock, 1);
            recipe.SetResult(this);
            recipe.AddRecipe();
        }
    }
}
 
h_1458821102_2557074_e8803da539.png

:c
Code:
using System;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace NopeMod.Items.Weapons.Melee
{
    public class ChaosSword : ModItem
    {
        public override void SetDefaults()
        {
            item.name = "Chaos Sword";
            item.damage = 15;
            item.melee = true;
            item.width = 52;
            item.height = 52;
            item.toolTip = "Sword of chaos.";
            item.useTime = 40;
            item.useAnimation = 40;
            item.useStyle = 1;
            item.knockBack = 4;
            item.value = 00001000;
            item.rare = 2;
            item.useSound = 1;
            item.autoReuse = false;
            item.shoot = 14;
            item.shootSpeed = 10;
        }
              
            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 newNPC = NPC.NewNPC(position.X, position.Y, NPCID.ChaosBall);
                    Main.npc[newNPC].velocity = new Vector2(speedX, speedY);
                    return false;
                }


        public override void AddRecipes()
        {
            ModRecipe recipe = new ModRecipe(mod);
            recipe.AddIngredient(ItemID.DirtBlock, 1);
            recipe.SetResult(this);
            recipe.AddRecipe();
        }
    }
}
My bad:
int newNPC = NPC.NewNPC((int)position.X, (int)position.Y, NPCID.ChaosBall);
 
Back
Top Bottom