diff --git a/data/itemRegs/weapons.yaml b/data/itemRegs/weapons.yaml
index a49d222..784ffc6 100644
--- a/data/itemRegs/weapons.yaml
+++ b/data/itemRegs/weapons.yaml
@@ -14,4 +14,8 @@
- id: staff_necromancy
scene_path: res://prefab/weapons/StaffNecromancy.tscn
icon_path: res://sprites/weapon/StaffNecromancy_Icon.png
+ max_stack_value: 1
+- id: iron_axe
+ scene_path: res://prefab/weapons/IronAxe.tscn
+ icon_path: res://sprites/weapon/StaffNecromancy_Icon.png
max_stack_value: 1
\ No newline at end of file
diff --git a/locals/Item.csv b/locals/Item.csv
index 4d2ca1c..8e4b9f3 100644
--- a/locals/Item.csv
+++ b/locals/Item.csv
@@ -8,4 +8,6 @@ item_necromancy_desc,法术的实体化弹丸。,The materialized projectile of
item_x3,三重射击法术,Triple shot spell,三重射撃術です
item_x3_desc,使发射器一次射出三颗弹丸。,Make the launcher shoot three pellets at a time.,発射機から一度に三つの弾丸を発射させます。
item_resignation_certificate,离职证明,Resignation certificate,退職証明書です
-item_resignation_certificate_desc,冷薄荷,感谢您在职时为公司做出的贡献。,"Cold Mint, thank you for your service to the company.",コールドミント、現役時代のご貢献ありがとうございました。
\ No newline at end of file
+item_resignation_certificate_desc,冷薄荷,感谢您在职时为公司做出的贡献。,"Cold Mint, thank you for your service to the company.",コールドミント、現役時代のご貢献ありがとうございました。
+item_iron_axe,铁斧子,Iron axe,鉄の斧です
+item_iron_axe_desc,铁斧子,Iron axe,鉄の斧です
\ No newline at end of file
diff --git a/prefab/roomTemplates/dungeon/initialRoom.tscn b/prefab/roomTemplates/dungeon/initialRoom.tscn
index 96e74bc..8b471e0 100644
--- a/prefab/roomTemplates/dungeon/initialRoom.tscn
+++ b/prefab/roomTemplates/dungeon/initialRoom.tscn
@@ -62,7 +62,7 @@ ItemId = "necromancy"
[node name="ItemMarker2D5" type="Marker2D" parent="."]
position = Vector2(381, 136)
script = ExtResource("3_v1tlc")
-ItemId = "resignation_certificate"
+ItemId = "iron_axe"
[node name="NavigationRegion2D" type="NavigationRegion2D" parent="."]
navigation_polygon = SubResource("NavigationPolygon_064c7")
diff --git a/prefab/weapons/IronAxe.tscn b/prefab/weapons/IronAxe.tscn
new file mode 100644
index 0000000..f17afba
--- /dev/null
+++ b/prefab/weapons/IronAxe.tscn
@@ -0,0 +1,57 @@
+[gd_scene load_steps=7 format=3 uid="uid://g1jrthe4ojdd"]
+
+[ext_resource type="Script" path="res://scripts/weapon/MeleeWeapon.cs" id="1_snmy1"]
+[ext_resource type="Texture2D" uid="uid://wt50kx6bup51" path="res://sprites/weapon/StaffNecromancy.png" id="3_cm7e6"]
+[ext_resource type="AudioStream" uid="uid://cak6chjjsu7wo" path="res://sounds/fire.wav" id="4_qimud"]
+
+[sub_resource type="RectangleShape2D" id="RectangleShape2D_obcq2"]
+size = Vector2(49, 5)
+
+[sub_resource type="RectangleShape2D" id="RectangleShape2D_14m1g"]
+size = Vector2(49, 5.25)
+
+[sub_resource type="RectangleShape2D" id="RectangleShape2D_2u0n7"]
+size = Vector2(102, 94)
+
+[node name="IronAxe" type="RigidBody2D"]
+collision_layer = 8
+collision_mask = 34
+angular_damp = -1.0
+script = ExtResource("1_snmy1")
+
+[node name="DamageArea2D" type="Area2D" parent="."]
+collision_layer = 8
+collision_mask = 102
+
+[node name="CollisionShape2D" type="CollisionShape2D" parent="DamageArea2D"]
+position = Vector2(25.5, 0.5)
+shape = SubResource("RectangleShape2D_obcq2")
+
+[node name="StaffOfTheUndead2" type="Sprite2D" parent="."]
+position = Vector2(30, 0)
+texture = ExtResource("3_cm7e6")
+
+[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
+position = Vector2(25.5, 0.375)
+shape = SubResource("RectangleShape2D_14m1g")
+
+[node name="Marker2D" type="Marker2D" parent="."]
+position = Vector2(65, 0)
+
+[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="Marker2D"]
+stream = ExtResource("4_qimud")
+bus = &"SoundEffect"
+
+[node name="TipLabel" type="Label" parent="."]
+offset_left = 6.0
+offset_top = 48.0
+offset_right = 46.0
+offset_bottom = 73.0
+
+[node name="WeaponDamageArea" type="Area2D" parent="."]
+collision_layer = 512
+collision_mask = 0
+
+[node name="CollisionShape2D" type="CollisionShape2D" parent="WeaponDamageArea"]
+position = Vector2(127, 1)
+shape = SubResource("RectangleShape2D_2u0n7")
diff --git a/project.godot b/project.godot
index 84becd8..ca91971 100644
--- a/project.godot
+++ b/project.godot
@@ -168,6 +168,7 @@ locale/translations=PackedStringArray("res://locals/DeathInfo.en.translation", "
2d_physics/layer_7="Mob"
2d_physics/layer_8="Wall"
2d_physics/layer_9="Furniture"
+2d_physics/layer_10="WeaponDamageArea"
[physics]
diff --git a/scripts/Config.cs b/scripts/Config.cs
index 47d1e3b..d808c10 100644
--- a/scripts/Config.cs
+++ b/scripts/Config.cs
@@ -241,7 +241,7 @@ public static class Config
///用于远程武器内的特殊物品类型
///
public const int Spell = 4;
-
+
///
/// Common item types
/// 普通的物品类型
@@ -578,6 +578,11 @@ public static class Config
/// 家具
///
public const int Furniture = 9;
+ ///
+ /// WeaponDamageArea
+ /// 武器伤害区域
+ ///
+ public const int WeaponDamageArea = 10;
}
///
diff --git a/scripts/debug/LogCat.cs b/scripts/debug/LogCat.cs
index 5907d05..21a0361 100644
--- a/scripts/debug/LogCat.cs
+++ b/scripts/debug/LogCat.cs
@@ -88,12 +88,18 @@ public static class LogCat
/// 房间
///
public const string Room = "Room";
-
+
///
/// ItemSpawn
/// 物品生成器
///
public const string ItemSpawn = "ItemSpawn";
+
+ ///
+ /// MeleeWeapon
+ /// 近战武器
+ ///
+ public const string MeleeWeapon = "MeleeWeapon";
}
diff --git a/scripts/weapon/MeleeWeapon.cs b/scripts/weapon/MeleeWeapon.cs
new file mode 100644
index 0000000..54f7508
--- /dev/null
+++ b/scripts/weapon/MeleeWeapon.cs
@@ -0,0 +1,115 @@
+using System.Collections.Generic;
+using ColdMint.scripts.character;
+using ColdMint.scripts.damage;
+using ColdMint.scripts.debug;
+using Godot;
+
+namespace ColdMint.scripts.weapon;
+
+///
+/// MeleeWeapon
+/// 近战武器
+///
+public partial class MeleeWeapon : WeaponTemplate
+{
+
+ ///
+ /// The damage area of the weapon
+ /// 武器的伤害区域
+ ///
+ private Area2D? _weaponDamageArea;
+
+ [Export]
+ private int _maxDamage = 1;
+ [Export]
+ private int _minDamage = 1;
+ private DamageTemplate? _damageTemplate;
+
+ private readonly List _characterTemplates =
+ [
+ ];
+ public override void _Ready()
+ {
+ base._Ready();
+ LogCat.Log("ready", LogCat.LogLabel.MeleeWeapon);
+ _weaponDamageArea = GetNode("WeaponDamageArea");
+ _weaponDamageArea.InputPickable = false;
+ _weaponDamageArea.SetCollisionMaskValue(Config.LayerNumber.Player, true);
+ _weaponDamageArea.SetCollisionMaskValue(Config.LayerNumber.Mob, true);
+ _weaponDamageArea.Monitoring = true;
+ _weaponDamageArea.BodyEntered += OnBodyEntered;
+ _weaponDamageArea.BodyExited += OnBodyExited;
+ _weaponDamageArea.AreaEntered += AreaEntered;
+ _weaponDamageArea.AreaExited += AreaExited;
+ _damageTemplate = new Damage();
+ _damageTemplate.MaxDamage = _maxDamage;
+ _damageTemplate.MinDamage = _minDamage;
+ _damageTemplate.Type = Config.DamageType.Physical;
+ LogCat.Log("success", LogCat.LogLabel.MeleeWeapon);
+ }
+
+ private void AreaExited(Node2D node2D)
+ {
+ LogCat.Log("AreaExited" + node2D.Name, LogCat.LogLabel.MeleeWeapon);
+
+ }
+
+ private void AreaEntered(Node2D node2D)
+ {
+ LogCat.Log("AreaEntered" + node2D.Name, LogCat.LogLabel.MeleeWeapon);
+
+ }
+ ///
+ /// OnBodyEntered
+ /// 当敌人进入攻击范围
+ ///
+ private void OnBodyEntered(Node2D node2D)
+ {
+ LogCat.Log("OnBodyEntered" + node2D.Name, LogCat.LogLabel.MeleeWeapon);
+ if (node2D is CharacterTemplate characterTemplate)
+ {
+ _characterTemplates.Add(characterTemplate);
+ }
+ }
+
+ ///
+ /// When the enemy is out of range
+ /// 当敌人离开攻击范围
+ ///
+ ///
+ private void OnBodyExited(Node node)
+ {
+ LogCat.Log("OnBodyExited" + node.Name, LogCat.LogLabel.MeleeWeapon);
+ if (node is CharacterTemplate characterTemplate)
+ {
+ _characterTemplates.Remove(characterTemplate);
+ }
+ }
+
+ protected override bool DoFire(Node2D? owner, Vector2 enemyGlobalPosition)
+ {
+ if (_weaponDamageArea == null)
+ {
+ return false;
+ }
+ if (_damageTemplate == null)
+ {
+ return false;
+ }
+ if (owner == null)
+ {
+ LogCat.LogError("owner_is_null", LogCat.LogLabel.MeleeWeapon);
+ return false;
+ }
+
+ if (_characterTemplates.Count == 0)
+ {
+ return false;
+ }
+ foreach (var characterTemplate in _characterTemplates)
+ {
+ characterTemplate.Damage(_damageTemplate);
+ }
+ return true;
+ }
+}
\ No newline at end of file