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