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