Add visual affects to Developer and Singularity items
This commit is contained in:
@@ -0,0 +1,36 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using System;
|
||||||
|
using Terraria;
|
||||||
|
using Terraria.ModLoader;
|
||||||
|
using Terraria.ID;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ForgottenWawiTech.Content.Items.Global
|
||||||
|
{
|
||||||
|
// Appends a rainbow developer marker line to items with the Developer rarity
|
||||||
|
public class DeveloperRarityTooltip : GlobalItem
|
||||||
|
{
|
||||||
|
public override bool InstancePerEntity => false;
|
||||||
|
|
||||||
|
private static int DevRarityId => ModContent.RarityType<Content.Rarities.FWTDeveloperItem>();
|
||||||
|
|
||||||
|
public override void ModifyTooltips(Item item, List<TooltipLine> tooltips)
|
||||||
|
{
|
||||||
|
if (item.rare != DevRarityId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Build a hue-cycling color for the tooltip text
|
||||||
|
float time = Main.GlobalTimeWrappedHourly;
|
||||||
|
// Cycle hue 0..1 over 5 seconds
|
||||||
|
float hue = (time / 5f) % 1f;
|
||||||
|
Color rainbow = Main.hslToRgb(hue, 1f, 0.5f);
|
||||||
|
|
||||||
|
var line = new TooltipLine(Mod, "DeveloperMarker", "-Developer Based Item-")
|
||||||
|
{
|
||||||
|
OverrideColor = rainbow
|
||||||
|
};
|
||||||
|
|
||||||
|
tooltips.Add(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using ReLogic.Content;
|
||||||
|
using Terraria;
|
||||||
|
using Terraria.GameContent;
|
||||||
|
using Terraria.ID;
|
||||||
|
using Terraria.ModLoader;
|
||||||
|
|
||||||
|
namespace ForgottenWawiTech.Content.Items.Global
|
||||||
|
{
|
||||||
|
// Visual effects for items that use the Singularity rarity
|
||||||
|
public class SingularityRarityVisuals : GlobalItem
|
||||||
|
{
|
||||||
|
public override bool InstancePerEntity => false;
|
||||||
|
|
||||||
|
private static int SingularityRarityId => ModContent.RarityType<Content.Rarities.SingularityItem>();
|
||||||
|
|
||||||
|
private static bool IsSingularity(Item item) => item.rare == SingularityRarityId;
|
||||||
|
|
||||||
|
private static Color GetSingularityColor()
|
||||||
|
{
|
||||||
|
// Reuse the rarity's animated color so visuals stay in sync
|
||||||
|
var rarity = ModContent.GetInstance<Content.Rarities.SingularityItem>();
|
||||||
|
return rarity.RarityColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float GetBreathing(float hz, float minScale = 0.85f, float maxScale = 1.15f)
|
||||||
|
{
|
||||||
|
float t = Main.GlobalTimeWrappedHourly * hz * MathHelper.TwoPi;
|
||||||
|
float s = (float)(Math.Sin(t) * 0.5 + 0.5); // 0..1
|
||||||
|
return MathHelper.Lerp(minScale, maxScale, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PostDrawInInventory(Item item, SpriteBatch spriteBatch, Vector2 position, Rectangle frame, Color drawColor, Color itemColor, Vector2 origin, float scale)
|
||||||
|
{
|
||||||
|
if (!IsSingularity(item))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Texture2D texture = TextureAssets.Item[item.type].Value;
|
||||||
|
|
||||||
|
// Subtle chromatic aberration: red and blue edge offsets
|
||||||
|
float aberrPixels = 1f;
|
||||||
|
Color redTint = new Color(255, 60, 60) * 0.25f;
|
||||||
|
Color blueTint = new Color(60, 60, 255) * 0.25f;
|
||||||
|
|
||||||
|
spriteBatch.Draw(texture, position + new Vector2(aberrPixels, 0f), frame, redTint, 0f, origin, scale, SpriteEffects.None, 0f);
|
||||||
|
spriteBatch.Draw(texture, position + new Vector2(-aberrPixels, 0f), frame, blueTint, 0f, origin, scale, SpriteEffects.None, 0f);
|
||||||
|
|
||||||
|
// Optional glow overlay if a _Glow texture exists
|
||||||
|
if (TryGetGlowTexture(item, out var glowTex))
|
||||||
|
{
|
||||||
|
Color glowColor = GetSingularityColor();
|
||||||
|
float breathe = GetBreathing(0.5f, 0.9f, 1.2f);
|
||||||
|
spriteBatch.Draw(glowTex, position, frame, glowColor * 0.6f, 0f, origin, scale * breathe, SpriteEffects.None, 0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool PreDrawInWorld(Item item, SpriteBatch spriteBatch, Color lightColor, Color alphaColor, ref float rotation, ref float scale, int whoAmI)
|
||||||
|
{
|
||||||
|
if (!IsSingularity(item))
|
||||||
|
return true; // not ours, let vanilla draw
|
||||||
|
|
||||||
|
Texture2D texture = TextureAssets.Item[item.type].Value;
|
||||||
|
Rectangle frame = Main.itemAnimations[item.type] != null
|
||||||
|
? Main.itemAnimations[item.type].GetFrame(texture)
|
||||||
|
: texture.Frame();
|
||||||
|
|
||||||
|
Vector2 drawPos = item.Center - Main.screenPosition;
|
||||||
|
Vector2 origin = frame.Size() / 2f;
|
||||||
|
|
||||||
|
// Sync light with rarity color (subtle)
|
||||||
|
Color pulse = GetSingularityColor();
|
||||||
|
Lighting.AddLight(item.Center, pulse.ToVector3() * 0.35f);
|
||||||
|
|
||||||
|
// Subtle chromatic aberration edges
|
||||||
|
float aberrPixels = 1f;
|
||||||
|
Color redTint = new Color(255, 60, 60) * 0.20f;
|
||||||
|
Color blueTint = new Color(60, 60, 255) * 0.20f;
|
||||||
|
|
||||||
|
spriteBatch.Draw(texture, drawPos + new Vector2(aberrPixels, 0f), frame, redTint, rotation, origin, scale, SpriteEffects.None, 0f);
|
||||||
|
spriteBatch.Draw(texture, drawPos + new Vector2(-aberrPixels, 0f), frame, blueTint, rotation, origin, scale, SpriteEffects.None, 0f);
|
||||||
|
|
||||||
|
// Optional glow overlay if a _Glow texture exists
|
||||||
|
if (TryGetGlowTexture(item, out var glowTex))
|
||||||
|
{
|
||||||
|
float breathe = GetBreathing(0.5f, 0.9f, 1.15f);
|
||||||
|
spriteBatch.Draw(glowTex, drawPos, frame, pulse * 0.7f, rotation, origin, scale * breathe, SpriteEffects.None, 0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true; // continue with default draw
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void HoldItem(Item item, Player player)
|
||||||
|
{
|
||||||
|
if (!IsSingularity(item))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Color pulse = GetSingularityColor();
|
||||||
|
// Add light at the player's hand
|
||||||
|
Lighting.AddLight(player.MountedCenter, pulse.ToVector3() * 0.45f);
|
||||||
|
|
||||||
|
// Faint rotating dust ring to simulate an event horizon while held
|
||||||
|
int points = 8;
|
||||||
|
float radius = 10f;
|
||||||
|
float speed = 2.2f; // rotations per second
|
||||||
|
float t = Main.GlobalTimeWrappedHourly * speed * MathHelper.TwoPi;
|
||||||
|
for (int i = 0; i < points; i++)
|
||||||
|
{
|
||||||
|
float angle = t + (i / (float)points) * MathHelper.TwoPi;
|
||||||
|
Vector2 pos = player.MountedCenter + angle.ToRotationVector2() * radius;
|
||||||
|
Dust d = Dust.NewDustPerfect(pos, DustID.PurpleTorch, Vector2.Zero, 150, pulse, 0.9f);
|
||||||
|
if (d != null)
|
||||||
|
{
|
||||||
|
d.noGravity = true;
|
||||||
|
d.velocity = Vector2.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryGetGlowTexture(Item item, out Texture2D texture)
|
||||||
|
{
|
||||||
|
texture = null;
|
||||||
|
// Only attempt for modded items that likely follow the _Glow convention
|
||||||
|
if (item.ModItem == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
string path = item.ModItem.Texture + "_Glow";
|
||||||
|
if (ModContent.HasAsset(path))
|
||||||
|
{
|
||||||
|
Asset<Texture2D> asset = ModContent.Request<Texture2D>(path, AssetRequestMode.AsyncLoad);
|
||||||
|
if (asset.IsLoaded)
|
||||||
|
{
|
||||||
|
texture = asset.Value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user