first commit

This commit is contained in:
2026-06-04 23:22:13 +03:00
commit d329f501be
310 changed files with 36395 additions and 0 deletions
+228
View File
@@ -0,0 +1,228 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace OTGIntegrated.Crafting
{
public sealed class CraftingUI : MonoBehaviour
{
public GameObject panelRoot;
public Transform recipeListRoot;
public Text ingredientsText;
public Text resultText;
public Text descriptionText;
public Text messageText;
public Button craftButton;
public Button closeButton;
public Font uiFont;
private CraftingSystem craftingSystem;
private OTGIntegrated.Inventory.Inventory inventory;
private RecipeData selectedRecipe;
private readonly List<GameObject> spawnedButtons = new List<GameObject>();
public void Initialize(CraftingSystem system, OTGIntegrated.Inventory.Inventory playerInventory)
{
craftingSystem = system;
inventory = playerInventory;
if (craftingSystem != null)
{
craftingSystem.OnCraftingChanged -= Refresh;
craftingSystem.OnCraftingChanged += Refresh;
}
if (inventory != null)
{
inventory.OnInventoryChanged -= Refresh;
inventory.OnInventoryChanged += Refresh;
}
if (craftButton != null)
{
craftButton.onClick.RemoveAllListeners();
craftButton.onClick.AddListener(() =>
{
if (craftingSystem != null && selectedRecipe != null)
{
craftingSystem.Craft(selectedRecipe);
}
});
}
if (closeButton != null)
{
closeButton.onClick.RemoveAllListeners();
closeButton.onClick.AddListener(() => FindObjectOfType<OTGIntegrated.UI.UIManager>()?.CloseCurrentWindow());
}
Refresh();
}
private void OnEnable()
{
Refresh();
}
private void OnDestroy()
{
if (craftingSystem != null)
{
craftingSystem.OnCraftingChanged -= Refresh;
}
if (inventory != null)
{
inventory.OnInventoryChanged -= Refresh;
}
}
public void Refresh()
{
if (recipeListRoot == null || craftingSystem == null)
{
return;
}
ClearButtons();
if (selectedRecipe == null && craftingSystem.availableRecipes.Count > 0)
{
selectedRecipe = craftingSystem.availableRecipes[0];
}
for (int i = 0; i < craftingSystem.availableRecipes.Count; i++)
{
RecipeData recipe = craftingSystem.availableRecipes[i];
CreateRecipeButton(recipe);
}
UpdateDetails();
}
private void CreateRecipeButton(RecipeData recipe)
{
GameObject root = new GameObject(recipe != null ? recipe.displayName : "Recipe", typeof(RectTransform), typeof(Image), typeof(Button));
root.transform.SetParent(recipeListRoot, false);
spawnedButtons.Add(root);
RectTransform rect = root.GetComponent<RectTransform>();
rect.sizeDelta = new Vector2(300f, 46f);
bool canCraft = craftingSystem != null && craftingSystem.CanCraft(recipe);
Image image = root.GetComponent<Image>();
image.color = recipe == selectedRecipe
? new Color(0.82f, 0.58f, 0.18f, 0.95f)
: canCraft ? new Color(0.14f, 0.28f, 0.22f, 0.92f) : new Color(0.12f, 0.13f, 0.16f, 0.88f);
Text label = CreateText(root.transform, "Text", recipe != null ? recipe.displayName : "Recipe", 17, TextAnchor.MiddleLeft);
label.rectTransform.anchorMin = new Vector2(0f, 0f);
label.rectTransform.anchorMax = new Vector2(1f, 1f);
label.rectTransform.offsetMin = new Vector2(14f, 0f);
label.rectTransform.offsetMax = new Vector2(-8f, 0f);
Button button = root.GetComponent<Button>();
button.onClick.AddListener(() =>
{
selectedRecipe = recipe;
Refresh();
});
}
private void UpdateDetails()
{
if (selectedRecipe == null)
{
if (ingredientsText != null) ingredientsText.text = "Рецепт не выбран.";
if (resultText != null) resultText.text = string.Empty;
if (descriptionText != null) descriptionText.text = string.Empty;
if (craftButton != null) craftButton.interactable = false;
return;
}
if (ingredientsText != null)
{
ingredientsText.text = BuildIngredientStatus(selectedRecipe);
}
if (resultText != null)
{
string resultName = selectedRecipe.resultItem != null ? selectedRecipe.resultItem.displayName : "Нет результата";
resultText.text = $"Результат\n{resultName} x{selectedRecipe.resultAmount}";
}
if (descriptionText != null)
{
descriptionText.text = selectedRecipe.description;
}
if (messageText != null)
{
messageText.text = craftingSystem != null ? craftingSystem.lastMessage : string.Empty;
}
if (craftButton != null)
{
craftButton.interactable = craftingSystem != null && craftingSystem.CanCraft(selectedRecipe);
}
}
private string BuildIngredientStatus(RecipeData recipe)
{
if (recipe == null || recipe.ingredients == null)
{
return "Ингредиенты отсутствуют.";
}
System.Text.StringBuilder builder = new System.Text.StringBuilder();
builder.AppendLine("Ингредиенты");
for (int i = 0; i < recipe.ingredients.Length; i++)
{
Ingredient ingredient = recipe.ingredients[i];
if (ingredient == null || ingredient.item == null)
{
continue;
}
int owned = inventory != null ? inventory.GetAmount(ingredient.item) : 0;
bool enough = owned >= ingredient.amount;
builder.Append(enough ? "<color=#88E08A>" : "<color=#FF8888>");
builder.Append(ingredient.item.displayName);
builder.Append(": ");
builder.Append(owned);
builder.Append(" / ");
builder.Append(ingredient.amount);
builder.AppendLine("</color>");
}
return builder.ToString();
}
private Text CreateText(Transform parent, string name, string value, int fontSize, TextAnchor anchor)
{
GameObject textObject = new GameObject(name, typeof(RectTransform), typeof(Text));
textObject.transform.SetParent(parent, false);
Text text = textObject.GetComponent<Text>();
text.text = value;
text.font = uiFont != null ? uiFont : Resources.GetBuiltinResource<Font>("Arial.ttf");
text.fontSize = fontSize;
text.alignment = anchor;
text.supportRichText = true;
text.color = new Color(0.94f, 0.93f, 0.88f, 1f);
return text;
}
private void ClearButtons()
{
for (int i = 0; i < spawnedButtons.Count; i++)
{
if (spawnedButtons[i] != null)
{
Destroy(spawnedButtons[i]);
}
}
spawnedButtons.Clear();
}
}
}