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(); 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(); 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 asset = ModContent.Request(path, AssetRequestMode.AsyncLoad); if (asset.IsLoaded) { texture = asset.Value; return true; } } return false; } } }