Fixed an issue where players could pick up items in the backpack after throwing it.Supports placing items across item containers
修复玩家扔出背包后,再捡起背包内的物品消失的问题。支持跨容器替换物品了。
This commit is contained in:
parent
4f2208bd60
commit
31a1d292d8
|
@ -175,7 +175,7 @@ public static class Config
|
||||||
/// <para>EmptyVariant</para>
|
/// <para>EmptyVariant</para>
|
||||||
/// <para>空变量</para>
|
/// <para>空变量</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly Variant EmptyVariant = new();
|
public static readonly Variant EmptyVariant = new();
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -243,7 +243,12 @@ public static class Config
|
||||||
/// <para>Replace</para>
|
/// <para>Replace</para>
|
||||||
/// <para>被替换</para>
|
/// <para>被替换</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Replace
|
Replace,
|
||||||
|
/// <summary>
|
||||||
|
/// <para>Clear</para>
|
||||||
|
/// <para>被清空</para>
|
||||||
|
/// </summary>
|
||||||
|
Clear
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum OsEnum
|
public enum OsEnum
|
||||||
|
|
|
@ -15,10 +15,7 @@ public partial class HotBar : HBoxContainer
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
base._Ready();
|
base._Ready();
|
||||||
var universalItemContainer = new UniversalItemContainer(Config.HotBarSize)
|
var universalItemContainer = new UniversalItemContainer(Config.HotBarSize);
|
||||||
{
|
|
||||||
EnablePlaceholder = true
|
|
||||||
};
|
|
||||||
_itemContainer = universalItemContainer;
|
_itemContainer = universalItemContainer;
|
||||||
_itemContainer.SupportSelect = true;
|
_itemContainer.SupportSelect = true;
|
||||||
_itemContainerDisplay = new ItemSlotContainerDisplay(this);
|
_itemContainerDisplay = new ItemSlotContainerDisplay(this);
|
||||||
|
|
|
@ -4,6 +4,11 @@ namespace ColdMint.scripts.inventory;
|
||||||
|
|
||||||
public interface IItem
|
public interface IItem
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <para>The position of the item in the container</para>
|
||||||
|
/// <para>物品在容器内的位置</para>
|
||||||
|
/// </summary>
|
||||||
|
public int Index { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>ID of current item</para>
|
/// <para>ID of current item</para>
|
||||||
/// <para>当前物品的ID</para>
|
/// <para>当前物品的ID</para>
|
||||||
|
|
|
@ -50,8 +50,12 @@ public interface IItemContainer
|
||||||
/// <para>Gets a placeholder object</para>
|
/// <para>Gets a placeholder object</para>
|
||||||
/// <para>获取占位符对象</para>
|
/// <para>获取占位符对象</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="index">
|
||||||
|
///<para>index</para>
|
||||||
|
///<para>占位符代替的索引</para>
|
||||||
|
/// </param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IItem? GetPlaceHolderItem();
|
IItem GetPlaceHolderItem(int index);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>Gets the selected location</para>
|
/// <para>Gets the selected location</para>
|
||||||
|
@ -88,7 +92,13 @@ public interface IItemContainer
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
bool ReplaceItem(int index, IItem item);
|
bool ReplaceItem(int index, IItem item);
|
||||||
|
|
||||||
bool ReplaceItem(IItem oldItem, IItem newItem);
|
/// <summary>
|
||||||
|
/// <para>ClearItem</para>
|
||||||
|
/// <para>清理物品</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool ClearItem(int index);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>Gets the item in the specified location, equivalent to <see cref="GetItem"/></para>
|
/// <para>Gets the item in the specified location, equivalent to <see cref="GetItem"/></para>
|
||||||
|
@ -128,14 +138,6 @@ public interface IItemContainer
|
||||||
/// </returns>
|
/// </returns>
|
||||||
int RemoveItem(int itemIndex, int number);
|
int RemoveItem(int itemIndex, int number);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <para>Remove item</para>
|
|
||||||
/// <para>移除物品</para>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="item"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
int RemoveItem(IItem item, int number);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>Gets the used capacity of the item container</para>
|
/// <para>Gets the used capacity of the item container</para>
|
||||||
/// <para>获取物品容器已使用的容量</para>
|
/// <para>获取物品容器已使用的容量</para>
|
||||||
|
|
|
@ -118,12 +118,16 @@ public abstract class ItemContainerDisplayTemplate : IItemContainerDisplay
|
||||||
var item = itemContainer.GetItem(index);
|
var item = itemContainer.GetItem(index);
|
||||||
if (item == null)
|
if (item == null)
|
||||||
{
|
{
|
||||||
item = itemContainer.GetPlaceHolderItem();
|
item = itemContainer.GetPlaceHolderItem(index);
|
||||||
}
|
}
|
||||||
if (item != null)
|
if (itemContainer.SupportSelect)
|
||||||
{
|
{
|
||||||
item.IsSelect = index == itemContainer.GetSelectIndex();
|
item.IsSelect = index == itemContainer.GetSelectIndex();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item.IsSelect = false;
|
||||||
|
}
|
||||||
itemDisplay.Update(item);
|
itemDisplay.Update(item);
|
||||||
itemDisplay.ShowSelf();
|
itemDisplay.ShowSelf();
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,12 @@ public partial class ItemSlotNode : MarginContainer, IItemDisplay
|
||||||
|
|
||||||
public override void _DropData(Vector2 atPosition, Variant data)
|
public override void _DropData(Vector2 atPosition, Variant data)
|
||||||
{
|
{
|
||||||
|
//The item is empty and the corresponding item container cannot be retrieved.
|
||||||
|
//物品为空,无法获取对应的物品容器。
|
||||||
|
if (Item is null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
var type = data.VariantType;
|
var type = data.VariantType;
|
||||||
if (type == Variant.Type.Nil)
|
if (type == Variant.Type.Nil)
|
||||||
{
|
{
|
||||||
|
@ -89,10 +95,20 @@ public partial class ItemSlotNode : MarginContainer, IItemDisplay
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Item is null || Item is PlaceholderItem)
|
|
||||||
|
if (Item is PlaceholderItem placeholderItem)
|
||||||
{
|
{
|
||||||
sourceItem.ItemContainer?.RemoveItem(sourceItem, -1);
|
var placeholderItemContainer = placeholderItem.ItemContainer;
|
||||||
Item?.ItemContainer?.ReplaceItem(Item, sourceItem);
|
var sourceItemContainer = sourceItem.ItemContainer;
|
||||||
|
var sourceItemIndex = sourceItem.Index;
|
||||||
|
if (placeholderItemContainer != null)
|
||||||
|
{
|
||||||
|
placeholderItemContainer.ReplaceItem(placeholderItem.Index, sourceItem);
|
||||||
|
}
|
||||||
|
if (sourceItemContainer != null)
|
||||||
|
{
|
||||||
|
sourceItemContainer.ClearItem(sourceItemIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,18 +35,30 @@ public partial class Packsack : PickAbleTemplate
|
||||||
if (control is PacksackUi packsackUi)
|
if (control is PacksackUi packsackUi)
|
||||||
{
|
{
|
||||||
packsackUi.Title = Name;
|
packsackUi.Title = Name;
|
||||||
packsackUi.ItemContainer = ItemContainer;
|
packsackUi.ItemContainer = SelfItemContainer;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public IItemContainer? ItemContainer { get; private set; }
|
public override void CopyAttributes(Node node)
|
||||||
|
{
|
||||||
|
base.CopyAttributes(node);
|
||||||
|
if (node is Packsack packsack)
|
||||||
|
{
|
||||||
|
SelfItemContainer = packsack.SelfItemContainer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IItemContainer? SelfItemContainer { get; set; }
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
base._Ready();
|
base._Ready();
|
||||||
ItemContainer = new UniversalItemContainer(NumberSlots);
|
if (SelfItemContainer == null)
|
||||||
ItemContainer.SupportSelect = false;
|
{
|
||||||
|
SelfItemContainer = new UniversalItemContainer(NumberSlots);
|
||||||
|
SelfItemContainer.SupportSelect = false;
|
||||||
|
}
|
||||||
GameSceneDepend.DynamicUiGroup?.RegisterControl(Path, () =>
|
GameSceneDepend.DynamicUiGroup?.RegisterControl(Path, () =>
|
||||||
{
|
{
|
||||||
var packedScene = GD.Load<PackedScene>(Path);
|
var packedScene = GD.Load<PackedScene>(Path);
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace ColdMint.scripts.inventory;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PlaceholderItem : IItem
|
public class PlaceholderItem : IItem
|
||||||
{
|
{
|
||||||
|
public int Index { get; set; }
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
public Texture2D Icon { get; }
|
public Texture2D Icon { get; }
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
|
|
|
@ -110,6 +110,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
|
||||||
|
|
||||||
var nextAvailableIndex = _nextAvailableIndex;
|
var nextAvailableIndex = _nextAvailableIndex;
|
||||||
_itemDictionary[nextAvailableIndex] = item;
|
_itemDictionary[nextAvailableIndex] = item;
|
||||||
|
item.Index = nextAvailableIndex;
|
||||||
item.ItemContainer = this;
|
item.ItemContainer = this;
|
||||||
UpdateNextAvailableIndex();
|
UpdateNextAvailableIndex();
|
||||||
UpdateSelectStatus(nextAvailableIndex, item);
|
UpdateSelectStatus(nextAvailableIndex, item);
|
||||||
|
@ -169,6 +170,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
|
||||||
}
|
}
|
||||||
var finalNextAvailableIndex = _nextAvailableIndex;
|
var finalNextAvailableIndex = _nextAvailableIndex;
|
||||||
_itemDictionary[finalNextAvailableIndex] = item;
|
_itemDictionary[finalNextAvailableIndex] = item;
|
||||||
|
item.Index = finalNextAvailableIndex;
|
||||||
item.ItemContainer = this;
|
item.ItemContainer = this;
|
||||||
UpdateNextAvailableIndex();
|
UpdateNextAvailableIndex();
|
||||||
UpdateSelectStatus(finalNextAvailableIndex, item);
|
UpdateSelectStatus(finalNextAvailableIndex, item);
|
||||||
|
@ -182,11 +184,16 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SupportSelect { get; set; }
|
public bool SupportSelect { get; set; }
|
||||||
public bool EnablePlaceholder { get; set; }
|
|
||||||
|
|
||||||
public IItem? GetPlaceHolderItem()
|
|
||||||
|
public IItem GetPlaceHolderItem(int index)
|
||||||
{
|
{
|
||||||
return EnablePlaceholder ? new PlaceholderItem() : null;
|
var placeholderItem = new PlaceholderItem
|
||||||
|
{
|
||||||
|
Index = index,
|
||||||
|
ItemContainer = this
|
||||||
|
};
|
||||||
|
return placeholderItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetSelectIndex()
|
public int GetSelectIndex()
|
||||||
|
@ -208,6 +215,8 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
|
||||||
{
|
{
|
||||||
var oldItem = GetItem(index);
|
var oldItem = GetItem(index);
|
||||||
_itemDictionary[index] = item;
|
_itemDictionary[index] = item;
|
||||||
|
item.Index = index;
|
||||||
|
item.ItemContainer = this;
|
||||||
ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent
|
ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent
|
||||||
{
|
{
|
||||||
NewItem = item,
|
NewItem = item,
|
||||||
|
@ -219,12 +228,25 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ReplaceItem(IItem oldItem, IItem newItem)
|
|
||||||
|
public bool ClearItem(int index)
|
||||||
{
|
{
|
||||||
var index = GetIndexByItem(oldItem);
|
var result = _itemDictionary.Remove(index);
|
||||||
return index != UnknownIndex && ReplaceItem(index, newItem);
|
if (result)
|
||||||
|
{
|
||||||
|
ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent
|
||||||
|
{
|
||||||
|
NewItem = null,
|
||||||
|
NewIndex = index,
|
||||||
|
OldIndex = index,
|
||||||
|
OldItem = null,
|
||||||
|
Type = Config.ItemDataChangeEventType.Clear
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int RemoveSelectItem(int number)
|
public int RemoveSelectItem(int number)
|
||||||
{
|
{
|
||||||
return RemoveItem(_selectIndex, number);
|
return RemoveItem(_selectIndex, number);
|
||||||
|
@ -276,37 +298,6 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
|
||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int RemoveItem(IItem item, int number)
|
|
||||||
{
|
|
||||||
var index = GetIndexByItem(item);
|
|
||||||
return index == UnknownIndex ? 0 : RemoveItem(index, number);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <para>Find the corresponding index based on the item object</para>
|
|
||||||
/// <para>根据物品对象查找对应的索引</para>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="item"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private int GetIndexByItem(IItem item)
|
|
||||||
{
|
|
||||||
if (totalCapacity <= 0)
|
|
||||||
{
|
|
||||||
return UnknownIndex;
|
|
||||||
}
|
|
||||||
for (var i = 0; i < totalCapacity; i++)
|
|
||||||
{
|
|
||||||
var contains = _itemDictionary.ContainsKey(i);
|
|
||||||
if (!contains) continue;
|
|
||||||
if (item == _itemDictionary[i])
|
|
||||||
{
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return UnknownIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetUsedCapacity()
|
public int GetUsedCapacity()
|
||||||
{
|
{
|
||||||
return _itemDictionary.Count;
|
return _itemDictionary.Count;
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace ColdMint.scripts.pickable;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class PickAbleTemplate : RigidBody2D, IItem
|
public partial class PickAbleTemplate : RigidBody2D, IItem
|
||||||
{
|
{
|
||||||
|
public int Index { get; set; }
|
||||||
//Do not export this field because the ID is specified within yaml.
|
//Do not export this field because the ID is specified within yaml.
|
||||||
//不要导出此字段,因为ID是在yaml内指定的。
|
//不要导出此字段,因为ID是在yaml内指定的。
|
||||||
public virtual string Id { get; set; } = "ID";
|
public virtual string Id { get; set; } = "ID";
|
||||||
|
@ -292,7 +293,7 @@ public partial class PickAbleTemplate : RigidBody2D, IItem
|
||||||
/// <para>请在此函数内复制节点属性</para>
|
/// <para>请在此函数内复制节点属性</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="node"></param>
|
/// <param name="node"></param>
|
||||||
public void CopyAttributes(Node node)
|
public virtual void CopyAttributes(Node node)
|
||||||
{
|
{
|
||||||
if (node is not PickAbleTemplate pickAbleTemplate)
|
if (node is not PickAbleTemplate pickAbleTemplate)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user