Flamethrower Projectile Help

JonersBean

Terrarian
I am trying to make a flamethrower projectile but i haven't got the animation to work

C#:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using Terraria;
using Terraria.Audio;
using Terraria.GameContent;
using Terraria.ID;
using Terraria.ModLoader;
using ZeriumMod.Content.Effects.Debuff;

namespace ZeriumMod.Content.Items.Projectiles.RangedProjectile
{
    public class RadioactiveFlames : ModProjectile
    {
        public ref float DelayTimer => ref Projectile.ai[23];
        public static readonly int FrameCount = 7; // Amount of frames we have on our animation spritesheet.
        public static readonly int AnimationSpeed = 10; // In ticks.
        public static readonly string AnimationSheetPath = "ZeriumMod/Content/Items/Projectiles/RangedProjectile/RadioactiveFlames";

        public override void SetStaticDefaults()
        {
            ProjectileID.Sets.TrailCacheLength[Projectile.type] = 5; // The length of old position to be recorded
            ProjectileID.Sets.TrailingMode[Projectile.type] = 0; // The recording mode
            Main.projFrames[Projectile.type] = 7;
        }

        public override void SetDefaults() {
            Projectile.width = 90; // The width of projectile hitbox
            Projectile.height = 90; // The height of projectile hitbox
            Projectile.aiStyle = 23; // The ai style of the projectile, please reference the source code of Terraria
            Projectile.friendly = true; // Can the projectile deal damage to enemies?
            Projectile.hostile = false; // Can the projectile deal damage to the player?
            Projectile.DamageType = DamageClass.Ranged; // Is the projectile shoot by a ranged weapon?
            Projectile.penetrate = 100; // How many monsters the projectile can penetrate. (OnTileCollide below also decrements penetrate for bounces as well)
            Projectile.timeLeft = 90; // The live time for the projectile (60 = 1 second, so 600 is 10 seconds)
            Projectile.alpha = 0; // The transparency of the projectile, 255 for completely transparent. (aiStyle 1 quickly fades the projectile in) Make sure to delete this if you aren't using an aiStyle that fades in. You'll wonder why your projectile is invisible.
            Projectile.light = 1f; // How much light emit around the projectile
            Projectile.ignoreWater = true; // Does the projectile's speed be influenced by water?
            Projectile.tileCollide = true; // Can the projectile collide with tiles?
            Projectile.extraUpdates = 1; // Set to above 0 if you want the projectile to update multiple time in a frame

            AIType = ProjectileID.Flames; // Act exactly like default Bullet
        }   
        public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) {
            target.AddBuff(ModContent.BuffType<RadiationBurnDebuff>(), 120);
            target.AddBuff(BuffID.OnFire, 240);
        }
        
        public override bool OnTileCollide(Vector2 oldVelocity) {
            // If collide with tile, reduce the penetrate.
            // So the projectile can reflect at most 5 times
            Projectile.penetrate--;
            if (Projectile.penetrate <= 0) {
                Projectile.Kill();
            }

            return false;
        }
            public override bool PreDraw(ref Color lightColor) {
            // Draws an afterimage trail. See https://github.com/tModLoader/tModLoader/wiki/Basic-Projectile#afterimage-trail for more information.

            Texture2D texture = TextureAssets.Projectile[Type].Value;

            Vector2 drawOrigin = new Vector2(texture.Width * 0.5f, Projectile.height * 0.5f);
            for (int k = Projectile.oldPos.Length - 1; k > 0; k--) {
                Vector2 drawPos = (Projectile.oldPos[k] - Main.screenPosition) + drawOrigin + new Vector2(0f, Projectile.gfxOffY);
                Color color = Projectile.GetAlpha(lightColor) * ((Projectile.oldPos.Length - k) / (float)Projectile.oldPos.Length);
                Main.EntitySpriteDraw(texture, drawPos, null, color, Projectile.rotation, drawOrigin, Projectile.scale, SpriteEffects.None, 0);
            }

            return true;
        }

        public override void OnKill(int timeLeft) {
            // This code and the similar code above in OnTileCollide spawn dust from the tiles collided with. SoundID.Item10 is the bounce sound you hear.
            Collision.HitTiles(Projectile.position + Projectile.velocity, Projectile.velocity, Projectile.width, Projectile.height);
            SoundEngine.PlaySound(SoundID.Item10, Projectile.position);
        }
    }
}
 

Attachments

  • RadioactiveFlames.png
    RadioactiveFlames.png
    6.9 KB · Views: 26
You have to manually change Projectile.frame and Projectile.frameCounter yourself. Projectile.frame is which frame is being used, being on [0, Main.projFrames[Type]). Projectile.frameCounter is a variable you can use to keep track of time. You may do this like this:
C#:
const int TIME_PER_FRAME = 6;

public override void AI()
{
    Projectile.frameCounter++;
    if(Projectile.frameCounter >= TIME_PER_FRAME)
    {
        Projectile.frameCounter = 0;
        Projectile.frame = (Projectile.frame + 1) % Main.projFrames[Type];
    }
}
You also need to draw the after images with this frame too:
C#:
int frameHeight = texture.Height() / Main.projFrames[Type];
Rectangle currentFrame = new Rectangle(0, frameHeight * Projectile.frame, texture.Width(), frameHeight);
The third argument of SpriteBatch.Draw()/Main.EntitySpriteDraw() is the "source rectangle".
 
For that third arguement, would i just put the name of the File down or path along with it?
 
You would put currentFrame
 
What references do I need for this?
C#:
            public override bool PreDraw(ref Color lightColor) {
            // Draws an afterimage trail. See https://github.com/tModLoader/tModLoader/wiki/Basic-Projectile#afterimage-trail for more information.

            Texture2D texture = TextureAssets.Projectile[Type].Value;

            Vector2 drawOrigin = new Vector2(texture.Width * 0.5f, Projectile.height * 0.5f);
            for (int k = Projectile.oldPos.Length - 1; k > 0; k--)
            {
                int frameHeight = texture.Height() / Main.projFrames[Type];
                Rectangle currentFrame = new Rectangle(0, frameHeight * Projectile.frame, texture.Width(), frameHeight);
                Vector2 drawPos = (Projectile.oldPos[k] - Main.screenPosition) + drawOrigin + new Vector2(0f, Projectile.gfxOffY);
                Color color = Projectile.GetAlpha(lightColor) * ((Projectile.oldPos.Length - k) / (float)Projectile.oldPos.Length);
                Main.EntitySpriteDraw(texture, drawPos, null, color, Projectile.rotation, currentFrame, Projectile.scale, SpriteEffects.None, 0);
                
            }

            return true;
        }

Here are the references I have

C#:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using Terraria;
using Terraria.Audio;
using Terraria.GameContent;
using Terraria.ID;
using Terraria.ModLoader;
using ZeriumMod.Content.Effects.Debuff;
 
Back
Top Bottom