Projectile Penetration

DottWolf

Terrarian
Hello, Recently been trying to make a mod with scythes that can be thrown and tried to make a scythe that works as a boomerang, the scythe should be being thrown, hit multiple times dealing a lot of damage (like the zenith does) and then come back, my problem is that my projectile isn't penetraing the enemy a lot, it deals damage but some of the scythes doesn't and I was wanting to see if someone could help me with it

Code of weapon:

using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.DataStructures;
using Microsoft.Xna.Framework;
using ScythesEVrywhere.Content.Projectiles;
namespace ScythesEVrywhere.Content.Items
{
// This is a basic item template.
// Please see tModLoader's ExampleMod for every other example:
// tModLoader/ExampleMod at stable · tModLoader/tModLoader
public class GhostReaper : ModItem
{
// The Display Name and Tooltip of this item can be edited in the 'Localization/en-US_Mods.ScythesEVrywhere.hjson' file.
public override void SetDefaults()
{
Item.damage = 200;
Item.DamageType = DamageClass.Melee;
Item.width = 72;
Item.height = 102;
Item.useTime = 8;
Item.useAnimation = 8;
Item.useStyle = ItemUseStyleID.Swing;
Item.knockBack = 5;
Item.value = Item.buyPrice(gold: 10);
Item.rare = ItemRarityID.Red;
Item.UseSound = SoundID.Item1;
Item.autoReuse = true;
Item.shoot = ModContent.ProjectileType<GhostReaperProjectile>();
Item.shootSpeed = 15;
Item.crit = 15;
Item.noUseGraphic = true;
Item.noMelee = true;

}
public override void AddRecipes()
{
Recipe recipe = CreateRecipe();
recipe.AddIngredient(ItemID.DirtBlock, 10);
recipe.AddTile(TileID.WorkBenches);
recipe.Register();
}
}
}

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Code of the Proj:

using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace ScythesEVrywhere.Content.Projectiles
{
public class GhostReaperProjectile : ModProjectile
{
public override void SetDefaults()
{
Projectile.width = 72;
Projectile.height = 102;
Projectile.aiStyle = ProjAIStyleID.Boomerang;
Projectile.friendly = true;
Projectile.hostile = false;
Projectile.penetrate = -1;
Projectile.tileCollide = false;
Projectile.DamageType = DamageClass.Melee;
Projectile.damage = 180;
Projectile.timeLeft = 100;
Projectile.light = 1f;
Projectile.extraUpdates = 0;
Projectile.ignoreWater = true;
Projectile.ownerHitCheck = true;
}
public override void AI()
{
for(int i = 0; i < 100; i++)
{
NPC target = Main.npc;
//If the npc is hostile
if(target.friendly)
{
//Get the shoot trajectory from the projectile and target
float shootToX = target.position.X + (float)target.width * 0.5f - Projectile.Center.X;
float shootToY = target.position.Y - Projectile.Center.Y;
float distance = (float)System.Math.Sqrt((double)(shootToX * shootToX + shootToY * shootToY));
//If the distance between the live targeted npc and the projectile is less than 480 pixels
if(distance < 480f && !target.friendly && target.active)
{
//Divide the factor, 3f, which is the desired velocity
distance = 3f / distance;

//Multiply the distance by a multiplier if you wish the projectile to have go faster
shootToX *= distance * 5;
shootToY *= distance * 5;
//Set the velocities to the shoot values
Projectile.velocity.X = shootToX;
Projectile.velocity.Y = shootToY;
}
}
}
}
}

}
 
It's hard to tell what you are trying to do based on the projectile. GhostReaperProjectile.AI() has a contradiction that prevents it's unique behavior, causing it to act exactly the same as a normal wooden boomerang. Even without the errors, it looks like it would just move towards the nearest enemy, hovering on them until it despawns.
Are you trying to make a projectile that homes in on enemies, stays on the enemy, then returns? If so, then how do you intend to determine how long the projectile should stay on the enemy? Number of hits? Duration?
 
Last edited:
It's hard to tell what you are trying to do based on the projectile. GhostReaperProjectile.AI() has a contradiction that prevents it's unique behavior, causing it to act exactly the same as a normal wooden boomerang. Even without the errors, it looks like it would just move towards the nearest enemy, hovering on them until it despawns.
Are you trying to make a projectile that homes in on enemies, stays on the enemy, then returns? If so, then how do you intend to determine how long the projectile should stay on the enemy? Number of hits? Duration?
No no, was just a weapon you throw and comes back, I was searching for the frames invulnerability but now I would like that the weapon could go through the enemy, because it only hits and then comes back, I want it go through it and then come back
 
Index 0 of Projectile.ai is used to keep track if the wooden boomerang projectile is returning or not. Index 1 of Projectile.ai is used as a counter for when the projectile should start returning. If Projectile.ai[0] is non-zero, then it's returning. If projectile.ai[1] is greater than 0, then the projectile probably still has duration left. When the boomerang projectile hits an enemy, Projectile.ai[0] is set to 1 and it's velocity is made negative, but only if the value at index 0 was zero. This means that if you want to make the boomerang act as though it hasn't hit an enemy when it has, then you would do:
C#:
public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone)
{
    Projectile.ai[0] = 0;
    if(Projectile.ai[1] != 0)
        Projectile.velocity *= -1;
}
You need the "Projectile.ai[1] != 0" since the boomerang doesn't reflect off enemies on the way back
 
Last edited:
Back
Top Bottom