From fcffdf37205e1668d0c1d158ef73d244d1598959 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Mon, 10 Jun 2024 13:50:12 +0800 Subject: [PATCH 01/17] Update C# version to 12 --- ColdMint.Traveler.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/ColdMint.Traveler.csproj b/ColdMint.Traveler.csproj index dafdfc5..c893429 100644 --- a/ColdMint.Traveler.csproj +++ b/ColdMint.Traveler.csproj @@ -6,5 +6,6 @@ true ColdMint enable + 12 \ No newline at end of file From 0880feb2988416d1b9203d8609da971a94f51505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Mon, 10 Jun 2024 23:08:48 +0800 Subject: [PATCH 02/17] Add new item interfaces and manager --- scripts/item/IItemStack.cs | 36 ++++++++++++++++++++ scripts/item/IItem_New.cs | 24 ++++++++++++++ scripts/item/ItemType.cs | 25 ++++++++++++++ scripts/item/ItemTypeManager.cs | 59 +++++++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+) create mode 100644 scripts/item/IItemStack.cs create mode 100644 scripts/item/IItem_New.cs create mode 100644 scripts/item/ItemType.cs create mode 100644 scripts/item/ItemTypeManager.cs diff --git a/scripts/item/IItemStack.cs b/scripts/item/IItemStack.cs new file mode 100644 index 0000000..23c0bae --- /dev/null +++ b/scripts/item/IItemStack.cs @@ -0,0 +1,36 @@ +using Godot; + +namespace ColdMint.scripts.item; + +public interface IItemStack +{ + /// + /// ID of items inside current stack + /// + string Id { get; } + + /// + /// Max number of current stack + /// + int MaxQuantity { get; } + + /// + /// Quantity of current stack + /// + int Quantity { get; set; } + + /// + /// Icon of current item + /// + Texture2D Icon { get; } + + /// + /// Display name of current item + /// + string Name { get; } + + /// + /// Description of current item, which may show in inventory + /// + string? Description { get; } +} \ No newline at end of file diff --git a/scripts/item/IItem_New.cs b/scripts/item/IItem_New.cs new file mode 100644 index 0000000..520a995 --- /dev/null +++ b/scripts/item/IItem_New.cs @@ -0,0 +1,24 @@ +using Godot; + +namespace ColdMint.scripts.item; + +//Todo: Merge this with IItem (and, then change this ugly name +public interface IItem_New +{ + /// + /// ID of current item + /// + string Id { get; } + /// + /// Icon of current item + /// + Texture2D Icon { get; } + /// + /// Display name of current item + /// + string Name { get; } + /// + /// Description of current item, which may show in inventory + /// + string? Description { get; } +} \ No newline at end of file diff --git a/scripts/item/ItemType.cs b/scripts/item/ItemType.cs new file mode 100644 index 0000000..4e33524 --- /dev/null +++ b/scripts/item/ItemType.cs @@ -0,0 +1,25 @@ +using System; + +using Godot; + +namespace ColdMint.scripts.item; + +public readonly struct ItemType +{ + /// + /// Item id of this type + /// + public string Id { get; init; } + /// + /// A function returns a new item instance of this type + /// + public Func Getter { get; init; } + /// + /// Default icon of items of this type + /// + public Texture2D? Texture { get; init; } + /// + /// Max number in item stack of this type + /// + public int MaxStackQuantity { get; init; } +} \ No newline at end of file diff --git a/scripts/item/ItemTypeManager.cs b/scripts/item/ItemTypeManager.cs new file mode 100644 index 0000000..d46be7b --- /dev/null +++ b/scripts/item/ItemTypeManager.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; + +using ColdMint.scripts.utils; + +using Godot; + +namespace ColdMint.scripts.item; + +public static class ItemTypeManager +{ + // Register items statically here + static ItemTypeManager() { } + + private static Dictionary Registry { get; } = []; + private static Texture2D DefaultTexture { get; } = new PlaceholderTexture2D(); + + + /// + /// Register a item type. + /// Return false if the item id already exist. + /// + /// Whether the registration was successful. + public static bool Register(ItemType itemType) => Registry.TryAdd(itemType.Id, itemType); + + /// + /// Creates a new instance of the item registered to the given id. + /// Returns null when the id is not registered. + /// + public static IItem_New? NewItem(string id) => + Registry.TryGetValue(id, out var itemType) ? itemType.Getter() : null; + + /// + /// Get the translated default name of the item type for the given id + /// + /// + /// Translated default name of the item id if it exists. Else, return the id itself + /// + public static string DefaultNameOf(string id) => TranslationServerUtils.Translate($"item_{id}") ?? id; + + /// + /// Get the translated default description of the item type for the given id + /// + /// + /// Translated default description of the item id if it exists. Else, return null + /// + public static string? DefaultDescriptionOf(string id) => TranslationServerUtils.Translate($"item_{id}_desc"); + + /// + /// Get the default icon of the item type for the given id + /// + /// + /// Translated default icon of the item id if it exists. Else, return a placeholder + /// + public static Texture2D DefaultIconOf(string id) => + Registry.TryGetValue(id, out var itemType) + ? itemType.Texture ?? DefaultTexture + : DefaultTexture; +} \ No newline at end of file From 026c7ff32f90177819455e6143c25214776ddbc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Wed, 12 Jun 2024 00:51:40 +0800 Subject: [PATCH 03/17] Add single item stack type, move the weapon namespace into the item namespace, and I think it's ready to be merged into the new interface --- locals/Slogan.ja.translation | Bin 877 -> 548 bytes project.godot | 1 - scripts/behaviorTree/ai/AiPickNode.cs | 3 +- scripts/character/CharacterTemplate.cs | 46 ++++++------------ scripts/character/Player.cs | 18 ++++--- scripts/inventory/HotBar.cs | 3 +- scripts/item/IItemStack.cs | 25 ++++++++-- scripts/item/ItemType.cs | 8 ++- scripts/item/ItemTypeManager.cs | 7 ++- scripts/item/SingleItemStack.cs | 21 ++++++++ scripts/item/StackType.cs | 8 +++ scripts/{ => item}/weapon/ProjectileWeapon.cs | 4 +- scripts/{ => item}/weapon/WeaponTemplate.cs | 4 +- 13 files changed, 94 insertions(+), 54 deletions(-) create mode 100644 scripts/item/SingleItemStack.cs create mode 100644 scripts/item/StackType.cs rename scripts/{ => item}/weapon/ProjectileWeapon.cs (98%) rename scripts/{ => item}/weapon/WeaponTemplate.cs (99%) diff --git a/locals/Slogan.ja.translation b/locals/Slogan.ja.translation index 16ad9fc68dbbd239ae30c46bcd584be05ea6ee91..5b1b7dfbcf34f9e806cd7d1ce7c71b7a6341f1ba 100644 GIT binary patch literal 548 zcmV+<0^9vkQ$s@n000005C8ya0{{RF0ssIgwJ-f(X#y1x0EQV|L=cga#tHyl40m_qzQ~&20s| z@8)`T3PS)$089X1;3-3KPAU2gEJYCmSz@x9plkzOvC1xxthAMEO6^}TM}r3)<9HGI z1B_+X7O#m#tz?7zV2P|vCBv`aAMgYC1$-RX;HU98TQgc2ZXb3yzv=V34;b>N zd|uaq6+W*+06m}Afj}Ie*98|wNJf4bEiG!AELm%EoOEZf&?Rvjhp1H&vqUg5Kd%Cav4J|J*{ znIbz6eG&j6x}=@%-5ye_QQaCvoQdG%901RnpCV~wqKEgk21|$5u3sT{a~F5+?l>D) zj$`ZMphfv@g>9#E3@6=*^D|_D3x2~JP8T?GIzh)?f5=zEW)^LZiA3*Y5E~K004THo m1DnVG^c}26w|a}tRLcOSE$kCS{hxDZpv0ho-#ll2^Y+Zcz2#fw>%zCAh=;*3&I64(qRO$uaWK*M)@%A`X5#n7bxRCvTQ~I^9L5bs_zNbt+uv6a&wGOJhW`wA))Rau{2m;i%LLyGkD<8i3H~HJyQ`kyOYjxA zAy4o<@GUs5GQ)4;97~qQ% z^9N0GZ+7Ndl+BZSLGDrU@s4I3FK}zSE7-Y6Zkyaf(YH6Zw#YptH|x)H&1*Ss->1Gd zasA(`#0@zuwLT}ltv=4zmyl`RSl?+pUpdate finished items ///更新完成后的物品 /// - protected virtual void WhenUpdateCurrentItem(Node2D? currentItem) - { - } + protected virtual void WhenUpdateCurrentItem(Node2D? currentItem) { } //Define a pick up range //定义一个拾起范围 @@ -210,8 +210,8 @@ public partial class CharacterTemplate : CharacterBody2D base._Ready(); PickingRangeBodiesList = new List(); CharacterName = GetMeta("Name", Name).AsString(); - CampId = GetMeta("CampId", Config.CampId.Default).AsString(); - MaxHp = GetMeta("MaxHp", Config.DefaultMaxHp).AsInt32(); + CampId = GetMeta("CampId", Config.CampId.Default).AsString(); + MaxHp = GetMeta("MaxHp", Config.DefaultMaxHp).AsInt32(); string lootListId = GetMeta("LootListId", string.Empty).AsString(); if (!string.IsNullOrEmpty(lootListId)) { @@ -219,6 +219,7 @@ public partial class CharacterTemplate : CharacterBody2D //如果指定了战利品表,那么获取战利品表。 _lootList = LootListManager.GetLootList(lootListId); } + if (MaxHp <= 0) { //If Max blood volume is 0 or less, set Max blood volume to 10 @@ -317,7 +318,7 @@ public partial class CharacterTemplate : CharacterBody2D { weaponTemplate.Owner = this; weaponTemplate.SetCollisionMaskValue(Config.LayerNumber.Platform, false); - weaponTemplate.SetCollisionMaskValue(Config.LayerNumber.Ground, false); + weaponTemplate.SetCollisionMaskValue(Config.LayerNumber.Ground, false); weaponTemplate.EnableContactInjury = false; weaponTemplate.Sleeping = true; } @@ -467,9 +468,7 @@ public partial class CharacterTemplate : CharacterBody2D _additionalForce = force; } - protected virtual void OnHit(DamageTemplate damageTemplate) - { - } + protected virtual void OnHit(DamageTemplate damageTemplate) { } /// /// Handle the event of character death @@ -599,22 +598,9 @@ public partial class CharacterTemplate : CharacterBody2D /// protected void ThrowItem(int index, int number, Vector2 velocity) { - if (_itemContainer == null) - { - return; - } + var itemSlotNode = _itemContainer?.GetItemSlotNode(index); - var itemSlotNode = _itemContainer.GetItemSlotNode(index); - if (itemSlotNode == null) - { - return; - } - - var item = itemSlotNode.GetItem(); - if (item == null) - { - return; - } + var item = itemSlotNode?.GetItem(); if (item is not Node2D node2D) { @@ -639,7 +625,7 @@ public partial class CharacterTemplate : CharacterBody2D //We cannot immediately resume the physical collision when the weapon is discharged, which will cause the weapon to collide with the ground and platform earlier, preventing the weapon from flying. //仍出武器时,我们不能立即恢复物理碰撞,立即恢复会导致武器更早的与地面和平台碰撞,阻止武器的飞行。 weaponTemplate.EnableContactInjury = true; - weaponTemplate.SetCollisionMaskValue(Config.LayerNumber.Ground, true); + weaponTemplate.SetCollisionMaskValue(Config.LayerNumber.Ground, true); weaponTemplate.SetCollisionMaskValue(Config.LayerNumber.Platform, true); timer.QueueFree(); }; @@ -669,11 +655,11 @@ public partial class CharacterTemplate : CharacterBody2D //在物品容器内移除物品 if (number < 0) { - itemSlotNode.RemoveItem(item.Quantity); + itemSlotNode!.RemoveItem(item.Quantity); } else { - itemSlotNode.RemoveItem(number); + itemSlotNode!.RemoveItem(number); } } @@ -728,7 +714,5 @@ public partial class CharacterTemplate : CharacterBody2D } - protected virtual void HookPhysicsProcess(ref Vector2 velocity, double delta) - { - } + protected virtual void HookPhysicsProcess(ref Vector2 velocity, double delta) { } } \ No newline at end of file diff --git a/scripts/character/Player.cs b/scripts/character/Player.cs index c91571d..0e234cc 100644 --- a/scripts/character/Player.cs +++ b/scripts/character/Player.cs @@ -1,11 +1,13 @@ using System; using System.Text; using System.Threading.Tasks; + using ColdMint.scripts.damage; using ColdMint.scripts.deathInfo; using ColdMint.scripts.map.events; using ColdMint.scripts.utils; -using ColdMint.scripts.weapon; +using ColdMint.scripts.item.weapon; + using Godot; namespace ColdMint.scripts.character; @@ -101,7 +103,7 @@ public partial class Player : CharacterTemplate operationTipBuilder.Append(Config.OperationTipActionColor); operationTipBuilder.Append(']'); operationTipBuilder.Append( - TranslationServerUtils.Translate(InputMap.ActionGetEvents("ui_down")[0].AsText())); + TranslationServerUtils.Translate(InputMap.ActionGetEvents("ui_down")[0].AsText())); operationTipBuilder.Append("[/color]"); operationTipBuilder.Append(TranslationServerUtils.Translate("jump_down")); } @@ -115,7 +117,7 @@ public partial class Player : CharacterTemplate operationTipBuilder.Append(Config.OperationTipActionColor); operationTipBuilder.Append(']'); operationTipBuilder.Append( - TranslationServerUtils.Translate(InputMap.ActionGetEvents("pick_up")[0].AsText())); + TranslationServerUtils.Translate(InputMap.ActionGetEvents("pick_up")[0].AsText())); operationTipBuilder.Append("[/color]"); operationTipBuilder.Append(TranslationServerUtils.Translate("pick_up")); operationTipLabel.Text = operationTipBuilder.ToString(); @@ -139,7 +141,7 @@ public partial class Player : CharacterTemplate operationTipBuilder.Append(Config.OperationTipActionColor); operationTipBuilder.Append(']'); operationTipBuilder.Append( - TranslationServerUtils.Translate(InputMap.ActionGetEvents("use_item")[0].AsText())); + TranslationServerUtils.Translate(InputMap.ActionGetEvents("use_item")[0].AsText())); operationTipBuilder.Append("[/color]"); operationTipBuilder.Append(TranslationServerUtils.Translate("use_item")); operationTipBuilder.Append(TranslationServerUtils.Translate(weaponTemplate.Name)); @@ -243,8 +245,8 @@ public partial class Player : CharacterTemplate } _parabola.Points = CurrentItem == null - ? _emptyVector2Array - : ParabolicUtils.ComputeParabolic(ItemMarker2D.Position, GetThrowVelocity(), Gravity, 0.1f); + ? _emptyVector2Array + : ParabolicUtils.ComputeParabolic(ItemMarker2D.Position, GetThrowVelocity(), Gravity, 0.1f); } @@ -400,8 +402,8 @@ public partial class Player : CharacterTemplate var rotationDegreesNode2D = node2D.RotationDegrees; var rotationDegreesNode2DAbs = Math.Abs(rotationDegreesNode2D); _floatLabel.Position = rotationDegreesNode2DAbs > 90 - ? new Vector2(0, PromptTextDistance) - : new Vector2(0, -PromptTextDistance); + ? new Vector2(0, PromptTextDistance) + : new Vector2(0, -PromptTextDistance); _floatLabel.RotationDegrees = 0 - rotationDegreesNode2D; var label = _floatLabel.GetNode public static IItem_New? NewItem(string id) => - Registry.TryGetValue(id, out var itemType) ? itemType.Getter() : null; + Registry.TryGetValue(id, out var itemType) ? itemType.NewItemFunc() : null; /// /// Get the translated default name of the item type for the given id @@ -54,6 +54,9 @@ public static class ItemTypeManager /// public static Texture2D DefaultIconOf(string id) => Registry.TryGetValue(id, out var itemType) - ? itemType.Texture ?? DefaultTexture + ? itemType.Icon ?? DefaultTexture : DefaultTexture; + + public static int MaxStackQuantityOf(string id) => Registry.TryGetValue(id, out var itemType) ? itemType.MaxStackQuantity : 0; + public static StackType? StackTypeOf(string id) => Registry.TryGetValue(id, out var itemType) ? itemType.StackType : null; } \ No newline at end of file diff --git a/scripts/item/SingleItemStack.cs b/scripts/item/SingleItemStack.cs new file mode 100644 index 0000000..b853990 --- /dev/null +++ b/scripts/item/SingleItemStack.cs @@ -0,0 +1,21 @@ +using ColdMint.scripts.inventory; + +using Godot; + +namespace ColdMint.scripts.item; + +/// +/// Item stack in inventory +/// +//maybe we'd move this into inventory namespace +public readonly struct SingleItemStack(IItem_New item) : IItemStack +{ + public IItem_New Item { get; init; } = item; + + public string Id => Item.Id; + public int MaxQuantity => 1; + public int Quantity => 1; + public Texture2D Icon => Item.Icon; + public string Name => Item.Name; + public string? Description => Item.Description; +} \ No newline at end of file diff --git a/scripts/item/StackType.cs b/scripts/item/StackType.cs new file mode 100644 index 0000000..85998ba --- /dev/null +++ b/scripts/item/StackType.cs @@ -0,0 +1,8 @@ +namespace ColdMint.scripts.item; + +public enum StackType +{ + Common, + Unique, + Unstackable, +} \ No newline at end of file diff --git a/scripts/weapon/ProjectileWeapon.cs b/scripts/item/weapon/ProjectileWeapon.cs similarity index 98% rename from scripts/weapon/ProjectileWeapon.cs rename to scripts/item/weapon/ProjectileWeapon.cs index 71ea042..a66de38 100644 --- a/scripts/weapon/ProjectileWeapon.cs +++ b/scripts/item/weapon/ProjectileWeapon.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; + using ColdMint.scripts.debug; using ColdMint.scripts.projectile; + using Godot; -namespace ColdMint.scripts.weapon; +namespace ColdMint.scripts.item.weapon; /// /// Projectile weapons diff --git a/scripts/weapon/WeaponTemplate.cs b/scripts/item/weapon/WeaponTemplate.cs similarity index 99% rename from scripts/weapon/WeaponTemplate.cs rename to scripts/item/weapon/WeaponTemplate.cs index c3c27be..bf4611f 100644 --- a/scripts/weapon/WeaponTemplate.cs +++ b/scripts/item/weapon/WeaponTemplate.cs @@ -1,11 +1,13 @@ using System; + using ColdMint.scripts.camp; using ColdMint.scripts.character; using ColdMint.scripts.damage; using ColdMint.scripts.inventory; + using Godot; -namespace ColdMint.scripts.weapon; +namespace ColdMint.scripts.item.weapon; /// /// WeaponTemplate From 7f20a7233ce99b75cc3ab3fbc660079ae1bfdf45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Wed, 12 Jun 2024 01:57:55 +0800 Subject: [PATCH 04/17] Initial migration of existing item interactions to the new interface --- prefab/weapons/staffOfTheUndead.tscn | 3 +- scripts/character/CharacterTemplate.cs | 5 +- scripts/item/IItemStack.cs | 10 ++-- scripts/item/IItem_New.cs | 7 +++ scripts/item/ItemType.cs | 4 -- scripts/item/ItemTypeManager.cs | 1 - scripts/item/StackType.cs | 8 ---- scripts/item/weapon/WeaponTemplate.cs | 66 +++++++++++++++----------- 8 files changed, 53 insertions(+), 51 deletions(-) delete mode 100644 scripts/item/StackType.cs diff --git a/prefab/weapons/staffOfTheUndead.tscn b/prefab/weapons/staffOfTheUndead.tscn index 54bad3f..9faac93 100644 --- a/prefab/weapons/staffOfTheUndead.tscn +++ b/prefab/weapons/staffOfTheUndead.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=6 format=3 uid="uid://dnnn2xyayiehk"] [ext_resource type="Texture2D" uid="uid://e6670ykyq145" path="res://sprites/weapon/staffOfTheUndead.png" id="1_ms3us"] -[ext_resource type="Script" path="res://scripts/weapon/ProjectileWeapon.cs" id="1_w8hhv"] +[ext_resource type="Script" path="res://scripts/item/weapon/ProjectileWeapon.cs" id="1_w8hhv"] [ext_resource type="Texture2D" uid="uid://b2blj0yf4ohx3" path="res://icon.svg" id="2_l5lni"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_obcq2"] @@ -14,6 +14,7 @@ size = Vector2(49, 5.25) collision_layer = 8 collision_mask = 34 script = ExtResource("1_w8hhv") +Id = "staff_of_the_undead" metadata/Projectiles = PackedStringArray("res://prefab/projectile/curseOfTheUndead.tscn") metadata/Name = "staff_of_the_undead" metadata/FiringIntervalArray = PackedInt64Array(5000, 500, 250) diff --git a/scripts/character/CharacterTemplate.cs b/scripts/character/CharacterTemplate.cs index e483543..5aa1650 100644 --- a/scripts/character/CharacterTemplate.cs +++ b/scripts/character/CharacterTemplate.cs @@ -7,6 +7,7 @@ using ColdMint.scripts.damage; using ColdMint.scripts.debug; using ColdMint.scripts.health; using ColdMint.scripts.inventory; +using ColdMint.scripts.item; using ColdMint.scripts.utils; using ColdMint.scripts.item.weapon; @@ -352,9 +353,9 @@ public partial class CharacterTemplate : CharacterBody2D return false; } - if (_currentItem is WeaponTemplate weaponTemplate) + if (_currentItem is IItem_New item) { - weaponTemplate.Fire(this, position); + item.Use(this, position); } return true; diff --git a/scripts/item/IItemStack.cs b/scripts/item/IItemStack.cs index cb4d467..f476c63 100644 --- a/scripts/item/IItemStack.cs +++ b/scripts/item/IItemStack.cs @@ -40,12 +40,10 @@ public interface IItemStack /// /// Create a new ItemStack with the given item as the first item /// - public static IItemStack? FromItem(IItem_New item) => ItemTypeManager.StackTypeOf(item.Id) switch + public static IItemStack FromItem(IItem_New item) => ItemTypeManager.MaxStackQuantityOf(item.Id) switch { - StackType.Common => throw new NotImplementedException(), - StackType.Unique => throw new NotImplementedException(), - StackType.Unstackable => new SingleItemStack(item), - null => null, - _ => throw new ArgumentException() + 1 => new SingleItemStack(item), + > 1 => throw new NotImplementedException(), + var other => throw new ArgumentException($"item {item} of type '{item.Id}' has unexpected max stack quantity {other}") }; } \ No newline at end of file diff --git a/scripts/item/IItem_New.cs b/scripts/item/IItem_New.cs index 520a995..d98e25d 100644 --- a/scripts/item/IItem_New.cs +++ b/scripts/item/IItem_New.cs @@ -21,4 +21,11 @@ public interface IItem_New /// Description of current item, which may show in inventory /// string? Description { get; } + + /// + /// Execute when current item is used
e.g. when player clicks left mouse button with current item in hand
+ ///
+ /// Owner of current item, if any + /// Target position, such as the position of the cursor when used by the player + void Use(Node2D? owner, Vector2 targetGlobalPosition); } \ No newline at end of file diff --git a/scripts/item/ItemType.cs b/scripts/item/ItemType.cs index 1174596..308370b 100644 --- a/scripts/item/ItemType.cs +++ b/scripts/item/ItemType.cs @@ -22,8 +22,4 @@ public readonly struct ItemType /// Max number in item stack of this type ///
public int MaxStackQuantity { get; init; } - /// - /// Determines how items of this type will be stacked - /// - public StackType StackType { get; init; } } \ No newline at end of file diff --git a/scripts/item/ItemTypeManager.cs b/scripts/item/ItemTypeManager.cs index f7f1bce..b8e82ea 100644 --- a/scripts/item/ItemTypeManager.cs +++ b/scripts/item/ItemTypeManager.cs @@ -58,5 +58,4 @@ public static class ItemTypeManager : DefaultTexture; public static int MaxStackQuantityOf(string id) => Registry.TryGetValue(id, out var itemType) ? itemType.MaxStackQuantity : 0; - public static StackType? StackTypeOf(string id) => Registry.TryGetValue(id, out var itemType) ? itemType.StackType : null; } \ No newline at end of file diff --git a/scripts/item/StackType.cs b/scripts/item/StackType.cs deleted file mode 100644 index 85998ba..0000000 --- a/scripts/item/StackType.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace ColdMint.scripts.item; - -public enum StackType -{ - Common, - Unique, - Unstackable, -} \ No newline at end of file diff --git a/scripts/item/weapon/WeaponTemplate.cs b/scripts/item/weapon/WeaponTemplate.cs index bf4611f..cd029a3 100644 --- a/scripts/item/weapon/WeaponTemplate.cs +++ b/scripts/item/weapon/WeaponTemplate.cs @@ -13,18 +13,27 @@ namespace ColdMint.scripts.item.weapon; /// WeaponTemplate /// 武器模板 ///
-public partial class WeaponTemplate : RigidBody2D, IItem +public abstract partial class WeaponTemplate : RigidBody2D, IItem_New { private float _gravity = ProjectSettings.GetSetting("physics/2d/default_gravity").AsSingle(); - public string? Id { get; set; } - public int Quantity { get; set; } - public int MaxStackQuantity { get; set; } - public Texture2D? Icon { get; set; } - public new string? Name { get; set; } - public string? Description { get; set; } - public Action? OnUse { get; set; } - public Func? OnInstantiation { get; set; } + //Implements IItem + [Export] public virtual string Id { get; private set; } = "ID"; + + protected virtual Texture2D? UniqueIcon { get; set; } + public Texture2D Icon => UniqueIcon ?? ItemTypeManager.DefaultIconOf(Id); + + protected string? UniqueName { get; set; } + public new string Name => UniqueName ?? ItemTypeManager.DefaultNameOf(Id); + + protected string? UniqueDescription { get; set; } + public string? Description => UniqueDescription ?? ItemTypeManager.DefaultDescriptionOf(Id); + + + public void Use(Node2D? owner, Vector2 targetGlobalPosition) + { + Fire(owner, targetGlobalPosition); + } /// /// Owner @@ -39,8 +48,8 @@ public partial class WeaponTemplate : RigidBody2D, IItem /// public bool EnableContactInjury; - private int _minContactInjury; - private int _maxContactInjury; + [Export] private int _minContactInjury = 1; + [Export] private int _maxContactInjury = 2; private DateTime? _lastFiringTime; @@ -49,6 +58,7 @@ public partial class WeaponTemplate : RigidBody2D, IItem /// 开火间隔 /// private TimeSpan _firingInterval; + [Export] private long _firingIntervalAsMillisecond = 100; /// @@ -59,7 +69,7 @@ public partial class WeaponTemplate : RigidBody2D, IItem ///When the weapon is fired, how much recoil is applied to the user, in units: the number of cells, and the X direction of the force is automatically inferred. ///武器开火,要对使用者施加多大的后坐力,单位:格数,力的X方向是自动推断的。 /// - private Vector2 _recoil; + [Export] private Vector2 _recoil; /// /// This area represents the collision range of the weapon, and when other nodes enter this area, they will deal damage. @@ -75,16 +85,18 @@ public partial class WeaponTemplate : RigidBody2D, IItem RayCast2D = GetNode("RayCast2D"); _area2D = GetNode("Area2D"); _area2D.BodyEntered += OnBodyEnter; - Id = GetMeta("ID", "1").AsString(); - Quantity = GetMeta("Quantity", "1").AsInt32(); - MaxStackQuantity = GetMeta("MaxStackQuantity", Config.MaxStackQuantity).AsInt32(); - Icon = GetMeta("Icon", "").As(); - Name = GetMeta("Name", "").AsString(); - Description = GetMeta("Description", "").AsString(); - _firingInterval = TimeSpan.FromMilliseconds(GetMeta("FiringInterval", "100").AsInt64()); - _minContactInjury = GetMeta("MinContactInjury", "1").AsInt32(); - _maxContactInjury = GetMeta("MaxContactInjury", "2").AsInt32(); - _recoil = GetMeta("Recoil", Vector2.Zero).AsVector2(); + // Id = GetMeta("ID", "1").AsString(); + // Quantity = GetMeta("Quantity", "1").AsInt32(); + // MaxStackQuantity = GetMeta("MaxStackQuantity", Config.MaxStackQuantity).AsInt32(); + // Icon = GetMeta("Icon", "").As(); + // Name = GetMeta("Name", "").AsString(); + // Description = GetMeta("Description", "").AsString(); + // _firingInterval = TimeSpan.FromMilliseconds(GetMeta("FiringInterval", "100").AsInt64()); + // _minContactInjury = GetMeta("MinContactInjury", "1").AsInt32(); + // _maxContactInjury = GetMeta("MaxContactInjury", "2").AsInt32(); + // _recoil = GetMeta("Recoil", Vector2.Zero).AsVector2(); + + _firingInterval = TimeSpan.FromMilliseconds(_firingIntervalAsMillisecond); } @@ -118,7 +130,7 @@ public partial class WeaponTemplate : RigidBody2D, IItem //Determine if your side can cause damage //判断所属的阵营是否可以造成伤害 var canCauseHarm = CampManager.CanCauseHarm(CampManager.GetCamp(ownerCharacterTemplate.CampId), - CampManager.GetCamp(characterTemplate.CampId)); + CampManager.GetCamp(characterTemplate.CampId)); if (!canCauseHarm) { return; @@ -145,9 +157,7 @@ public partial class WeaponTemplate : RigidBody2D, IItem /// 翻转武器 /// /// - public void Flip(bool facingLeft) - { - } + public void Flip(bool facingLeft) { } public override void _PhysicsProcess(double delta) { @@ -224,7 +234,5 @@ public partial class WeaponTemplate : RigidBody2D, IItem /// Execute fire /// 执行开火 /// - protected virtual void DoFire(Node2D? owner, Vector2 enemyGlobalPosition) - { - } + protected abstract void DoFire(Node2D? owner, Vector2 enemyGlobalPosition); } \ No newline at end of file From e9656d69926ee1fd093b6e915d2f4efc739429fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Wed, 12 Jun 2024 02:22:04 +0800 Subject: [PATCH 05/17] (temp): Just a small refactoring in the huge interaction code (regarding ItemSlot and ItemStack), but I think it's necessary to leave a save point, after all, I have to go to sleep first --- scripts/character/CharacterTemplate.cs | 2 +- scripts/inventory/IItem.cs | 4 +- scripts/inventory/IItemContainer.cs | 10 +-- scripts/inventory/ItemSlotNode.cs | 86 +++++++++++++++----------- scripts/item/IItemStack.cs | 11 ++++ 5 files changed, 71 insertions(+), 42 deletions(-) diff --git a/scripts/character/CharacterTemplate.cs b/scripts/character/CharacterTemplate.cs index 5aa1650..8494134 100644 --- a/scripts/character/CharacterTemplate.cs +++ b/scripts/character/CharacterTemplate.cs @@ -277,7 +277,7 @@ public partial class CharacterTemplate : CharacterBody2D { //Empty reference checking is implicitly performed here. //此处隐式的执行了空引用检查。 - if (pickAbleItem is not IItem item) + if (pickAbleItem is not IItem_New item) { return false; } diff --git a/scripts/inventory/IItem.cs b/scripts/inventory/IItem.cs index 4cdbb0d..6de2d52 100644 --- a/scripts/inventory/IItem.cs +++ b/scripts/inventory/IItem.cs @@ -3,6 +3,7 @@ using Godot; namespace ColdMint.scripts.inventory; +/* public interface IItem { /// @@ -53,4 +54,5 @@ public interface IItem /// 当从背包内取出,实例化物品时 /// Func? OnInstantiation { get; set; } -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/scripts/inventory/IItemContainer.cs b/scripts/inventory/IItemContainer.cs index c275c7d..9678df3 100644 --- a/scripts/inventory/IItemContainer.cs +++ b/scripts/inventory/IItemContainer.cs @@ -1,4 +1,6 @@ -namespace ColdMint.scripts.inventory; +using ColdMint.scripts.item; + +namespace ColdMint.scripts.inventory; /// /// item container @@ -16,7 +18,7 @@ public interface IItemContainer /// /// /// - bool CanAddItem(IItem item); + bool CanAddItem(IItem_New item); /// /// Implement methods for adding items @@ -24,7 +26,7 @@ public interface IItemContainer /// /// /// - bool AddItem(IItem item); + bool AddItem(IItem_New item); /// /// Gets the selected location @@ -81,5 +83,5 @@ public interface IItemContainer ///Return null if there is no slot to place the item in ///若没有槽可放置此物品,则返回null /// - ItemSlotNode? Matching(IItem item); + ItemSlotNode? Matching(IItem_New item); } \ No newline at end of file diff --git a/scripts/inventory/ItemSlotNode.cs b/scripts/inventory/ItemSlotNode.cs index a5d30be..93a07f5 100644 --- a/scripts/inventory/ItemSlotNode.cs +++ b/scripts/inventory/ItemSlotNode.cs @@ -1,4 +1,6 @@ +using ColdMint.scripts.item; using ColdMint.scripts.utils; + using Godot; namespace ColdMint.scripts.inventory; @@ -9,7 +11,8 @@ namespace ColdMint.scripts.inventory; /// public partial class ItemSlotNode : MarginContainer { - private IItem? _item; + //private IItem? _item; + private IItemStack? _itemStack; private TextureRect? _backgroundTextureRect; private TextureRect? _iconTextureRect; private Label? _quantityLabel; @@ -35,56 +38,69 @@ public partial class ItemSlotNode : MarginContainer public TextureRect? BackgroundTextureRect => _backgroundTextureRect; /// - /// Get the items in the item slot - /// 获取物品槽内的物品 + /// Get the item stack in the item slot + /// 获取物品槽内的物品堆 /// /// - public IItem? GetItem() - { - return _item; - } + public IItemStack GetItemStack() => _itemStack; /// /// Removes the specified number of items from the item slot /// 在物品槽内移除指定数量的物品 /// /// - /// - public bool RemoveItem(int number) + /// + /// The remaining number, if the number of items in the current item stack is less than the specified number. Otherwise,0 + /// 若物品槽内物品少于指定的数量,返回相差的数量。否则返回0 + /// + public int RemoveItem(int number) { - if (_item == null) + if (_itemStack == null) { - return false; + return number; } - var newNumber = _item.Quantity - number; - if (newNumber <= 0) - { - //If the specified number of items is removed, the number of items is less than or equal to 0. Then we return the removal successful and empty the inventory. - //如果移除指定数量的物品后,物品数量小于或等于0。那么我们返回移除成功,并清空物品栏。 - ClearItem(); - return true; - } + var result = _itemStack.RemoveItem(number); + //If the specified number of items is removed, the number of items is less than or equal to 0. Then we empty the inventory. + //如果移除指定数量的物品后,物品数量小于或等于0。那么我们清空物品栏。 + if (_itemStack.Quantity == 0) ClearSlot(); else { - _item.Quantity = newNumber; - UpdateTooltipText(_item); - UpdateQuantityLabel(_item.Quantity); - return true; + UpdateTooltipText(_itemStack); + UpdateQuantityLabel(_itemStack.Quantity); } + + return result; + + // var newNumber = _item.Quantity - number; + // if (newNumber <= 0) + // { + // //If the specified number of items is removed, the number of items is less than or equal to 0. Then we return the removal successful and empty the inventory. + // //如果移除指定数量的物品后,物品数量小于或等于0。那么我们返回移除成功,并清空物品栏。 + // ClearItem(); + // return true; + // } + // else + // { + // _item.Quantity = newNumber; + // UpdateTooltipText(_item); + // UpdateQuantityLabel(_item.Quantity); + // return true; + // } } /// - /// Empty the items in the item slot - /// 清空物品槽内的物品 + /// Empty the item slot + /// 清空物品槽 /// /// - ///This method does not calculate how many items should be left. If you want to remove a specified number of items, call the RemoveItem method. - ///此方法不会计算物品应该剩余多少个。若您希望移除指定数量的物品,请调用RemoveItem方法。 + ///This method does not calculate how many items should be left. If you want to remove a specified number of items, call the method. + ///此方法不会计算物品应该剩余多少个。若您希望移除指定数量的物品,请调用方法。 /// - public void ClearItem() + public void ClearSlot() { - _item = null; + _itemStack = null; + if (_iconTextureRect != null) { _iconTextureRect.Texture = null; @@ -95,12 +111,10 @@ public partial class ItemSlotNode : MarginContainer _control.TooltipText = null; } - if (_quantityLabel != null) - { - _quantityLabel.Hide(); - } + _quantityLabel?.Hide(); } + //Todo: I searched until here. /// /// Can the specified item be placed in the item slot? @@ -186,9 +200,9 @@ public partial class ItemSlotNode : MarginContainer if (debugText != null) { _control.TooltipText = string.Format(debugText, item.Id, - TranslationServerUtils.Translate(item.Name), - item.Quantity, item.MaxStackQuantity, item.GetType().Name, - TranslationServerUtils.Translate(item.Description)); + TranslationServerUtils.Translate(item.Name), + item.Quantity, item.MaxStackQuantity, item.GetType().Name, + TranslationServerUtils.Translate(item.Description)); } } else diff --git a/scripts/item/IItemStack.cs b/scripts/item/IItemStack.cs index f476c63..1ff6bd9 100644 --- a/scripts/item/IItemStack.cs +++ b/scripts/item/IItemStack.cs @@ -37,6 +37,17 @@ public interface IItemStack string? Description { get; } + /// + /// Removes the specified number of items from current item stack + /// 在当前物品堆移除指定数量的物品 + /// + /// + /// + /// The remaining number, if the number of items in the current item stack is less than the specified number. Otherwise,0 + /// 若物品槽内物品少于指定的数量,返回相差的数量。否则返回0 + /// + public int RemoveItem(int number); + /// /// Create a new ItemStack with the given item as the first item /// From 9b3701b49cb90239c59f6849b9b7688d88af5100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Wed, 12 Jun 2024 17:57:38 +0800 Subject: [PATCH 06/17] (temp):ItemSlot has already changed into new interfaces --- scripts/character/CharacterTemplate.cs | 27 +-- scripts/inventory/HotBar.cs | 4 +- scripts/inventory/ItemSlotNode.cs | 267 +++++++++++++++---------- scripts/item/IItemStack.cs | 83 +++++++- scripts/item/IItem_New.cs | 5 + scripts/item/SingleItemStack.cs | 28 ++- 6 files changed, 285 insertions(+), 129 deletions(-) diff --git a/scripts/character/CharacterTemplate.cs b/scripts/character/CharacterTemplate.cs index 8494134..4422ab2 100644 --- a/scripts/character/CharacterTemplate.cs +++ b/scripts/character/CharacterTemplate.cs @@ -41,14 +41,7 @@ public partial class CharacterTemplate : CharacterBody2D //Item containers are used to store items. //物品容器用于存储物品。 - private IItemContainer? _itemContainer; - - - public IItemContainer? ItemContainer - { - get => _itemContainer; - set => _itemContainer = value; - } + public IItemContainer? ItemContainer { get; set; } //Items currently held //当前持有的物品 @@ -282,14 +275,14 @@ public partial class CharacterTemplate : CharacterBody2D return false; } - if (_itemContainer == null) + if (ItemContainer == null) { return false; } //Get the currently selected node //拿到当前选择的节点 - var itemSlotNode = _itemContainer.GetSelectItemSlotNode(); + var itemSlotNode = ItemContainer.GetSelectItemSlotNode(); if (itemSlotNode == null) { return false; @@ -297,7 +290,7 @@ public partial class CharacterTemplate : CharacterBody2D //First check if we can pick up the item. //先检查我们能否拾起此物品。 - var canPick = _itemContainer.CanAddItem(item); + var canPick = ItemContainer.CanAddItem(item); if (!canPick) { return false; @@ -305,7 +298,7 @@ public partial class CharacterTemplate : CharacterBody2D //Is it successfully added to the container? //再检查是否成功的添加到容器内了? - var addSuccess = _itemContainer.AddItem(item); + var addSuccess = ItemContainer.AddItem(item); if (!addSuccess) { return false; @@ -504,7 +497,7 @@ public partial class CharacterTemplate : CharacterBody2D /// protected virtual void EnterThePickingRangeBody(Node node) { - if (node is not IItem) + if (node is not IItem_New item) { return; } @@ -519,7 +512,7 @@ public partial class CharacterTemplate : CharacterBody2D /// protected virtual void ExitThePickingRangeBody(Node node) { - if (node is not IItem) + if (node is not IItem_New) { return; } @@ -549,12 +542,12 @@ public partial class CharacterTemplate : CharacterBody2D { //If the item container is null, then return //如果物品容器为null,那么返回 - if (_itemContainer == null) + if (ItemContainer == null) { return; } - var len = _itemContainer.GetItemSlotCount(); + var len = ItemContainer.GetItemSlotCount(); if (len == 0) { return; @@ -599,7 +592,7 @@ public partial class CharacterTemplate : CharacterBody2D /// protected void ThrowItem(int index, int number, Vector2 velocity) { - var itemSlotNode = _itemContainer?.GetItemSlotNode(index); + var itemSlotNode = ItemContainer?.GetItemSlotNode(index); var item = itemSlotNode?.GetItem(); diff --git a/scripts/inventory/HotBar.cs b/scripts/inventory/HotBar.cs index 4fb129a..f9dda26 100644 --- a/scripts/inventory/HotBar.cs +++ b/scripts/inventory/HotBar.cs @@ -339,7 +339,7 @@ public partial class HotBar : HBoxContainer, IItemContainer { return false; } - return itemSlotNode.SetItem(item); + return itemSlotNode.ReplaceItemStack(item); } public int GetSelectIndex() @@ -374,7 +374,7 @@ public partial class HotBar : HBoxContainer, IItemContainer foreach (var itemSlotNode in _itemSlotNodes) { - if (itemSlotNode.CanSetItem(item)) + if (itemSlotNode.CanAddItem(item)) { //If there is an item slot to put this item in, then we return it. //如果有物品槽可放置此物品,那么我们返回它。 diff --git a/scripts/inventory/ItemSlotNode.cs b/scripts/inventory/ItemSlotNode.cs index 93a07f5..ea526a6 100644 --- a/scripts/inventory/ItemSlotNode.cs +++ b/scripts/inventory/ItemSlotNode.cs @@ -42,7 +42,49 @@ public partial class ItemSlotNode : MarginContainer /// 获取物品槽内的物品堆 /// /// - public IItemStack GetItemStack() => _itemStack; + public IItemStack? GetItemStack() => _itemStack; + + /// + /// If present, get the item at the top of the item stack in this slot + /// 如果存在,获取该槽位中物品堆顶部的物品 + /// + public IItem_New? GetItem() => _itemStack?.GetItem(); + + /// + /// If present, remove an item in this slot and return it. + /// 如果存在,移除该槽位中的一个物品并将其返回 + /// + /// + public IItem_New? PickItem() + { + if (_itemStack is null) return null; + + var result = _itemStack.PickItem(); + if (_itemStack.Quantity == 0) ClearSlot(); + else UpdateAllDisplay(); + + return result; + } + + /// + /// Remove the specified number of items and return them as a new item stack + /// 取出当前物品槽中指定数量的物品,并作为新的物品堆返回 + /// + /// + /// Quantity to be taken out, inputs below zero represent all items + /// 要取出的数量,小于0的输入代表全部物品 + /// + /// + public IItemStack? PickItems(int value) + { + if (_itemStack is null) return null; + + var result = _itemStack.PickItems(value); + if (_itemStack.Quantity == 0) ClearSlot(); + else UpdateAllDisplay(); + + return result; + } /// /// Removes the specified number of items from the item slot @@ -53,6 +95,9 @@ public partial class ItemSlotNode : MarginContainer /// The remaining number, if the number of items in the current item stack is less than the specified number. Otherwise,0 /// 若物品槽内物品少于指定的数量,返回相差的数量。否则返回0 /// + /// + /// 会将移除的物品从游戏中删除,如果目的并非如此,请考虑使用 + /// public int RemoveItem(int number) { if (_itemStack == null) @@ -64,133 +109,139 @@ public partial class ItemSlotNode : MarginContainer //If the specified number of items is removed, the number of items is less than or equal to 0. Then we empty the inventory. //如果移除指定数量的物品后,物品数量小于或等于0。那么我们清空物品栏。 if (_itemStack.Quantity == 0) ClearSlot(); - else - { - UpdateTooltipText(_itemStack); - UpdateQuantityLabel(_itemStack.Quantity); - } + else UpdateAllDisplay(); return result; - - // var newNumber = _item.Quantity - number; - // if (newNumber <= 0) - // { - // //If the specified number of items is removed, the number of items is less than or equal to 0. Then we return the removal successful and empty the inventory. - // //如果移除指定数量的物品后,物品数量小于或等于0。那么我们返回移除成功,并清空物品栏。 - // ClearItem(); - // return true; - // } - // else - // { - // _item.Quantity = newNumber; - // UpdateTooltipText(_item); - // UpdateQuantityLabel(_item.Quantity); - // return true; - // } } + /// + /// Remove item stack from slot and return it, equivalent to ReplaceItemStack(null) + /// 从当前槽位中移出并返回物品堆,等价于ReplaceItemStack(null) + /// + /// + public IItemStack? RemoveItemStack() => ReplaceItemStack(null); + /// /// Empty the item slot - /// 清空物品槽 + /// 清空当前物品槽 /// /// - ///This method does not calculate how many items should be left. If you want to remove a specified number of items, call the method. - ///此方法不会计算物品应该剩余多少个。若您希望移除指定数量的物品,请调用方法。 + ///This method will remove all items stored in the item slots from the game, if this is not what you want to do, consider using the method. + ///此方法会从游戏中移除储存于物品槽中的所有物品,若这不是您希望的操作,请考虑使用方法。 /// public void ClearSlot() { + _itemStack?.ClearStack(); _itemStack = null; - - if (_iconTextureRect != null) - { - _iconTextureRect.Texture = null; - } - if (_control != null) - { - _control.TooltipText = null; - } - - _quantityLabel?.Hide(); + UpdateAllDisplay(); } - //Todo: I searched until here. - /// /// Can the specified item be placed in the item slot? /// 指定的物品是否可设置在物品槽内? /// /// /// - public bool CanSetItem(IItem item) + public bool CanAddItem(IItem_New item) { - if (_item == null) - { - return true; - } - - //This inventory already has items, but the items in this inventory are not the same as the incoming items - //这个物品栏已经有物品了,但是这个物品栏的物品和传入的物品不一样 - if (_item.Id != item.Id) - { - return false; - } - - var newQuantity = _item.Quantity + item.Quantity; - if (newQuantity > item.MaxStackQuantity) - { - //If the amount of the current item exceeds the maximum stack amount after placing it in this inventory - //如果将当前物品放置到这个物品栏后,数量超过了最大叠加数量 - return false; - } - - return true; + if (_itemStack == null) return true; + return _itemStack.CanAddItem(item); } /// - /// Sets items for the item slot - /// 为物品槽设置物品 + /// + /// Set item stack for this slot, this will completely replace current item stack. + /// If you want the item stack to be added to current stack, use the . + /// + /// 为物品槽设置物品堆,将完全替换掉当前物品堆。如果想要物品堆叠加至该物品堆,请使用 /// - /// - /// - public bool SetItem(IItem item) + /// + /// The item stack that was previously in this slot + /// 该槽位中原本的物品堆 + /// + public IItemStack? ReplaceItemStack(IItemStack? newItemStack) { - if (!CanSetItem(item)) - { - return false; - } + var result = _itemStack; + _itemStack = newItemStack; - if (_item == null) - { - if (item.Icon != null && _iconTextureRect != null) - { - _iconTextureRect.Texture = item.Icon; - } + UpdateAllDisplay(); - _item = item; - UpdateTooltipText(item); - UpdateQuantityLabel(item.Quantity); - return true; + return result; + } + + /// + /// Try to add an item to this slot, if it can't be added to this slot, return false + /// 尝试向当前槽位中加入物品,如果该物品不能被放入该槽位,返回false + /// + public bool AddItem(IItem_New item) + { + bool result; + if (_itemStack is null) + { + _itemStack = IItemStack.FromItem(item); + result = true; } else { - var newQuantity = _item.Quantity + item.Quantity; - _item.Quantity = newQuantity; - UpdateTooltipText(item); - UpdateQuantityLabel(newQuantity); - return true; + result = _itemStack.AddItem(item); } + + if (result) + { + UpdateAllDisplay(); + } + + return result; + } + + /// + /// Try to combine an item stack into this slot + /// 尝试将一个物品堆合并至该槽位中 + /// + /// + /// Number of items remaining in the source item pile after the operation is completed + /// 操作完成后,源物品堆中剩余的物品数 + /// + public int AddItemStack(IItemStack itemStack) + { + int result; + if (_itemStack is null) + { + _itemStack = itemStack; + result = 0; + } + else + { + result = _itemStack.TakeFrom(itemStack); + } + + UpdateAllDisplay(); + return result; + } + + + /// + /// Update all displays of this slot + /// 更新该槽位的一切显示信息 + /// + private void UpdateAllDisplay() + { + UpdateIconTexture(); + UpdateQuantityLabel(); + UpdateTooltipText(); } /// /// Update item tips /// 更新物品的提示内容 /// - /// - private void UpdateTooltipText(IItem item) + private void UpdateTooltipText() { - if (_control == null) + if (_control == null) return; + if (_itemStack == null) { + _control.TooltipText = null; return; } @@ -199,16 +250,16 @@ public partial class ItemSlotNode : MarginContainer var debugText = TranslationServerUtils.Translate("item_prompt_debug"); if (debugText != null) { - _control.TooltipText = string.Format(debugText, item.Id, - TranslationServerUtils.Translate(item.Name), - item.Quantity, item.MaxStackQuantity, item.GetType().Name, - TranslationServerUtils.Translate(item.Description)); + _control.TooltipText = string.Format(debugText, _itemStack.Id, + TranslationServerUtils.Translate(_itemStack.Name), + _itemStack.Quantity, _itemStack.MaxQuantity, _itemStack.GetType().Name, + TranslationServerUtils.Translate(_itemStack.Description)); } } else { - _control.TooltipText = TranslationServerUtils.Translate(item.Name) + "\n" + - TranslationServerUtils.Translate(item.Description); + _control.TooltipText = TranslationServerUtils.Translate(_itemStack.Name) + "\n" + + TranslationServerUtils.Translate(_itemStack.Description); } } @@ -216,28 +267,36 @@ public partial class ItemSlotNode : MarginContainer /// Update quantity label /// 更新数量标签 /// - /// - private void UpdateQuantityLabel(int? quantity) + private void UpdateQuantityLabel() { if (_quantityLabel == null) { return; } - switch (quantity) + switch (_itemStack?.Quantity) { - case null: + case null or 1: _quantityLabel.Hide(); return; - case > 1: - //When the quantity is greater than 1, we display the quantity. - //当数量大于1时,我们显示数量 - _quantityLabel.Text = quantity.ToString(); + default: + //When the quantity is not null or 1, we display the quantity. + //当数量不为null或1时,我们显示数量 + _quantityLabel.Text = _itemStack?.Quantity.ToString(); _quantityLabel.Show(); break; - default: - _quantityLabel.Hide(); - break; + } + } + + /// + /// Update texture of the icon rect + /// 更新显示的物品图标 + /// + private void UpdateIconTexture() + { + if (_iconTextureRect != null) + { + _iconTextureRect.Texture = _itemStack?.Icon; } } diff --git a/scripts/item/IItemStack.cs b/scripts/item/IItemStack.cs index 1ff6bd9..1ebfba7 100644 --- a/scripts/item/IItemStack.cs +++ b/scripts/item/IItemStack.cs @@ -4,6 +4,9 @@ using Godot; namespace ColdMint.scripts.item; +/// +/// Item stack in an inventory slot +/// public interface IItemStack { /// @@ -36,10 +39,81 @@ public interface IItemStack /// string? Description { get; } + /// + /// Determine whether a specified item can be accommodated + /// 判断能否容纳指定物品 + /// + /// + public bool CanAddItem(IItem_New item); /// - /// Removes the specified number of items from current item stack - /// 在当前物品堆移除指定数量的物品 + /// Hold a given item + /// + /// Item to hold by current stack + /// Whether successful + public bool AddItem(IItem_New item); + + /// + /// 判断能从指定物品堆中接收的物品数量 + /// + /// + /// 向该物品堆中放入物品的物品堆 + /// Item stack to add to the current stack + /// + /// + public int CanTakeFrom(IItemStack itemStack); + + /// + /// 将指定物品堆中尽可能多的物品移动至当前物品堆中,被移入当前堆的物品应从原物品堆中移除。 + /// + /// + /// 被移入当前堆的物品堆 + /// + /// + /// 操作结束后原物品堆中剩余的物品数 + /// + public int TakeFrom(IItemStack itemStack); + + /// + /// Get item instance at the top of current stack without removing it from stack + /// 获取当前物品堆顶部的物品实例而不取出该物品 + /// + /// + /// + public IItem_New? GetItem(); + + /// + /// Pop the item instance at the top of current item stack and return it + /// 取出当前物品堆顶部的物品实例并返回该物品 + /// + /// + /// + public IItem_New? PickItem(); + + /// + /// Remove the specified number of items and return them as a new item stack + /// 取出当前堆中指定数量的物品,并作为新的物品堆返回 + /// + /// + /// + /// Quantity to be taken out, inputs below zero represent all items + /// 要取出的数量,小于0的输入代表全部物品 + /// + /// + /// The item stack that is taken out, can be null if out nothing, should not be the current item stack itself + /// 取出的物品堆,没有取出物品时可为null,不应是当前物品堆自身 + /// + public IItemStack? PickItems(int value); + + /// + /// + /// Removes the specified number of items from current item stack,removed items should be removed from the game
+ /// If you don't want remove them from game, consider and + ///
+ /// + /// 在当前物品堆移除指定数量的物品,被移除的物品应当从游戏中移除。
+ /// 如果您不想将它们从游戏中移除,请考虑: + ///
///
/// /// @@ -48,6 +122,11 @@ public interface IItemStack /// public int RemoveItem(int number); + /// + /// Clear current stack, which means should dispose all items inside current stack here + /// + public void ClearStack(); + /// /// Create a new ItemStack with the given item as the first item /// diff --git a/scripts/item/IItem_New.cs b/scripts/item/IItem_New.cs index d98e25d..a046842 100644 --- a/scripts/item/IItem_New.cs +++ b/scripts/item/IItem_New.cs @@ -28,4 +28,9 @@ public interface IItem_New /// Owner of current item, if any /// Target position, such as the position of the cursor when used by the player void Use(Node2D? owner, Vector2 targetGlobalPosition); + + /// + /// Execute when current item be removed from game. + /// + void Destroy(); } \ No newline at end of file diff --git a/scripts/item/SingleItemStack.cs b/scripts/item/SingleItemStack.cs index b853990..d7c3415 100644 --- a/scripts/item/SingleItemStack.cs +++ b/scripts/item/SingleItemStack.cs @@ -1,21 +1,41 @@ -using ColdMint.scripts.inventory; +using System; + +using ColdMint.scripts.inventory; using Godot; namespace ColdMint.scripts.item; /// -/// Item stack in inventory +/// Item stack of single item /// //maybe we'd move this into inventory namespace -public readonly struct SingleItemStack(IItem_New item) : IItemStack +public struct SingleItemStack(IItem_New item) : IItemStack { public IItem_New Item { get; init; } = item; public string Id => Item.Id; public int MaxQuantity => 1; - public int Quantity => 1; + public int Quantity { get; set; } = 1; public Texture2D Icon => Item.Icon; public string Name => Item.Name; public string? Description => Item.Description; + + public bool CanAddItem(IItem_New item) => false; + + public bool AddItem(IItem_New item) => false; + + public int CanTakeFrom(IItemStack itemStack) => 0; + + public int TakeFrom(IItemStack itemStack) => 0; + + public int RemoveItem(int number) + { + + } + + public void ClearStack() + { + throw new System.NotImplementedException(); + } } \ No newline at end of file From 3d6b71ef0ca77956242261a79d635a13558a0c16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Wed, 12 Jun 2024 21:53:27 +0800 Subject: [PATCH 07/17] implement SingleItemStack, prepare for combine master --- scripts/item/SingleItemStack.cs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/scripts/item/SingleItemStack.cs b/scripts/item/SingleItemStack.cs index d7c3415..86850bf 100644 --- a/scripts/item/SingleItemStack.cs +++ b/scripts/item/SingleItemStack.cs @@ -10,7 +10,7 @@ namespace ColdMint.scripts.item; /// Item stack of single item /// //maybe we'd move this into inventory namespace -public struct SingleItemStack(IItem_New item) : IItemStack +public class SingleItemStack(IItem_New item) : IItemStack { public IItem_New Item { get; init; } = item; @@ -28,14 +28,29 @@ public struct SingleItemStack(IItem_New item) : IItemStack public int CanTakeFrom(IItemStack itemStack) => 0; public int TakeFrom(IItemStack itemStack) => 0; + + public IItem_New? GetItem() + { + throw new NotImplementedException(); + } + + public IItem_New? PickItem() + { + throw new NotImplementedException(); + } + + public IItemStack? PickItems(int value) + { + throw new NotImplementedException(); + } public int RemoveItem(int number) { - + throw new NotImplementedException(); } public void ClearStack() { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } } \ No newline at end of file From 16b3a5a10653b32f3f2a73e572b0cab7c8487da7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Thu, 13 Jun 2024 01:18:55 +0800 Subject: [PATCH 08/17] =?UTF-8?q?UniversalItemContainer=20refactored=20don?= =?UTF-8?q?e=20UniversalItemContainer=E8=B0=83=E6=95=99=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/inventory/CommonItem.cs | 4 +- scripts/inventory/IItemContainer.cs | 128 ++++++++++++++++++-- scripts/inventory/ItemSlotNode.cs | 18 +-- scripts/inventory/UniversalItemContainer.cs | 111 +++++++++++------ scripts/item/IItemStack.cs | 11 +- 5 files changed, 216 insertions(+), 56 deletions(-) diff --git a/scripts/inventory/CommonItem.cs b/scripts/inventory/CommonItem.cs index 884383d..fbaccfc 100644 --- a/scripts/inventory/CommonItem.cs +++ b/scripts/inventory/CommonItem.cs @@ -3,6 +3,7 @@ using Godot; namespace ColdMint.scripts.inventory; +/* /// /// Common goods /// 普通的物品 @@ -17,4 +18,5 @@ public class CommonItem : IItem public string? Description { get; set; } public Action? OnUse { get; set; } public Func? OnInstantiation { get; set; } -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/scripts/inventory/IItemContainer.cs b/scripts/inventory/IItemContainer.cs index 5fb1cc7..1cb88fc 100644 --- a/scripts/inventory/IItemContainer.cs +++ b/scripts/inventory/IItemContainer.cs @@ -1,3 +1,7 @@ +using System; +using System.Collections; +using System.Collections.Generic; + using ColdMint.scripts.item; using Godot; @@ -30,6 +34,17 @@ public interface IItemContainer /// bool AddItem(IItem_New item); + /// + /// Add an stack of items to this container + /// 向当前容器中存入一堆物品 + /// + /// + /// + /// If the source item stack is empty after the operation is completed + /// 操作完成后,源物品堆是否被取空 + /// + bool AddItemStack(IItemStack itemStack); + /// /// Gets the selected location /// 获取选中的位置 @@ -43,14 +58,42 @@ public interface IItemContainer /// /// ItemSlotNode? GetSelectItemSlotNode(); + + /// + /// If present, remove an item from the slot at the currently selected location and return it. + /// 如果存在,移除当前选中位置的槽位中的一个物品并将其返回 + /// + /// + IItem_New? PickItemFromItemSlotBySelectIndex(); + + /// + /// Remove the specified number of items from the item slot at the currently selected location, and return them as a new item stack + /// 取出当前选中位置的物品槽中指定数量的物品,并作为新的物品堆返回 + /// + /// + /// Quantity to be taken out, inputs below zero represent all items + /// 要取出的数量,小于0的输入代表全部物品 + /// + /// + IItemStack? PickItemsFromItemSlotBySelectIndex( int value); /// /// Removes an item from the inventory at the currently selected location /// 移除当前选中位置物品栏内的物品 /// - /// - /// - bool RemoveItemFromItemSlotBySelectIndex(int number); + /// + /// Quantity to be removed, inputs below zero represent all items + /// 要删除的数量,小于0的输入代表全部物品 + /// + /// + /// The remaining number, if the number of items in the current item stack is less than the specified number. Otherwise,0 + /// 若物品槽内物品少于指定的数量,返回相差的数量。否则返回0 + /// + /// + /// Will remove the removed items from the game, if that is not the intent, consider using the + /// 会将移除的物品从游戏中删除,如果目的并非如此,请考虑使用 + /// + int RemoveItemFromItemSlotBySelectIndex(int number); /// /// Gets the number of item slots @@ -67,25 +110,90 @@ public interface IItemContainer /// ItemSlotNode? GetItemSlotNode(int index); + /// + /// If present, remove an item from the slot in the specified location and return it. + /// 如果存在,移除指定位置的槽位中的一个物品并将其返回 + /// + /// + IItem_New? PickItemFromItemSlot(int itemSlotIndex); + + /// + /// Remove the specified number of items from the item slot in the specified location, and return them as a new item stack + /// 取出指定位置的物品槽中指定数量的物品,并作为新的物品堆返回 + /// + /// + /// + /// Quantity to be taken out, inputs below zero represent all items + /// 要取出的数量,小于0的输入代表全部物品 + /// + /// + IItemStack? PickItemsFromItemSlot(int itemSlotIndex, int value); + /// /// Removes an item from the item slot in the specified location /// 在指定位置的物品槽内移除物品 /// /// - /// - /// - bool RemoveItemFromItemSlot(int itemSlotIndex, int number); + /// + /// Quantity to be removed, inputs below zero represent all items + /// 要删除的数量,小于0的输入代表全部物品 + /// + /// + /// The remaining number, if the number of items in the current item stack is less than the specified number. Otherwise,0 + /// 若物品槽内物品少于指定的数量,返回相差的数量。否则返回0 + /// + /// + /// Will remove the removed items from the game, if that is not the intent, consider using the + /// 会将移除的物品从游戏中删除,如果目的并非如此,请考虑使用 + /// + int RemoveItemFromItemSlot(int itemSlotIndex, int number); /// - /// Based on the given item, match the item slots where it can be placed + /// Based on the given item, match the item slots where it can be added to /// 根据给定的物品,匹配可放置它的物品槽 /// /// /// - ///Return null if there is no slot to place the item in - ///若没有槽可放置此物品,则返回null + /// Return null if there is no slot to place the item in + /// 若没有槽可放置此物品,则返回null /// - ItemSlotNode? Matching(IItem_New item); + ItemSlotNode? Match(IItem_New item); + + /// + /// Based on the given item stack, match the item slots where it can be added to + /// 根据给定的物品堆,匹配可放置它的物品槽 + /// + /// + /// + /// Return null if there is no slot to add the item slot in + /// 若没有槽可放置此物品堆,则返回null + /// + ItemSlotNode? Match(IItemStack stack); + + /// + /// Match the first item slot that has item stack that satisfies the predicate + /// 匹配首个拥有满足指定条件的物品堆的物品槽 + /// + /// + /// + /// Return null if there is no slot satisfies the predicate + /// 若没有满足条件的槽位,返回null + /// + /// + ItemSlotNode? Match(Func predicate); + + /// + /// Match all item slots that has item stack that satisfies the predicate + /// 匹配所有拥有满足指定条件的物品堆的物品槽 + /// + /// + /// + /// IEnumerable for the item slot matched to, will be empty if there's no slot satisfies the predicate + /// 包含匹配到的槽位的IEnumerable,当没有满足条件的槽位时为空 + /// + /// + IEnumerable MatchAll(Func predicate); + /// /// AddItemSlot diff --git a/scripts/inventory/ItemSlotNode.cs b/scripts/inventory/ItemSlotNode.cs index ea526a6..b129e1c 100644 --- a/scripts/inventory/ItemSlotNode.cs +++ b/scripts/inventory/ItemSlotNode.cs @@ -90,13 +90,17 @@ public partial class ItemSlotNode : MarginContainer /// Removes the specified number of items from the item slot /// 在物品槽内移除指定数量的物品 /// - /// + /// + /// Quantity to be removed, inputs below zero represent all items + /// 要删除的数量,小于0的输入代表全部物品 + /// /// /// The remaining number, if the number of items in the current item stack is less than the specified number. Otherwise,0 /// 若物品槽内物品少于指定的数量,返回相差的数量。否则返回0 /// /// - /// 会将移除的物品从游戏中删除,如果目的并非如此,请考虑使用 + /// Will remove the removed items from the game, if that is not the intent, consider using the + /// 会将移除的物品从游戏中删除,如果目的并非如此,请考虑使用 /// public int RemoveItem(int number) { @@ -200,16 +204,16 @@ public partial class ItemSlotNode : MarginContainer /// 尝试将一个物品堆合并至该槽位中 /// /// - /// Number of items remaining in the source item pile after the operation is completed - /// 操作完成后,源物品堆中剩余的物品数 + /// If the source item stack is empty after the operation is completed + /// 操作完成后,源物品堆是否被取空 /// - public int AddItemStack(IItemStack itemStack) + public bool AddItemStack(IItemStack itemStack) { - int result; + bool result; if (_itemStack is null) { _itemStack = itemStack; - result = 0; + result = false; } else { diff --git a/scripts/inventory/UniversalItemContainer.cs b/scripts/inventory/UniversalItemContainer.cs index 538b695..975f837 100644 --- a/scripts/inventory/UniversalItemContainer.cs +++ b/scripts/inventory/UniversalItemContainer.cs @@ -1,6 +1,11 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Linq; + using ColdMint.scripts.character; +using ColdMint.scripts.item; using ColdMint.scripts.utils; + using Godot; namespace ColdMint.scripts.inventory; @@ -30,20 +35,34 @@ public class UniversalItemContainer : IItemContainer //_selectIndex默认为0. private int _selectIndex; - public bool CanAddItem(IItem item) + public bool CanAddItem(IItem_New item) { - return Matching(item) != null; + return Match(item) != null; } - public bool AddItem(IItem item) + public bool AddItem(IItem_New item) { - var itemSlotNode = Matching(item); + var itemSlotNode = Match(item); if (itemSlotNode == null) { return false; } - return itemSlotNode.SetItem(item); + return itemSlotNode.AddItem(item); + } + + public bool AddItemStack(IItemStack itemStack) + { + while (true) + { + var itemSlotNode = Match(itemStack); + + if (itemSlotNode == null) + return false; + + if (itemSlotNode.AddItemStack(itemStack)) + return true; + } } public int GetSelectIndex() @@ -68,10 +87,11 @@ public class UniversalItemContainer : IItemContainer return null; } - public bool RemoveItemFromItemSlotBySelectIndex(int number) - { - return RemoveItemFromItemSlot(_selectIndex, number); - } + public IItem_New? PickItemFromItemSlotBySelectIndex() => PickItemFromItemSlot(_selectIndex); + + public IItemStack? PickItemsFromItemSlotBySelectIndex(int value) => PickItemsFromItemSlot(_selectIndex, value); + + public int RemoveItemFromItemSlotBySelectIndex(int number) => RemoveItemFromItemSlot(_selectIndex, number); public int GetItemSlotCount() { @@ -94,42 +114,65 @@ public class UniversalItemContainer : IItemContainer return _itemSlotNodes[safeIndex]; } - public bool RemoveItemFromItemSlot(int itemSlotIndex, int number) + public IItem_New? PickItemFromItemSlot(int itemSlotIndex) { - if (_itemSlotNodes == null) - { - return false; - } - + if (_itemSlotNodes == null) return null; var safeIndex = GetSafeIndex(itemSlotIndex); if (safeIndex == UnknownIndex) { - return false; + return null; + } + + var itemSlot = _itemSlotNodes[safeIndex]; + return itemSlot.PickItem(); + } + + public IItemStack? PickItemsFromItemSlot(int itemSlotIndex, int value) + { + if (_itemSlotNodes == null) return null; + var safeIndex = GetSafeIndex(itemSlotIndex); + if (safeIndex == UnknownIndex) + { + return null; + } + + var itemSlot = _itemSlotNodes[safeIndex]; + return itemSlot.PickItems(value); + } + + public int RemoveItemFromItemSlot(int itemSlotIndex, int number) + { + if (_itemSlotNodes == null) return number; + var safeIndex = GetSafeIndex(itemSlotIndex); + if (safeIndex == UnknownIndex) + { + return number; } var itemSlot = _itemSlotNodes[safeIndex]; return itemSlot.RemoveItem(number); } - public ItemSlotNode? Matching(IItem item) + public ItemSlotNode? Match(IItem_New item) { - if (_itemSlotNodes == null || _itemSlotNodes.Count == 0) - { - return null; - } + //Find and return the first slot that can hold this item, if the list is null or not found, return null + //寻找并返回第一个遇到的可放置此物品的物品槽,若列表为空或不存在,将返回null + return _itemSlotNodes?.FirstOrDefault(itemSlotNode => itemSlotNode.CanAddItem(item)); + } + public ItemSlotNode? Match(IItemStack stack) + { + throw new NotImplementedException(); + } - foreach (var itemSlotNode in _itemSlotNodes) - { - if (itemSlotNode.CanSetItem(item)) - { - //If there is an item slot to put this item in, then we return it. - //如果有物品槽可放置此物品,那么我们返回它。 - return itemSlotNode; - } - } + public ItemSlotNode? Match(Func predicate) + { + throw new NotImplementedException(); + } - return null; + public IEnumerable MatchAll(Func predicate) + { + throw new NotImplementedException(); } @@ -139,8 +182,8 @@ public class UniversalItemContainer : IItemContainer /// /// /// - ///-1 is returned on failure, and the index that does not result in an out-of-bounds subscript is returned on success - ///失败返回-1,成功返回不会导致下标越界的索引 + /// -1 is returned on failure, and the index that does not result in an out-of-bounds subscript is returned on success + /// 失败返回-1,成功返回不会导致下标越界的索引 /// private int GetSafeIndex(int itemSlotIndex) { diff --git a/scripts/item/IItemStack.cs b/scripts/item/IItemStack.cs index 1ebfba7..8507679 100644 --- a/scripts/item/IItemStack.cs +++ b/scripts/item/IItemStack.cs @@ -70,9 +70,9 @@ public interface IItemStack /// 被移入当前堆的物品堆 /// /// - /// 操作结束后原物品堆中剩余的物品数 + /// 操作结束后原物品堆是否为空 /// - public int TakeFrom(IItemStack itemStack); + public bool TakeFrom(IItemStack itemStack); /// /// Get item instance at the top of current stack without removing it from stack @@ -112,10 +112,13 @@ public interface IItemStack /// /// /// 在当前物品堆移除指定数量的物品,被移除的物品应当从游戏中移除。
- /// 如果您不想将它们从游戏中移除,请考虑: + /// 如果您并不打算将它们从游戏中移除,请考虑使用 ///
///
- /// + /// + /// Quantity to be removed, inputs below zero represent all items + /// 要删除的数量,小于0的输入代表全部物品 + /// /// /// The remaining number, if the number of items in the current item stack is less than the specified number. Otherwise,0 /// 若物品槽内物品少于指定的数量,返回相差的数量。否则返回0 From 16a2d405019fefed4e160cfccdbbe188657ace57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Thu, 13 Jun 2024 01:51:51 +0800 Subject: [PATCH 09/17] It's done. --- locals/Log.en.translation | Bin 1946 -> 1946 bytes locals/Log.ja.translation | Bin 2825 -> 2825 bytes locals/Log.zh.translation | Bin 2197 -> 2197 bytes locals/Slogan.ja.translation | Bin 765 -> 765 bytes locals/slogan.en.translation | Bin 666 -> 666 bytes locals/slogan.zh.translation | Bin 713 -> 713 bytes scripts/character/CharacterTemplate.cs | 54 ++++++++++++++++------- scripts/inventory/ItemSlotNode.cs | 2 + scripts/item/SingleItemStack.cs | 4 +- scripts/item/weapon/WeaponTemplate.cs | 7 ++- scripts/projectile/ProjectileTemplate.cs | 26 ++++++----- scripts/utils/NodeUtils.cs | 2 +- 12 files changed, 64 insertions(+), 31 deletions(-) diff --git a/locals/Log.en.translation b/locals/Log.en.translation index 3b2867b042ae128471bbb4d3e8be889a6f882294..26a2d18cd01ee755eba438f7287fd40f3fd7467c 100644 GIT binary patch delta 18 ZcmbQmKZ}2ZG$U)CQF2M~W(CG7HUKrK1!4dI delta 18 ZcmbQmKZ}2ZG$U(CURh4wW(CG7HUKz61*!l5 diff --git a/locals/Log.ja.translation b/locals/Log.ja.translation index ae0f9249ff9cc3df2d93fc552d2558b1e280e8b6..bcce44b179ae100f45cc89df2a5d6125119f52b9 100644 GIT binary patch delta 18 ZcmeAa>lE7{&B&UVZ;@-dS%L8-Cjc|e1%Lnm delta 18 ZcmeAa>lE7{&B$6=UQ(L9S%L8-CjdBM1{weW diff --git a/locals/Log.zh.translation b/locals/Log.zh.translation index a879ff0126fe830b1da85e9b55abdf106bba6b8a..b618fc91b966e5a60c0d12853c9e80bbe3277004 100644 GIT binary patch delta 18 ZcmbO#I8|_iG$U(Dfk|c3W(CGlb^tX*1yKM1 delta 18 ZcmbO#I8|_iG$U(qWofG6W(CGlb^tbk1!VvL diff --git a/locals/Slogan.ja.translation b/locals/Slogan.ja.translation index e44c84c9eaa7fd4576956a3f74e9a6dc87e8dc85..db766f6e265c289e9a8cac10d6cb05b37e3865d6 100644 GIT binary patch delta 35 rcmey%`j>TrEr;KlmkHBU7l}^{RG65+GqG?LYk{$8cIsvY#=DFF2e%EI delta 35 rcmey%`j>TrEr;)lcMN|kqBtf7Dojk^nOL}rHOC;+$aJ#;<6TAo2C)rd diff --git a/locals/slogan.en.translation b/locals/slogan.en.translation index afca76212737fdd2ebf6a5dc5db4c21d2ba12ea9..77ebe612cb8c3192f0892dd0521191b2abfbd24d 100644 GIT binary patch delta 35 rcmbQmI*WCJEysk4i1_-k delta 35 rcmbQmI*WCJEl2znBN5B=1>O?_6(%O|Oe|c*YLZr2X|`E`v5FA@+R+Qy diff --git a/locals/slogan.zh.translation b/locals/slogan.zh.translation index 357757f11e93c472f909446519db091dd54945d3..04ff43419af368263662db24f056efcd3f80688a 100644 GIT binary patch delta 35 rcmX@fdXja5Er*7a)`q$3ax^9eDojk^nOL}rwJh1tz<9F)<4Q&V=RXWE delta 35 rcmX@fdXja5Eyw%W27wn^=4nj~RG65+GqG?LYe`B@M)_t1#+8f!2rmul diff --git a/scripts/character/CharacterTemplate.cs b/scripts/character/CharacterTemplate.cs index aff45c9..75e2fb0 100644 --- a/scripts/character/CharacterTemplate.cs +++ b/scripts/character/CharacterTemplate.cs @@ -485,8 +485,8 @@ public partial class CharacterTemplate : CharacterBody2D /// /// public void GenerateLootObjects(Node parentNode, - LootData[] lootDataArray, - Vector2 position) + LootData[] lootDataArray, + Vector2 position) { LootListManager.GenerateLootObjects(parentNode, lootDataArray, position); } @@ -617,8 +617,8 @@ public partial class CharacterTemplate : CharacterBody2D /// 抛出物品 /// /// - ///Item slot subscript in item container - ///物品容器内的物品槽下标 + ///Item slot index in item container + ///物品容器内的物品槽位置 /// /// /// How many to throw @@ -633,8 +633,41 @@ public partial class CharacterTemplate : CharacterBody2D protected void ThrowItem(int index, int number, Vector2 velocity) { var itemSlotNode = ItemContainer?.GetItemSlotNode(index); + if (itemSlotNode is null) return; - var item = itemSlotNode?.GetItem(); + if (number < 0) + { + while (!itemSlotNode.IsEmpty()) + { + ThrowOneItem(itemSlotNode, velocity); + } + } + else + { + for (int i = 0; i < number && !itemSlotNode.IsEmpty(); i++) + { + ThrowOneItem(itemSlotNode, velocity); + } + } + } + + /// + /// Throw item + /// 抛出物品 + /// + /// + ///Item slot index in item container + ///物品容器内的物品槽位置 + /// + /// + ///The speed to be applied to the item + ///要施加到物品上的速度 + /// + protected void ThrowOneItem(ItemSlotNode itemSlotNode, Vector2 velocity) + { + //Pick an item from the item container + //从物品容器内取出一个物品 + var item = itemSlotNode?.PickItem(); if (item is not Node2D node2D) { @@ -685,17 +718,6 @@ public partial class CharacterTemplate : CharacterBody2D rigidBody2D.LinearVelocity = velocity; break; } - - //Remove items from the item container - //在物品容器内移除物品 - if (number < 0) - { - itemSlotNode!.RemoveItem(item.Quantity); - } - else - { - itemSlotNode!.RemoveItem(number); - } } /// diff --git a/scripts/inventory/ItemSlotNode.cs b/scripts/inventory/ItemSlotNode.cs index b129e1c..9208cd5 100644 --- a/scripts/inventory/ItemSlotNode.cs +++ b/scripts/inventory/ItemSlotNode.cs @@ -37,6 +37,8 @@ public partial class ItemSlotNode : MarginContainer public TextureRect? BackgroundTextureRect => _backgroundTextureRect; + public bool IsEmpty() => _itemStack == null; + /// /// Get the item stack in the item slot /// 获取物品槽内的物品堆 diff --git a/scripts/item/SingleItemStack.cs b/scripts/item/SingleItemStack.cs index 86850bf..839066e 100644 --- a/scripts/item/SingleItemStack.cs +++ b/scripts/item/SingleItemStack.cs @@ -27,8 +27,8 @@ public class SingleItemStack(IItem_New item) : IItemStack public int CanTakeFrom(IItemStack itemStack) => 0; - public int TakeFrom(IItemStack itemStack) => 0; - + public bool TakeFrom(IItemStack itemStack) => false; + public IItem_New? GetItem() { throw new NotImplementedException(); diff --git a/scripts/item/weapon/WeaponTemplate.cs b/scripts/item/weapon/WeaponTemplate.cs index 851cca1..6b5d314 100644 --- a/scripts/item/weapon/WeaponTemplate.cs +++ b/scripts/item/weapon/WeaponTemplate.cs @@ -35,6 +35,11 @@ public abstract partial class WeaponTemplate : RigidBody2D, IItem_New Fire(owner, targetGlobalPosition); } + public virtual void Destroy() + { + QueueFree(); + } + /// /// Whether the weapon is currently picked up @@ -168,7 +173,7 @@ public abstract partial class WeaponTemplate : RigidBody2D, IItem_New //Determine if your side can cause damage //判断所属的阵营是否可以造成伤害 - var canCauseHarm = CampManager.CanCauseHarm(CampManager.GetCamp(ownerCharacterTemplate.CampId), + var canCauseHarm = CampManager.CanCauseHarm(CampManager.GetCamp(ownerCharacterTemplate.CampId), CampManager.GetCamp(characterTemplate.CampId)); if (!canCauseHarm) { diff --git a/scripts/projectile/ProjectileTemplate.cs b/scripts/projectile/ProjectileTemplate.cs index 8d8b4f5..3079f72 100644 --- a/scripts/projectile/ProjectileTemplate.cs +++ b/scripts/projectile/ProjectileTemplate.cs @@ -1,8 +1,11 @@ using System; + using ColdMint.scripts.camp; using ColdMint.scripts.character; using ColdMint.scripts.damage; -using ColdMint.scripts.weapon; +using ColdMint.scripts.item; +using ColdMint.scripts.item.weapon; + using Godot; namespace ColdMint.scripts.projectile; @@ -64,10 +67,10 @@ public partial class ProjectileTemplate : CharacterBody2D Area2D.Monitoring = true; Area2D.BodyEntered += OnBodyEnter; Area2D.BodyExited += OnBodyExited; - Durability = GetMeta("Durability", "1").AsDouble(); - MaxDamage = GetMeta("MaxDamage", "7").AsInt32(); - MinDamage = GetMeta("MinDamage", "5").AsInt32(); - DamageType = GetMeta("DamageType", Config.DamageType.Physical).AsInt32(); + Durability = GetMeta("Durability", "1").AsDouble(); + MaxDamage = GetMeta("MaxDamage", "7").AsInt32(); + MinDamage = GetMeta("MinDamage", "5").AsInt32(); + DamageType = GetMeta("DamageType", Config.DamageType.Physical).AsInt32(); KnockbackForce = GetMeta("Knockback", Vector2.Zero).AsVector2(); //life(ms) //子弹的存在时间(毫秒) @@ -111,7 +114,9 @@ public partial class ProjectileTemplate : CharacterBody2D return true; } - if (target is WeaponTemplate) + //Match any item now + //现在使它识别任何物品 + if (target is IItem_New) { //Bullets are allowed to strike objects. //允许子弹撞击物品。 @@ -126,7 +131,7 @@ public partial class ProjectileTemplate : CharacterBody2D //First get the owner's camp and compare it with the target camp //先获取主人的阵营与目标阵营进行比较 var canCauseHarm = CampManager.CanCauseHarm(CampManager.GetCamp(ownerCharacterTemplate.CampId), - CampManager.GetCamp(characterTemplate.CampId)); + CampManager.GetCamp(characterTemplate.CampId)); return canCauseHarm; } @@ -169,7 +174,8 @@ public partial class ProjectileTemplate : CharacterBody2D force.Y = KnockbackForce.Y * Config.CellSize; characterTemplate.AddForce(force); } - }else if (target is WeaponTemplate weaponTemplate) + } + else if (target is WeaponTemplate weaponTemplate) { if (KnockbackForce != Vector2.Zero) { @@ -225,9 +231,7 @@ public partial class ProjectileTemplate : CharacterBody2D /// 当子弹离开节点时 /// /// - protected virtual void OnBodyExited(Node2D node) - { - } + protected virtual void OnBodyExited(Node2D node) { } /// diff --git a/scripts/utils/NodeUtils.cs b/scripts/utils/NodeUtils.cs index 5714db6..44ac247 100644 --- a/scripts/utils/NodeUtils.cs +++ b/scripts/utils/NodeUtils.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using ColdMint.scripts.debug; -using ColdMint.scripts.weapon; +using ColdMint.scripts.item.weapon; using Godot; namespace ColdMint.scripts.utils; From 94a2e78efc72f8343a16e1550bd15f746defe4dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Thu, 13 Jun 2024 03:04:12 +0800 Subject: [PATCH 10/17] =?UTF-8?q?Fixed=20all=20the=20bugs=20that=20prevent?= =?UTF-8?q?ed=20the=20game=20from=20working,=20added=20static=20item=20reg?= =?UTF-8?q?istration=20on=20startup=20=E9=98=BB=E7=A2=8D=E6=B8=B8=E6=88=8F?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E7=9A=84bug=E5=B7=B2=E5=B0=BD=E6=95=B0?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=8C=E6=B7=BB=E5=8A=A0=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E6=97=B6=E7=9A=84=E9=9D=99=E6=80=81=E7=89=A9=E5=93=81=E6=B3=A8?= =?UTF-8?q?=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locals/Weapon.csv | 4 +-- locals/Weapon.en.translation | Bin 494 -> 494 bytes locals/Weapon.ja.translation | Bin 573 -> 573 bytes locals/Weapon.zh.translation | Bin 525 -> 525 bytes scripts/character/CharacterTemplate.cs | 37 +++++++++----------- scripts/inventory/ItemSlotNode.cs | 12 +++---- scripts/inventory/UniversalItemContainer.cs | 6 ++-- scripts/item/IItemStack.cs | 1 + scripts/item/ItemType.cs | 10 +++--- scripts/item/ItemTypeManager.cs | 12 ++++--- scripts/item/SingleItemStack.cs | 19 +++++++--- scripts/loader/uiLoader/MainMenuLoader.cs | 8 +++++ 12 files changed, 64 insertions(+), 45 deletions(-) diff --git a/locals/Weapon.csv b/locals/Weapon.csv index 7bfa22a..7be7cae 100644 --- a/locals/Weapon.csv +++ b/locals/Weapon.csv @@ -1,3 +1,3 @@ id,zh,en,ja -staff_of_the_undead,死灵法杖,StaffOfTheUndead,ネクロポリスの杖です -staff_of_the_undead_desc,发射诅咒,可将敌人转化为邪恶的怪物。,Cast a curse that transforms enemies into evil monsters.,呪いを発射して、敵を邪悪な怪物に変えることができます。 \ No newline at end of file +item_staff_of_the_undead,死灵法杖,StaffOfTheUndead,ネクロポリスの杖です +item_staff_of_the_undead_desc,发射诅咒,可将敌人转化为邪恶的怪物。,Cast a curse that transforms enemies into evil monsters.,呪いを発射して、敵を邪悪な怪物に変えることができます。 \ No newline at end of file diff --git a/locals/Weapon.en.translation b/locals/Weapon.en.translation index 46fb4a6b4c5a33a88bf373fe48e7937b78e55165..3a92161063c4ac7240cf1aa7ee4ab4c4adbbdf9e 100644 GIT binary patch delta 95 zcmaFI{Em5pG$U)KVOD0vWCcbu&;LNc00bbK4M?*Bu>uhD05KyJM~l1<1Tq-}fLIVJ V29o=^YoQ@XObLiBC(mc}2LQQp6hQz0 delta 95 zcmaFI{Em5pG$X5NQEGDWWCcbuPX-|P4+LybniWVZ05J~`GeU9vscqKuhD05KyJM~l1<1Tq=qp%^Cq RbJs#ckXR51PhQ8^4*;dw6u1Ej<&B$t8T9{=%S%J~j^FI(U00D?*1JbNOtN_G3K+Fim(IW2yflLNoD29pu R+_lgUBxVl6lh-lE0|0526O8}> delta 95 zcmeBW>1Ej<&B&TnY*bo2S%J~jlK}|+0|6V9W(Cp;K+FTgj8GhZYTI>QAln>@Vd9c} QAJl+C3?Mn)$?F*70eQa@i2wiq diff --git a/scripts/character/CharacterTemplate.cs b/scripts/character/CharacterTemplate.cs index 75e2fb0..b2531af 100644 --- a/scripts/character/CharacterTemplate.cs +++ b/scripts/character/CharacterTemplate.cs @@ -67,7 +67,7 @@ public partial class CharacterTemplate : CharacterBody2D /// protected virtual void WhenUpdateCurrentItem(Node2D? currentItem) { } - //Define a pick up range + //Define a pickup range //定义一个拾起范围 private Area2D? _pickingArea; @@ -122,7 +122,7 @@ public partial class CharacterTemplate : CharacterBody2D /// protected List? PickingRangeBodiesList; - public Node[] PickingRangeBodies => PickingRangeBodiesList?.ToArray() ?? Array.Empty(); + public Node[] PickingRangeBodies => PickingRangeBodiesList?.ToArray() ?? []; /// /// Resurrected character @@ -155,7 +155,7 @@ public partial class CharacterTemplate : CharacterBody2D } /// - /// Find the nearest item within the pick up area(Does not include items currently held) + /// Find the nearest item within the pickup area(Does not include items currently held) /// 在拾捡范围内查找距离最近的物品(不包括当前持有的物品) /// /// @@ -179,7 +179,7 @@ public partial class CharacterTemplate : CharacterBody2D /// - /// Get all weapons within range of the pick up + /// Get all weapons within range of the pickup /// 获取所有在拾捡范围内的武器 /// /// @@ -401,7 +401,7 @@ public partial class CharacterTemplate : CharacterBody2D { if (targetCamp.Id == playerCamp.Id) { - //If an attack is allowed and you are on the same side, it is displayed as a friendly color (friend damage). + //If an attack is allowed, and you are on the same side, it is displayed as a friendly color (friend damage). //如果允许攻击,且属于同一阵营,则显示为友好颜色(友伤) _healthBar.SetFriendlyTones(); } @@ -537,7 +537,7 @@ public partial class CharacterTemplate : CharacterBody2D /// protected virtual void EnterThePickingRangeBody(Node node) { - if (node is not IItem_New item) + if (node is not IItem_New) { return; } @@ -651,23 +651,20 @@ public partial class CharacterTemplate : CharacterBody2D } } - /// - /// Throw item - /// 抛出物品 - /// - /// - ///Item slot index in item container - ///物品容器内的物品槽位置 - /// - /// - ///The speed to be applied to the item - ///要施加到物品上的速度 - /// - protected void ThrowOneItem(ItemSlotNode itemSlotNode, Vector2 velocity) + /// + /// Throw item + /// 抛出物品 + /// + /// + /// + /// The speed to be applied to the item + /// 要施加到物品上的速度 + /// + private void ThrowOneItem(ItemSlotNode itemSlotNode, Vector2 velocity) { //Pick an item from the item container //从物品容器内取出一个物品 - var item = itemSlotNode?.PickItem(); + var item = itemSlotNode.PickItem(); if (item is not Node2D node2D) { diff --git a/scripts/inventory/ItemSlotNode.cs b/scripts/inventory/ItemSlotNode.cs index 9208cd5..58f8524 100644 --- a/scripts/inventory/ItemSlotNode.cs +++ b/scripts/inventory/ItemSlotNode.cs @@ -62,8 +62,8 @@ public partial class ItemSlotNode : MarginContainer if (_itemStack is null) return null; var result = _itemStack.PickItem(); - if (_itemStack.Quantity == 0) ClearSlot(); - else UpdateAllDisplay(); + if (_itemStack.Quantity == 0) _itemStack = null; + UpdateAllDisplay(); return result; } @@ -82,8 +82,8 @@ public partial class ItemSlotNode : MarginContainer if (_itemStack is null) return null; var result = _itemStack.PickItems(value); - if (_itemStack.Quantity == 0) ClearSlot(); - else UpdateAllDisplay(); + if (_itemStack.Quantity == 0) _itemStack = null; + UpdateAllDisplay(); return result; } @@ -114,8 +114,8 @@ public partial class ItemSlotNode : MarginContainer var result = _itemStack.RemoveItem(number); //If the specified number of items is removed, the number of items is less than or equal to 0. Then we empty the inventory. //如果移除指定数量的物品后,物品数量小于或等于0。那么我们清空物品栏。 - if (_itemStack.Quantity == 0) ClearSlot(); - else UpdateAllDisplay(); + if (_itemStack.Quantity == 0) _itemStack = null; + UpdateAllDisplay(); return result; } diff --git a/scripts/inventory/UniversalItemContainer.cs b/scripts/inventory/UniversalItemContainer.cs index 975f837..3de0b44 100644 --- a/scripts/inventory/UniversalItemContainer.cs +++ b/scripts/inventory/UniversalItemContainer.cs @@ -162,17 +162,17 @@ public class UniversalItemContainer : IItemContainer public ItemSlotNode? Match(IItemStack stack) { - throw new NotImplementedException(); + return _itemSlotNodes?.FirstOrDefault(itemSlotNode => itemSlotNode.CanAddItem(stack.GetItem()!)); } public ItemSlotNode? Match(Func predicate) { - throw new NotImplementedException(); + return _itemSlotNodes?.FirstOrDefault(node => predicate(node.GetItemStack())); } public IEnumerable MatchAll(Func predicate) { - throw new NotImplementedException(); + return from node in _itemSlotNodes where predicate(node.GetItemStack()) select node; } diff --git a/scripts/item/IItemStack.cs b/scripts/item/IItemStack.cs index 8507679..40a1a32 100644 --- a/scripts/item/IItemStack.cs +++ b/scripts/item/IItemStack.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using Godot; diff --git a/scripts/item/ItemType.cs b/scripts/item/ItemType.cs index 308370b..395670c 100644 --- a/scripts/item/ItemType.cs +++ b/scripts/item/ItemType.cs @@ -4,22 +4,22 @@ using Godot; namespace ColdMint.scripts.item; -public readonly struct ItemType +public readonly struct ItemType(string id, Func newItemFunc, Texture2D? icon, int maxStackQuantity) { /// /// Item id of this type /// - public string Id { get; init; } + public string Id { get; init; } = id; /// /// A function returns a new item instance of this type /// - public Func NewItemFunc { get; init; } + public Func NewItemFunc { get; init; } = newItemFunc; /// /// Default icon of items of this type /// - public Texture2D? Icon { get; init; } + public Texture2D? Icon { get; init; } = icon; /// /// Max number in item stack of this type /// - public int MaxStackQuantity { get; init; } + public int MaxStackQuantity { get; init; } = maxStackQuantity; } \ No newline at end of file diff --git a/scripts/item/ItemTypeManager.cs b/scripts/item/ItemTypeManager.cs index b8e82ea..c97aefb 100644 --- a/scripts/item/ItemTypeManager.cs +++ b/scripts/item/ItemTypeManager.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using ColdMint.scripts.utils; @@ -10,14 +9,19 @@ namespace ColdMint.scripts.item; public static class ItemTypeManager { // Register items statically here - static ItemTypeManager() { } + public static void StaticRegister() + { + var staffOfTheUndeadScene = ResourceLoader.Load("res://prefab/weapons/staffOfTheUndead.tscn"); + var staffOfTheUndead = new ItemType("staff_of_the_undead", () => staffOfTheUndeadScene.Instantiate(), null, 1); + Register(staffOfTheUndead); + } private static Dictionary Registry { get; } = []; private static Texture2D DefaultTexture { get; } = new PlaceholderTexture2D(); /// - /// Register a item type. + /// Register an item type. /// Return false if the item id already exist. /// /// Whether the registration was successful. diff --git a/scripts/item/SingleItemStack.cs b/scripts/item/SingleItemStack.cs index 839066e..0a31888 100644 --- a/scripts/item/SingleItemStack.cs +++ b/scripts/item/SingleItemStack.cs @@ -31,26 +31,35 @@ public class SingleItemStack(IItem_New item) : IItemStack public IItem_New? GetItem() { - throw new NotImplementedException(); + return Quantity == 1 ? Item : null; } public IItem_New? PickItem() { - throw new NotImplementedException(); + Quantity = 0; + return Item; } public IItemStack? PickItems(int value) { - throw new NotImplementedException(); + if (value == 0) return null; + else + { + Quantity = 0; + return new SingleItemStack(Item); + } } public int RemoveItem(int number) { - throw new NotImplementedException(); + if (number == 0) return 0; + Quantity = 0; + Item.Destroy(); + return Math.Max(number - 1, 0); } public void ClearStack() { - throw new NotImplementedException(); + RemoveItem(1); } } \ No newline at end of file diff --git a/scripts/loader/uiLoader/MainMenuLoader.cs b/scripts/loader/uiLoader/MainMenuLoader.cs index 9dd308d..133d287 100644 --- a/scripts/loader/uiLoader/MainMenuLoader.cs +++ b/scripts/loader/uiLoader/MainMenuLoader.cs @@ -1,12 +1,15 @@ using System; using System.IO; using System.Text; + using ColdMint.scripts.camp; using ColdMint.scripts.deathInfo; using ColdMint.scripts.debug; using ColdMint.scripts.inventory; +using ColdMint.scripts.item; using ColdMint.scripts.map; using ColdMint.scripts.map.roomInjectionProcessor; + using Godot; namespace ColdMint.scripts.loader.uiLoader; @@ -57,6 +60,7 @@ public partial class MainMenuLoader : UiLoaderTemplate testLootList.AddLootEntry(lootEntry); LootListManager.RegisterLootList(testLootList); } + DeathInfoGenerator.RegisterDeathInfoHandler(new SelfDeathInfoHandler()); MapGenerator.RegisterRoomInjectionProcessor(new ChanceRoomInjectionProcessor()); MapGenerator.RegisterRoomInjectionProcessor(new TimeIntervalRoomInjectorProcessor()); @@ -82,6 +86,10 @@ public partial class MainMenuLoader : UiLoaderTemplate var aborigines = new Camp(Config.CampId.Aborigines); CampManager.AddCamp(aborigines); _gameScene = (PackedScene)GD.Load("res://scenes/game.tscn"); + + //Temp: Register ItemType + //临时:注册物品类型 + ItemTypeManager.StaticRegister(); } public override void InitializeUi() From 23877e82cc8fcc5ad93bbfcb75d55c54f0875096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Thu, 13 Jun 2024 03:07:55 +0800 Subject: [PATCH 11/17] =?UTF-8?q?Remove=20old=20item=20interfaces,rename?= =?UTF-8?q?=20new=20=E7=A7=BB=E9=99=A4=E6=97=A7=E7=9A=84=E7=89=A9=E5=93=81?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=EF=BC=8C=E9=87=8D=E5=91=BD=E5=90=8D=E6=96=B0?= =?UTF-8?q?=E7=9A=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/character/CharacterTemplate.cs | 8 +-- scripts/inventory/CommonItem.cs | 22 -------- scripts/inventory/IItem.cs | 58 --------------------- scripts/inventory/IItemContainer.cs | 10 ++-- scripts/inventory/ItemSlotNode.cs | 8 +-- scripts/inventory/UniversalItemContainer.cs | 10 ++-- scripts/item/{IItem_New.cs => IItem.cs} | 3 +- scripts/item/IItemStack.cs | 10 ++-- scripts/item/ItemType.cs | 4 +- scripts/item/ItemTypeManager.cs | 4 +- scripts/item/SingleItemStack.cs | 12 ++--- scripts/item/weapon/WeaponTemplate.cs | 2 +- scripts/projectile/ProjectileTemplate.cs | 2 +- 13 files changed, 36 insertions(+), 117 deletions(-) delete mode 100644 scripts/inventory/CommonItem.cs delete mode 100644 scripts/inventory/IItem.cs rename scripts/item/{IItem_New.cs => IItem.cs} (92%) diff --git a/scripts/character/CharacterTemplate.cs b/scripts/character/CharacterTemplate.cs index b2531af..fabc156 100644 --- a/scripts/character/CharacterTemplate.cs +++ b/scripts/character/CharacterTemplate.cs @@ -271,7 +271,7 @@ public partial class CharacterTemplate : CharacterBody2D { //Empty reference checking is implicitly performed here. //此处隐式的执行了空引用检查。 - if (pickAbleItem is not IItem_New item) + if (pickAbleItem is not IItem item) { return false; } @@ -348,7 +348,7 @@ public partial class CharacterTemplate : CharacterBody2D return false; } - if (_currentItem is IItem_New item) + if (_currentItem is IItem item) { item.Use(this, position); } @@ -537,7 +537,7 @@ public partial class CharacterTemplate : CharacterBody2D /// protected virtual void EnterThePickingRangeBody(Node node) { - if (node is not IItem_New) + if (node is not IItem) { return; } @@ -552,7 +552,7 @@ public partial class CharacterTemplate : CharacterBody2D /// protected virtual void ExitThePickingRangeBody(Node node) { - if (node is not IItem_New) + if (node is not IItem) { return; } diff --git a/scripts/inventory/CommonItem.cs b/scripts/inventory/CommonItem.cs deleted file mode 100644 index fbaccfc..0000000 --- a/scripts/inventory/CommonItem.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using Godot; - -namespace ColdMint.scripts.inventory; - -/* -/// -/// Common goods -/// 普通的物品 -/// -public class CommonItem : IItem -{ - public string? Id { get; set; } - public int Quantity { get; set; } - public int MaxStackQuantity { get; set; } - public Texture2D? Icon { get; set; } - public string? Name { get; set; } - public string? Description { get; set; } - public Action? OnUse { get; set; } - public Func? OnInstantiation { get; set; } -} -*/ \ No newline at end of file diff --git a/scripts/inventory/IItem.cs b/scripts/inventory/IItem.cs deleted file mode 100644 index 6de2d52..0000000 --- a/scripts/inventory/IItem.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using Godot; - -namespace ColdMint.scripts.inventory; - -/* -public interface IItem -{ - /// - /// Item and ID - /// 物品还有ID - /// - string? Id { get; set; } - - /// - /// Represents the quantity of this item - /// 表示此物品的数量 - /// - int Quantity { get; set; } - - /// - /// How many can this item stack up to - /// 这个物品最多叠加到多少个 - /// - int MaxStackQuantity { get; set; } - - /// - /// Items can be set with Icon - /// 物品可以设置图标 - /// - Texture2D? Icon { get; set; } - - /// - /// Item has a name - /// 物品有名称 - /// - string? Name { get; set; } - - /// - /// Description - /// 描述 - /// - string? Description { get; set; } - - - /// - /// When using items - /// 当使用物品时 - /// - Action? OnUse { get; set; } - - /// - /// When removing items from the backpack, instantiate them - /// 当从背包内取出,实例化物品时 - /// - Func? OnInstantiation { get; set; } -} -*/ \ No newline at end of file diff --git a/scripts/inventory/IItemContainer.cs b/scripts/inventory/IItemContainer.cs index 1cb88fc..e10b9bd 100644 --- a/scripts/inventory/IItemContainer.cs +++ b/scripts/inventory/IItemContainer.cs @@ -24,7 +24,7 @@ public interface IItemContainer /// /// /// - bool CanAddItem(IItem_New item); + bool CanAddItem(IItem item); /// /// Implement methods for adding items @@ -32,7 +32,7 @@ public interface IItemContainer /// /// /// - bool AddItem(IItem_New item); + bool AddItem(IItem item); /// /// Add an stack of items to this container @@ -64,7 +64,7 @@ public interface IItemContainer /// 如果存在,移除当前选中位置的槽位中的一个物品并将其返回 /// /// - IItem_New? PickItemFromItemSlotBySelectIndex(); + IItem? PickItemFromItemSlotBySelectIndex(); /// /// Remove the specified number of items from the item slot at the currently selected location, and return them as a new item stack @@ -115,7 +115,7 @@ public interface IItemContainer /// 如果存在,移除指定位置的槽位中的一个物品并将其返回 /// /// - IItem_New? PickItemFromItemSlot(int itemSlotIndex); + IItem? PickItemFromItemSlot(int itemSlotIndex); /// /// Remove the specified number of items from the item slot in the specified location, and return them as a new item stack @@ -157,7 +157,7 @@ public interface IItemContainer /// Return null if there is no slot to place the item in /// 若没有槽可放置此物品,则返回null /// - ItemSlotNode? Match(IItem_New item); + ItemSlotNode? Match(IItem item); /// /// Based on the given item stack, match the item slots where it can be added to diff --git a/scripts/inventory/ItemSlotNode.cs b/scripts/inventory/ItemSlotNode.cs index 58f8524..f6b27d4 100644 --- a/scripts/inventory/ItemSlotNode.cs +++ b/scripts/inventory/ItemSlotNode.cs @@ -50,14 +50,14 @@ public partial class ItemSlotNode : MarginContainer /// If present, get the item at the top of the item stack in this slot /// 如果存在,获取该槽位中物品堆顶部的物品 /// - public IItem_New? GetItem() => _itemStack?.GetItem(); + public IItem? GetItem() => _itemStack?.GetItem(); /// /// If present, remove an item in this slot and return it. /// 如果存在,移除该槽位中的一个物品并将其返回 /// /// - public IItem_New? PickItem() + public IItem? PickItem() { if (_itemStack is null) return null; @@ -149,7 +149,7 @@ public partial class ItemSlotNode : MarginContainer /// /// /// - public bool CanAddItem(IItem_New item) + public bool CanAddItem(IItem item) { if (_itemStack == null) return true; return _itemStack.CanAddItem(item); @@ -180,7 +180,7 @@ public partial class ItemSlotNode : MarginContainer /// Try to add an item to this slot, if it can't be added to this slot, return false /// 尝试向当前槽位中加入物品,如果该物品不能被放入该槽位,返回false /// - public bool AddItem(IItem_New item) + public bool AddItem(IItem item) { bool result; if (_itemStack is null) diff --git a/scripts/inventory/UniversalItemContainer.cs b/scripts/inventory/UniversalItemContainer.cs index 3de0b44..24a9062 100644 --- a/scripts/inventory/UniversalItemContainer.cs +++ b/scripts/inventory/UniversalItemContainer.cs @@ -35,12 +35,12 @@ public class UniversalItemContainer : IItemContainer //_selectIndex默认为0. private int _selectIndex; - public bool CanAddItem(IItem_New item) + public bool CanAddItem(IItem item) { return Match(item) != null; } - public bool AddItem(IItem_New item) + public bool AddItem(IItem item) { var itemSlotNode = Match(item); if (itemSlotNode == null) @@ -87,7 +87,7 @@ public class UniversalItemContainer : IItemContainer return null; } - public IItem_New? PickItemFromItemSlotBySelectIndex() => PickItemFromItemSlot(_selectIndex); + public IItem? PickItemFromItemSlotBySelectIndex() => PickItemFromItemSlot(_selectIndex); public IItemStack? PickItemsFromItemSlotBySelectIndex(int value) => PickItemsFromItemSlot(_selectIndex, value); @@ -114,7 +114,7 @@ public class UniversalItemContainer : IItemContainer return _itemSlotNodes[safeIndex]; } - public IItem_New? PickItemFromItemSlot(int itemSlotIndex) + public IItem? PickItemFromItemSlot(int itemSlotIndex) { if (_itemSlotNodes == null) return null; var safeIndex = GetSafeIndex(itemSlotIndex); @@ -153,7 +153,7 @@ public class UniversalItemContainer : IItemContainer return itemSlot.RemoveItem(number); } - public ItemSlotNode? Match(IItem_New item) + public ItemSlotNode? Match(IItem item) { //Find and return the first slot that can hold this item, if the list is null or not found, return null //寻找并返回第一个遇到的可放置此物品的物品槽,若列表为空或不存在,将返回null diff --git a/scripts/item/IItem_New.cs b/scripts/item/IItem.cs similarity index 92% rename from scripts/item/IItem_New.cs rename to scripts/item/IItem.cs index a046842..8c9efc5 100644 --- a/scripts/item/IItem_New.cs +++ b/scripts/item/IItem.cs @@ -2,8 +2,7 @@ namespace ColdMint.scripts.item; -//Todo: Merge this with IItem (and, then change this ugly name -public interface IItem_New +public interface IItem { /// /// ID of current item diff --git a/scripts/item/IItemStack.cs b/scripts/item/IItemStack.cs index 40a1a32..e5ab606 100644 --- a/scripts/item/IItemStack.cs +++ b/scripts/item/IItemStack.cs @@ -45,14 +45,14 @@ public interface IItemStack /// 判断能否容纳指定物品 /// /// - public bool CanAddItem(IItem_New item); + public bool CanAddItem(IItem item); /// /// Hold a given item /// /// Item to hold by current stack /// Whether successful - public bool AddItem(IItem_New item); + public bool AddItem(IItem item); /// /// 判断能从指定物品堆中接收的物品数量 @@ -81,7 +81,7 @@ public interface IItemStack /// /// /// - public IItem_New? GetItem(); + public IItem? GetItem(); /// /// Pop the item instance at the top of current item stack and return it @@ -89,7 +89,7 @@ public interface IItemStack /// /// /// - public IItem_New? PickItem(); + public IItem? PickItem(); /// /// Remove the specified number of items and return them as a new item stack @@ -134,7 +134,7 @@ public interface IItemStack /// /// Create a new ItemStack with the given item as the first item /// - public static IItemStack FromItem(IItem_New item) => ItemTypeManager.MaxStackQuantityOf(item.Id) switch + public static IItemStack FromItem(IItem item) => ItemTypeManager.MaxStackQuantityOf(item.Id) switch { 1 => new SingleItemStack(item), > 1 => throw new NotImplementedException(), diff --git a/scripts/item/ItemType.cs b/scripts/item/ItemType.cs index 395670c..d12b93a 100644 --- a/scripts/item/ItemType.cs +++ b/scripts/item/ItemType.cs @@ -4,7 +4,7 @@ using Godot; namespace ColdMint.scripts.item; -public readonly struct ItemType(string id, Func newItemFunc, Texture2D? icon, int maxStackQuantity) +public readonly struct ItemType(string id, Func newItemFunc, Texture2D? icon, int maxStackQuantity) { /// /// Item id of this type @@ -13,7 +13,7 @@ public readonly struct ItemType(string id, Func newItemFunc, Texture2 /// /// A function returns a new item instance of this type /// - public Func NewItemFunc { get; init; } = newItemFunc; + public Func NewItemFunc { get; init; } = newItemFunc; /// /// Default icon of items of this type /// diff --git a/scripts/item/ItemTypeManager.cs b/scripts/item/ItemTypeManager.cs index c97aefb..663d736 100644 --- a/scripts/item/ItemTypeManager.cs +++ b/scripts/item/ItemTypeManager.cs @@ -12,7 +12,7 @@ public static class ItemTypeManager public static void StaticRegister() { var staffOfTheUndeadScene = ResourceLoader.Load("res://prefab/weapons/staffOfTheUndead.tscn"); - var staffOfTheUndead = new ItemType("staff_of_the_undead", () => staffOfTheUndeadScene.Instantiate(), null, 1); + var staffOfTheUndead = new ItemType("staff_of_the_undead", () => staffOfTheUndeadScene.Instantiate(), null, 1); Register(staffOfTheUndead); } @@ -31,7 +31,7 @@ public static class ItemTypeManager /// Creates a new instance of the item registered to the given id. /// Returns null when the id is not registered. /// - public static IItem_New? NewItem(string id) => + public static IItem? NewItem(string id) => Registry.TryGetValue(id, out var itemType) ? itemType.NewItemFunc() : null; /// diff --git a/scripts/item/SingleItemStack.cs b/scripts/item/SingleItemStack.cs index 0a31888..a384172 100644 --- a/scripts/item/SingleItemStack.cs +++ b/scripts/item/SingleItemStack.cs @@ -10,9 +10,9 @@ namespace ColdMint.scripts.item; /// Item stack of single item /// //maybe we'd move this into inventory namespace -public class SingleItemStack(IItem_New item) : IItemStack +public class SingleItemStack(IItem item) : IItemStack { - public IItem_New Item { get; init; } = item; + public IItem Item { get; init; } = item; public string Id => Item.Id; public int MaxQuantity => 1; @@ -21,20 +21,20 @@ public class SingleItemStack(IItem_New item) : IItemStack public string Name => Item.Name; public string? Description => Item.Description; - public bool CanAddItem(IItem_New item) => false; + public bool CanAddItem(IItem item) => false; - public bool AddItem(IItem_New item) => false; + public bool AddItem(IItem item) => false; public int CanTakeFrom(IItemStack itemStack) => 0; public bool TakeFrom(IItemStack itemStack) => false; - public IItem_New? GetItem() + public IItem? GetItem() { return Quantity == 1 ? Item : null; } - public IItem_New? PickItem() + public IItem? PickItem() { Quantity = 0; return Item; diff --git a/scripts/item/weapon/WeaponTemplate.cs b/scripts/item/weapon/WeaponTemplate.cs index 6b5d314..e8bd693 100644 --- a/scripts/item/weapon/WeaponTemplate.cs +++ b/scripts/item/weapon/WeaponTemplate.cs @@ -13,7 +13,7 @@ namespace ColdMint.scripts.item.weapon; /// WeaponTemplate /// 武器模板 /// -public abstract partial class WeaponTemplate : RigidBody2D, IItem_New +public abstract partial class WeaponTemplate : RigidBody2D, IItem { private float _gravity = ProjectSettings.GetSetting("physics/2d/default_gravity").AsSingle(); diff --git a/scripts/projectile/ProjectileTemplate.cs b/scripts/projectile/ProjectileTemplate.cs index 3079f72..a98d1bf 100644 --- a/scripts/projectile/ProjectileTemplate.cs +++ b/scripts/projectile/ProjectileTemplate.cs @@ -116,7 +116,7 @@ public partial class ProjectileTemplate : CharacterBody2D //Match any item now //现在使它识别任何物品 - if (target is IItem_New) + if (target is IItem) { //Bullets are allowed to strike objects. //允许子弹撞击物品。 From c1aecf21d7599112ae2d039eb5acab3e5db84a3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Thu, 13 Jun 2024 10:43:54 +0800 Subject: [PATCH 12/17] Implements IEnumerable for IItemContainer. --- scripts/inventory/IItemContainer.cs | 16 ++++++++++++---- scripts/inventory/UniversalItemContainer.cs | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/scripts/inventory/IItemContainer.cs b/scripts/inventory/IItemContainer.cs index e10b9bd..5adcedb 100644 --- a/scripts/inventory/IItemContainer.cs +++ b/scripts/inventory/IItemContainer.cs @@ -16,7 +16,7 @@ namespace ColdMint.scripts.inventory; ///Item containers can store items. Things like backpacks and Hotbars are containers with visual pages. ///物品容器可以储存物品。像背包和hotbar是具有可视化页面的容器。 /// -public interface IItemContainer +public interface IItemContainer : IEnumerable { /// /// Can the specified item be added to the container? @@ -58,7 +58,7 @@ public interface IItemContainer /// /// ItemSlotNode? GetSelectItemSlotNode(); - + /// /// If present, remove an item from the slot at the currently selected location and return it. /// 如果存在,移除当前选中位置的槽位中的一个物品并将其返回 @@ -75,7 +75,7 @@ public interface IItemContainer /// 要取出的数量,小于0的输入代表全部物品 /// /// - IItemStack? PickItemsFromItemSlotBySelectIndex( int value); + IItemStack? PickItemsFromItemSlotBySelectIndex(int value); /// /// Removes an item from the inventory at the currently selected location @@ -110,6 +110,14 @@ public interface IItemContainer /// ItemSlotNode? GetItemSlotNode(int index); + /// + /// Gets the item slot for the specified location, equals to + /// 获取指定位置的物品槽,等同于 + /// + /// + /// + ItemSlotNode? this[int index] => GetItemSlotNode(index); + /// /// If present, remove an item from the slot in the specified location and return it. /// 如果存在,移除指定位置的槽位中的一个物品并将其返回 @@ -128,7 +136,7 @@ public interface IItemContainer /// /// IItemStack? PickItemsFromItemSlot(int itemSlotIndex, int value); - + /// /// Removes an item from the item slot in the specified location /// 在指定位置的物品槽内移除物品 diff --git a/scripts/inventory/UniversalItemContainer.cs b/scripts/inventory/UniversalItemContainer.cs index 6532bac..998cda1 100644 --- a/scripts/inventory/UniversalItemContainer.cs +++ b/scripts/inventory/UniversalItemContainer.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; @@ -9,6 +10,8 @@ using ColdMint.scripts.utils; using Godot; +using JetBrains.Annotations; + namespace ColdMint.scripts.inventory; /// @@ -348,4 +351,17 @@ public class UniversalItemContainer : IItemContainer _selectIndex = newSelectIndex; } + + + [MustDisposeResource] + public IEnumerator GetEnumerator() + { + return _itemSlotNodes?.GetEnumerator() ?? Enumerable.Empty().GetEnumerator(); + } + + [MustDisposeResource] + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } } \ No newline at end of file From e307a5829959f71d9457f1a9d76a3d953f6ca968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Thu, 13 Jun 2024 11:04:51 +0800 Subject: [PATCH 13/17] Make packsack new interface, too. --- ColdMint.Traveler.csproj | 3 ++ locals/Item.en.translation | Bin 570 -> 570 bytes locals/Item.ja.translation | Bin 693 -> 693 bytes locals/Item.zh.translation | Bin 609 -> 609 bytes prefab/packsacks/packsack.tscn | 1 + scripts/character/Player.cs | 1 + scripts/inventory/Packsack.cs | 46 ++++++++++++++++++-------- scripts/item/ItemTypeManager.cs | 9 ++++- scripts/item/weapon/WeaponTemplate.cs | 2 +- 9 files changed, 46 insertions(+), 16 deletions(-) diff --git a/ColdMint.Traveler.csproj b/ColdMint.Traveler.csproj index c893429..ec53ff3 100644 --- a/ColdMint.Traveler.csproj +++ b/ColdMint.Traveler.csproj @@ -8,4 +8,7 @@ enable 12 + + + \ No newline at end of file diff --git a/locals/Item.en.translation b/locals/Item.en.translation index 1c8ae5245b84c7d6c4aac1b1b6a586822361efa6..f16d6d9617920b6cb1672fab2900d03969731584 100644 GIT binary patch delta 149 zcmdnRvWsPdG$X57T5)FnWCcdE`u{+{00eA6%mc)%K&$}7VnECY#nB?~1A$Bi0U#EH zih<zNUahOTLN+1bgdiKKw1WfRe=~}mpl-MGcZiP%9siO DS85fr delta 149 zcmdnRvWsPdG$U)CQJO`@WCcdEdIlh117ZOn{tpDKKw1Ha#ekR*isMghyAG090%A)b zW`c@)Jlp)s2*~DyVg(7=$JRi$3=pdVF-*TC-v>1y7i@Mc}BPT|3JV11Z+Ue1H`OAtN_GfK+Fim(IW2yflLNoD29pW w9XrkH0u*D1VkRIBlKZ)9p&>}EITXiD*Sg^iWUE3k$S!#xE?{7o{DiR<09J7p6#xJL delta 148 zcmaFJ@{nbNG$Tu)Sz_X3c}BN-1|VPqVgVrj4+N}0S^ public partial class Packsack : RigidBody2D, IItem { - public string? Id { get; set; } - public int Quantity { get; set; } - public int MaxStackQuantity { get; set; } - public Texture2D? Icon { get; set; } - public new string? Name { get; set; } - public string? Description { get; set; } - public Action? OnUse { get; set; } - public Func? OnInstantiation { get; set; } + [Export] public string Id { get; protected set; } = "place_holder_id"; + + protected Texture2D? UniqueIcon { get; set; } + public Texture2D Icon => UniqueIcon ?? ItemTypeManager.DefaultIconOf(Id); + + protected string? UniqueName { get; set; } + public new string Name => UniqueName ?? ItemTypeManager.DefaultNameOf(Id); + + protected string? UniqueDescription { get; set; } + public string? Description => UniqueDescription ?? ItemTypeManager.DefaultDescriptionOf(Id); + + public void Use(Node2D? owner, Vector2 targetGlobalPosition) { } + + public void Destroy() + { + if (_itemContainer == null) return; + foreach (var itemSlot in _itemContainer) + { + itemSlot.ClearSlot(); + } + + QueueFree(); + } private IItemContainer? _itemContainer; public override void _Ready() { base._Ready(); - Id = GetMeta("ID", "1").AsString(); - Quantity = GetMeta("Quantity", "1").AsInt32(); - MaxStackQuantity = GetMeta("MaxStackQuantity", Config.MaxStackQuantity).AsInt32(); - Icon = GetMeta("Icon", "").As(); - Name = GetMeta("Name", "").AsString(); - Description = GetMeta("Description", "").AsString(); + // Id = GetMeta("ID", "1").AsString(); + // Quantity = GetMeta("Quantity", "1").AsInt32(); + // MaxStackQuantity = GetMeta("MaxStackQuantity", Config.MaxStackQuantity).AsInt32(); + // Icon = GetMeta("Icon", "").As(); + // Name = GetMeta("Name", "").AsString(); + // Description = GetMeta("Description", "").AsString(); _itemContainer = new UniversalItemContainer(); } diff --git a/scripts/item/ItemTypeManager.cs b/scripts/item/ItemTypeManager.cs index 663d736..c2e116d 100644 --- a/scripts/item/ItemTypeManager.cs +++ b/scripts/item/ItemTypeManager.cs @@ -12,8 +12,15 @@ public static class ItemTypeManager public static void StaticRegister() { var staffOfTheUndeadScene = ResourceLoader.Load("res://prefab/weapons/staffOfTheUndead.tscn"); - var staffOfTheUndead = new ItemType("staff_of_the_undead", () => staffOfTheUndeadScene.Instantiate(), null, 1); + var staffOfTheUndeadIcon = ResourceLoader.Load("res://sprites/weapon/staffOfTheUndead.png"); + var staffOfTheUndead = + new ItemType("staff_of_the_undead", () => staffOfTheUndeadScene.Instantiate(), staffOfTheUndeadIcon, 1); Register(staffOfTheUndead); + + var packsackScene = ResourceLoader.Load("res://prefab/packsacks/packsack.tscn"); + var packsackIcon = ResourceLoader.Load("res://sprites/Player.png"); + var packsack = new ItemType("packsack", () => packsackScene.Instantiate(), packsackIcon, 1); + Register(packsack); } private static Dictionary Registry { get; } = []; diff --git a/scripts/item/weapon/WeaponTemplate.cs b/scripts/item/weapon/WeaponTemplate.cs index e8bd693..b4be423 100644 --- a/scripts/item/weapon/WeaponTemplate.cs +++ b/scripts/item/weapon/WeaponTemplate.cs @@ -20,7 +20,7 @@ public abstract partial class WeaponTemplate : RigidBody2D, IItem //Implements IItem [Export] public virtual string Id { get; private set; } = "ID"; - protected virtual Texture2D? UniqueIcon { get; set; } + protected Texture2D? UniqueIcon { get; set; } public Texture2D Icon => UniqueIcon ?? ItemTypeManager.DefaultIconOf(Id); protected string? UniqueName { get; set; } From dde7bb16caf4e4c581e1db69bfe7d925d2c443c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Thu, 13 Jun 2024 11:14:24 +0800 Subject: [PATCH 14/17] Replace metadata of items with export vars --- prefab/packsacks/packsack.tscn | 5 --- prefab/weapons/staffOfTheUndead.tscn | 9 +---- scripts/item/weapon/ProjectileWeapon.cs | 50 +++++++++++++------------ 3 files changed, 28 insertions(+), 36 deletions(-) diff --git a/prefab/packsacks/packsack.tscn b/prefab/packsacks/packsack.tscn index 9520244..31b1f76 100644 --- a/prefab/packsacks/packsack.tscn +++ b/prefab/packsacks/packsack.tscn @@ -11,11 +11,6 @@ collision_layer = 8 collision_mask = 38 script = ExtResource("1_8ehup") Id = "packsack" -metadata/Id = "Packsack" -metadata/MaxStackQuantity = 1 -metadata/Icon = ExtResource("2_e1ale") -metadata/Name = "packsack" -metadata/Description = "packsack_desc" [node name="Player" type="Sprite2D" parent="."] texture = ExtResource("2_e1ale") diff --git a/prefab/weapons/staffOfTheUndead.tscn b/prefab/weapons/staffOfTheUndead.tscn index 6bd0176..d4732bf 100644 --- a/prefab/weapons/staffOfTheUndead.tscn +++ b/prefab/weapons/staffOfTheUndead.tscn @@ -2,7 +2,7 @@ [ext_resource type="Texture2D" uid="uid://e6670ykyq145" path="res://sprites/weapon/staffOfTheUndead.png" id="1_ms3us"] [ext_resource type="Script" path="res://scripts/item/weapon/ProjectileWeapon.cs" id="1_w8hhv"] -[ext_resource type="Texture2D" uid="uid://b2blj0yf4ohx3" path="res://icon.svg" id="2_l5lni"] +[ext_resource type="PackedScene" uid="uid://c01av43yk1q71" path="res://prefab/projectile/curseOfTheUndead.tscn" id="2_34250"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_obcq2"] size = Vector2(49, 5) @@ -14,14 +14,9 @@ size = Vector2(49, 5.25) collision_layer = 8 collision_mask = 34 script = ExtResource("1_w8hhv") +ProjectileScenes = [ExtResource("2_34250")] Id = "staff_of_the_undead" metadata/Projectiles = PackedStringArray("res://prefab/projectile/curseOfTheUndead.tscn") -metadata/Name = "staff_of_the_undead" -metadata/FiringIntervalArray = PackedInt64Array(5000, 500, 250) -metadata/Icon = ExtResource("2_l5lni") -metadata/ID = "StaffOfTheUndead" -metadata/MaxStackQuantity = 1 -metadata/Description = "staff_of_the_undead_desc" [node name="DamageArea2D" type="Area2D" parent="."] collision_layer = 8 diff --git a/scripts/item/weapon/ProjectileWeapon.cs b/scripts/item/weapon/ProjectileWeapon.cs index afbd3f9..323caa2 100644 --- a/scripts/item/weapon/ProjectileWeapon.cs +++ b/scripts/item/weapon/ProjectileWeapon.cs @@ -24,31 +24,35 @@ public partial class ProjectileWeapon : WeaponTemplate /// private Marker2D? _marker2D; - /// - /// List of projectiles - /// 抛射体列表 - /// - private string[]? _projectiles; + // /// + // /// List of projectiles + // /// 抛射体列表 + // /// + // private string[]? _projectiles; + // + // private Dictionary? _projectileCache; + + [Export] protected PackedScene[] ProjectileScenes { get; set; } = []; - private Dictionary? _projectileCache; private Node2D? _projectileContainer; public override void _Ready() { base._Ready(); _marker2D = GetNode("Marker2D"); - _projectileCache = new Dictionary(); - _projectiles = GetMeta("Projectiles", "").AsStringArray(); - foreach (var projectileItem in _projectiles) - { - var packedScene = GD.Load(projectileItem); - if (packedScene == null) - { - continue; - } - _projectileCache.Add(projectileItem, packedScene); - } + // _projectileCache = new Dictionary(); + // _projectiles = GetMeta("Projectiles", "").AsStringArray(); + // foreach (var projectileItem in _projectiles) + // { + // var packedScene = GD.Load(projectileItem); + // if (packedScene == null) + // { + // continue; + // } + // + // _projectileCache.Add(projectileItem, packedScene); + // } _projectileContainer = GetNode("/root/Game/ProjectileContainer") as Node2D; } @@ -56,13 +60,10 @@ public partial class ProjectileWeapon : WeaponTemplate protected override void DoFire(Node2D? owner, Vector2 enemyGlobalPosition) { - if (_projectileCache == null || _projectiles == null || owner == null || _projectileContainer == null || - _marker2D == null) - { - return; - } + if (owner == null || _projectileContainer == null || _marker2D == null) return; - if (_projectiles.IsEmpty()) + //空列表检查 + if (ProjectileScenes is []) { LogCat.LogError("projectiles_is_empty"); return; @@ -70,7 +71,8 @@ public partial class ProjectileWeapon : WeaponTemplate //Get the first projectile //获取第一个抛射体 - var projectileScene = _projectileCache[_projectiles[0]]; + var projectileScene = ProjectileScenes[0]; + // var projectileScene = _projectileCache[_projectiles[0]]; var projectile = NodeUtils.InstantiatePackedScene(projectileScene, _projectileContainer); if (projectile == null) return; projectile.Owner = owner; From 229098b2619449102ee609d1a3a9484ef8a7a49d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Thu, 13 Jun 2024 13:53:10 +0800 Subject: [PATCH 15/17] Added all basic item stacks; Move item stacks to new namespace --- scripts/inventory/IItemContainer.cs | 1 + scripts/inventory/ItemSlotNode.cs | 3 +- scripts/inventory/Packsack.cs | 2 + scripts/inventory/UniversalItemContainer.cs | 1 + scripts/item/ICommonItem.cs | 28 ++++ scripts/item/IItem.cs | 41 +++++- scripts/item/itemStacks/CommonItemStack.cs | 89 +++++++++++++ scripts/item/{ => itemStacks}/IItemStack.cs | 27 ++-- .../item/{ => itemStacks}/SingleItemStack.cs | 32 +++-- scripts/item/itemStacks/UniqueItemStack.cs | 123 ++++++++++++++++++ scripts/item/weapon/WeaponTemplate.cs | 2 + 11 files changed, 317 insertions(+), 32 deletions(-) create mode 100644 scripts/item/ICommonItem.cs create mode 100644 scripts/item/itemStacks/CommonItemStack.cs rename scripts/item/{ => itemStacks}/IItemStack.cs (89%) rename scripts/item/{ => itemStacks}/SingleItemStack.cs (57%) create mode 100644 scripts/item/itemStacks/UniqueItemStack.cs diff --git a/scripts/inventory/IItemContainer.cs b/scripts/inventory/IItemContainer.cs index 5adcedb..d68cab5 100644 --- a/scripts/inventory/IItemContainer.cs +++ b/scripts/inventory/IItemContainer.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Collections.Generic; using ColdMint.scripts.item; +using ColdMint.scripts.item.itemStacks; using Godot; diff --git a/scripts/inventory/ItemSlotNode.cs b/scripts/inventory/ItemSlotNode.cs index f6b27d4..4cf060b 100644 --- a/scripts/inventory/ItemSlotNode.cs +++ b/scripts/inventory/ItemSlotNode.cs @@ -1,4 +1,5 @@ using ColdMint.scripts.item; +using ColdMint.scripts.item.itemStacks; using ColdMint.scripts.utils; using Godot; @@ -256,7 +257,7 @@ public partial class ItemSlotNode : MarginContainer var debugText = TranslationServerUtils.Translate("item_prompt_debug"); if (debugText != null) { - _control.TooltipText = string.Format(debugText, _itemStack.Id, + _control.TooltipText = string.Format(debugText, _itemStack.GetItem()?.Id, TranslationServerUtils.Translate(_itemStack.Name), _itemStack.Quantity, _itemStack.MaxQuantity, _itemStack.GetType().Name, TranslationServerUtils.Translate(_itemStack.Description)); diff --git a/scripts/inventory/Packsack.cs b/scripts/inventory/Packsack.cs index bd517da..3e2a42b 100644 --- a/scripts/inventory/Packsack.cs +++ b/scripts/inventory/Packsack.cs @@ -37,6 +37,8 @@ public partial class Packsack : RigidBody2D, IItem QueueFree(); } + public bool CanStackWith(IItem item) => false; + private IItemContainer? _itemContainer; public override void _Ready() diff --git a/scripts/inventory/UniversalItemContainer.cs b/scripts/inventory/UniversalItemContainer.cs index 998cda1..da798f7 100644 --- a/scripts/inventory/UniversalItemContainer.cs +++ b/scripts/inventory/UniversalItemContainer.cs @@ -6,6 +6,7 @@ using System.Linq; using ColdMint.scripts.character; using ColdMint.scripts.debug; using ColdMint.scripts.item; +using ColdMint.scripts.item.itemStacks; using ColdMint.scripts.utils; using Godot; diff --git a/scripts/item/ICommonItem.cs b/scripts/item/ICommonItem.cs new file mode 100644 index 0000000..4f50c0e --- /dev/null +++ b/scripts/item/ICommonItem.cs @@ -0,0 +1,28 @@ +using ColdMint.scripts.item.itemStacks; + +namespace ColdMint.scripts.item; + +/// +/// Special item interface that make item common, which means will stack in a +/// 该特殊的物品接口使得物品成为平凡物品,换言之,将会堆叠在中。 +/// +/// +/// Make this the class itself +/// 应当为当前类自身 +/// +/// +/// +/// Notice when you implement: To avoid unexpected behavior, unless you understand what you're doing, the method +/// of an item that implements the interface must only match its own exact same instance. +/// +/// 实现时注意:为避免意外行为,除非你明白自己在做什么,否则实现接口的物品的方法必须只和自己完全相同的实例匹配。 +/// +public interface ICommonItem : IItem +{ + /// + /// Method to copy an instance same with self. Will be used to pick out item instance from a + /// 复制与自身相同的实例的方法。将用于从 中拿取新的物品实例。 + /// + /// + ICommonItem CopyInstance(); +} \ No newline at end of file diff --git a/scripts/item/IItem.cs b/scripts/item/IItem.cs index 8c9efc5..fe49c47 100644 --- a/scripts/item/IItem.cs +++ b/scripts/item/IItem.cs @@ -1,4 +1,6 @@ -using Godot; +using ColdMint.scripts.item.itemStacks; + +using Godot; namespace ColdMint.scripts.item; @@ -32,4 +34,41 @@ public interface IItem /// Execute when current item be removed from game. /// void Destroy(); + + /// + /// Return true if this item can be stacked with the given item in one stack + /// 若该物品是否能与给定物品堆叠在同一个物品堆上,返回true + /// + /// + /// + /// ! Note in the implementation: the correspondence of this predicate must be an equivalence relation over the full set of stackable items + /// (i.e., be able to derive a division into the full set of stackable items).
+ /// Or if the item is not stackable, make it always return false. + ///
+ /// + /// !实现时注意:该谓词的对应关系必须是在全部可堆叠的物品集合上的等价关系(即能导出一个对可堆叠物品全集的划分)。
+ /// 或如果该物品不可堆叠,令其永远返回false。
+ ///
+ /// + /// If it is necessary to implement special stacking relationships (e.g. containers that can be stacked to hold items), + /// customize the special type, implement the special stacking determination in it by overriding , + /// and override the method so that it returns an instance of that custom ItemStack. + /// + /// + /// 如果有必要实现特殊的堆叠关系(如可以用堆叠来收纳物品的容器),请自定义特殊的类型,在其中重写以实现特殊的堆叠判定, + /// 并重写方法使其返回该自定义ItemStack实例。 + /// + ///
+ bool CanStackWith(IItem item); + + /// + /// If this item need a special stack type, return the special item stack instance that contains the item. If else, just leave this null. + /// 如果该项目需要特殊的物品堆类型,重写此方法来返回包含该物品的特殊物品堆实例。否则,保留原本的null返回值。 + /// + /// + /// DO NOT use this method to create stack from item, use instead + /// **不要**使用此方法从一个物品创建堆,请使用 。 + /// + /// + IItemStack? SpecialStack() => null; } \ No newline at end of file diff --git a/scripts/item/itemStacks/CommonItemStack.cs b/scripts/item/itemStacks/CommonItemStack.cs new file mode 100644 index 0000000..443790e --- /dev/null +++ b/scripts/item/itemStacks/CommonItemStack.cs @@ -0,0 +1,89 @@ +using System; + +using Godot; + +namespace ColdMint.scripts.item.itemStacks; + +/// +/// +/// one of the basic item stacks, where there is only one instance of an item actually held in the stack, +/// meaning that all items are identical (or completely random in some ways) +/// +/// 平凡物品堆,基础物品堆之一,堆中实际保存的物品实例仅有一个,意味着所有物品都完全一致(或某些方面完全随机) +/// +/// +/// +public class CommonItemStack(ICommonItem innerItem) : IItemStack +{ + public int MaxQuantity { get; } = ItemTypeManager.MaxStackQuantityOf(innerItem.Id); + public int Quantity { get; private set; } = 1; + public bool Empty => Quantity == 0; + public Texture2D Icon => innerItem.Icon; + public string Name => $"{innerItem.Name}({Quantity})"; + public string? Description => innerItem.Description; + + public bool CanAddItem(IItem item1) + { + return innerItem.CanStackWith(item1) && (Quantity < MaxQuantity); + } + + public bool AddItem(IItem item) + { + if (!CanAddItem(item)) return false; + Quantity++; + return true; + } + + public int CanTakeFrom(IItemStack itemStack) + { + if (itemStack.Empty || !innerItem.CanStackWith(itemStack.GetItem()!)) return 0; + return Math.Min(itemStack.Quantity, MaxQuantity - Quantity); + } + + public bool TakeFrom(IItemStack itemStack) + { + var number = CanTakeFrom(itemStack); + itemStack.RemoveItem(number); + Quantity += number; + return itemStack.Empty; + } + + public IItem? GetItem() + { + return Empty ? null : innerItem; + } + + public IItem? PickItem() + { + if (Empty) return null; + Quantity--; + if (Empty) innerItem.Destroy(); + return innerItem.CopyInstance(); + } + + public IItemStack? PickItems(int value) + { + if (Empty) return null; + var result = new CommonItemStack(innerItem.CopyInstance()); + var n = Math.Min(Quantity, value); + result.Quantity = n; + Quantity -= n; + if (Empty) innerItem.Destroy(); + return result; + } + + public int RemoveItem(int number) + { + var n = Math.Min(number, Quantity); + Quantity -= n; + if (Empty) innerItem.Destroy(); + return number - n; + } + + public void ClearStack() + { + if (Empty) return; + Quantity = 0; + innerItem.Destroy(); + } +} \ No newline at end of file diff --git a/scripts/item/IItemStack.cs b/scripts/item/itemStacks/IItemStack.cs similarity index 89% rename from scripts/item/IItemStack.cs rename to scripts/item/itemStacks/IItemStack.cs index e5ab606..8e77872 100644 --- a/scripts/item/IItemStack.cs +++ b/scripts/item/itemStacks/IItemStack.cs @@ -1,20 +1,14 @@ using System; -using System.Diagnostics.CodeAnalysis; using Godot; -namespace ColdMint.scripts.item; +namespace ColdMint.scripts.item.itemStacks; /// /// Item stack in an inventory slot /// public interface IItemStack { - /// - /// ID of items inside current stack - /// - string Id { get; } - /// /// Max number of current stack /// @@ -25,6 +19,11 @@ public interface IItemStack ///
int Quantity { get; } + /// + /// True if this stack is empty + /// + bool Empty { get; } + /// /// Icon of current item /// @@ -134,10 +133,12 @@ public interface IItemStack /// /// Create a new ItemStack with the given item as the first item /// - public static IItemStack FromItem(IItem item) => ItemTypeManager.MaxStackQuantityOf(item.Id) switch - { - 1 => new SingleItemStack(item), - > 1 => throw new NotImplementedException(), - var other => throw new ArgumentException($"item {item} of type '{item.Id}' has unexpected max stack quantity {other}") - }; + public static IItemStack FromItem(IItem item) => + item.SpecialStack() ?? + ItemTypeManager.MaxStackQuantityOf(item.Id) switch + { + 1 => new SingleItemStack(item), + > 1 => item is ICommonItem commonItem ? new CommonItemStack(commonItem) : new UniqueItemStack(item), + var other => throw new ArgumentException($"item {item} of type '{item.Id}' has unexpected max stack quantity {other}") + }; } \ No newline at end of file diff --git a/scripts/item/SingleItemStack.cs b/scripts/item/itemStacks/SingleItemStack.cs similarity index 57% rename from scripts/item/SingleItemStack.cs rename to scripts/item/itemStacks/SingleItemStack.cs index a384172..61fc628 100644 --- a/scripts/item/SingleItemStack.cs +++ b/scripts/item/itemStacks/SingleItemStack.cs @@ -1,22 +1,21 @@ using System; -using ColdMint.scripts.inventory; - using Godot; -namespace ColdMint.scripts.item; +namespace ColdMint.scripts.item.itemStacks; /// -/// Item stack of single item +/// One of the basic item stacks, there are always one item in stack +/// 单身狗物品堆,基础物品堆之一,堆中永远只会有一个物品 /// -//maybe we'd move this into inventory namespace +/// public class SingleItemStack(IItem item) : IItemStack { public IItem Item { get; init; } = item; - public string Id => Item.Id; public int MaxQuantity => 1; - public int Quantity { get; set; } = 1; + public int Quantity => 1; + public bool Empty { get; private set; } = false; public Texture2D Icon => Item.Icon; public string Name => Item.Name; public string? Description => Item.Description; @@ -31,29 +30,28 @@ public class SingleItemStack(IItem item) : IItemStack public IItem? GetItem() { - return Quantity == 1 ? Item : null; + return Empty ? null : Item; } public IItem? PickItem() { - Quantity = 0; + if (Empty) return null; + Empty = true; return Item; } public IItemStack? PickItems(int value) { - if (value == 0) return null; - else - { - Quantity = 0; - return new SingleItemStack(Item); - } + if (value == 0 || Empty) return null; + + Empty = true; + return new SingleItemStack(Item); } public int RemoveItem(int number) { - if (number == 0) return 0; - Quantity = 0; + if (number == 0 || Empty) return 0; + Empty = true; Item.Destroy(); return Math.Max(number - 1, 0); } diff --git a/scripts/item/itemStacks/UniqueItemStack.cs b/scripts/item/itemStacks/UniqueItemStack.cs new file mode 100644 index 0000000..7f9af3f --- /dev/null +++ b/scripts/item/itemStacks/UniqueItemStack.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Godot; + +namespace ColdMint.scripts.item.itemStacks; + +/// +/// One of the basic item stacks, where each item in the stack maintains its original state (allowing for items that are not identical to each other) +/// 独特物品堆,基础物品堆之一,堆中的每一个物品会保持各自原本的状态(允许互不相同的物品存在) +/// +/// +public class UniqueItemStack : IItemStack +{ + private readonly Stack _items; + + public UniqueItemStack(IItem item) + { + _items = []; + _items.Push(item); + MaxQuantity = ItemTypeManager.MaxStackQuantityOf(item.Id); + } + + private UniqueItemStack(UniqueItemStack from) + { + _items = from._items; + MaxQuantity = from.MaxQuantity; + Quantity = from.Quantity; + from.Quantity = 0; + } + + public int MaxQuantity { get; } + public int Quantity { get; private set; } = 1; + public bool Empty => Quantity == 0; + public Texture2D Icon => GetItem()?.Icon ?? new PlaceholderTexture2D(); + public string Name => $"{GetItem()?.Name}({Quantity})"; + public string? Description => GetItem()?.Description; + + public bool CanAddItem(IItem item) + { + //当两个物品相容,且当前堆未满时,我们返回true + return (GetItem()?.CanStackWith(item) ?? false) && (Quantity < MaxQuantity); + } + + public bool AddItem(IItem item) + { + if (!CanAddItem(item)) return false; + _items.Push(item); + Quantity++; + return true; + } + + public int CanTakeFrom(IItemStack itemStack) + { + if (!(itemStack.GetItem() is { } item)) return 0; + //如果两个物品相容,那么可以获取的数量取决于当前物品堆空位的大小和对方物品数量中较小的一方 + if (CanAddItem(item)) + return Mathf.Min(itemStack.Quantity, MaxQuantity - Quantity); + else return 0; + } + + public bool TakeFrom(IItemStack itemStack) + { + var value = CanTakeFrom(itemStack); + for (int i = 0; i < value; i++) + { + //一个如果代码没有出错就用不到的安全检查 + if (!AddItem(itemStack.PickItem()!)) break; + } + + return itemStack.Empty; + } + + public IItem? GetItem() + { + return Empty ? null : _items.Peek(); + } + + public IItem? PickItem() + { + if (Empty) return null; + Quantity--; + return _items.Pop(); + } + + public IItemStack? PickItems(int value) + { + if (Empty) return null; + + if (value < 0) value = Quantity; + + var result = new UniqueItemStack(PickItem()!); + //计算剩余的要取出的数量 + var restToMove = Math.Min(value - 1, Quantity); + for (int i = 0; i < restToMove; i++) + { + result.AddItem(PickItem()!); + } + + return result; + } + + public int RemoveItem(int number) + { + if (number < 0) number = Quantity; + while (number > 0 && Quantity > 0) + { + PickItem()!.Destroy(); + number--; + } + + return number; + } + + public void ClearStack() + { + while (Quantity > 0) + { + PickItem()!.Destroy(); + } + } +} \ No newline at end of file diff --git a/scripts/item/weapon/WeaponTemplate.cs b/scripts/item/weapon/WeaponTemplate.cs index b4be423..d934fd7 100644 --- a/scripts/item/weapon/WeaponTemplate.cs +++ b/scripts/item/weapon/WeaponTemplate.cs @@ -40,6 +40,8 @@ public abstract partial class WeaponTemplate : RigidBody2D, IItem QueueFree(); } + public bool CanStackWith(IItem item) => false; + /// /// Whether the weapon is currently picked up From 9561b46e1baba9786457189d423d0d9611ec9f2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Thu, 13 Jun 2024 14:13:55 +0800 Subject: [PATCH 16/17] Clean up the code and fill in the comments --- scripts/inventory/Packsack.cs | 6 ------ scripts/item/ItemType.cs | 4 ++++ scripts/item/ItemTypeManager.cs | 4 +++- scripts/item/itemStacks/IItemStack.cs | 25 ++++++++++++++++++++----- scripts/item/weapon/ProjectileWeapon.cs | 21 --------------------- scripts/item/weapon/WeaponTemplate.cs | 11 ----------- 6 files changed, 27 insertions(+), 44 deletions(-) diff --git a/scripts/inventory/Packsack.cs b/scripts/inventory/Packsack.cs index 3e2a42b..99b61a1 100644 --- a/scripts/inventory/Packsack.cs +++ b/scripts/inventory/Packsack.cs @@ -44,12 +44,6 @@ public partial class Packsack : RigidBody2D, IItem public override void _Ready() { base._Ready(); - // Id = GetMeta("ID", "1").AsString(); - // Quantity = GetMeta("Quantity", "1").AsInt32(); - // MaxStackQuantity = GetMeta("MaxStackQuantity", Config.MaxStackQuantity).AsInt32(); - // Icon = GetMeta("Icon", "").As(); - // Name = GetMeta("Name", "").AsString(); - // Description = GetMeta("Description", "").AsString(); _itemContainer = new UniversalItemContainer(); } diff --git a/scripts/item/ItemType.cs b/scripts/item/ItemType.cs index d12b93a..01ac9b8 100644 --- a/scripts/item/ItemType.cs +++ b/scripts/item/ItemType.cs @@ -8,18 +8,22 @@ public readonly struct ItemType(string id, Func newItemFunc, Texture2D? i { /// /// Item id of this type + /// 该类型物品的id /// public string Id { get; init; } = id; /// /// A function returns a new item instance of this type + /// 用于创建该类型的物品实例的函数 /// public Func NewItemFunc { get; init; } = newItemFunc; /// /// Default icon of items of this type + /// 该类型物品的默认图标 /// public Texture2D? Icon { get; init; } = icon; /// /// Max number in item stack of this type + /// 该类型物品的最大堆叠数量 /// public int MaxStackQuantity { get; init; } = maxStackQuantity; } \ No newline at end of file diff --git a/scripts/item/ItemTypeManager.cs b/scripts/item/ItemTypeManager.cs index c2e116d..4d35cfa 100644 --- a/scripts/item/ItemTypeManager.cs +++ b/scripts/item/ItemTypeManager.cs @@ -8,7 +8,9 @@ namespace ColdMint.scripts.item; public static class ItemTypeManager { - // Register items statically here + /// + /// Register items statically here + /// public static void StaticRegister() { var staffOfTheUndeadScene = ResourceLoader.Load("res://prefab/weapons/staffOfTheUndead.tscn"); diff --git a/scripts/item/itemStacks/IItemStack.cs b/scripts/item/itemStacks/IItemStack.cs index 8e77872..34d8fce 100644 --- a/scripts/item/itemStacks/IItemStack.cs +++ b/scripts/item/itemStacks/IItemStack.cs @@ -11,31 +11,44 @@ public interface IItemStack { /// /// Max number of current stack + /// 当前物品堆的最大物品数量 /// int MaxQuantity { get; } /// /// Quantity of current stack + /// 当前物品堆的物品数量 /// int Quantity { get; } /// /// True if this stack is empty + /// 当物品堆空时为真 /// + /// + /// + /// This attribute is used to check if the item stack is empty after the operation for subsequent processing,
+ /// i.e. there should not be any item stacks with this attribute true outside of the operation process + ///
+ /// 此属性用于检查操作后该物品堆是否为空以便后续处理,也就是说在操作过程以外的时候不应当存在任何该属性为true的物品堆 + ///
bool Empty { get; } /// - /// Icon of current item + /// Icon of current item stack + /// 当前物品堆显示的图标 /// Texture2D Icon { get; } /// - /// Display name of current item + /// Display name of current item stack + /// 当前物品堆显示的名称 /// string Name { get; } /// - /// Description of current item, which may show in inventory + /// Description of current item stack, which may show in inventory + /// 当前物品堆的描述,可能显示在物品栏中 /// string? Description { get; } @@ -126,12 +139,14 @@ public interface IItemStack public int RemoveItem(int number); /// - /// Clear current stack, which means should dispose all items inside current stack here + /// Clear current stack, which means should remove all items inside current stack from the game here + /// 清除当前物品堆,意味着从游戏中移除当前堆中的所有物品。 /// public void ClearStack(); /// - /// Create a new ItemStack with the given item as the first item + /// Create a new ItemStack with the given item as the first item + /// 以给定的物品为第一个物品创建物品堆 /// public static IItemStack FromItem(IItem item) => item.SpecialStack() ?? diff --git a/scripts/item/weapon/ProjectileWeapon.cs b/scripts/item/weapon/ProjectileWeapon.cs index 323caa2..a8394e0 100644 --- a/scripts/item/weapon/ProjectileWeapon.cs +++ b/scripts/item/weapon/ProjectileWeapon.cs @@ -24,14 +24,6 @@ public partial class ProjectileWeapon : WeaponTemplate ///
private Marker2D? _marker2D; - // /// - // /// List of projectiles - // /// 抛射体列表 - // /// - // private string[]? _projectiles; - // - // private Dictionary? _projectileCache; - [Export] protected PackedScene[] ProjectileScenes { get; set; } = []; private Node2D? _projectileContainer; @@ -41,19 +33,6 @@ public partial class ProjectileWeapon : WeaponTemplate base._Ready(); _marker2D = GetNode("Marker2D"); - // _projectileCache = new Dictionary(); - // _projectiles = GetMeta("Projectiles", "").AsStringArray(); - // foreach (var projectileItem in _projectiles) - // { - // var packedScene = GD.Load(projectileItem); - // if (packedScene == null) - // { - // continue; - // } - // - // _projectileCache.Add(projectileItem, packedScene); - // } - _projectileContainer = GetNode("/root/Game/ProjectileContainer") as Node2D; } diff --git a/scripts/item/weapon/WeaponTemplate.cs b/scripts/item/weapon/WeaponTemplate.cs index d934fd7..77759f1 100644 --- a/scripts/item/weapon/WeaponTemplate.cs +++ b/scripts/item/weapon/WeaponTemplate.cs @@ -104,17 +104,6 @@ public abstract partial class WeaponTemplate : RigidBody2D, IItem _damageArea2D.BodyEntered += OnBodyEnter; _damageArea2D.BodyExited += OnBodyExited; - // Id = GetMeta("ID", "1").AsString(); - // Quantity = GetMeta("Quantity", "1").AsInt32(); - // MaxStackQuantity = GetMeta("MaxStackQuantity", Config.MaxStackQuantity).AsInt32(); - // Icon = GetMeta("Icon", "").As(); - // Name = GetMeta("Name", "").AsString(); - // Description = GetMeta("Description", "").AsString(); - // _firingInterval = TimeSpan.FromMilliseconds(GetMeta("FiringInterval", "100").AsInt64()); - // _minContactInjury = GetMeta("MinContactInjury", "1").AsInt32(); - // _maxContactInjury = GetMeta("MaxContactInjury", "2").AsInt32(); - // _recoil = GetMeta("Recoil", Vector2.Zero).AsVector2(); - _firingInterval = TimeSpan.FromMilliseconds(_firingIntervalAsMillisecond); } From 662e9b136a724127dc06236711fec87cc691c2d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Thu, 13 Jun 2024 14:18:11 +0800 Subject: [PATCH 17/17] move Packsack.cs to item namespace --- prefab/packsacks/packsack.tscn | 5 ++--- scripts/{inventory => item}/Packsack.cs | 7 ++----- scripts/utils/NodeUtils.cs | 2 ++ 3 files changed, 6 insertions(+), 8 deletions(-) rename scripts/{inventory => item}/Packsack.cs (91%) diff --git a/prefab/packsacks/packsack.tscn b/prefab/packsacks/packsack.tscn index 31b1f76..a6ec43c 100644 --- a/prefab/packsacks/packsack.tscn +++ b/prefab/packsacks/packsack.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=4 format=3 uid="uid://cn10fimoem04m"] -[ext_resource type="Script" path="res://scripts/inventory/Packsack.cs" id="1_8ehup"] +[ext_resource type="Script" path="res://scripts/item/Packsack.cs" id="1_slakl"] [ext_resource type="Texture2D" uid="uid://b1twcink38sh0" path="res://sprites/Player.png" id="2_e1ale"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_xqyue"] @@ -9,8 +9,7 @@ size = Vector2(41, 57) [node name="RigidBody2D" type="RigidBody2D"] collision_layer = 8 collision_mask = 38 -script = ExtResource("1_8ehup") -Id = "packsack" +script = ExtResource("1_slakl") [node name="Player" type="Sprite2D" parent="."] texture = ExtResource("2_e1ale") diff --git a/scripts/inventory/Packsack.cs b/scripts/item/Packsack.cs similarity index 91% rename from scripts/inventory/Packsack.cs rename to scripts/item/Packsack.cs index 99b61a1..1afc8b0 100644 --- a/scripts/inventory/Packsack.cs +++ b/scripts/item/Packsack.cs @@ -1,11 +1,8 @@ -using System; - -using ColdMint.scripts.debug; -using ColdMint.scripts.item; +using ColdMint.scripts.inventory; using Godot; -namespace ColdMint.scripts.inventory; +namespace ColdMint.scripts.item; /// /// packsack diff --git a/scripts/utils/NodeUtils.cs b/scripts/utils/NodeUtils.cs index e109d13..0a3f37d 100644 --- a/scripts/utils/NodeUtils.cs +++ b/scripts/utils/NodeUtils.cs @@ -6,6 +6,8 @@ using ColdMint.scripts.inventory; using ColdMint.scripts.item.weapon; using Godot; +using Packsack = ColdMint.scripts.item.Packsack; + namespace ColdMint.scripts.utils; ///