using SoulHarvest.Common;
using SoulHarvest.Items;
using SoulHarvest.Tiles;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using Terraria;
using Terraria.Audio;
using Terraria.GameContent;
using Terraria.GameContent.UI.Elements;
using Terraria.ID;
using Terraria.Localization;
using Terraria.ModLoader;
using Terraria.UI;
namespace SoulHarvest.UI;
internal sealed class AltarRecipeEntry : UIElement
{
private readonly Item result;
private readonly List<Item> ingredients = [];
private readonly List<int> requiredTiles = [];
private readonly float layoutScale;
private readonly int ingredientColumns;
private readonly int ingredientRows;
public AltarRecipeEntry(Recipe recipe, float layoutScale)
{
this.layoutScale = layoutScale;
result = recipe.createItem.Clone();
foreach (Item ingredient in recipe.requiredItem)
if (!ingredient.IsAir)
ingredients.Add(ingredient.Clone());
requiredTiles.AddRange(recipe.requiredTile);
ingredientColumns = Math.Max(1, Math.Min(4, ingredients.Count));
ingredientRows = Math.Max(1, (ingredients.Count + ingredientColumns - 1) / ingredientColumns);
Width.Set(0f, 1f);
Height.Set(Math.Max(104f, 64f + ingredientRows * 44f) * layoutScale, 0f);
}
protected override void DrawSelf(SpriteBatch spriteBatch)
{
Rectangle bounds = GetDimensions().ToRectangle();
Texture2D pixel = TextureAssets.MagicPixel.Value;
Color background = IsMouseHovering ? new Color(42, 35, 63) : new Color(29, 24, 47);
spriteBatch.Draw(pixel, bounds, background * 0.97f);
AltarDrawHelpers.DrawBorder(spriteBatch, pixel, bounds, new Color(91, 69, 123), Math.Max(1, (int)MathF.Round(2f * layoutScale)));
spriteBatch.Draw(pixel, new Rectangle(bounds.X, bounds.Y, Math.Max(2, (int)MathF.Round(3f * layoutScale)), bounds.Height), new Color(127, 69, 166));
Vector2 resultCenter = new(bounds.X + 34f * layoutScale, bounds.Y + 40f * layoutScale);
AltarDrawHelpers.DrawItemSlot(spriteBatch, pixel, resultCenter, 48f * layoutScale, new Color(51, 35, 70), new Color(117, 73, 147));
AltarDrawHelpers.DrawItemIcon(spriteBatch, result, resultCenter, 40f * layoutScale);
string resultName = AltarDrawHelpers.FitText(result.Name, 118f * layoutScale, 0.68f * layoutScale);
Utils.DrawBorderString(
spriteBatch,
resultName,
new Vector2(bounds.X + 62f * layoutScale, bounds.Y + 16f * layoutScale),
new Color(235, 220, 255),
0.68f * layoutScale);
if (result.stack > 1)
Utils.DrawBorderString(spriteBatch, $"×{result.stack}", new Vector2(bounds.X + 62f * layoutScale, bounds.Y + 43f * layoutScale), Color.White, 0.62f * layoutScale);
int dividerX = bounds.X + (int)MathF.Round(176f * layoutScale);
spriteBatch.Draw(pixel, new Rectangle(dividerX, bounds.Y + (int)MathF.Round(10f * layoutScale), Math.Max(1, (int)MathF.Round(layoutScale)), bounds.Height - (int)MathF.Round(38f * layoutScale)), new Color(83, 60, 108) * 0.72f);
float ingredientsLeft = bounds.X + 188f * layoutScale;
float ingredientsWidth = Math.Max(1f, bounds.Right - 8f * layoutScale - ingredientsLeft);
float cellWidth = ingredientsWidth / ingredientColumns;
for (int index = 0; index < ingredients.Count; index++)
{
Item ingredient = ingredients[index];
int column = index % ingredientColumns;
int row = index / ingredientColumns;
float centerX = ingredientsLeft + cellWidth * (column + 0.5f);
float centerY = bounds.Y + (ingredientRows == 1 ? 34f : 27f + row * 44f) * layoutScale;
Vector2 iconCenter = new(centerX, centerY);
AltarDrawHelpers.DrawItemSlot(spriteBatch, pixel, iconCenter, 39f * layoutScale, new Color(37, 31, 53), new Color(82, 66, 104));
AltarDrawHelpers.DrawItemIcon(spriteBatch, ingredient, iconCenter, 31f * layoutScale);
string amount = ingredient.stack > 1 ? $"×{ingredient.stack}" : string.Empty;
if (ingredientRows == 1)
{
string ingredientText = AltarDrawHelpers.FitText(ingredient.Name + (amount.Length > 0 ? $" {amount}" : string.Empty), Math.Max(40f * layoutScale, cellWidth - 4f * layoutScale), 0.55f * layoutScale);
Vector2 textSize = FontAssets.MouseText.Value.MeasureString(ingredientText) * (0.55f * layoutScale);
Utils.DrawBorderString(spriteBatch, ingredientText, new Vector2(centerX - textSize.X * 0.5f, bounds.Y + 58f * layoutScale), Color.White, 0.55f * layoutScale);
}
else if (amount.Length > 0)
{
Vector2 amountSize = FontAssets.MouseText.Value.MeasureString(amount) * (0.48f * layoutScale);
Utils.DrawBorderString(spriteBatch, amount, iconCenter + new Vector2(17f, 14f) * layoutScale - amountSize, Color.White, 0.48f * layoutScale);
}
int hitboxSize = Math.Max(1, (int)MathF.Round(42f * layoutScale));
Rectangle iconHitbox = new((int)(iconCenter.X - hitboxSize * 0.5f), (int)(iconCenter.Y - hitboxSize * 0.5f), hitboxSize, hitboxSize);
if (iconHitbox.Contains(Main.MouseScreen.ToPoint()))
Main.instance.MouseText($"{ingredient.Name}{(amount.Length > 0 ? $" {amount}" : string.Empty)}");
}
string station = GetCraftingStationText();
Utils.DrawBorderString(
spriteBatch,
Language.GetTextValue("Mods.SoulHarvest.UI.RecipeCraftingStation", station),
new Vector2(bounds.X + 12f * layoutScale, bounds.Bottom - 24f * layoutScale),
new Color(137, 211, 225),
0.58f * layoutScale);
float resultHitboxSize = 52f * layoutScale;
Rectangle resultHitbox = new((int)(resultCenter.X - resultHitboxSize * 0.5f), (int)(resultCenter.Y - resultHitboxSize * 0.5f), (int)resultHitboxSize, (int)resultHitboxSize);
if (resultHitbox.Contains(Main.MouseScreen.ToPoint()) && resultName != result.Name)
Main.instance.MouseText(result.Name);
}
private string GetCraftingStationText()
{
if (requiredTiles.Count == 0)
return Language.GetTextValue("Mods.SoulHarvest.UI.RecipeStationByHand");
List<string> names = [];
foreach (int tileType in requiredTiles)
{
string name = tileType switch
{
TileID.WorkBenches => Language.GetTextValue("Mods.SoulHarvest.UI.RecipeStationWorkbench"),
TileID.Anvils => Language.GetTextValue("Mods.SoulHarvest.UI.RecipeStationAnvil"),
_ when tileType == ModContent.TileType<DeathAltarTile>() => Language.GetTextValue("Mods.SoulHarvest.UI.RecipeStationDeathAltar"),
_ => Language.GetTextValue("Mods.SoulHarvest.UI.RecipeStationUnknown", tileType)
};
if (!names.Contains(name))
names.Add(name);
}
return string.Join(" / ", names);
}
}
using SoulHarvest.Common;
using SoulHarvest.Items;
using SoulHarvest.Tiles;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using Terraria;
using Terraria.Audio;
using Terraria.GameContent;
using Terraria.GameContent.UI.Elements;
using Terraria.ID;
using Terraria.Localization;
using Terraria.ModLoader;
using Terraria.UI;
namespace SoulHarvest.UI;
internal sealed class AltarRecipeEntry : UIElement
{
private readonly Item result;
private readonly List<Item> ingredients = [];
private readonly List<int> requiredTiles = [];
private readonly float layoutScale;
private readonly int ingredientColumns;
private readonly int ingredientRows;
public AltarRecipeEntry(Recipe recipe, float layoutScale)
{
this.layoutScale = layoutScale;
result = recipe.createItem.Clone();
foreach (Item ingredient in recipe.requiredItem)
if (!ingredient.IsAir)
ingredients.Add(ingredient.Clone());
requiredTiles.AddRange(recipe.requiredTile);
ingredientColumns = Math.Max(1, Math.Min(4, ingredients.Count));
ingredientRows = Math.Max(1, (ingredients.Count + ingredientColumns - 1) / ingredientColumns);
Width.Set(0f, 1f);
Height.Set(Math.Max(104f, 64f + ingredientRows * 44f) * layoutScale, 0f);
}
protected override void DrawSelf(SpriteBatch spriteBatch)
{
Rectangle bounds = GetDimensions().ToRectangle();
Texture2D pixel = TextureAssets.MagicPixel.Value;
Color background = IsMouseHovering ? new Color(42, 35, 63) : new Color(29, 24, 47);
spriteBatch.Draw(pixel, bounds, background * 0.97f);
AltarDrawHelpers.DrawBorder(spriteBatch, pixel, bounds, new Color(91, 69, 123), Math.Max(1, (int)MathF.Round(2f * layoutScale)));
spriteBatch.Draw(pixel, new Rectangle(bounds.X, bounds.Y, Math.Max(2, (int)MathF.Round(3f * layoutScale)), bounds.Height), new Color(127, 69, 166));
Vector2 resultCenter = new(bounds.X + 34f * layoutScale, bounds.Y + 40f * layoutScale);
AltarDrawHelpers.DrawItemSlot(spriteBatch, pixel, resultCenter, 48f * layoutScale, new Color(51, 35, 70), new Color(117, 73, 147));
AltarDrawHelpers.DrawItemIcon(spriteBatch, result, resultCenter, 40f * layoutScale);
string resultName = AltarDrawHelpers.FitText(result.Name, 118f * layoutScale, 0.68f * layoutScale);
Utils.DrawBorderString(
spriteBatch,
resultName,
new Vector2(bounds.X + 62f * layoutScale, bounds.Y + 16f * layoutScale),
new Color(235, 220, 255),
0.68f * layoutScale);
if (result.stack > 1)
Utils.DrawBorderString(spriteBatch, $"×{result.stack}", new Vector2(bounds.X + 62f * layoutScale, bounds.Y + 43f * layoutScale), Color.White, 0.62f * layoutScale);
int dividerX = bounds.X + (int)MathF.Round(176f * layoutScale);
spriteBatch.Draw(pixel, new Rectangle(dividerX, bounds.Y + (int)MathF.Round(10f * layoutScale), Math.Max(1, (int)MathF.Round(layoutScale)), bounds.Height - (int)MathF.Round(38f * layoutScale)), new Color(83, 60, 108) * 0.72f);
float ingredientsLeft = bounds.X + 188f * layoutScale;
float ingredientsWidth = Math.Max(1f, bounds.Right - 8f * layoutScale - ingredientsLeft);
float cellWidth = ingredientsWidth / ingredientColumns;
for (int index = 0; index < ingredients.Count; index++)
{
Item ingredient = ingredients[index];
int column = index % ingredientColumns;
int row = index / ingredientColumns;
float centerX = ingredientsLeft + cellWidth * (column + 0.5f);
float centerY = bounds.Y + (ingredientRows == 1 ? 34f : 27f + row * 44f) * layoutScale;
Vector2 iconCenter = new(centerX, centerY);
AltarDrawHelpers.DrawItemSlot(spriteBatch, pixel, iconCenter, 39f * layoutScale, new Color(37, 31, 53), new Color(82, 66, 104));
AltarDrawHelpers.DrawItemIcon(spriteBatch, ingredient, iconCenter, 31f * layoutScale);
string amount = ingredient.stack > 1 ? $"×{ingredient.stack}" : string.Empty;
if (ingredientRows == 1)
{
string ingredientText = AltarDrawHelpers.FitText(ingredient.Name + (amount.Length > 0 ? $" {amount}" : string.Empty), Math.Max(40f * layoutScale, cellWidth - 4f * layoutScale), 0.55f * layoutScale);
Vector2 textSize = FontAssets.MouseText.Value.MeasureString(ingredientText) * (0.55f * layoutScale);
Utils.DrawBorderString(spriteBatch, ingredientText, new Vector2(centerX - textSize.X * 0.5f, bounds.Y + 58f * layoutScale), Color.White, 0.55f * layoutScale);
}
else if (amount.Length > 0)
{
Vector2 amountSize = FontAssets.MouseText.Value.MeasureString(amount) * (0.48f * layoutScale);
Utils.DrawBorderString(spriteBatch, amount, iconCenter + new Vector2(17f, 14f) * layoutScale - amountSize, Color.White, 0.48f * layoutScale);
}
int hitboxSize = Math.Max(1, (int)MathF.Round(42f * layoutScale));
Rectangle iconHitbox = new((int)(iconCenter.X - hitboxSize * 0.5f), (int)(iconCenter.Y - hitboxSize * 0.5f), hitboxSize, hitboxSize);
if (iconHitbox.Contains(Main.MouseScreen.ToPoint()))
Main.instance.MouseText($"{ingredient.Name}{(amount.Length > 0 ? $" {amount}" : string.Empty)}");
}
string station = GetCraftingStationText();
Utils.DrawBorderString(
spriteBatch,
Language.GetTextValue("Mods.SoulHarvest.UI.RecipeCraftingStation", station),
new Vector2(bounds.X + 12f * layoutScale, bounds.Bottom - 24f * layoutScale),
new Color(137, 211, 225),
0.58f * layoutScale);
float resultHitboxSize = 52f * layoutScale;
Rectangle resultHitbox = new((int)(resultCenter.X - resultHitboxSize * 0.5f), (int)(resultCenter.Y - resultHitboxSize * 0.5f), (int)resultHitboxSize, (int)resultHitboxSize);
if (resultHitbox.Contains(Main.MouseScreen.ToPoint()) && resultName != result.Name)
Main.instance.MouseText(result.Name);
}
private string GetCraftingStationText()
{
if (requiredTiles.Count == 0)
return Language.GetTextValue("Mods.SoulHarvest.UI.RecipeStationByHand");
List<string> names = [];
foreach (int tileType in requiredTiles)
{
string name = tileType switch
{
TileID.WorkBenches => Language.GetTextValue("Mods.SoulHarvest.UI.RecipeStationWorkbench"),
TileID.Anvils => Language.GetTextValue("Mods.SoulHarvest.UI.RecipeStationAnvil"),
_ when tileType == ModContent.TileType<DeathAltarTile>() => Language.GetTextValue("Mods.SoulHarvest.UI.RecipeStationDeathAltar"),
_ => Language.GetTextValue("Mods.SoulHarvest.UI.RecipeStationUnknown", tileType)
};
if (!names.Contains(name))
names.Add(name);
}
return string.Join(" / ", names);
}
}