Added Trident of the Sunken
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.7 KiB |
@@ -0,0 +1,48 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Terraria;
|
||||
using Terraria.Audio;
|
||||
using Terraria.ID;
|
||||
using Terraria.ModLoader;
|
||||
using ForgottenWawiTech.Content.Projectiles.TridentOfTheSunken;
|
||||
|
||||
namespace ForgottenWawiTech.Content.Items.Weapons.Magic
|
||||
{
|
||||
public class TridentOfTheSunken : ModItem
|
||||
{
|
||||
public override void SetStaticDefaults()
|
||||
{
|
||||
Item.ResearchUnlockCount = 1;
|
||||
}
|
||||
|
||||
public override void SetDefaults()
|
||||
{
|
||||
Item.damage = 5000;
|
||||
Item.DamageType = DamageClass.Magic;
|
||||
Item.knockBack = 6f;
|
||||
Item.width = 64;
|
||||
Item.height = 64;
|
||||
Item.useStyle = ItemUseStyleID.Shoot;
|
||||
Item.useAnimation = 30;
|
||||
Item.useTime = 30;
|
||||
Item.noMelee = true;
|
||||
Item.noUseGraphic = true;
|
||||
Item.channel = true;
|
||||
Item.mana = 24;
|
||||
Item.rare = ItemRarityID.Red;
|
||||
Item.value = Item.buyPrice(platinum: 3);
|
||||
Item.UseSound = SoundID.Item43;
|
||||
Item.shoot = ModContent.ProjectileType<TridentOfTheSunkenHoldout>();
|
||||
Item.shootSpeed = 0f;
|
||||
}
|
||||
|
||||
public override bool CanUseItem(Player player)
|
||||
{
|
||||
return player.ownedProjectileCounts[Item.shoot] == 0;
|
||||
}
|
||||
|
||||
public override void HoldItem(Player player)
|
||||
{
|
||||
Lighting.AddLight(player.Center, new Vector3(0.05f, 0.12f, 0.2f));
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
@@ -0,0 +1,51 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Terraria;
|
||||
using Terraria.ID;
|
||||
using Terraria.ModLoader;
|
||||
|
||||
namespace ForgottenWawiTech.Content.Projectiles.TridentOfTheSunken
|
||||
{
|
||||
public class TridentOfTheSunkenBlast : ModProjectile
|
||||
{
|
||||
public override string Texture => "Terraria/Images/Projectile_647"; // Duke Fishron bubble burst as placeholder
|
||||
|
||||
public override void SetDefaults()
|
||||
{
|
||||
Projectile.width = 10;
|
||||
Projectile.height = 10;
|
||||
Projectile.friendly = true;
|
||||
Projectile.hostile = false;
|
||||
Projectile.DamageType = DamageClass.Magic;
|
||||
Projectile.timeLeft = 2;
|
||||
Projectile.penetrate = -1;
|
||||
Projectile.tileCollide = false;
|
||||
Projectile.ignoreWater = true;
|
||||
Projectile.usesLocalNPCImmunity = true;
|
||||
Projectile.localNPCHitCooldown = -1;
|
||||
Projectile.alpha = 255;
|
||||
}
|
||||
|
||||
public override void AI()
|
||||
{
|
||||
if (Projectile.localAI[0] <= 0f)
|
||||
{
|
||||
Projectile.localAI[0] = 320f; // default radius if not provided
|
||||
}
|
||||
|
||||
float radius = Projectile.localAI[0];
|
||||
Projectile.position = Projectile.Center - new Vector2(radius);
|
||||
Projectile.width = Projectile.height = (int)(radius * 2f);
|
||||
Projectile.Center = Projectile.position + new Vector2(radius);
|
||||
|
||||
Lighting.AddLight(Projectile.Center, 0.2f, 0.35f, 0.8f);
|
||||
}
|
||||
|
||||
public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone)
|
||||
{
|
||||
target.AddBuff(BuffID.Suffocation, 600);
|
||||
}
|
||||
|
||||
public override bool? CanDamage() => true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Terraria;
|
||||
using Terraria.Audio;
|
||||
using Terraria.DataStructures;
|
||||
using Terraria.ID;
|
||||
using Terraria.ModLoader;
|
||||
|
||||
namespace ForgottenWawiTech.Content.Projectiles.TridentOfTheSunken
|
||||
{
|
||||
public class TridentOfTheSunkenHoldout : ModProjectile
|
||||
{
|
||||
private const int MaxChargeTime = 60;
|
||||
private const int RequiredChargeTime = 60;
|
||||
// Slight offsets so the player grips the center of the sprite instead of the trident hovering ahead.
|
||||
private const float HoldoutForwardOffset = 12f;
|
||||
private const float HoldoutVerticalOffset = -6f;
|
||||
|
||||
private ref float Charge => ref Projectile.ai[0];
|
||||
private ref float HasFired => ref Projectile.ai[1];
|
||||
|
||||
public override string Texture => "ForgottenWawiTech/Content/Items/Weapons/Magic/TridentOfTheSunken";
|
||||
|
||||
public override void SetDefaults()
|
||||
{
|
||||
Projectile.width = 30;
|
||||
Projectile.height = 256;
|
||||
Projectile.friendly = false;
|
||||
Projectile.hostile = false;
|
||||
Projectile.penetrate = -1;
|
||||
Projectile.tileCollide = false;
|
||||
Projectile.ignoreWater = true;
|
||||
}
|
||||
|
||||
public override void AI()
|
||||
{
|
||||
Player player = Main.player[Projectile.owner];
|
||||
int tridentType = ModContent.ItemType<Items.Weapons.Magic.TridentOfTheSunken>();
|
||||
if (player.dead || player.HeldItem.type != tridentType)
|
||||
{
|
||||
Projectile.Kill();
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 handPosition = player.RotatedRelativePoint(player.MountedCenter, true);
|
||||
player.heldProj = Projectile.whoAmI;
|
||||
player.itemAnimation = player.itemTime = 2;
|
||||
|
||||
Vector2 aim = Projectile.velocity;
|
||||
if (Main.myPlayer == player.whoAmI)
|
||||
{
|
||||
aim = Main.MouseWorld - handPosition;
|
||||
if (aim.LengthSquared() < 0.01f)
|
||||
{
|
||||
aim = new Vector2(player.direction, 0f);
|
||||
}
|
||||
aim.Normalize();
|
||||
|
||||
player.ChangeDir(aim.X >= 0f ? 1 : -1);
|
||||
Projectile.velocity = aim;
|
||||
}
|
||||
|
||||
Vector2 anchorOffset = new Vector2(player.direction * HoldoutForwardOffset, HoldoutVerticalOffset * player.gravDir);
|
||||
Projectile.Center = handPosition + anchorOffset;
|
||||
|
||||
Projectile.direction = player.direction;
|
||||
Projectile.spriteDirection = player.direction;
|
||||
Projectile.rotation = 0f;
|
||||
|
||||
if (player.channel)
|
||||
{
|
||||
Charge = MathHelper.Clamp(Charge + 1f, 0f, MaxChargeTime);
|
||||
if (Charge == RequiredChargeTime)
|
||||
{
|
||||
ReadyFeedback(player);
|
||||
}
|
||||
else if (Charge % 15f == 0f)
|
||||
{
|
||||
SoundEngine.PlaySound(SoundID.Item15 with { Volume = 0.3f }, player.Center);
|
||||
}
|
||||
}
|
||||
else if (HasFired == 0f)
|
||||
{
|
||||
if (Main.myPlayer == player.whoAmI && Charge >= RequiredChargeTime)
|
||||
{
|
||||
FireProjectile(player, handPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
CancelCharge(player);
|
||||
}
|
||||
}
|
||||
|
||||
Projectile.timeLeft = 2;
|
||||
}
|
||||
|
||||
public override void Kill(int timeLeft)
|
||||
{
|
||||
if (HasFired == 0f && Main.player[Projectile.owner] is Player player && player.active && !player.dead)
|
||||
{
|
||||
Vector2 handPosition = player.RotatedRelativePoint(player.MountedCenter, true);
|
||||
if (Main.myPlayer == player.whoAmI && Charge >= RequiredChargeTime)
|
||||
{
|
||||
FireProjectile(player, handPosition);
|
||||
}
|
||||
else if (Charge < RequiredChargeTime)
|
||||
{
|
||||
CancelCharge(player, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FireProjectile(Player player, Vector2 spawnPosition)
|
||||
{
|
||||
if (Charge < RequiredChargeTime)
|
||||
{
|
||||
CancelCharge(player);
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 aim = Projectile.velocity;
|
||||
if (aim.LengthSquared() < 0.01f)
|
||||
{
|
||||
aim = new Vector2(player.direction, 0f);
|
||||
}
|
||||
aim.Normalize();
|
||||
|
||||
float chargeProgress = MathHelper.Clamp(Charge / MaxChargeTime, 0f, 1f);
|
||||
float speed = MathHelper.Lerp(7f, 12f, chargeProgress);
|
||||
|
||||
int baseDamage = player.GetWeaponDamage(player.HeldItem);
|
||||
int damage = (int)(baseDamage * MathHelper.Lerp(1f, 1.6f, chargeProgress));
|
||||
float knockBack = player.GetWeaponKnockback(player.HeldItem, player.HeldItem.knockBack) * MathHelper.Lerp(1f, 1.2f, chargeProgress);
|
||||
|
||||
IEntitySource source = player.GetSource_ItemUse(player.HeldItem);
|
||||
int proj = Projectile.NewProjectile(source, spawnPosition, aim * speed, ModContent.ProjectileType<TridentOfTheSunkenShot>(), damage, knockBack, player.whoAmI, chargeProgress);
|
||||
|
||||
if (Main.projectile.IndexInRange(proj))
|
||||
{
|
||||
Main.projectile[proj].localAI[0] = chargeProgress;
|
||||
}
|
||||
|
||||
SoundEngine.PlaySound(SoundID.Item72 with { Volume = 0.8f }, spawnPosition);
|
||||
HasFired = 1f;
|
||||
Projectile.netUpdate = true;
|
||||
Projectile.Kill();
|
||||
}
|
||||
|
||||
private void ReadyFeedback(Player player)
|
||||
{
|
||||
if (Main.dedServ)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SoundEngine.PlaySound(SoundID.Item33 with { Volume = 0.6f, Pitch = -0.1f }, Projectile.Center);
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
Vector2 velocity = Main.rand.NextVector2Circular(1.2f, 1.2f) * Main.rand.NextFloat(0.8f, 1.4f);
|
||||
Dust dust = Dust.NewDustDirect(Projectile.Center - new Vector2(5f, 85f), 16, 16, DustID.BlueFairy, velocity.X, velocity.Y, 100, default, 1.1f);
|
||||
dust.noGravity = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void CancelCharge(Player player, bool killProjectile = true)
|
||||
{
|
||||
if (HasFired != 0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HasFired = -1f;
|
||||
Projectile.netUpdate = true;
|
||||
SoundEngine.PlaySound(SoundID.MenuClose with { Volume = 0.6f }, player.Center);
|
||||
if (killProjectile && Projectile.active)
|
||||
{
|
||||
Projectile.Kill();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Terraria;
|
||||
using Terraria.Audio;
|
||||
using Terraria.ID;
|
||||
using Terraria.ModLoader;
|
||||
|
||||
namespace ForgottenWawiTech.Content.Projectiles.TridentOfTheSunken
|
||||
{
|
||||
public class TridentOfTheSunkenShot : ModProjectile
|
||||
{
|
||||
private const float ExplosionRadiusBlocks = 20f;
|
||||
private const int ExplosionDamage = 5000;
|
||||
private const int DrownDuration = 600; // 10 seconds
|
||||
|
||||
private bool HasDetonated
|
||||
{
|
||||
get => Projectile.localAI[1] == 1f;
|
||||
set => Projectile.localAI[1] = value ? 1f : 0f;
|
||||
}
|
||||
|
||||
public override void SetDefaults()
|
||||
{
|
||||
Projectile.width = 256;
|
||||
Projectile.height = 30;
|
||||
Projectile.friendly = true;
|
||||
Projectile.hostile = false;
|
||||
Projectile.DamageType = DamageClass.Magic;
|
||||
Projectile.penetrate = 1;
|
||||
Projectile.aiStyle = 0;
|
||||
Projectile.tileCollide = true;
|
||||
Projectile.ignoreWater = false;
|
||||
Projectile.extraUpdates = 1;
|
||||
Projectile.timeLeft = 180;
|
||||
}
|
||||
|
||||
public override void AI()
|
||||
{
|
||||
if (Projectile.velocity.LengthSquared() > 0.0001f)
|
||||
{
|
||||
Projectile.direction = Projectile.spriteDirection = Projectile.velocity.X >= 0f ? 1 : -1;
|
||||
Projectile.rotation = Projectile.velocity.ToRotation();
|
||||
if (Projectile.spriteDirection == -1)
|
||||
{
|
||||
Projectile.rotation += MathHelper.Pi;
|
||||
}
|
||||
}
|
||||
Lighting.AddLight(Projectile.Center, 0.1f, 0.2f, 0.6f);
|
||||
|
||||
if (Main.rand.NextBool(3))
|
||||
{
|
||||
Dust dust = Dust.NewDustDirect(Projectile.position, Projectile.width, Projectile.height, DustID.WaterCandle, 0f, 0f, 150, default, 1.1f);
|
||||
dust.velocity *= 0.3f;
|
||||
dust.noGravity = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnTileCollide(Vector2 oldVelocity)
|
||||
{
|
||||
Detonate();
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone)
|
||||
{
|
||||
target.AddBuff(BuffID.Suffocation, DrownDuration);
|
||||
Detonate();
|
||||
Projectile.Kill();
|
||||
}
|
||||
|
||||
public override void Kill(int timeLeft)
|
||||
{
|
||||
Detonate();
|
||||
}
|
||||
|
||||
private void Detonate()
|
||||
{
|
||||
if (HasDetonated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HasDetonated = true;
|
||||
|
||||
if (Projectile.owner == Main.myPlayer)
|
||||
{
|
||||
float radiusPixels = ExplosionRadiusBlocks * 16f;
|
||||
int explosion = Projectile.NewProjectile(Projectile.GetSource_Death(), Projectile.Center, Vector2.Zero, ModContent.ProjectileType<TridentOfTheSunkenBlast>(), ExplosionDamage, 8f, Projectile.owner, radiusPixels);
|
||||
if (Main.projectile.IndexInRange(explosion))
|
||||
{
|
||||
Main.projectile[explosion].localAI[0] = radiusPixels;
|
||||
}
|
||||
}
|
||||
|
||||
SoundEngine.PlaySound(SoundID.Item14 with { Volume = 1f, Pitch = -0.2f }, Projectile.Center);
|
||||
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
Vector2 velocity = Main.rand.NextVector2Unit() * Main.rand.NextFloat(2f, 6f);
|
||||
Dust dust = Dust.NewDustDirect(Projectile.position, Projectile.width, Projectile.height, DustID.BlueCrystalShard, velocity.X, velocity.Y, 150, default, 1.2f);
|
||||
dust.noGravity = true;
|
||||
}
|
||||
Projectile.timeLeft = Math.Min(Projectile.timeLeft, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
@@ -780,6 +780,16 @@ Items: {
|
||||
'''
|
||||
}
|
||||
|
||||
TridentOfTheSunken: {
|
||||
DisplayName: Trident of the Sunken
|
||||
Tooltip:
|
||||
'''
|
||||
Hold to flood the spear with abyssal pressure.
|
||||
Release to anchor a drowning tide where it lands.
|
||||
Enemies caught in the surge suffer crushing depth.
|
||||
'''
|
||||
}
|
||||
|
||||
TranscendentOmnitool: {
|
||||
DisplayName: Transcendent Omnitool
|
||||
Tooltip:
|
||||
@@ -1065,6 +1075,9 @@ Projectiles: {
|
||||
TranscendentAscendantDrone.DisplayName: Ascendant Swarm Drone
|
||||
TranscendentAscendantBolt.DisplayName: Ascendant Swarm Bolt
|
||||
TranscendentNaniteShard.DisplayName: Nanite Shard
|
||||
TridentOfTheSunkenShot.DisplayName: Trident Of The Sunken Shot
|
||||
TridentOfTheSunkenHoldout.DisplayName: Trident Of The Sunken Holdout
|
||||
TridentOfTheSunkenBlast.DisplayName: Trident Of The Sunken Blast
|
||||
}
|
||||
|
||||
Prefixes: {
|
||||
|
||||
@@ -108,6 +108,12 @@ I personally think only the Avalian Trader should be considered until we have a
|
||||
- A circular contained singularity that functions as an axe, hammer and pickaxe (on toggle). Maybe some glowing effects to show the singularity contained within?
|
||||
- [ ] Singularity Multitool
|
||||
- A high-tech multitool infused with singularity energy, capable of performing various functions such as mining, chopping, and hammering with enhanced efficiency.
|
||||
- [ ] Trident Of The Sunken
|
||||
- [x] Item icon for the charged trident staff.
|
||||
- [x] Holdout sprite (`TridentOfTheSunkenHoldout`).
|
||||
- [x] Spear projectile sprite (`TridentOfTheSunkenShot`).
|
||||
- [ ] Explosion FX sprite (`TridentOfTheSunkenBlast`).
|
||||
- A trident that is charged with Abyss energy, throwing out and creating mini tsunamis that make enemies suffocate in crushing depth pressure.
|
||||
|
||||
### Summon Items
|
||||
- [ ] Corrupted Beacon (final boss summon)
|
||||
@@ -117,6 +123,7 @@ I personally think only the Avalian Trader should be considered until we have a
|
||||
- [x] Niko Summon
|
||||
|
||||
### Treasure Bags
|
||||
|
||||
Based off Vanilla treasure bags as much as possible!!!
|
||||
- [ ] Lexy
|
||||
- [ ] Lyyka
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<h2>An expansion to pre-hardmode and endgame technology</h2>
|
||||
<p>
|
||||
The Forgotten Wawi Tech is a Terraria mod that introduces advanced technology and weaponry inspired by the Avali and Protogen species. This mod adds a variety of new items, weapons, armor, and crafting materials that allow players to harness the power of futuristic technology in their adventures.
|
||||
Calamity is not required, but highly recommended for the full experience.
|
||||
Aliquip veniam nulla nisi minim do elit dolor. Ea mollit ea velit est incididunt veniam irure commodo sit irure ad eu elit. Quis occaecat dolore dolore id tempor tempor consequat dolor velit sunt ipsum. Ad quis nisi nisi laboris non commodo eu officia.
|
||||
</p>
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<h2>An expansion to pre-hardmode and endgame technology</h2>
|
||||
<p>
|
||||
The Forgotten Wawi Tech is a Terraria mod that introduces advanced technology and weaponry inspired by the Avali and Protogen species. This mod adds a variety of new items, weapons, armor, and crafting materials that allow players to harness the power of futuristic technology in their adventures.
|
||||
Calamity is not required, but highly recommended for the full experience.
|
||||
Aliquip veniam nulla nisi minim do elit dolor. Ea mollit ea velit est incididunt veniam irure commodo sit irure ad eu elit. Quis occaecat dolore dolore id tempor tempor consequat dolor velit sunt ipsum. Ad quis nisi nisi laboris non commodo eu officia.
|
||||
</p>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user