Standalone [1.3] tModLoader - A Modding API

I can't even get it to shoot multiple projectiles via Shoot, I'm a moron.
For that you'll need to use Projectile.NewProjectile, which has an annoying number of parameters. I think I have it so for the most part Shoot has parameters in the same order as Projectile.NewProjectile.
Looks like this method is this:
public static int NewProjectile(float X, float Y, float SpeedX, float SpeedY, int Type, int Damage, float KnockBack, int Owner = 255, float ai0 = 0f, float ai1 = 0f)
 
For that you'll need to use Projectile.NewProjectile, which has an annoying number of parameters. I think I have it so for the most part Shoot has parameters in the same order as Projectile.NewProjectile.
Looks like this method is this:
public static int NewProjectile(float X, float Y, float SpeedX, float SpeedY, int Type, int Damage, float KnockBack, int Owner = 255, float ai0 = 0f, float ai1 = 0f)

Yeah I got that far. But it doesn't really execute the for loop until it hits the max value, it just does it once.
 
Huh. They're all being given different speeds, right?

Now it is actually working, I have no clue what I did wrong.
Here's the code: (need to finetune the speeds)
Now the scythe shoots projectiles in random directions, but because my numbers are really bad it is not so 'random' that's why I said it needs finetuning

Code:
            int i;
            for (i = 0; i < Main.rand.Next(4); i++)
            {
                speedX = (speedX + Main.rand.NextFloat() / 16f) + 2f;
                speedY = (speedY + Main.rand.NextFloat() / 8f) + 2f;
                Projectile.NewProjectile(position.X, position.Y, speedX, speedY, item.shoot, damage, knockBack, item.owner);
            }

            //randomize the velocity a bit
            speedX *= (Main.rand.NextFloat() + -2f + Main.rand.NextFloat());
            speedY *= (-2f + Main.rand.NextFloat());
            return true;
 
For anybody who needs them, here's a couple of common use examples for the shoot function.

The first fires each shot in a random spread:
Code:
public override bool Shoot(Player player, ref Microsoft.Xna.Framework.Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack)
{
    float spread = 45f * 0.0174f;//45 degrees converted to radians
    float baseSpeed = (float)Math.Sqrt(speedX * speedX + speedY * speedY);
    double baseAngle = Math.Atan2(speedX, speedY);
    double randomAngle = baseAngle+(Main.rand.NextFloat()-0.5f)*spread;
    speedX = baseSpeed*(float)Math.Sin(randomAngle);
    speedY = baseSpeed*(float)Math.Cos(randomAngle);
    return true;
}

And the second fires eight shots simultaneously in an evenly spaced arc:
Code:
public override bool Shoot(Player player, ref Microsoft.Xna.Framework.Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack)
{
    float spread = 45f * 0.0174f;
    float baseSpeed = (float)Math.Sqrt(speedX * speedX + speedY * speedY);
    double startAngle = Math.Atan2(speedX, speedY)- spread/2;
    double deltaAngle = spread/8f;
    double offsetAngle;
    int i;
    for (i = 0; i < 8;i++ )
    {
        offsetAngle = startAngle + deltaAngle * i;
        Terraria.Projectile.NewProjectile(position.X, position.Y, baseSpeed*(float)Math.Sin(offsetAngle), baseSpeed*(float)Math.Cos(offsetAngle), item.shoot, damage, knockBack, item.owner);
    }
    return false;
}

Edit: Fixed speed issue.
 
Last edited:
For anybody who needs them, here's a couple of common use examples for the shoot function.

The first fires each shot in a random spread:
Code:
public override bool Shoot(Player player, ref Microsoft.Xna.Framework.Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack)
{
    float spread = 45f * 0.0174f;//45 degrees converted to radians
    double baseAngle = Math.Atan2(speedX, speedY);
    double randomAngle = baseAngle+(Main.rand.NextFloat()-0.5f)*spread;
    speedX = (float)Math.Sin(randomAngle);
    speedY = (float)Math.Cos(randomAngle);
    return true;
}

And the second fires eight shots simultaneously in an evenly spaced arc:
Code:
public override bool Shoot(Player player, ref Microsoft.Xna.Framework.Vector2 position, ref float speedX, ref float speedY, ref int type, ref int damage, ref float knockBack)
{
    float spread = 45f * 0.0174f;
    double startAngle = Math.Atan2(speedX, speedY)- spread/2;
    double deltaAngle = spread/8f;
    double offsetAngle;
    int i;
    for (i = 0; i < 8;i++ )
    {
        offsetAngle = startAngle + deltaAngle * i;
        Terraria.Projectile.NewProjectile(position.X, position.Y, (float)Math.Sin(offsetAngle), (float)Math.Cos(offsetAngle), item.shoot, damage, knockBack, item.owner);
    }
    return false;
}

Edit: Those where tested with demon scythes, the speed is wrong. I'll have an updated one that works with regular projectiles in a minute.

Cool stuff! How would one fire the same projectiles, (even spaced arc) in the opposite direction and a bit faster? Also, they don't feel quite right as they are all fired some space above my cursor, so aiming is really difficult

edit: I got it to shoot both forward and backward, not sure how to do top and bottom

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)
        {
            float spread = 45f * 0.0174f;
            double startAngle = Math.Atan2(speedX, speedY)- spread/2;
            double deltaAngle = spread/8f;
            double offsetAngle;
            int i;
            for (i = 0; i < Main.rand.Next(3,5); i++ )
            {
                offsetAngle = startAngle + deltaAngle * i;
                Terraria.Projectile.NewProjectile(position.X, position.Y, (float)Math.Sin(offsetAngle), (float)Math.Cos(offsetAngle), item.shoot, damage, knockBack, item.owner);
                Terraria.Projectile.NewProjectile(position.X, position.Y, (float)-Math.Sin(offsetAngle), (float)-Math.Cos(offsetAngle), item.shoot, damage, knockBack, item.owner);
            }
            return false;
        }
 
Last edited:
I Have a problem.. I downloaded the new version.. but when i patch my normal terraria, and want to open it, there will be an error message displaying:
The programm can't be opened because Windows is not able to run it.
I don't know what the problem is but i shall go to the software releaser, said at least windows and well so i do now :D
 
I Have a problem.. I downloaded the new version.. but when i patch my normal terraria, and want to open it, there will be an error message displaying:
The programm can't be opened because Windows is not able to run it.
I don't know what the problem is but i shall go to the software releaser, said at least windows and well so i do now :D

Redownload the vanilla .exe file via Steam and run it at least once before attempting to install tModLoader.
 
I Have a problem.. I downloaded the new version.. but when i patch my normal terraria, and want to open it, there will be an error message displaying:
The programm can't be opened because Windows is not able to run it.
I don't know what the problem is but i shall go to the software releaser, said at least windows and well so i do now :D
Hm. When you use a decompiler such as IlSpy, is it able to at least detect that the patched file is a program? (No need to actually decompile.)
 
Wohoo got it to work! Fires in plenty directions now! hehe..


(this is with hitting 1x)
13uOhhW.png



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)
{
    float spread = 45f * 0.0174f;
    double startAngle = Math.Atan2(speedX, speedY)- spread/2;
    double deltaAngle = spread/8f;
    double offsetAngle;
    int i;
    for (i = 0; i < 4; i++ )
    {
        offsetAngle = (startAngle + deltaAngle * (i + i*i) / 2f) + 32f * i;
        Terraria.Projectile.NewProjectile(position.X, position.Y, (float)(Math.Sin(offsetAngle)*5f), (float)(Math.Cos(offsetAngle)*5f), item.shoot, damage, knockBack, item.owner);
        Terraria.Projectile.NewProjectile(position.X, position.Y, (float)(-Math.Sin(offsetAngle)*5f), (float)(-Math.Cos(offsetAngle)*5f), item.shoot, damage, knockBack, item.owner);
    }
    return false;
}
 
I'm thinking, would it be possible to send a light effect with a projectile? Or would you have to create your own custom projectile?
 
For that you'd actually have to create your own projectile.

Alright. By the way I noticed that when creating your own soul you need to add this to SetDefaults:
Code:
ItemID.Sets.AnimatesAsSoul[item.type] = true;

If you don't the animation becomes messed up when you drop it. (for me it went way too fast)
 
It basically allows you to do things like add dust to your sword swings (for example, melee enchantments and the magma stone do this).

What kind of code would I need for that? I tried figuring out these things myself looking into the Terraria code, but it's so much.. I have no clue where to look and what to look for.
 
What kind of code would I need for that? I tried figuring out these things myself looking into the Terraria code, but it's so much.. I have no clue where to look and what to look for.
Here's some example code which is similar to what the magma stone causes:
Code:
int dust = Dust.NewDust(new Vector2((float)hitbox.X, (float)hitbox.Y), hitbox.Width, hitbox.Height, 6, player.velocity.X * 0.2f + (float)(player.direction * 3), player.velocity.Y * 0.2f, 100, default(Color), 2.5f);
Main.dust[dust].noGravity = true;
Main.dust[dust].velocity *= 2f;
A ton of stuff is for whatever reason thrown into a single ItemCheck method in the Player class.
 
Here's some example code which is similar to what the magma stone causes:
Code:
int dust = Dust.NewDust(new Vector2((float)hitbox.X, (float)hitbox.Y), hitbox.Width, hitbox.Height, 6, player.velocity.X * 0.2f + (float)(player.direction * 3), player.velocity.Y * 0.2f, 100, default(Color), 2.5f);
Main.dust[dust].noGravity = true;
Main.dust[dust].velocity *= 2f;
A ton of stuff is for whatever reason thrown into a single ItemCheck method in the Player class.

Alright thanks for the example. That code works perfect.
So I was trying this, to add light sources when swinging.. I disabled all other light sources with this weapon.. but these don't show up so it doesn't seem possible?
Code:
        public override void MeleeEffects(Player player, Rectangle hitbox)
        {
            //int dust = Dust.NewDust(new Vector2((float)hitbox.X, (float)hitbox.Y), hitbox.Width, hitbox.Height, 27, player.velocity.X * 0.2f + (float)(player.direction * 3), player.velocity.Y * 0.2f, 100, default(Color), 1.75f);
            //Main.dust[dust].noGravity = true;
            //Main.dust[dust].velocity *= 1.66f;

            var FrontLightPos = new Vector2((float)player.position.X * 0.2f, (float)player.position.Y);
            var BackLightPos = new Vector2((float)player.position.X / 0.2f, (float)player.position.Y);

            Lighting.AddLight(FrontLightPos, 0.75f, 0f, 0f);
            Lighting.AddLight(BackLightPos, 0f, 0f, 0.75f);
        }
 
Alright thanks for the example. That code works perfect.
So I was trying this, to add light sources when swinging.. I disabled all other light sources with this weapon.. but these don't show up so it doesn't seem possible?
Code:
        public override void MeleeEffects(Player player, Rectangle hitbox)
        {
            //int dust = Dust.NewDust(new Vector2((float)hitbox.X, (float)hitbox.Y), hitbox.Width, hitbox.Height, 27, player.velocity.X * 0.2f + (float)(player.direction * 3), player.velocity.Y * 0.2f, 100, default(Color), 1.75f);
            //Main.dust[dust].noGravity = true;
            //Main.dust[dust].velocity *= 1.66f;

            var FrontLightPos = new Vector2((float)player.position.X * 0.2f, (float)player.position.Y);
            var BackLightPos = new Vector2((float)player.position.X / 0.2f, (float)player.position.Y);

            Lighting.AddLight(FrontLightPos, 0.75f, 0f, 0f);
            Lighting.AddLight(BackLightPos, 0f, 0f, 0.75f);
        }
The problem here is that you're multiplying player.position, which is the player's position in the world. So it's creating light, just very far away. You probably meant to use + and - instead of * and /.
Also, I had no idea AddLight was overloaded; this will make things so much easier for me :p
 
The problem here is that you're multiplying player.position, which is the player's position in the world. So it's creating light, just very far away. You probably meant to use + and - instead of * and /.
Also, I had no idea AddLight was overloaded; this will make things so much easier for me :p

Oh yes you're right, I had to do + and -.. I'm stupid
Also found this chart of dust particles:
MMzsoqX.png

[DOUBLEPOST=1437504174,1437504024][/DOUBLEPOST]I'm hoping you add tiles in soon :D
 
Back
Top Bottom