Commit pending working-tree changes (local edits, line endings)

This commit is contained in:
cthangover committed 2026-10-21 12:31:48 +02:00
1 parent 134cc686ec
commit 422802b12e
10 files changed
+317 -317

No files matched your search

+37 -37
View File
@@ -1,37 +1,37 @@
# Godot 4.x # Godot 4.x
.godot/ .godot/
.idea/ .idea/
sdk/ sdk/
bin/ bin/
obj/ obj/
#ai #ai
.omo/ .omo/
.opencode/ .opencode/
gen/ gen/
obj/ obj/
bin/ bin/
*.tres~ *.tres~
*.tscn~ *.tscn~
# GDScript LSP # GDScript LSP
.godot/ .godot/
# Export # Export
*.exe *.exe
*.dmg *.dmg
*.apk *.apk
*.aab *.aab
*.pck *.pck
*.zip *.zip
*.log *.log
# OS # OS
.DS_Store .DS_Store
Thumbs.db Thumbs.db
# Editor # Editor
*.import *.import
*.godot.uid *.godot.uid
+13 -13
View File
@@ -1,14 +1,14 @@
{ {
"Kind": "item", "Kind": "item",
"Items": [ "Items": [
{ {
"Id": "recipe/wolf_meat_to_ration", "Id": "recipe/wolf_meat_to_ration",
"Name": "items/recipe/wolf_meat_to_ration/name", "Name": "items/recipe/wolf_meat_to_ration/name",
"Description": "items/recipe/wolf_meat_to_ration/desc", "Description": "items/recipe/wolf_meat_to_ration/desc",
"Cost": 1, "Cost": 1,
"Sprite": "recipe/cooking_recipe", "Sprite": "recipe/cooking_recipe",
"ItemType": "Recipe,Used", "ItemType": "Recipe,Used",
"ItemAction": "action/recipe/wolf_meat_to_ration" "ItemAction": "action/recipe/wolf_meat_to_ration"
} }
] ]
} }
+22 -22
View File
@@ -1,22 +1,22 @@
mod_cooking_name = Cooking mod_cooking_name = Cooking
mod_cooking_desc = Cooking mechanic: the kitchen workbench in home_kitchen with recipe-based cooking (e.g. wolf meat into rations), a ration statistics panel and the cooking scenario. mod_cooking_desc = Cooking mechanic: the kitchen workbench in home_kitchen with recipe-based cooking (e.g. wolf meat into rations), a ration statistics panel and the cooking scenario.
ui/cook/cook = Cook ui/cook/cook = Cook
ui/cook/close = Close ui/cook/close = Close
ui/cook/title = Food preparation ui/cook/title = Food preparation
ui/cook/recipe_time = {0} minutes ui/cook/recipe_time = {0} minutes
ui/cook/recipe_out = Cooking result: {0} ui/cook/recipe_out = Cooking result: {0}
ui/diner/rationcount = Rations: {0} ui/diner/rationcount = Rations: {0}
ui/diner/rationday = Daily consumption: {0} ui/diner/rationday = Daily consumption: {0}
ui/diner/rationmax = Supplies will last {0} days ui/diner/rationmax = Supplies will last {0} days
items/food/ration/name = Ration items/food/ration/name = Ration
items/food/ration/desc = A daily ration unit for one person items/food/ration/desc = A daily ration unit for one person
items/food/wolf_meat/name = Wolf cutlet items/food/wolf_meat/name = Wolf cutlet
items/food/wolf_meat/desc = Raw wolf meat items/food/wolf_meat/desc = Raw wolf meat
items/resource/branches/name = Branches items/resource/branches/name = Branches
items/resource/branches/desc = Fuel for a campfire items/resource/branches/desc = Fuel for a campfire
recipe/wolf_meat_to_ration/name = Ration from wolf meat recipe/wolf_meat_to_ration/name = Ration from wolf meat
recipe/wolf_meat_to_ration/desc = A recipe describing how to properly cook wolf meat to make it safe to eat recipe/wolf_meat_to_ration/desc = A recipe describing how to properly cook wolf meat to make it safe to eat
items/recipe/wolf_meat_to_ration/name = Recipe: ration from wolf meat items/recipe/wolf_meat_to_ration/name = Recipe: ration from wolf meat
items/recipe/wolf_meat_to_ration/desc = Teaches how to cook wolf meat into rations that are safe to eat items/recipe/wolf_meat_to_ration/desc = Teaches how to cook wolf meat into rations that are safe to eat
mod_cooking/rations_per_character = Rations per person per day mod_cooking/rations_per_character = Rations per person per day
+22 -22
View File
@@ -1,22 +1,22 @@
mod_cooking_name = Готовка mod_cooking_name = Готовка
mod_cooking_desc = Механика готовки: верстак на кухне home_kitchen с рецептами (например, волчье мясо в рационы), панель статистики рационов и сценар готовки. mod_cooking_desc = Механика готовки: верстак на кухне home_kitchen с рецептами (например, волчье мясо в рационы), панель статистики рационов и сценар готовки.
ui/cook/cook = Готовить ui/cook/cook = Готовить
ui/cook/close = Выйти ui/cook/close = Выйти
ui/cook/title = Приготовление еды ui/cook/title = Приготовление еды
ui/cook/recipe_time = {0} минут ui/cook/recipe_time = {0} минут
ui/cook/recipe_out = Результат приготовления: {0} ui/cook/recipe_out = Результат приготовления: {0}
ui/diner/rationcount = Пайков: {0} ui/diner/rationcount = Пайков: {0}
ui/diner/rationday = Потребление в сутки: {0} ui/diner/rationday = Потребление в сутки: {0}
ui/diner/rationmax = Запасов хватит на {0} дней ui/diner/rationmax = Запасов хватит на {0} дней
items/food/ration/name = Рацион items/food/ration/name = Рацион
items/food/ration/desc = Единица суточного рациона для одного человека items/food/ration/desc = Единица суточного рациона для одного человека
items/food/wolf_meat/name = Волчья вырезка items/food/wolf_meat/name = Волчья вырезка
items/food/wolf_meat/desc = Сырое мясо волка items/food/wolf_meat/desc = Сырое мясо волка
items/resource/branches/name = Ветки items/resource/branches/name = Ветки
items/resource/branches/desc = Топливо для костра items/resource/branches/desc = Топливо для костра
recipe/wolf_meat_to_ration/name = Рацион из волчьего мяса recipe/wolf_meat_to_ration/name = Рацион из волчьего мяса
recipe/wolf_meat_to_ration/desc = Рецепт описывает как правильно приготовить волчатину, чтобы безопасно употребить её в пищу recipe/wolf_meat_to_ration/desc = Рецепт описывает как правильно приготовить волчатину, чтобы безопасно употребить её в пищу
items/recipe/wolf_meat_to_ration/name = Рецепт: рацион из волчьего мяса items/recipe/wolf_meat_to_ration/name = Рецепт: рацион из волчьего мяса
items/recipe/wolf_meat_to_ration/desc = Учит готовить из волчатины рационы, которые безопасно есть items/recipe/wolf_meat_to_ration/desc = Учит готовить из волчатины рационы, которые безопасно есть
mod_cooking/rations_per_character = Рационов на персонажа в сутки mod_cooking/rations_per_character = Рационов на персонажа в сутки
+3 -3
View File
@@ -1,3 +1,3 @@
rooms/kitchen/prompt = A room equipped as a kitchen rooms/kitchen/prompt = A room equipped as a kitchen
rooms/kitchen/opt_exit = Leave rooms/kitchen/opt_exit = Leave
rooms/kitchen/opt_cook = Cook rooms/kitchen/opt_cook = Cook
+3 -3
View File
@@ -1,3 +1,3 @@
rooms/kitchen/prompt = Комната оборудованная под кухню rooms/kitchen/prompt = Комната оборудованная под кухню
rooms/kitchen/opt_exit = Выйти rooms/kitchen/opt_exit = Выйти
rooms/kitchen/opt_cook = Готовить rooms/kitchen/opt_cook = Готовить
+27 -27
View File
@@ -1,28 +1,28 @@
{ {
"Kind": "recipe", "Kind": "recipe",
"Items": [ "Items": [
{ {
"Id": "recipe/wolf_meat_to_ration", "Id": "recipe/wolf_meat_to_ration",
"Name": "recipe/wolf_meat_to_ration/name", "Name": "recipe/wolf_meat_to_ration/name",
"Description": "recipe/wolf_meat_to_ration/desc", "Description": "recipe/wolf_meat_to_ration/desc",
"Type": "Cooking", "Type": "Cooking",
"Time": 15, "Time": 15,
"Input": [ "Input": [
{ {
"Id": "food/wolf_meat", "Id": "food/wolf_meat",
"Count": 1 "Count": 1
}, },
{ {
"Id": "resource/branches", "Id": "resource/branches",
"Count": 2 "Count": 2
} }
], ],
"Output": [ "Output": [
{ {
"Id": "food/ration", "Id": "food/ration",
"Count": 1 "Count": 1
} }
] ]
} }
] ]
} }
+56 -56
View File
@@ -1,56 +1,56 @@
using System.Collections.Generic; using System.Collections.Generic;
using Cthangover.Core.Mods; using Cthangover.Core.Mods;
using Cthangover.Core.Settings; using Cthangover.Core.Settings;
namespace Cthangover.Cooking namespace Cthangover.Cooking
{ {
/// <summary> /// <summary>
/// Exposes a user-configurable setting for the number of rations /// Exposes a user-configurable setting for the number of rations
/// consumed per character per in-game day. Registered automatically /// consumed per character per in-game day. Registered automatically
/// via <see cref="ModSettingsRegistry"/> when the cooking mod /// via <see cref="ModSettingsRegistry"/> when the cooking mod
/// assembly loads. /// assembly loads.
/// ///
/// The static <see cref="RationsPerCharacter"/> property is the /// The static <see cref="RationsPerCharacter"/> property is the
/// canonical source of truth shared with <c>RationStatisticsPanel</c> /// canonical source of truth shared with <c>RationStatisticsPanel</c>
/// and any future consumption logic. It is updated by the core on /// and any future consumption logic. It is updated by the core on
/// boot (from persisted JSON) and on every UI change. /// boot (from persisted JSON) and on every UI change.
/// </summary> /// </summary>
public class CookingSettings : IModSettings public class CookingSettings : IModSettings
{ {
/// <summary> /// <summary>
/// Current value for rations consumed per character per day. /// Current value for rations consumed per character per day.
/// Default is 1. Updated by <see cref="ReadValues"/> on boot /// Default is 1. Updated by <see cref="ReadValues"/> on boot
/// and whenever the player changes the setting in the menu. /// and whenever the player changes the setting in the menu.
/// </summary> /// </summary>
public static int RationsPerCharacter { get; private set; } = 1; public static int RationsPerCharacter { get; private set; } = 1;
public IReadOnlyList<ModSettingDefinition> GetDefinitions() public IReadOnlyList<ModSettingDefinition> GetDefinitions()
{ {
return new List<ModSettingDefinition> return new List<ModSettingDefinition>
{ {
new() new()
{ {
Key = "rations_per_character", Key = "rations_per_character",
Name = "mod_cooking/rations_per_character", Name = "mod_cooking/rations_per_character",
Type = SettingType.Slider, Type = SettingType.Slider,
DefaultValue = "1", DefaultValue = "1",
Min = 1f, Min = 1f,
Max = 10f, Max = 10f,
Step = 1f, Step = 1f,
}, },
}; };
} }
public void WriteValues(DataBlob blob) public void WriteValues(DataBlob blob)
{ {
blob.SetInt("rations_per_character", RationsPerCharacter); blob.SetInt("rations_per_character", RationsPerCharacter);
} }
public void ReadValues(DataBlob blob) public void ReadValues(DataBlob blob)
{ {
RationsPerCharacter = blob.GetInt("rations_per_character", 1); RationsPerCharacter = blob.GetInt("rations_per_character", 1);
if (RationsPerCharacter < 1) if (RationsPerCharacter < 1)
RationsPerCharacter = 1; RationsPerCharacter = 1;
} }
} }
} }
+64 -64
View File
@@ -1,65 +1,65 @@
using Cthangover.Cooking; using Cthangover.Cooking;
using System; using System;
using Cthangover.Core.Settings; using Cthangover.Core.Settings;
using Cthangover.Core.UI; using Cthangover.Core.UI;
using Godot; using Godot;
using Cthangover.Mods.Interface.Base.Lists; using Cthangover.Mods.Interface.Base.Lists;
namespace Mods.Cooking.Rations namespace Mods.Cooking.Rations
{ {
/// <summary> /// <summary>
/// Displays live ration statistics on the dinner/ration UI screen. /// Displays live ration statistics on the dinner/ration UI screen.
/// Shows the player the current ration count, how many rations are /// Shows the player the current ration count, how many rations are
/// consumed daily (one per character), and the maximum number of days /// consumed daily (one per character), and the maximum number of days
/// the party can survive on available rations. Listens to /// the party can survive on available rations. Listens to
/// <see cref="Core.Items.InventoryBag.Change"/> events to refresh /// <see cref="Core.Items.InventoryBag.Change"/> events to refresh
/// automatically whenever the inventory is modified. /// automatically whenever the inventory is modified.
/// </summary> /// </summary>
public class RationStatisticsPanel : Widget public class RationStatisticsPanel : Widget
{ {
private RichTextLabel label; private RichTextLabel label;
private Action<string, int> _onInventoryChange; private Action<string, int> _onInventoryChange;
protected override void OnceConstruct() protected override void OnceConstruct()
{ {
label = GetNode<RichTextLabel>("RationMargin/RationLabel"); label = GetNode<RichTextLabel>("RationMargin/RationLabel");
_onInventoryChange = (_, _) => UpdateInfo(); _onInventoryChange = (_, _) => UpdateInfo();
GameData.Instance.Runtime.Inventory.Change += _onInventoryChange; GameData.Instance.Runtime.Inventory.Change += _onInventoryChange;
} }
protected override void ShowConstruct() protected override void ShowConstruct()
{ {
UpdateInfo(); UpdateInfo();
} }
protected override void OnceDestruct() protected override void OnceDestruct()
{ {
GameData.Instance.Runtime.Inventory.Change -= _onInventoryChange; GameData.Instance.Runtime.Inventory.Change -= _onInventoryChange;
} }
/// <summary> /// <summary>
/// Recomputes and refreshes the ration-statistics text. /// Recomputes and refreshes the ration-statistics text.
/// Reads current ration inventory via <see cref="Core.Items.InventoryBag.CheckCount"/> /// Reads current ration inventory via <see cref="Core.Items.InventoryBag.CheckCount"/>
/// for <c>"food/ration"</c> and the total character count from /// for <c>"food/ration"</c> and the total character count from
/// <see cref="CharacterData"/>. Formats three localized lines: /// <see cref="CharacterData"/>. Formats three localized lines:
/// total rations, daily consumption, and remaining days /// total rations, daily consumption, and remaining days
/// (rations divided by character count, clamped to 1 minimum). /// (rations divided by character count, clamped to 1 minimum).
/// </summary> /// </summary>
public void UpdateInfo() public void UpdateInfo()
{ {
if (label == null) if (label == null)
return; return;
var rationCount = GameData.Instance.Runtime.Inventory.CheckCount("food/ration"); var rationCount = GameData.Instance.Runtime.Inventory.CheckCount("food/ration");
var characterCount = GameData.Instance.Runtime.CharacterData.Characters.Count; var characterCount = GameData.Instance.Runtime.CharacterData.Characters.Count;
var perChar = CookingSettings.RationsPerCharacter; var perChar = CookingSettings.RationsPerCharacter;
var dailyConsumption = characterCount * perChar; var dailyConsumption = characterCount * perChar;
label.Text = string.Format(TranslationServer.Translate("ui/diner/rationcount"), rationCount) + label.Text = string.Format(TranslationServer.Translate("ui/diner/rationcount"), rationCount) +
"\n" + string.Format(TranslationServer.Translate("ui/diner/rationday"), dailyConsumption) + "\n" + string.Format(TranslationServer.Translate("ui/diner/rationday"), dailyConsumption) +
"\n" + string.Format(TranslationServer.Translate("ui/diner/rationmax"), rationCount / Mathf.Max(1, dailyConsumption)); "\n" + string.Format(TranslationServer.Translate("ui/diner/rationmax"), rationCount / Mathf.Max(1, dailyConsumption));
} }
} }
} }
+70 -70
View File
@@ -1,71 +1,71 @@
using Cthangover.Core.Items; using Cthangover.Core.Items;
using Cthangover.Core.Settings; using Cthangover.Core.Settings;
using Cthangover.Core.UI; using Cthangover.Core.UI;
using Cthangover.Core.UI.Theming; using Cthangover.Core.UI.Theming;
using Cthangover.Core.Utils; using Cthangover.Core.Utils;
using Godot; using Godot;
using Cthangover.Mods.Interface.Base.Lists; using Cthangover.Mods.Interface.Base.Lists;
namespace Mods.Cooking.Workbench namespace Mods.Cooking.Workbench
{ {
/// <summary> /// <summary>
/// Renders a single ingredient row inside a <see cref="RecipeItemBehaviour"/> /// Renders a single ingredient row inside a <see cref="RecipeItemBehaviour"/>
/// on the cooking workbench. Displays the ingredient's item icon and the /// on the cooking workbench. Displays the ingredient's item icon and the
/// required count. When <see cref="CheckAndUpdate"/> is called, compares /// required count. When <see cref="CheckAndUpdate"/> is called, compares
/// inventory count against the recipe requirement and tints the icon and /// inventory count against the recipe requirement and tints the icon and
/// count text grey if the player lacks enough items. /// count text grey if the player lacks enough items.
/// </summary> /// </summary>
public class RecipeIconItemBehaviour : Widget public class RecipeIconItemBehaviour : Widget
{ {
private static readonly Color NormalColor = UiTokens.InkBright; private static readonly Color NormalColor = UiTokens.InkBright;
private static readonly Color NotItemsColor = UiTokens.Muted; private static readonly Color NotItemsColor = UiTokens.Muted;
private TextureRect img; private TextureRect img;
private Label txt; private Label txt;
private IIngredient ingredient; private IIngredient ingredient;
protected override void OnceConstruct() protected override void OnceConstruct()
{ {
img = GetNode<TextureRect>("Img"); img = GetNode<TextureRect>("Img");
txt = GetNode<Label>("Txt"); txt = GetNode<Label>("Txt");
} }
/// <summary> /// <summary>
/// Binds this icon widget to a recipe ingredient definition. /// Binds this icon widget to a recipe ingredient definition.
/// Sets the icon texture from <c>ingredient.Item.Sprite</c> (logs an error /// Sets the icon texture from <c>ingredient.Item.Sprite</c> (logs an error
/// if the item reference is null) and displays the required count as text. /// if the item reference is null) and displays the required count as text.
/// The <paramref name="hasItems"/> flag is currently unused but reserved /// The <paramref name="hasItems"/> flag is currently unused but reserved
/// for future visual pre-initialization. /// for future visual pre-initialization.
/// </summary> /// </summary>
public void Init(IIngredient ingredient, bool hasItems) public void Init(IIngredient ingredient, bool hasItems)
{ {
EnsureConstructed(); EnsureConstructed();
this.ingredient = ingredient; this.ingredient = ingredient;
if (ingredient.Item != null) if (ingredient.Item != null)
{ {
img.Texture = ingredient.Item.Sprite; img.Texture = ingredient.Item.Sprite;
} }
else else
{ {
GameLogger.Log("MOD_TEST", $"RecipeIconItemBehaviour::Init ingredient.Item is NULL", LogLevel.Error); GameLogger.Log("MOD_TEST", $"RecipeIconItemBehaviour::Init ingredient.Item is NULL", LogLevel.Error);
} }
txt.Text = ingredient.Count.ToString(); txt.Text = ingredient.Count.ToString();
} }
/// <summary> /// <summary>
/// Evaluates whether the player's inventory contains enough of the /// Evaluates whether the player's inventory contains enough of the
/// required ingredient. Tints the icon and count text to /// required ingredient. Tints the icon and count text to
/// <c>NormalColor</c> (bright ink) when satisfied or <c>NotItemsColor</c> /// <c>NormalColor</c> (bright ink) when satisfied or <c>NotItemsColor</c>
/// (muted) when insufficient. Called by the parent /// (muted) when insufficient. Called by the parent
/// <see cref="RecipeItemBehaviour"/> during state refresh. /// <see cref="RecipeItemBehaviour"/> during state refresh.
/// </summary> /// </summary>
/// <returns><c>true</c> if inventory meets or exceeds the required count.</returns> /// <returns><c>true</c> if inventory meets or exceeds the required count.</returns>
public bool CheckAndUpdate() public bool CheckAndUpdate()
{ {
var result = GameData.Instance.Runtime.Inventory.CheckCount(ingredient.Item) >= ingredient.Count; var result = GameData.Instance.Runtime.Inventory.CheckCount(ingredient.Item) >= ingredient.Count;
txt.AddThemeColorOverride("font_color", result ? NormalColor : NotItemsColor); txt.AddThemeColorOverride("font_color", result ? NormalColor : NotItemsColor);
img.Modulate = result ? UiTokens.White : NotItemsColor; img.Modulate = result ? UiTokens.White : NotItemsColor;
return result; return result;
} }
} }
} }