2024-06-16 07:28:16 +00:00
|
|
|
|
using System;
|
|
|
|
|
using ColdMint.scripts.camp;
|
|
|
|
|
using ColdMint.scripts.character;
|
|
|
|
|
using ColdMint.scripts.damage;
|
2024-06-27 15:11:30 +00:00
|
|
|
|
using ColdMint.scripts.debug;
|
2024-06-22 11:21:06 +00:00
|
|
|
|
using ColdMint.scripts.inventory;
|
2024-08-01 15:30:28 +00:00
|
|
|
|
using ColdMint.scripts.utils;
|
2024-06-16 07:28:16 +00:00
|
|
|
|
using Godot;
|
|
|
|
|
|
|
|
|
|
namespace ColdMint.scripts.pickable;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>Templates for all fallen objects</para>
|
|
|
|
|
/// <para>所有掉落物的模板</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
public partial class PickAbleTemplate : RigidBody2D, IItem
|
|
|
|
|
{
|
2024-09-28 14:59:25 +00:00
|
|
|
|
public int Index { get; set; }
|
2024-08-01 15:30:28 +00:00
|
|
|
|
//Do not export this field because the ID is specified within yaml.
|
|
|
|
|
//不要导出此字段,因为ID是在yaml内指定的。
|
|
|
|
|
public virtual string Id { get; set; } = "ID";
|
2024-06-16 10:35:00 +00:00
|
|
|
|
[Export] protected Texture2D? UniqueIcon { get; set; }
|
2024-09-30 00:56:00 +00:00
|
|
|
|
|
|
|
|
|
public void ShowSelf()
|
|
|
|
|
{
|
|
|
|
|
Show();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void QueueFreeSelf()
|
|
|
|
|
{
|
|
|
|
|
QueueFree();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void HideSelf()
|
|
|
|
|
{
|
|
|
|
|
Hide();
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-16 07:28:16 +00:00
|
|
|
|
public Texture2D Icon => UniqueIcon ?? ItemTypeManager.DefaultIconOf(Id);
|
2024-08-01 15:30:28 +00:00
|
|
|
|
|
|
|
|
|
public new string Name
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
var key = $"item_{Id}";
|
|
|
|
|
return TranslationServerUtils.Translate(key) ?? key;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-10-01 07:01:34 +00:00
|
|
|
|
|
2024-06-16 07:28:16 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>Owner</para>
|
|
|
|
|
/// <para>主人</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
public new Node2D? Owner { get; set; }
|
|
|
|
|
|
2024-08-01 15:30:28 +00:00
|
|
|
|
public string Description
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
var key = $"item_{Id}_desc";
|
|
|
|
|
return TranslationServerUtils.Translate(key) ?? key;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-21 14:55:31 +00:00
|
|
|
|
public int Quantity { get; set; } = 1;
|
2024-06-16 07:28:16 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>Whether the item is currently picked up</para>
|
|
|
|
|
/// <para>当前物品是否被捡起了</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool Picked { get; set; }
|
|
|
|
|
|
2024-09-23 13:03:39 +00:00
|
|
|
|
public int MaxQuantity { get; set; } = 1;
|
2024-10-04 02:21:09 +00:00
|
|
|
|
public virtual int ItemType
|
|
|
|
|
{
|
|
|
|
|
get => Config.ItemType.Unknown;
|
|
|
|
|
}
|
2024-10-01 07:01:34 +00:00
|
|
|
|
|
|
|
|
|
private bool _isSelected;
|
|
|
|
|
|
|
|
|
|
public bool IsSelect
|
|
|
|
|
{
|
|
|
|
|
get => _isSelected;
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (_isSelected == value)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
_isSelected = value;
|
|
|
|
|
OnSelectChange(value);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-10-04 02:21:09 +00:00
|
|
|
|
|
2024-09-27 15:24:22 +00:00
|
|
|
|
public IItemContainer? ItemContainer { get; set; }
|
2024-09-29 15:30:42 +00:00
|
|
|
|
public IItemContainer? SelfItemContainer { get; set; }
|
2024-09-18 13:28:54 +00:00
|
|
|
|
|
2024-08-20 14:17:07 +00:00
|
|
|
|
private Label? _tipLabel;
|
2024-09-23 13:03:39 +00:00
|
|
|
|
|
2024-10-01 07:01:34 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para></para>
|
|
|
|
|
/// <para>当选中状态发生改变时</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="isSelected"></param>
|
|
|
|
|
protected virtual void OnSelectChange(bool isSelected)
|
|
|
|
|
{
|
2024-10-04 02:21:09 +00:00
|
|
|
|
|
2024-10-01 07:01:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-22 08:51:42 +00:00
|
|
|
|
public IItem? CreateItem(int number)
|
|
|
|
|
{
|
|
|
|
|
if (number == 0)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var duplicate = Duplicate();
|
|
|
|
|
if (duplicate is PickAbleTemplate pickAbleTemplate)
|
|
|
|
|
{
|
|
|
|
|
pickAbleTemplate.CopyAttributes(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (duplicate is not Node2D newNode2D)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
newNode2D.GlobalPosition = GlobalPosition;
|
|
|
|
|
if (duplicate is not IItem newItem)
|
|
|
|
|
{
|
|
|
|
|
duplicate.QueueFree();
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (number < 0)
|
|
|
|
|
{
|
|
|
|
|
newItem.Quantity = Quantity;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
newItem.Quantity = Math.Min(Quantity, number);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return newItem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public int MergeableItemCount(IItem other, int unallocatedQuantity)
|
|
|
|
|
{
|
|
|
|
|
var freeQuantity = MaxQuantity - Quantity;
|
|
|
|
|
if (freeQuantity == 0)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (other.Id != Id)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Math.Min(freeQuantity, unallocatedQuantity);
|
|
|
|
|
}
|
2024-06-21 11:16:40 +00:00
|
|
|
|
|
2024-10-05 12:56:50 +00:00
|
|
|
|
public virtual bool Use(Node2D? owner, Vector2 targetGlobalPosition)
|
2024-06-21 11:16:40 +00:00
|
|
|
|
{
|
2024-10-05 12:56:50 +00:00
|
|
|
|
return false;
|
2024-06-21 11:16:40 +00:00
|
|
|
|
}
|
2024-06-16 07:28:16 +00:00
|
|
|
|
|
2024-10-01 07:01:34 +00:00
|
|
|
|
public virtual void OnThrow(Vector2 velocity)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-10 08:03:07 +00:00
|
|
|
|
private CollisionShape2D? _collisionShape2D;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>Whether the resource has been loaded</para>
|
|
|
|
|
/// <para>是否已加载过资源了</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
private bool _loadedResource;
|
|
|
|
|
|
2024-06-16 07:28:16 +00:00
|
|
|
|
public override void _Ready()
|
|
|
|
|
{
|
2024-10-10 08:03:07 +00:00
|
|
|
|
LoadingResource();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void LoadingResource()
|
|
|
|
|
{
|
|
|
|
|
if (_loadedResource)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-08-20 14:17:07 +00:00
|
|
|
|
_tipLabel = GetNodeOrNull<Label>("TipLabel");
|
2024-10-10 08:03:07 +00:00
|
|
|
|
_collisionShape2D = GetNode<CollisionShape2D>("CollisionShape2D");
|
2024-08-20 14:17:07 +00:00
|
|
|
|
InputPickable = true;
|
2024-09-18 13:28:54 +00:00
|
|
|
|
SetCollisionMaskValue(Config.LayerNumber.Wall, true);
|
|
|
|
|
SetCollisionMaskValue(Config.LayerNumber.Platform, true);
|
|
|
|
|
SetCollisionMaskValue(Config.LayerNumber.Floor, true);
|
2024-10-09 09:36:59 +00:00
|
|
|
|
SetCollisionMaskValue(Config.LayerNumber.Barrier, true);
|
2024-10-10 08:03:07 +00:00
|
|
|
|
_loadedResource = true;
|
2024-06-16 07:28:16 +00:00
|
|
|
|
}
|
2024-10-11 02:22:28 +00:00
|
|
|
|
|
2024-08-20 14:17:07 +00:00
|
|
|
|
public override void _MouseEnter()
|
|
|
|
|
{
|
|
|
|
|
if (Picked)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-09-18 13:28:54 +00:00
|
|
|
|
|
2024-08-20 14:17:07 +00:00
|
|
|
|
if (_tipLabel == null)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-09-18 13:28:54 +00:00
|
|
|
|
|
2024-08-20 14:17:07 +00:00
|
|
|
|
_tipLabel.Visible = true;
|
|
|
|
|
_tipLabel.Text = Name;
|
|
|
|
|
//Vertical Centering Tip
|
|
|
|
|
//垂直居中提示
|
|
|
|
|
var oldPosition = _tipLabel.Position;
|
|
|
|
|
oldPosition.X = -_tipLabel.Size.X / 2;
|
|
|
|
|
_tipLabel.Rotation = -Rotation;
|
|
|
|
|
_tipLabel.Position = oldPosition;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void _MouseExit()
|
|
|
|
|
{
|
|
|
|
|
if (_tipLabel == null)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-09-18 13:28:54 +00:00
|
|
|
|
|
2024-08-20 14:17:07 +00:00
|
|
|
|
_tipLabel.Visible = false;
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-16 07:28:16 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>Flip item</para>
|
|
|
|
|
/// <para>翻转物品</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="facingLeft"></param>
|
2024-06-21 11:16:40 +00:00
|
|
|
|
public void Flip(bool facingLeft)
|
|
|
|
|
{
|
|
|
|
|
}
|
2024-06-16 07:28:16 +00:00
|
|
|
|
|
2024-10-10 08:03:07 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>Collision forbidden shape</para>
|
|
|
|
|
/// <para>禁用碰撞形状</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
///<para>Prevents pickables from blocking projectiles.</para>
|
|
|
|
|
///<para>防止可拾捡物阻挡抛射体。</para>
|
|
|
|
|
/// </remarks>
|
|
|
|
|
public void DisabledCollisionShape2D()
|
|
|
|
|
{
|
|
|
|
|
if (_collisionShape2D != null)
|
|
|
|
|
{
|
|
|
|
|
_collisionShape2D.Disabled = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>EnabledCollisionShape2D</para>
|
|
|
|
|
/// <para>启用碰撞形状</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void EnabledCollisionShape2D()
|
|
|
|
|
{
|
|
|
|
|
if (_collisionShape2D != null)
|
|
|
|
|
{
|
|
|
|
|
_collisionShape2D.Disabled = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-20 14:17:07 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// <para>Please copy node properties within this function</para>
|
|
|
|
|
/// <para>请在此函数内复制节点属性</para>
|
|
|
|
|
/// </summary>
|
2024-10-05 02:20:55 +00:00
|
|
|
|
/// <param name="originalNode"></param>
|
|
|
|
|
public void CopyAttributes(Node originalNode)
|
2024-08-20 14:17:07 +00:00
|
|
|
|
{
|
2024-10-05 02:20:55 +00:00
|
|
|
|
if (originalNode is not PickAbleTemplate originalPickAbleTemplate)
|
2024-08-20 14:17:07 +00:00
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-10-05 02:20:55 +00:00
|
|
|
|
Id = originalPickAbleTemplate.Id;
|
|
|
|
|
SelfItemContainer = originalPickAbleTemplate.SelfItemContainer;
|
2024-08-20 14:17:07 +00:00
|
|
|
|
}
|
2024-06-16 07:28:16 +00:00
|
|
|
|
}
|