diff --git a/locals/Log.csv b/locals/Log.csv
index 4ccf893..ca1cd8d 100644
--- a/locals/Log.csv
+++ b/locals/Log.csv
@@ -4,7 +4,6 @@ log_missing_parameters,缺少参数。,Missing parameters.,パラメータが不
log_room_root_node_must_be_node2d,房间根节点必须是 Node2D。,Room root node must be an instance of Node2D.,ルートノードはNode2Dでなければなりません。
log_width_or_height_of_room_slot_must_be_1,房间槽的宽度或高度必须为1。,The width or height of the room slot must be 1.,部屋の溝の幅または高さは1でなければなりません。
log_connected_room_timeout,连接房间超时。,Timeout when connecting rooms.,接続部屋はタイムアウトです。
-log_projectiles_is_empty,未设置抛射体。,The projectile is not set.,射出体は設置されていません。
log_map_generator_missing_parameters,地图生成器缺少参数。,Map generator missing parameters.,マップジェネレータが不足しています。
log_map_generator_attempts_to_parse_empty_layout_diagrams,地图生成器尝试解析空的布局图。,Map generator attempts to parse empty layout diagrams.,マップジェネレータは空のレイアウト図を解析しようとしています。
log_map_generator_has_no_starting_room_data,地图生成器没有起点房间数据。,Map generator has no starting room data.,マップ生成器に起点部屋データはありません。
diff --git a/prefab/weapons/StaffNecromancy.tscn b/prefab/weapons/StaffNecromancy.tscn
index 92893ae..0dd8ae1 100644
--- a/prefab/weapons/StaffNecromancy.tscn
+++ b/prefab/weapons/StaffNecromancy.tscn
@@ -1,8 +1,7 @@
-[gd_scene load_steps=8 format=3 uid="uid://dnnn2xyayiehk"]
+[gd_scene load_steps=7 format=3 uid="uid://dnnn2xyayiehk"]
[ext_resource type="Texture2D" uid="uid://wt50kx6bup51" path="res://sprites/weapon/StaffNecromancy.png" id="1_ms3us"]
[ext_resource type="Script" path="res://scripts/weapon/ProjectileWeapon.cs" id="1_w8hhv"]
-[ext_resource type="PackedScene" uid="uid://c01av43yk1q71" path="res://prefab/projectile/curseOfTheUndead.tscn" id="2_mwli5"]
[ext_resource type="Texture2D" uid="uid://dg5vwprt66w4j" path="res://sprites/weapon/StaffNecromancy_Icon.png" id="3_31iau"]
[ext_resource type="AudioStream" uid="uid://cak6chjjsu7wo" path="res://sounds/fire.wav" id="4_ffr2k"]
@@ -17,9 +16,7 @@ collision_layer = 8
collision_mask = 34
angular_damp = -1.0
script = ExtResource("1_w8hhv")
-OffsetAngle = 0.087
-ProjectileScenes = [ExtResource("2_mwli5")]
-Sequentially = true
+NumberSlots = 5
FiringIntervalAsMillisecond = 300
_recoilStrength = 5
UniqueIcon = ExtResource("3_31iau")
diff --git a/scripts/Config.cs b/scripts/Config.cs
index ffe96c9..dece38c 100644
--- a/scripts/Config.cs
+++ b/scripts/Config.cs
@@ -197,6 +197,45 @@ public static class Config
{
return OS.HasFeature("editor");
}
+
+ ///
+ /// ItemType
+ /// 物品类型
+ ///
+ public static class ItemType
+ {
+ ///
+ /// Unknown
+ /// 未知的
+ ///
+ public const int Unknown = 0;
+ ///
+ /// Placeholder
+ /// 占位符
+ ///
+ public const int Placeholder = 1;
+ ///
+ /// Packsack
+ /// 背包
+ ///
+ public const int Packsack = 2;
+
+ ///
+ /// ProjectileWeapon
+ /// 远程武器
+ ///
+ public const int ProjectileWeapon = 3;
+
+ ///
+ /// Magic
+ /// 法术
+ ///
+ ///
+ ///Type of special item used in Projectile weapons
+ ///用于远程武器内的特殊物品类型
+ ///
+ public const int Magic = 4;
+ }
///
/// Room Injector ID
diff --git a/scripts/inventory/HotBar.cs b/scripts/inventory/HotBar.cs
index 3515b0f..6e1826a 100644
--- a/scripts/inventory/HotBar.cs
+++ b/scripts/inventory/HotBar.cs
@@ -11,13 +11,13 @@ public partial class HotBar : HBoxContainer
{
private IItemContainer? _itemContainer;
private IItemContainerDisplay? _itemContainerDisplay;
-
+
public override void _Ready()
{
base._Ready();
var universalItemContainer = new UniversalItemContainer(Config.HotBarSize);
_itemContainer = universalItemContainer;
- _itemContainer.CanContainContainer = true;
+ universalItemContainer.AllowItemTypesExceptPlaceholder();
_itemContainer.SupportSelect = true;
_itemContainerDisplay = new ItemSlotContainerDisplay(this);
_itemContainerDisplay.BindItemContainer(_itemContainer);
diff --git a/scripts/inventory/IItem.cs b/scripts/inventory/IItem.cs
index 38a4d69..185c316 100644
--- a/scripts/inventory/IItem.cs
+++ b/scripts/inventory/IItem.cs
@@ -62,6 +62,12 @@ public interface IItem
/// 最大物品数量
///
int MaxQuantity { get; }
+
+ ///
+ /// ItemType
+ /// 获取物品类型
+ ///
+ int ItemType { get; }
///
/// Check or not
diff --git a/scripts/inventory/IItemContainer.cs b/scripts/inventory/IItemContainer.cs
index 42bed97..2ccd95c 100644
--- a/scripts/inventory/IItemContainer.cs
+++ b/scripts/inventory/IItemContainer.cs
@@ -20,6 +20,20 @@ public interface IItemContainer
/// 当物品的数据发生改变时,例如数量增加,减少,或者新物品被添加到容器内触发此事件
///
Action? ItemDataChangeEvent { get; set; }
+
+ ///
+ /// Allow Adding Item By Type
+ /// 允许添加指定类型的物品
+ ///
+ ///
+ void AllowAddingItemByType(int itemType);
+
+ ///
+ /// Disallow Adding Item By Type
+ /// 禁止添加指定类型的物品
+ ///
+ ///
+ void DisallowAddingItemByType(int itemType);
///
/// Can the specified item be added to the container?
@@ -45,13 +59,7 @@ public interface IItemContainer
/// 此物品容器是否支持选中
///
bool SupportSelect { get; set; }
-
- ///
- /// Whether this item container supports items that CanContainItems=true, such as backpacks
- /// 此物品容器是否支持容纳CanContainItems=true的物品,例如背包
- ///
- bool CanContainContainer { get; set; }
-
+
///
/// Gets a placeholder object
/// 获取占位符对象
diff --git a/scripts/inventory/ItemSlotNode.cs b/scripts/inventory/ItemSlotNode.cs
index d9a58b8..d7e15b1 100644
--- a/scripts/inventory/ItemSlotNode.cs
+++ b/scripts/inventory/ItemSlotNode.cs
@@ -117,7 +117,7 @@ public partial class ItemSlotNode : MarginContainer, IItemDisplay
return;
}
- if (Item.SelfItemContainer != null)
+ if (Item.SelfItemContainer != null && Item.SelfItemContainer.CanAddItem(sourceItem))
{
//Use items and place them on the container.
//用物品,在物品容器上放置。
@@ -138,7 +138,7 @@ public partial class ItemSlotNode : MarginContainer, IItemDisplay
return;
}
- if (sourceItem.SelfItemContainer != null)
+ if (sourceItem.SelfItemContainer != null && sourceItem.SelfItemContainer.CanAddItem(Item))
{
//Use containers and place on top of items.
//用容器物品,在物品上放置。
diff --git a/scripts/inventory/Packsack.cs b/scripts/inventory/Packsack.cs
index b0768c9..bfaf81d 100644
--- a/scripts/inventory/Packsack.cs
+++ b/scripts/inventory/Packsack.cs
@@ -12,6 +12,11 @@ namespace ColdMint.scripts.inventory;
public partial class Packsack : PickAbleTemplate
{
private const string Path = "res://prefab/ui/packsackUI.tscn";
+
+ public override int ItemType
+ {
+ get => Config.ItemType.Packsack;
+ }
[Export] public int NumberSlots { get; set; }
public override void Use(Node2D? owner, Vector2 targetGlobalPosition)
{
@@ -54,7 +59,10 @@ public partial class Packsack : PickAbleTemplate
base._Ready();
if (SelfItemContainer == null)
{
- SelfItemContainer = new UniversalItemContainer(NumberSlots);
+ var universalItemContainer = new UniversalItemContainer(NumberSlots);
+ universalItemContainer.AllowItemTypesExceptPlaceholder();
+ universalItemContainer.DisallowAddingItemByType(Config.ItemType.Packsack);
+ SelfItemContainer = universalItemContainer;
SelfItemContainer.SupportSelect = false;
}
GameSceneDepend.DynamicUiGroup?.RegisterControl(Path, () =>
diff --git a/scripts/inventory/PlaceholderItem.cs b/scripts/inventory/PlaceholderItem.cs
index 4ae581d..419599c 100644
--- a/scripts/inventory/PlaceholderItem.cs
+++ b/scripts/inventory/PlaceholderItem.cs
@@ -13,17 +13,17 @@ public class PlaceholderItem : IItem
public void ShowSelf()
{
-
+
}
public void QueueFreeSelf()
{
-
+
}
public void HideSelf()
{
-
+
}
public Texture2D Icon { get; }
@@ -31,6 +31,10 @@ public class PlaceholderItem : IItem
public string? Description { get; } = null;
public int Quantity { get; set; } = 1;
public int MaxQuantity { get; } = 1;
+ public int ItemType
+ {
+ get => Config.ItemType.Placeholder;
+ }
public bool IsSelect { get; set; }
public bool CanContainItems { get; set; } = false;
public IItemContainer? ItemContainer { get; set; }
diff --git a/scripts/inventory/UniversalItemContainer.cs b/scripts/inventory/UniversalItemContainer.cs
index a4f7d2d..179058e 100644
--- a/scripts/inventory/UniversalItemContainer.cs
+++ b/scripts/inventory/UniversalItemContainer.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Reflection;
using ColdMint.scripts.map.events;
namespace ColdMint.scripts.inventory;
@@ -32,15 +33,59 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
///
private int _nextAvailableIndex;
+ ///
+ /// The type of item that can be added to the item container
+ /// 物品容器允许添加的物品类型
+ ///
+ private readonly HashSet _allowedItemTypes = new();
+
public Action? SelectedItemChangeEvent { get; set; }
public Action? ItemDataChangeEvent { get; set; }
+ ///
+ /// Allow Item Types Except Placeholder
+ /// 允许添加除占位符以外的所有物品类型
+ ///
+ public void AllowItemTypesExceptPlaceholder()
+ {
+ var itemTypeType = typeof(Config.ItemType);
+ //Get all fields
+ //获取所有字段
+ var fields = itemTypeType.GetFields(BindingFlags.Public | BindingFlags.Static);
+ //Traversal field
+ //遍历字段
+ foreach (var field in fields)
+ {
+ //Gets the value of the field
+ //获取字段的值
+ var value = field.GetValue(null);
+ if (value == null)
+ {
+ continue;
+ }
+ var intValue = (int)value;
+ if (intValue == Config.ItemType.Placeholder)
+ {
+ continue;
+ }
+ _allowedItemTypes.Add(intValue);
+ }
+ }
+
+ public void AllowAddingItemByType(int itemType)
+ {
+ _allowedItemTypes.Add(itemType);
+ }
+
+ public void DisallowAddingItemByType(int itemType)
+ {
+ _allowedItemTypes.Remove(itemType);
+ }
+
public bool CanAddItem(IItem item)
{
- if (item.SelfItemContainer != null && !CanContainContainer)
+ if (!_allowedItemTypes.Contains(item.ItemType))
{
- //The item to be added can hold other items, and this item container does not allow item containers.
- //要添加的物品能够容纳其他物品,且此物品容器不允许放置物品容器。
return false;
}
//If the capacity is not full, directly return to add items
@@ -200,8 +245,6 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
}
public bool SupportSelect { get; set; }
- public bool CanContainContainer { get; set; }
-
public IItem GetPlaceHolderItem(int index)
{
@@ -247,7 +290,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
public bool CanReplaceItem(int index, IItem item)
{
- if (item.SelfItemContainer != null && !CanContainContainer)
+ if (!_allowedItemTypes.Contains(item.ItemType))
{
return false;
}
diff --git a/scripts/pickable/MagicPickAble.cs b/scripts/pickable/MagicPickAble.cs
new file mode 100644
index 0000000..6c92a8a
--- /dev/null
+++ b/scripts/pickable/MagicPickAble.cs
@@ -0,0 +1,15 @@
+namespace ColdMint.scripts.pickable;
+
+///
+/// 法术
+///
+///
+///用于抛射体武器
+///
+public partial class MagicPickAble : PickAbleTemplate
+{
+ public override int ItemType
+ {
+ get => Config.ItemType.Magic;
+ }
+}
\ No newline at end of file
diff --git a/scripts/pickable/PickAbleTemplate.cs b/scripts/pickable/PickAbleTemplate.cs
index ef20605..59e0dca 100644
--- a/scripts/pickable/PickAbleTemplate.cs
+++ b/scripts/pickable/PickAbleTemplate.cs
@@ -92,6 +92,10 @@ public partial class PickAbleTemplate : RigidBody2D, IItem
public bool Picked { get; set; }
public int MaxQuantity { get; set; } = 1;
+ public virtual int ItemType
+ {
+ get => Config.ItemType.Unknown;
+ }
private bool _isSelected;
@@ -108,7 +112,7 @@ public partial class PickAbleTemplate : RigidBody2D, IItem
OnSelectChange(value);
}
}
-
+
public IItemContainer? ItemContainer { get; set; }
public IItemContainer? SelfItemContainer { get; set; }
@@ -121,7 +125,7 @@ public partial class PickAbleTemplate : RigidBody2D, IItem
///
protected virtual void OnSelectChange(bool isSelected)
{
-
+
}
public IItem? CreateItem(int number)
@@ -348,11 +352,4 @@ public partial class PickAbleTemplate : RigidBody2D, IItem
pickAbleTemplate.Id = Id;
}
-
- public virtual void Destroy()
- {
- QueueFree();
- }
-
- public bool CanStackWith(IItem item) => false;
}
\ No newline at end of file
diff --git a/scripts/projectile/IMagic.cs b/scripts/projectile/IMagic.cs
new file mode 100644
index 0000000..2b9351e
--- /dev/null
+++ b/scripts/projectile/IMagic.cs
@@ -0,0 +1,14 @@
+namespace ColdMint.scripts.projectile;
+
+///
+/// Magic
+/// 法术
+///
+///
+///For projectile weapons
+///用于抛射体武器
+///
+public interface IMagic
+{
+
+}
\ No newline at end of file
diff --git a/scripts/weapon/ProjectileWeapon.cs b/scripts/weapon/ProjectileWeapon.cs
index cd82379..5c982be 100644
--- a/scripts/weapon/ProjectileWeapon.cs
+++ b/scripts/weapon/ProjectileWeapon.cs
@@ -1,7 +1,5 @@
using ColdMint.scripts.debug;
-using ColdMint.scripts.projectile;
-using ColdMint.scripts.projectile.decorator;
-using ColdMint.scripts.utils;
+using ColdMint.scripts.inventory;
using Godot;
namespace ColdMint.scripts.weapon;
@@ -21,106 +19,28 @@ public partial class ProjectileWeapon : WeaponTemplate
/// 抛射体的生成位置
///
private Marker2D? _marker2D;
-
- ///
- /// Scattering radians
- /// 散射弧度
- ///
- [Export] protected float OffsetAngle;
-
- ///
- /// Offset angle mode
- /// 偏移角度模式
- ///
- [Export] protected int OffsetAngleMode = Config.OffsetAngleMode.Random;
-
- ///
- /// Whether the last offset angle is positive
- /// 上次的偏移角度是否为正向的
- ///
- private bool _positiveOffsetAngle = true;
-
- ///
- /// The number of projectiles fired at once
- /// 一次可以发射多少个子弹
- ///
- [Export] protected float NumberOfProjectiles = 1;
-
- [Export] protected PackedScene[] ProjectileScenes { get; set; } = [];
-
- ///
- /// Whether to launch in the order of the projectile list
- /// 是否按照抛射体列表的循序发射
- ///
- [Export]
- protected bool Sequentially { get; set; }
-
+
private int _projectileIndex;
+
+ ///
+ /// Number of slots for ranged weapons
+ /// 远程武器的槽位数量
+ ///
+ [Export] public int NumberSlots { get; set; }
+ public override int ItemType
+ {
+ get => Config.ItemType.ProjectileWeapon;
+ }
+
public override void _Ready()
{
base._Ready();
_marker2D = GetNode("Marker2D");
+ SelfItemContainer = new UniversalItemContainer(NumberSlots);
+ SelfItemContainer.AllowAddingItemByType(Config.ItemType.Magic);
}
-
- ///
- /// GetNextProjectileScene
- /// 获取下一个抛射体
- ///
- ///
- private PackedScene GetNextProjectileScene()
- {
- if (Sequentially)
- {
- _projectileIndex = (_projectileIndex + 1) % ProjectileScenes.Length;
- return ProjectileScenes[_projectileIndex];
- }
- else
- {
- return ProjectileScenes[RandomUtils.Instance.Next(ProjectileScenes.Length)];
- }
- }
-
-
- ///
- /// GetRandomAngle
- /// 获取随机的偏移弧度
- ///
- ///
- private float GetRandomAngle()
- {
- if (OffsetAngle == 0)
- {
- //If the offset angle is 0, then return 0
- //弧度为0,不用偏移。
- return 0;
- }
-
- if (OffsetAngleMode == Config.OffsetAngleMode.Cross)
- {
- float result;
- if (_positiveOffsetAngle)
- {
- result = -OffsetAngle / 2;
- }
- else
- {
- result = OffsetAngle / 2;
- }
-
- _positiveOffsetAngle = !_positiveOffsetAngle;
- return result;
- }
-
- if (OffsetAngleMode == Config.OffsetAngleMode.AlwaysSame)
- {
- return OffsetAngle;
- }
-
- var min = -OffsetAngle / 2;
- return min + RandomUtils.Instance.NextSingle() * OffsetAngle;
- }
-
+
protected override void DoFire(Node2D? owner, Vector2 enemyGlobalPosition)
{
@@ -141,39 +61,6 @@ public partial class ProjectileWeapon : WeaponTemplate
LogCat.LogError("projectile_container_is_null");
return;
}
-
- //Empty list check
- //空列表检查
- if (ProjectileScenes is [])
- {
- LogCat.LogError("projectiles_is_empty");
- return;
- }
-
- //Get the first projectile
- //获取第一个抛射体
- var projectileScene = GetNextProjectileScene();
- for (int i = 0; i < NumberOfProjectiles; i++)
- {
- var projectile = NodeUtils.InstantiatePackedScene(projectileScene);
- if (projectile == null) return;
- if (Config.IsDebug())
- {
- var nodeSpawnOnKillCharacterDecorator = new NodeSpawnOnKillCharacterDecorator
- {
- DefaultParentNode = this,
- PackedScenePath = "res://prefab/entitys/BlackenedAboriginalWarrior.tscn"
- };
- projectile.AddProjectileDecorator(nodeSpawnOnKillCharacterDecorator);
- }
-
- NodeUtils.CallDeferredAddChild(GameSceneDepend.ProjectileContainer, projectile);
- projectile.Owner = owner;
- projectile.TargetNode = GameSceneDepend.TemporaryTargetNode;
- projectile.Velocity =
- (_marker2D.GlobalPosition.DirectionTo(enemyGlobalPosition) * projectile.Speed)
- .Rotated(GetRandomAngle());
- projectile.Position = _marker2D.GlobalPosition;
- }
+
}
}
\ No newline at end of file