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>空变量</para>
|
||||
/// </summary>
|
||||
public static readonly Variant EmptyVariant = new();
|
||||
public static readonly Variant EmptyVariant = new();
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
@ -243,7 +243,12 @@ public static class Config
|
|||
/// <para>Replace</para>
|
||||
/// <para>被替换</para>
|
||||
/// </summary>
|
||||
Replace
|
||||
Replace,
|
||||
/// <summary>
|
||||
/// <para>Clear</para>
|
||||
/// <para>被清空</para>
|
||||
/// </summary>
|
||||
Clear
|
||||
}
|
||||
|
||||
public enum OsEnum
|
||||
|
|
|
@ -15,10 +15,7 @@ public partial class HotBar : HBoxContainer
|
|||
public override void _Ready()
|
||||
{
|
||||
base._Ready();
|
||||
var universalItemContainer = new UniversalItemContainer(Config.HotBarSize)
|
||||
{
|
||||
EnablePlaceholder = true
|
||||
};
|
||||
var universalItemContainer = new UniversalItemContainer(Config.HotBarSize);
|
||||
_itemContainer = universalItemContainer;
|
||||
_itemContainer.SupportSelect = true;
|
||||
_itemContainerDisplay = new ItemSlotContainerDisplay(this);
|
||||
|
|
|
@ -4,6 +4,11 @@ namespace ColdMint.scripts.inventory;
|
|||
|
||||
public interface IItem
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>The position of the item in the container</para>
|
||||
/// <para>物品在容器内的位置</para>
|
||||
/// </summary>
|
||||
public int Index { get; set; }
|
||||
/// <summary>
|
||||
/// <para>ID of current item</para>
|
||||
/// <para>当前物品的ID</para>
|
||||
|
|
|
@ -50,8 +50,12 @@ public interface IItemContainer
|
|||
/// <para>Gets a placeholder object</para>
|
||||
/// <para>获取占位符对象</para>
|
||||
/// </summary>
|
||||
/// <param name="index">
|
||||
///<para>index</para>
|
||||
///<para>占位符代替的索引</para>
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
IItem? GetPlaceHolderItem();
|
||||
IItem GetPlaceHolderItem(int index);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Gets the selected location</para>
|
||||
|
@ -88,7 +92,13 @@ public interface IItemContainer
|
|||
/// <returns></returns>
|
||||
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>
|
||||
/// <para>Gets the item in the specified location, equivalent to <see cref="GetItem"/></para>
|
||||
|
@ -128,14 +138,6 @@ public interface IItemContainer
|
|||
/// </returns>
|
||||
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>
|
||||
/// <para>Gets the used capacity of the item container</para>
|
||||
/// <para>获取物品容器已使用的容量</para>
|
||||
|
|
|
@ -118,12 +118,16 @@ public abstract class ItemContainerDisplayTemplate : IItemContainerDisplay
|
|||
var item = itemContainer.GetItem(index);
|
||||
if (item == null)
|
||||
{
|
||||
item = itemContainer.GetPlaceHolderItem();
|
||||
item = itemContainer.GetPlaceHolderItem(index);
|
||||
}
|
||||
if (item != null)
|
||||
if (itemContainer.SupportSelect)
|
||||
{
|
||||
item.IsSelect = index == itemContainer.GetSelectIndex();
|
||||
}
|
||||
else
|
||||
{
|
||||
item.IsSelect = false;
|
||||
}
|
||||
itemDisplay.Update(item);
|
||||
itemDisplay.ShowSelf();
|
||||
}
|
||||
|
|
|
@ -78,6 +78,12 @@ public partial class ItemSlotNode : MarginContainer, IItemDisplay
|
|||
|
||||
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;
|
||||
if (type == Variant.Type.Nil)
|
||||
{
|
||||
|
@ -89,10 +95,20 @@ public partial class ItemSlotNode : MarginContainer, IItemDisplay
|
|||
{
|
||||
return;
|
||||
}
|
||||
if (Item is null || Item is PlaceholderItem)
|
||||
|
||||
if (Item is PlaceholderItem placeholderItem)
|
||||
{
|
||||
sourceItem.ItemContainer?.RemoveItem(sourceItem, -1);
|
||||
Item?.ItemContainer?.ReplaceItem(Item, sourceItem);
|
||||
var placeholderItemContainer = placeholderItem.ItemContainer;
|
||||
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)
|
||||
{
|
||||
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()
|
||||
{
|
||||
base._Ready();
|
||||
ItemContainer = new UniversalItemContainer(NumberSlots);
|
||||
ItemContainer.SupportSelect = false;
|
||||
if (SelfItemContainer == null)
|
||||
{
|
||||
SelfItemContainer = new UniversalItemContainer(NumberSlots);
|
||||
SelfItemContainer.SupportSelect = false;
|
||||
}
|
||||
GameSceneDepend.DynamicUiGroup?.RegisterControl(Path, () =>
|
||||
{
|
||||
var packedScene = GD.Load<PackedScene>(Path);
|
||||
|
|
|
@ -8,6 +8,7 @@ namespace ColdMint.scripts.inventory;
|
|||
/// </summary>
|
||||
public class PlaceholderItem : IItem
|
||||
{
|
||||
public int Index { get; set; }
|
||||
public string Id { get; set; }
|
||||
public Texture2D Icon { get; }
|
||||
public string Name { get; }
|
||||
|
|
|
@ -110,6 +110,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
|
|||
|
||||
var nextAvailableIndex = _nextAvailableIndex;
|
||||
_itemDictionary[nextAvailableIndex] = item;
|
||||
item.Index = nextAvailableIndex;
|
||||
item.ItemContainer = this;
|
||||
UpdateNextAvailableIndex();
|
||||
UpdateSelectStatus(nextAvailableIndex, item);
|
||||
|
@ -169,6 +170,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
|
|||
}
|
||||
var finalNextAvailableIndex = _nextAvailableIndex;
|
||||
_itemDictionary[finalNextAvailableIndex] = item;
|
||||
item.Index = finalNextAvailableIndex;
|
||||
item.ItemContainer = this;
|
||||
UpdateNextAvailableIndex();
|
||||
UpdateSelectStatus(finalNextAvailableIndex, item);
|
||||
|
@ -182,11 +184,16 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
|
|||
}
|
||||
|
||||
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()
|
||||
|
@ -208,6 +215,8 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
|
|||
{
|
||||
var oldItem = GetItem(index);
|
||||
_itemDictionary[index] = item;
|
||||
item.Index = index;
|
||||
item.ItemContainer = this;
|
||||
ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent
|
||||
{
|
||||
NewItem = item,
|
||||
|
@ -219,12 +228,25 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
|
|||
return true;
|
||||
}
|
||||
|
||||
public bool ReplaceItem(IItem oldItem, IItem newItem)
|
||||
|
||||
public bool ClearItem(int index)
|
||||
{
|
||||
var index = GetIndexByItem(oldItem);
|
||||
return index != UnknownIndex && ReplaceItem(index, newItem);
|
||||
var result = _itemDictionary.Remove(index);
|
||||
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)
|
||||
{
|
||||
return RemoveItem(_selectIndex, number);
|
||||
|
@ -276,37 +298,6 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
|
|||
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()
|
||||
{
|
||||
return _itemDictionary.Count;
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace ColdMint.scripts.pickable;
|
|||
/// </summary>
|
||||
public partial class PickAbleTemplate : RigidBody2D, IItem
|
||||
{
|
||||
public int Index { get; set; }
|
||||
//Do not export this field because the ID is specified within yaml.
|
||||
//不要导出此字段,因为ID是在yaml内指定的。
|
||||
public virtual string Id { get; set; } = "ID";
|
||||
|
@ -292,7 +293,7 @@ public partial class PickAbleTemplate : RigidBody2D, IItem
|
|||
/// <para>请在此函数内复制节点属性</para>
|
||||
/// </summary>
|
||||
/// <param name="node"></param>
|
||||
public void CopyAttributes(Node node)
|
||||
public virtual void CopyAttributes(Node node)
|
||||
{
|
||||
if (node is not PickAbleTemplate pickAbleTemplate)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user