using SoulHarvest.Common;
using SoulHarvest.Items;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using ReLogic.Content;
using System;
using System.Collections.Generic;
using System.Text;
using Terraria;
using Terraria.Audio;
using Terraria.GameContent;
using Terraria.GameContent.UI.Elements;
using Terraria.GameInput;
using Terraria.ID;
using Terraria.Localization;
using Terraria.ModLoader;
using Terraria.UI;
namespace SoulHarvest.UI;
internal sealed class ReaperTreeDetailPanel : UIElement
{
private readonly ReaperTreeButton upgradeButton;
private ReaperTreeNodeModel? node;
private float layoutScale = 1f;
public ReaperTreeDetailPanel(ReaperProgressionPanel owner)
{
SetPadding(0f);
upgradeButton = new ReaperTreeButton(owner.RequestSelectedUpgrade, new Color(87, 25, 29), new Color(137, 32, 36), new Color(231, 69, 70));
Append(upgradeButton);
}
public void ApplyLayoutScale(float scale)
{
layoutScale = scale;
upgradeButton.Left.Set(12f * scale, 0f);
upgradeButton.Top.Set(-50f * scale, 1f);
upgradeButton.Width.Set(-24f * scale, 1f);
upgradeButton.Height.Set(38f * scale, 0f);
upgradeButton.ApplyLayoutScale(scale, 0.68f);
}
public void SetNode(ReaperTreeNodeModel selected) => node = selected;
public void RefreshActionState()
{
if (node is null)
{
upgradeButton.Enabled = false;
upgradeButton.SetText(Language.GetTextValue("Mods.SoulHarvest.UI.ReaperTree.SelectNodeButton"));
return;
}
upgradeButton.Enabled = node.CanRequest && node.Affordable;
string key = node.Completed ? "CompleteButton" : !node.CanRequest || !node.Affordable ? "LockedButton" : node.Kind == ReaperTreeNodeKind.Stage ? "IlluminateButton" : "UpgradeButton";
upgradeButton.SetText(Language.GetTextValue($"Mods.SoulHarvest.UI.ReaperTree.{key}"));
}
protected override void DrawSelf(SpriteBatch spriteBatch)
{
Rectangle bounds = GetDimensions().ToRectangle();
Texture2D pixel = TextureAssets.MagicPixel.Value;
spriteBatch.Draw(pixel, bounds, new Color(13, 12, 15) * 0.99f);
ReaperTreeDraw.DrawBorder(spriteBatch, pixel, bounds, new Color(72, 64, 60), Math.Max(1, (int)(2f * layoutScale)));
ReaperTreeDraw.DrawInsetBorder(spriteBatch, pixel, bounds, Math.Max(3, (int)(6f * layoutScale)), new Color(126, 41, 47) * 0.66f, 1);
if (node is null)
return;
Color color = node.Kind == ReaperTreeNodeKind.Common ? new Color(203, 197, 176) : ReaperUIData.GetPrimaryColor(node.Form);
float categoryScale = 0.5f * layoutScale;
string category = AltarDrawHelpers.FitText(node.Category, bounds.Width - 28f * layoutScale, categoryScale);
Utils.DrawBorderString(spriteBatch, category, new Vector2(bounds.X + 14f * layoutScale, bounds.Y + 14f * layoutScale), color * 0.86f, categoryScale);
Vector2 iconCenter = new(bounds.X + 38f * layoutScale, bounds.Y + 68f * layoutScale);
ReaperTreeDraw.DrawDiamond(spriteBatch, pixel, iconCenter, 26f * layoutScale, new Color(7, 7, 9));
ReaperTreeDraw.DrawDiamondOutline(spriteBatch, pixel, iconCenter, 28f * layoutScale, color * 0.72f, Math.Max(1f, 2f * layoutScale));
Texture2D formTexture = ReaperUIData.GetFormTexture(node.Form);
Rectangle frame = formTexture.Frame();
float iconScale = Math.Min(1f, 43f * layoutScale / Math.Max(frame.Width, frame.Height));
spriteBatch.Draw(formTexture, iconCenter, frame, node.Lit || node.Kind == ReaperTreeNodeKind.Base ? Color.White : new Color(102, 97, 98), 0f, frame.Size() * 0.5f, iconScale, SpriteEffects.None, 0f);
float titleScale = 0.68f * layoutScale;
float titleLeft = bounds.X + 70f * layoutScale;
string title = AltarDrawHelpers.FitText(node.Title, Math.Max(10f, bounds.Right - titleLeft - 15f * layoutScale), titleScale);
Utils.DrawBorderString(spriteBatch, title, new Vector2(titleLeft, bounds.Y + 48f * layoutScale), new Color(239, 226, 209), titleScale);
DrawLevels(spriteBatch, pixel, node, new Vector2(titleLeft + 3f * layoutScale, bounds.Y + 91f * layoutScale), color);
int dividerY = bounds.Y + (int)(118f * layoutScale);
spriteBatch.Draw(pixel, new Rectangle(bounds.X + (int)(14f * layoutScale), dividerY, bounds.Width - (int)(28f * layoutScale), Math.Max(1, (int)layoutScale)), new Color(103, 90, 82) * 0.52f);
float textScale = 0.54f * layoutScale;
float textLeft = bounds.X + 15f * layoutScale;
float textWidth = bounds.Width - 30f * layoutScale;
int availableLines = Math.Max(2, (int)((bounds.Height - 268f * layoutScale) / (17f * layoutScale)));
ReaperTreeDraw.DrawWrappedText(spriteBatch, node.Description, new Vector2(textLeft, bounds.Y + 134f * layoutScale), textWidth, textScale, new Color(187, 178, 169), availableLines);
int statusTop = Math.Max((int)(bounds.Y + 270f * layoutScale), (int)(bounds.Bottom - 151f * layoutScale));
spriteBatch.Draw(pixel, new Rectangle(bounds.X + (int)(14f * layoutScale), statusTop, bounds.Width - (int)(28f * layoutScale), Math.Max(1, (int)layoutScale)), new Color(103, 90, 82) * 0.52f);
string statusLabel = Language.GetTextValue("Mods.SoulHarvest.UI.ReaperTree.StatusLabel", node.Status);
ReaperTreeDraw.DrawWrappedText(spriteBatch, statusLabel, new Vector2(textLeft, statusTop + 13f * layoutScale), textWidth, 0.55f * layoutScale, node.CanRequest && node.Affordable ? color : new Color(211, 172, 164), 2);
if (!string.IsNullOrWhiteSpace(node.Cost))
ReaperTreeDraw.DrawWrappedText(spriteBatch, node.Cost, new Vector2(textLeft, statusTop + 47f * layoutScale), textWidth, 0.49f * layoutScale, new Color(161, 151, 143), 3);
}
private void DrawLevels(SpriteBatch batch, Texture2D pixel, ReaperTreeNodeModel selected, Vector2 start, Color color)
{
if ((selected.Kind is ReaperTreeNodeKind.Common
or ReaperTreeNodeKind.DeathUpgrade)
&& ReaperDefinitions.IsUnlimitedCommonNode(selected.CommonNode))
{
const int shownLevels = 8;
int filledLevels = selected.CurrentLevel == 0 ? 0 : (selected.CurrentLevel - 1) % shownLevels + 1;
float cycleSpacing = 12f * layoutScale;
for (int level = 0; level < shownLevels; level++)
{
bool filled = level < filledLevels;
ReaperTreeDraw.DrawDiamond(batch, pixel, start + new Vector2(level * cycleSpacing, 0f),
(filled ? 4.5f : 3.7f) * layoutScale,
filled ? color : new Color(55, 51, 51));
}
Utils.DrawBorderString(batch, $"∞ Lv.{selected.CurrentLevel}",
start + new Vector2((shownLevels + 0.2f) * cycleSpacing, -8f * layoutScale),
color, 0.52f * layoutScale);
return;
}
int maximum = Math.Max(1, selected.MaximumLevel);
float spacing = Math.Min(15f * layoutScale, Math.Max(30f * layoutScale, GetDimensions().Width - 90f * layoutScale) / maximum);
for (int level = 0; level < maximum; level++)
{
bool filled = level < selected.CurrentLevel;
ReaperTreeDraw.DrawDiamond(batch, pixel, start + new Vector2(level * spacing, 0f), (filled ? 4.5f : 3.7f) * layoutScale, filled ? color : new Color(55, 51, 51));
}
}
}
using SoulHarvest.Common;
using SoulHarvest.Items;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using ReLogic.Content;
using System;
using System.Collections.Generic;
using System.Text;
using Terraria;
using Terraria.Audio;
using Terraria.GameContent;
using Terraria.GameContent.UI.Elements;
using Terraria.GameInput;
using Terraria.ID;
using Terraria.Localization;
using Terraria.ModLoader;
using Terraria.UI;
namespace SoulHarvest.UI;
internal sealed class ReaperTreeDetailPanel : UIElement
{
private readonly ReaperTreeButton upgradeButton;
private ReaperTreeNodeModel? node;
private float layoutScale = 1f;
public ReaperTreeDetailPanel(ReaperProgressionPanel owner)
{
SetPadding(0f);
upgradeButton = new ReaperTreeButton(owner.RequestSelectedUpgrade, new Color(87, 25, 29), new Color(137, 32, 36), new Color(231, 69, 70));
Append(upgradeButton);
}
public void ApplyLayoutScale(float scale)
{
layoutScale = scale;
upgradeButton.Left.Set(12f * scale, 0f);
upgradeButton.Top.Set(-50f * scale, 1f);
upgradeButton.Width.Set(-24f * scale, 1f);
upgradeButton.Height.Set(38f * scale, 0f);
upgradeButton.ApplyLayoutScale(scale, 0.68f);
}
public void SetNode(ReaperTreeNodeModel selected) => node = selected;
public void RefreshActionState()
{
if (node is null)
{
upgradeButton.Enabled = false;
upgradeButton.SetText(Language.GetTextValue("Mods.SoulHarvest.UI.ReaperTree.SelectNodeButton"));
return;
}
upgradeButton.Enabled = node.CanRequest && node.Affordable;
string key = node.Completed ? "CompleteButton" : !node.CanRequest || !node.Affordable ? "LockedButton" : node.Kind == ReaperTreeNodeKind.Stage ? "IlluminateButton" : "UpgradeButton";
upgradeButton.SetText(Language.GetTextValue($"Mods.SoulHarvest.UI.ReaperTree.{key}"));
}
protected override void DrawSelf(SpriteBatch spriteBatch)
{
Rectangle bounds = GetDimensions().ToRectangle();
Texture2D pixel = TextureAssets.MagicPixel.Value;
spriteBatch.Draw(pixel, bounds, new Color(13, 12, 15) * 0.99f);
ReaperTreeDraw.DrawBorder(spriteBatch, pixel, bounds, new Color(72, 64, 60), Math.Max(1, (int)(2f * layoutScale)));
ReaperTreeDraw.DrawInsetBorder(spriteBatch, pixel, bounds, Math.Max(3, (int)(6f * layoutScale)), new Color(126, 41, 47) * 0.66f, 1);
if (node is null)
return;
Color color = node.Kind == ReaperTreeNodeKind.Common ? new Color(203, 197, 176) : ReaperUIData.GetPrimaryColor(node.Form);
float categoryScale = 0.5f * layoutScale;
string category = AltarDrawHelpers.FitText(node.Category, bounds.Width - 28f * layoutScale, categoryScale);
Utils.DrawBorderString(spriteBatch, category, new Vector2(bounds.X + 14f * layoutScale, bounds.Y + 14f * layoutScale), color * 0.86f, categoryScale);
Vector2 iconCenter = new(bounds.X + 38f * layoutScale, bounds.Y + 68f * layoutScale);
ReaperTreeDraw.DrawDiamond(spriteBatch, pixel, iconCenter, 26f * layoutScale, new Color(7, 7, 9));
ReaperTreeDraw.DrawDiamondOutline(spriteBatch, pixel, iconCenter, 28f * layoutScale, color * 0.72f, Math.Max(1f, 2f * layoutScale));
Texture2D formTexture = ReaperUIData.GetFormTexture(node.Form);
Rectangle frame = formTexture.Frame();
float iconScale = Math.Min(1f, 43f * layoutScale / Math.Max(frame.Width, frame.Height));
spriteBatch.Draw(formTexture, iconCenter, frame, node.Lit || node.Kind == ReaperTreeNodeKind.Base ? Color.White : new Color(102, 97, 98), 0f, frame.Size() * 0.5f, iconScale, SpriteEffects.None, 0f);
float titleScale = 0.68f * layoutScale;
float titleLeft = bounds.X + 70f * layoutScale;
string title = AltarDrawHelpers.FitText(node.Title, Math.Max(10f, bounds.Right - titleLeft - 15f * layoutScale), titleScale);
Utils.DrawBorderString(spriteBatch, title, new Vector2(titleLeft, bounds.Y + 48f * layoutScale), new Color(239, 226, 209), titleScale);
DrawLevels(spriteBatch, pixel, node, new Vector2(titleLeft + 3f * layoutScale, bounds.Y + 91f * layoutScale), color);
int dividerY = bounds.Y + (int)(118f * layoutScale);
spriteBatch.Draw(pixel, new Rectangle(bounds.X + (int)(14f * layoutScale), dividerY, bounds.Width - (int)(28f * layoutScale), Math.Max(1, (int)layoutScale)), new Color(103, 90, 82) * 0.52f);
float textScale = 0.54f * layoutScale;
float textLeft = bounds.X + 15f * layoutScale;
float textWidth = bounds.Width - 30f * layoutScale;
int availableLines = Math.Max(2, (int)((bounds.Height - 268f * layoutScale) / (17f * layoutScale)));
ReaperTreeDraw.DrawWrappedText(spriteBatch, node.Description, new Vector2(textLeft, bounds.Y + 134f * layoutScale), textWidth, textScale, new Color(187, 178, 169), availableLines);
int statusTop = Math.Max((int)(bounds.Y + 270f * layoutScale), (int)(bounds.Bottom - 151f * layoutScale));
spriteBatch.Draw(pixel, new Rectangle(bounds.X + (int)(14f * layoutScale), statusTop, bounds.Width - (int)(28f * layoutScale), Math.Max(1, (int)layoutScale)), new Color(103, 90, 82) * 0.52f);
string statusLabel = Language.GetTextValue("Mods.SoulHarvest.UI.ReaperTree.StatusLabel", node.Status);
ReaperTreeDraw.DrawWrappedText(spriteBatch, statusLabel, new Vector2(textLeft, statusTop + 13f * layoutScale), textWidth, 0.55f * layoutScale, node.CanRequest && node.Affordable ? color : new Color(211, 172, 164), 2);
if (!string.IsNullOrWhiteSpace(node.Cost))
ReaperTreeDraw.DrawWrappedText(spriteBatch, node.Cost, new Vector2(textLeft, statusTop + 47f * layoutScale), textWidth, 0.49f * layoutScale, new Color(161, 151, 143), 3);
}
private void DrawLevels(SpriteBatch batch, Texture2D pixel, ReaperTreeNodeModel selected, Vector2 start, Color color)
{
if ((selected.Kind is ReaperTreeNodeKind.Common
or ReaperTreeNodeKind.DeathUpgrade)
&& ReaperDefinitions.IsUnlimitedCommonNode(selected.CommonNode))
{
const int shownLevels = 8;
int filledLevels = selected.CurrentLevel == 0 ? 0 : (selected.CurrentLevel - 1) % shownLevels + 1;
float cycleSpacing = 12f * layoutScale;
for (int level = 0; level < shownLevels; level++)
{
bool filled = level < filledLevels;
ReaperTreeDraw.DrawDiamond(batch, pixel, start + new Vector2(level * cycleSpacing, 0f),
(filled ? 4.5f : 3.7f) * layoutScale,
filled ? color : new Color(55, 51, 51));
}
Utils.DrawBorderString(batch, $"∞ Lv.{selected.CurrentLevel}",
start + new Vector2((shownLevels + 0.2f) * cycleSpacing, -8f * layoutScale),
color, 0.52f * layoutScale);
return;
}
int maximum = Math.Max(1, selected.MaximumLevel);
float spacing = Math.Min(15f * layoutScale, Math.Max(30f * layoutScale, GetDimensions().Width - 90f * layoutScale) / maximum);
for (int level = 0; level < maximum; level++)
{
bool filled = level < selected.CurrentLevel;
ReaperTreeDraw.DrawDiamond(batch, pixel, start + new Vector2(level * spacing, 0f), (filled ? 4.5f : 3.7f) * layoutScale, filled ? color : new Color(55, 51, 51));
}
}
}