Initial migration of existing item interactions to the new interface

This commit is contained in:
霧雨烨 2024-06-12 01:57:55 +08:00
parent 026c7ff32f
commit 7f20a7233c
8 changed files with 53 additions and 51 deletions

View File

@ -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)

View File

@ -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;

View File

@ -40,12 +40,10 @@ public interface IItemStack
/// <summary>
/// Create a new ItemStack with the given item as the first item
/// </summary>
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}")
};
}

View File

@ -21,4 +21,11 @@ public interface IItem_New
/// <para>Description of current item, which may show in inventory</para>
/// </summary>
string? Description { get; }
/// <summary>
/// <para>Execute when current item is used <br/> e.g. when player clicks left mouse button with current item in hand</para>
/// </summary>
/// <param name="owner">Owner of current item, if any</param>
/// <param name="targetGlobalPosition">Target position, such as the position of the cursor when used by the player</param>
void Use(Node2D? owner, Vector2 targetGlobalPosition);
}

View File

@ -22,8 +22,4 @@ public readonly struct ItemType
/// <para>Max number in item stack of this type</para>
/// </summary>
public int MaxStackQuantity { get; init; }
/// <summary>
/// <para>Determines how items of this type will be stacked</para>
/// </summary>
public StackType StackType { get; init; }
}

View File

@ -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;
}

View File

@ -1,8 +0,0 @@
namespace ColdMint.scripts.item;
public enum StackType
{
Common,
Unique,
Unstackable,
}

View File

@ -13,18 +13,27 @@ namespace ColdMint.scripts.item.weapon;
/// <para>WeaponTemplate</para>
/// <para>武器模板</para>
/// </summary>
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<IItem>? OnUse { get; set; }
public Func<IItem, Node>? 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);
}
/// <summary>
/// <para>Owner</para>
@ -39,8 +48,8 @@ public partial class WeaponTemplate : RigidBody2D, IItem
/// </summary>
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
/// <para>开火间隔</para>
/// </summary>
private TimeSpan _firingInterval;
[Export] private long _firingIntervalAsMillisecond = 100;
/// <summary>
@ -59,7 +69,7 @@ public partial class WeaponTemplate : RigidBody2D, IItem
///<para>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.</para>
///<para>武器开火要对使用者施加多大的后坐力单位格数力的X方向是自动推断的。</para>
/// </remarks>
private Vector2 _recoil;
[Export] private Vector2 _recoil;
/// <summary>
/// <para>This area represents the collision range of the weapon, and when other nodes enter this area, they will deal damage.</para>
@ -75,16 +85,18 @@ public partial class WeaponTemplate : RigidBody2D, IItem
RayCast2D = GetNode<RayCast2D>("RayCast2D");
_area2D = GetNode<Area2D>("Area2D");
_area2D.BodyEntered += OnBodyEnter;
Id = GetMeta("ID", "1").AsString();
Quantity = GetMeta("Quantity", "1").AsInt32();
MaxStackQuantity = GetMeta("MaxStackQuantity", Config.MaxStackQuantity).AsInt32();
Icon = GetMeta("Icon", "").As<Texture2D>();
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<Texture2D>();
// 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
/// <para>翻转武器</para>
/// </summary>
/// <param name="facingLeft"></param>
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
/// <para>Execute fire</para>
/// <para>执行开火</para>
/// </summary>
protected virtual void DoFire(Node2D? owner, Vector2 enemyGlobalPosition)
{
}
protected abstract void DoFire(Node2D? owner, Vector2 enemyGlobalPosition);
}