Adjust the logic of how the player picks up items.
调整玩家捡起物品的逻辑。
This commit is contained in:
parent
801b3dd93b
commit
9435f76fc0
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using ColdMint.scripts.camp;
|
||||
using ColdMint.scripts.damage;
|
||||
using ColdMint.scripts.health;
|
||||
using ColdMint.scripts.inventory;
|
||||
using ColdMint.scripts.weapon;
|
||||
using Godot;
|
||||
|
||||
|
@ -29,6 +30,16 @@ public partial class CharacterTemplate : CharacterBody2D
|
|||
|
||||
protected string? CharacterName;
|
||||
|
||||
//Item containers are used to store items.
|
||||
//物品容器用于存储物品。
|
||||
protected IItemContainer? _itemContainer;
|
||||
|
||||
|
||||
public IItemContainer? ItemContainer
|
||||
{
|
||||
get => _itemContainer;
|
||||
set => _itemContainer = value;
|
||||
}
|
||||
|
||||
//Items currently held
|
||||
//当前持有的物品
|
||||
|
@ -167,31 +178,75 @@ public partial class CharacterTemplate : CharacterBody2D
|
|||
///<para>Whether successfully picked up</para>
|
||||
///<para>是否成功拾起</para>
|
||||
/// </returns>
|
||||
public bool PickItem(Node2D pickAbleItem)
|
||||
public bool PickItem(Node2D? pickAbleItem)
|
||||
{
|
||||
if (CurrentItem == null)
|
||||
if (pickAbleItem == null)
|
||||
{
|
||||
if (pickAbleItem is WeaponTemplate weaponTemplate)
|
||||
{
|
||||
if (weaponTemplate.Owner != null && weaponTemplate.Owner != this)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
weaponTemplate.Owner = this;
|
||||
weaponTemplate.SetCollisionMaskValue(Config.LayerNumber.Platform, false);
|
||||
weaponTemplate.SetCollisionMaskValue(Config.LayerNumber.Ground, false);
|
||||
weaponTemplate.EnableContactInjury = false;
|
||||
weaponTemplate.Sleeping = true;
|
||||
}
|
||||
|
||||
pickAbleItem.Reparent(ItemMarker2D);
|
||||
pickAbleItem.Position = Vector2.Zero;
|
||||
CurrentItem = pickAbleItem;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
if (_itemContainer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//Get the currently selected node
|
||||
//拿到当前选择的节点
|
||||
var itemSlotNode = _itemContainer.GetSelectItemSlotNode();
|
||||
if (itemSlotNode == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pickAbleItem is not IItem item)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//First check if we can pick up the item.
|
||||
//先检查我们能否拾起此物品。
|
||||
var canPick = _itemContainer.CanAddItem(item);
|
||||
if (!canPick)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//Is it successfully added to the container?
|
||||
//再检查是否成功的添加到容器内了?
|
||||
var addSuccess = _itemContainer.AddItem(item);
|
||||
if (!addSuccess)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//Set up routine handling of picked up items.
|
||||
//设置捡起物品的常规处理。
|
||||
//You can supplement picking up state handling for more types of objects here.
|
||||
//您可以在这里补充更多类型对象的捡起状态处理。
|
||||
if (pickAbleItem is WeaponTemplate weaponTemplate)
|
||||
{
|
||||
weaponTemplate.Owner = this;
|
||||
weaponTemplate.SetCollisionMaskValue(Config.LayerNumber.Platform, false);
|
||||
weaponTemplate.SetCollisionMaskValue(Config.LayerNumber.Ground, false);
|
||||
weaponTemplate.EnableContactInjury = false;
|
||||
weaponTemplate.Sleeping = true;
|
||||
}
|
||||
|
||||
if (itemSlotNode.GetItem() != null && itemSlotNode.GetItem() == item && CurrentItem == null)
|
||||
{
|
||||
//If the selected item slot in the item container is a newly picked item, and there is no item in the hand, then we put the selected item into the hand.
|
||||
//如果物品容器内选中的物品槽是刚刚捡到的物品,且手里没有物品持有,那么我们将选中的物品放到手上。
|
||||
CurrentItem = pickAbleItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
pickAbleItem.Visible = false;
|
||||
pickAbleItem.ProcessMode = ProcessModeEnum.Disabled;
|
||||
}
|
||||
|
||||
pickAbleItem.Reparent(ItemMarker2D);
|
||||
pickAbleItem.Position = Vector2.Zero;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -20,6 +20,9 @@ public partial class Player : CharacterTemplate
|
|||
|
||||
protected Control FloatLabel;
|
||||
|
||||
//Empty object projectile
|
||||
//空的物品抛射线
|
||||
private Vector2[] emptyVector2Array = new[] { Vector2.Zero };
|
||||
|
||||
//抛物线
|
||||
private Line2D Parabola;
|
||||
|
@ -172,39 +175,40 @@ public partial class Player : CharacterTemplate
|
|||
|
||||
protected override void HookPhysicsProcess(ref Vector2 velocity, double delta)
|
||||
{
|
||||
//When the collision state between the platform detection ray and the platform changes
|
||||
//在平台检测射线与平台碰撞状态改变时
|
||||
if (PlatformDetectionRayCast2D.IsColliding() != CollidingWithPlatform)
|
||||
{
|
||||
//When the state changes, update the action hint
|
||||
//当状态改变时,更新操作提示
|
||||
CollidingWithPlatform = PlatformDetectionRayCast2D.IsColliding();
|
||||
UpdateOperationTip();
|
||||
}
|
||||
|
||||
//If the character is on the ground, give an upward velocity when the jump button is pressed
|
||||
//如果角色正在地面上,按下跳跃键时,给予一个向上的速度
|
||||
if (Input.IsActionJustPressed("ui_up") && IsOnFloor())
|
||||
velocity.Y = JumpVelocity;
|
||||
|
||||
//Moving left and right
|
||||
//左右移动
|
||||
var axis = Input.GetAxis("ui_left", "ui_right");
|
||||
velocity.X = axis * Speed;
|
||||
|
||||
//Use items
|
||||
//使用物品
|
||||
if (Input.IsActionPressed("use_item"))
|
||||
{
|
||||
UseItem(GetGlobalMousePosition());
|
||||
}
|
||||
|
||||
//Pick up an item
|
||||
//捡起物品
|
||||
if (Input.IsActionJustPressed("pick_up"))
|
||||
{
|
||||
var success = PickItem(PickAbleItem);
|
||||
if (success)
|
||||
{
|
||||
if (PickAbleItem is WeaponTemplate weaponTemplate)
|
||||
{
|
||||
GameSceneNodeHolder.HotBar.AddItem(weaponTemplate);
|
||||
}
|
||||
|
||||
PickAbleItem = null;
|
||||
TotalNumberOfPickups--;
|
||||
if (FloatLabel != null)
|
||||
|
@ -221,6 +225,7 @@ public partial class Player : CharacterTemplate
|
|||
{
|
||||
if (CollidingWithPlatform)
|
||||
{
|
||||
//When the character stands on the platform and presses the ui_down key, we cancel the collision between the character and the platform
|
||||
//当角色站在平台上按下 ui_down 键时,我们取消角色与平台的碰撞
|
||||
var timer = new Timer();
|
||||
AddChild(timer);
|
||||
|
@ -237,16 +242,23 @@ public partial class Player : CharacterTemplate
|
|||
}
|
||||
|
||||
|
||||
//Display a parabola when an item is thrown
|
||||
//抛出物品时,显示抛物线
|
||||
if (Input.IsActionPressed("throw"))
|
||||
{
|
||||
if (CurrentItem != null)
|
||||
if (CurrentItem == null)
|
||||
{
|
||||
Parabola.Points = emptyVector2Array;
|
||||
}
|
||||
else
|
||||
{
|
||||
Parabola.Points =
|
||||
ParabolicUtils.ComputeParabolic(ItemMarker2D.Position, GetThrowVelocity(), Gravity, 0.1f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//When you raise your hand, throw the object
|
||||
//抬起手时,抛出物品
|
||||
if (Input.IsActionJustReleased("throw"))
|
||||
{
|
||||
|
@ -295,6 +307,7 @@ public partial class Player : CharacterTemplate
|
|||
|
||||
private Vector2 GetThrowVelocity()
|
||||
{
|
||||
//We take the mouse position, normalize it, and then multiply it by the distance the player can throw
|
||||
//我们拿到鼠标的位置,将其归一化处理,然后乘以玩家可扔出的距离
|
||||
return GetLocalMousePosition().Normalized() * throwingVelocity;
|
||||
}
|
||||
|
@ -307,18 +320,21 @@ public partial class Player : CharacterTemplate
|
|||
switch (axis)
|
||||
{
|
||||
case -1:
|
||||
//Minus 1, we move to the left
|
||||
//-1,向左移动
|
||||
FacingLeft = true;
|
||||
itemMarker2DPosition.X = -ReadOnlyItemMarkerOriginalX;
|
||||
Flip();
|
||||
break;
|
||||
case 1:
|
||||
//1, move to the right
|
||||
//1,向右移动
|
||||
FacingLeft = false;
|
||||
itemMarker2DPosition.X = ReadOnlyItemMarkerOriginalX;
|
||||
Flip();
|
||||
break;
|
||||
default:
|
||||
//0, when it's not pressed
|
||||
//0,没有按下时
|
||||
break;
|
||||
}
|
||||
|
@ -329,6 +345,7 @@ public partial class Player : CharacterTemplate
|
|||
protected override void Flip()
|
||||
{
|
||||
base.Flip();
|
||||
//If there is a weapon, flip it too
|
||||
//如果有武器的话,也要翻转
|
||||
if (CurrentItem != null)
|
||||
{
|
||||
|
@ -341,6 +358,13 @@ public partial class Player : CharacterTemplate
|
|||
|
||||
protected override void EnterThePickingRangeBody(Node node)
|
||||
{
|
||||
if (CurrentItem == node)
|
||||
{
|
||||
//If the node entering the pick range is the node held by the player, then return.
|
||||
//如果说进入拾捡范围的节点是玩家所持有的节点,那么返回。
|
||||
return;
|
||||
}
|
||||
|
||||
if (node is not Node2D)
|
||||
{
|
||||
return;
|
||||
|
@ -398,6 +422,7 @@ public partial class Player : CharacterTemplate
|
|||
TotalNumberOfPickups--;
|
||||
if (TotalNumberOfPickups == 0)
|
||||
{
|
||||
//Set to null if there are no more items to pick up
|
||||
//如果没有可捡的物品了,设置为null
|
||||
PickAbleItem = null;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace ColdMint.scripts.inventory;
|
|||
/// <para>HotBar</para>
|
||||
/// <para>快捷物品栏</para>
|
||||
/// </summary>
|
||||
public partial class HotBar : HBoxContainer
|
||||
public partial class HotBar : HBoxContainer, IItemContainer
|
||||
{
|
||||
private PackedScene _itemSlotPackedScene;
|
||||
private List<ItemSlotNode> _itemSlotNodes;
|
||||
|
@ -30,13 +30,6 @@ public partial class HotBar : HBoxContainer
|
|||
public override void _Process(double delta)
|
||||
{
|
||||
base._Process(delta);
|
||||
if (Input.IsActionPressed("throw"))
|
||||
{
|
||||
//Players are not allowed to switch current items while throwing them.
|
||||
//玩家在抛物品时禁止切换当前物品。
|
||||
return;
|
||||
}
|
||||
|
||||
if (Input.IsActionJustPressed("hotbar_next"))
|
||||
{
|
||||
var count = _itemSlotNodes.Count;
|
||||
|
@ -198,27 +191,39 @@ public partial class HotBar : HBoxContainer
|
|||
var item = _itemSlotNodes[newSelectIndex].GetItem();
|
||||
if (item == null)
|
||||
{
|
||||
LogCat.Log("选择" + oldSelectIndex + "新的为" + newSelectIndex + "空对象");
|
||||
GameSceneNodeHolder.Player.CurrentItem = null;
|
||||
LogCat.Log("我是空吗" + (GameSceneNodeHolder.Player.CurrentItem == null));
|
||||
if (GameSceneNodeHolder.Player != null)
|
||||
{
|
||||
GameSceneNodeHolder.Player.CurrentItem = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item is Node2D node2D)
|
||||
{
|
||||
LogCat.Log("我是空吗" + (GameSceneNodeHolder.Player.CurrentItem == null));
|
||||
LogCat.Log("选择" + oldSelectIndex + "新的为" + newSelectIndex + "已赋值" + node2D);
|
||||
node2D.ProcessMode = ProcessModeEnum.Inherit;
|
||||
node2D.Show();
|
||||
GameSceneNodeHolder.Player.CurrentItem = node2D;
|
||||
if (GameSceneNodeHolder.Player != null)
|
||||
{
|
||||
GameSceneNodeHolder.Player.CurrentItem = node2D;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GameSceneNodeHolder.Player.CurrentItem = null;
|
||||
if (GameSceneNodeHolder.Player != null)
|
||||
{
|
||||
GameSceneNodeHolder.Player.CurrentItem = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool CanAddItem(IItem item)
|
||||
{
|
||||
return Matching(item) != null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <para>Add an item to the HotBar</para>
|
||||
/// <para>在HotBar内添加一个物品</para>
|
||||
|
@ -227,9 +232,54 @@ public partial class HotBar : HBoxContainer
|
|||
/// <returns></returns>
|
||||
public bool AddItem(IItem item)
|
||||
{
|
||||
return _itemSlotNodes.Count != 0 && _itemSlotNodes.Any(itemSlotNode => itemSlotNode.SetItem(item));
|
||||
var itemSlotNode = Matching(item);
|
||||
if (itemSlotNode == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return itemSlotNode.SetItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
public ItemSlotNode? GetSelectItemSlotNode()
|
||||
{
|
||||
if (_itemSlotNodes.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (selectIndex < _itemSlotNodes.Count)
|
||||
{
|
||||
//Prevent subscripts from going out of bounds.
|
||||
//防止下标越界。
|
||||
return _itemSlotNodes[selectIndex];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public ItemSlotNode? Matching(IItem item)
|
||||
{
|
||||
if (_itemSlotNodes.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
foreach (var itemSlotNode in _itemSlotNodes)
|
||||
{
|
||||
if (itemSlotNode.CanSetItem(item))
|
||||
{
|
||||
//If there is an item slot to put this item in, then we return it.
|
||||
//如果有物品槽可放置此物品,那么我们返回它。
|
||||
return itemSlotNode;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Add items tank</para>
|
||||
|
|
|
@ -27,7 +27,7 @@ public interface IItem
|
|||
/// <para>Items can be set with Icon</para>
|
||||
/// <para>物品可以设置图标</para>
|
||||
/// </summary>
|
||||
Texture2D Icon { get; set; }
|
||||
Texture2D? Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para>Item has a name</para>
|
||||
|
|
46
scripts/inventory/IItemContainer.cs
Normal file
46
scripts/inventory/IItemContainer.cs
Normal file
|
@ -0,0 +1,46 @@
|
|||
namespace ColdMint.scripts.inventory;
|
||||
|
||||
/// <summary>
|
||||
/// <para>item container</para>
|
||||
/// <para>物品容器</para>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
///<para>Item containers can store items. Things like backpacks and Hotbars are containers with visual pages.</para>
|
||||
///<para>物品容器可以储存物品。像背包和hotbar是具有可视化页面的容器。</para>
|
||||
/// </remarks>
|
||||
public interface IItemContainer
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>Can the specified item be added to the container?</para>
|
||||
/// <para>指定的物品是否可添加到容器内?</para>
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
bool CanAddItem(IItem item);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Implement methods for adding items</para>
|
||||
/// <para>实现添加物品的方法</para>
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
bool AddItem(IItem item);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Gets the currently selected node</para>
|
||||
/// <para>获取当前选中的节点</para>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
ItemSlotNode? GetSelectItemSlotNode();
|
||||
|
||||
/// <summary>
|
||||
/// <para>Based on the given item, match the item slots where it can be placed</para>
|
||||
/// <para>根据给定的物品,匹配可放置它的物品槽</para>
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns>
|
||||
///<para>Return null if there is no slot to place the item in</para>
|
||||
///<para>若没有槽可放置此物品,则返回null</para>
|
||||
/// </returns>
|
||||
ItemSlotNode? Matching(IItem item);
|
||||
}
|
|
@ -8,189 +8,212 @@ namespace ColdMint.scripts.inventory;
|
|||
/// </summary>
|
||||
public partial class ItemSlotNode : MarginContainer
|
||||
{
|
||||
private IItem? _item;
|
||||
private TextureRect _backgroundTextureRect;
|
||||
private TextureRect _iconTextureRect;
|
||||
private Label _quantityLabel;
|
||||
private Control _control;
|
||||
private bool _isSelect;
|
||||
private Texture2D _backgroundTexture;
|
||||
private Texture2D _backgroundTextureWhenSelect;
|
||||
private IItem? _item;
|
||||
private TextureRect _backgroundTextureRect;
|
||||
private TextureRect _iconTextureRect;
|
||||
private Label _quantityLabel;
|
||||
private Control _control;
|
||||
private bool _isSelect;
|
||||
private Texture2D _backgroundTexture;
|
||||
private Texture2D _backgroundTextureWhenSelect;
|
||||
|
||||
public bool IsSelect
|
||||
{
|
||||
get => _isSelect;
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
_backgroundTextureRect.Texture = _backgroundTextureWhenSelect;
|
||||
}
|
||||
else
|
||||
{
|
||||
_backgroundTextureRect.Texture = _backgroundTexture;
|
||||
}
|
||||
public bool IsSelect
|
||||
{
|
||||
get => _isSelect;
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
_backgroundTextureRect.Texture = _backgroundTextureWhenSelect;
|
||||
}
|
||||
else
|
||||
{
|
||||
_backgroundTextureRect.Texture = _backgroundTexture;
|
||||
}
|
||||
|
||||
_isSelect = value;
|
||||
}
|
||||
}
|
||||
_isSelect = value;
|
||||
}
|
||||
}
|
||||
|
||||
public TextureRect BackgroundTextureRect => _backgroundTextureRect;
|
||||
public TextureRect BackgroundTextureRect => _backgroundTextureRect;
|
||||
|
||||
/// <summary>
|
||||
/// <para>Get the items in the item slot</para>
|
||||
/// <para>获取物品槽内的物品</para>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IItem? GetItem()
|
||||
{
|
||||
return _item;
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>Get the items in the item slot</para>
|
||||
/// <para>获取物品槽内的物品</para>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IItem? GetItem()
|
||||
{
|
||||
return _item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Removes the specified number of items from the item slot</para>
|
||||
/// <para>在物品槽内移除指定数量的物品</para>
|
||||
/// </summary>
|
||||
/// <param name="number"></param>
|
||||
/// <returns></returns>
|
||||
public bool RemoveItem(int number)
|
||||
{
|
||||
if (_item == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>Removes the specified number of items from the item slot</para>
|
||||
/// <para>在物品槽内移除指定数量的物品</para>
|
||||
/// </summary>
|
||||
/// <param name="number"></param>
|
||||
/// <returns></returns>
|
||||
public bool RemoveItem(int number)
|
||||
{
|
||||
if (_item == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var newNumber = _item.Quantity - number;
|
||||
if (newNumber <= 0)
|
||||
{
|
||||
//If the specified number of items is removed, the number of items is less than or equal to 0. Then we return the removal successful and empty the inventory.
|
||||
//如果移除指定数量的物品后,物品数量小于或等于0。那么我们返回移除成功,并清空物品栏。
|
||||
ClearItem();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_item.Quantity = newNumber;
|
||||
UpdateTooltipText(_item);
|
||||
UpdateQuantityLabel(_item.Quantity);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
var newNumber = _item.Quantity - number;
|
||||
if (newNumber <= 0)
|
||||
{
|
||||
//If the specified number of items is removed, the number of items is less than or equal to 0. Then we return the removal successful and empty the inventory.
|
||||
//如果移除指定数量的物品后,物品数量小于或等于0。那么我们返回移除成功,并清空物品栏。
|
||||
ClearItem();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_item.Quantity = newNumber;
|
||||
UpdateTooltipText(_item);
|
||||
UpdateQuantityLabel(_item.Quantity);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Empty the items in the item slot</para>
|
||||
/// <para>清空物品槽内的物品</para>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
///<para>This method does not calculate how many items should be left. If you want to remove a specified number of items, call the RemoveItem method.</para>
|
||||
///<para>此方法不会计算物品应该剩余多少个。若您希望移除指定数量的物品,请调用RemoveItem方法。</para>
|
||||
/// </remarks>
|
||||
public void ClearItem()
|
||||
{
|
||||
_item = null;
|
||||
_iconTextureRect.Texture = null;
|
||||
_control.TooltipText = null;
|
||||
_quantityLabel.Visible = false;
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>Empty the items in the item slot</para>
|
||||
/// <para>清空物品槽内的物品</para>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
///<para>This method does not calculate how many items should be left. If you want to remove a specified number of items, call the RemoveItem method.</para>
|
||||
///<para>此方法不会计算物品应该剩余多少个。若您希望移除指定数量的物品,请调用RemoveItem方法。</para>
|
||||
/// </remarks>
|
||||
public void ClearItem()
|
||||
{
|
||||
_item = null;
|
||||
_iconTextureRect.Texture = null;
|
||||
_control.TooltipText = null;
|
||||
_quantityLabel.Visible = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Sets items for the item slot</para>
|
||||
/// <para>为物品槽设置物品</para>
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
public bool SetItem(IItem item)
|
||||
{
|
||||
if (_item == null)
|
||||
{
|
||||
if (item.Icon != null)
|
||||
{
|
||||
_iconTextureRect.Texture = item.Icon;
|
||||
}
|
||||
|
||||
_item = item;
|
||||
UpdateTooltipText(item);
|
||||
UpdateQuantityLabel(item.Quantity);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//This inventory already has items, but the items in this inventory are not the same as the incoming items
|
||||
//这个物品栏已经有物品了,但是这个物品栏的物品和传入的物品不一样
|
||||
if (_item.Id != item.Id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>Can the specified item be placed in the item slot?</para>
|
||||
/// <para>指定的物品是否可设置在物品槽内?</para>
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
public bool CanSetItem(IItem item)
|
||||
{
|
||||
if (_item == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var newQuantity = _item.Quantity + item.Quantity;
|
||||
if (newQuantity > item.MaxStackQuantity)
|
||||
{
|
||||
//If the amount of the current item exceeds the maximum stack amount after placing it in this inventory
|
||||
//如果将当前物品放置到这个物品栏后,数量超过了最大叠加数量
|
||||
return false;
|
||||
}
|
||||
//This inventory already has items, but the items in this inventory are not the same as the incoming items
|
||||
//这个物品栏已经有物品了,但是这个物品栏的物品和传入的物品不一样
|
||||
if (_item.Id != item.Id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_item.Quantity = newQuantity;
|
||||
UpdateTooltipText(item);
|
||||
UpdateQuantityLabel(newQuantity);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
var newQuantity = _item.Quantity + item.Quantity;
|
||||
if (newQuantity > item.MaxStackQuantity)
|
||||
{
|
||||
//If the amount of the current item exceeds the maximum stack amount after placing it in this inventory
|
||||
//如果将当前物品放置到这个物品栏后,数量超过了最大叠加数量
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Update item tips</para>
|
||||
/// <para>更新物品的提示内容</para>
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
private void UpdateTooltipText(IItem item)
|
||||
{
|
||||
if (Config.IsDebug())
|
||||
{
|
||||
_control.TooltipText = string.Format(TranslationServer.Translate("item_prompt_debug"), item.Id,
|
||||
TranslationServer.Translate(item.Name),
|
||||
item.Quantity, item.MaxStackQuantity, item.GetType().Name,
|
||||
TranslationServer.Translate(item.Description));
|
||||
}
|
||||
else
|
||||
{
|
||||
_control.TooltipText = TranslationServer.Translate(item.Name) + "\n" +
|
||||
TranslationServer.Translate(item.Description);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Update quantity label</para>
|
||||
/// <para>更新数量标签</para>
|
||||
/// </summary>
|
||||
/// <param name="quantity"></param>
|
||||
private void UpdateQuantityLabel(int? quantity)
|
||||
{
|
||||
switch (quantity)
|
||||
{
|
||||
case null:
|
||||
_quantityLabel.Visible = false;
|
||||
return;
|
||||
case > 1:
|
||||
//When the quantity is greater than 1, we display the quantity.
|
||||
//当数量大于1时,我们显示数量
|
||||
_quantityLabel.Text = quantity.ToString();
|
||||
_quantityLabel.Visible = true;
|
||||
break;
|
||||
default:
|
||||
_quantityLabel.Visible = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>Sets items for the item slot</para>
|
||||
/// <para>为物品槽设置物品</para>
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
public bool SetItem(IItem item)
|
||||
{
|
||||
if (!CanSetItem(item))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_backgroundTexture = GD.Load<Texture2D>("res://sprites/ui/ItemBarEmpty.png");
|
||||
_backgroundTextureWhenSelect = GD.Load<Texture2D>("res://sprites/ui/ItemBarFocus.png");
|
||||
_backgroundTextureRect =
|
||||
GetNode<TextureRect>("BackgroundTexture");
|
||||
_iconTextureRect = GetNode<TextureRect>("BackgroundTexture/CenterContainer/IconTextureRect");
|
||||
_quantityLabel = GetNode<Label>("Control/QuantityLabel");
|
||||
_control = GetNode<Control>("Control");
|
||||
_quantityLabel.Visible = false;
|
||||
}
|
||||
}
|
||||
if (_item == null)
|
||||
{
|
||||
if (item.Icon != null)
|
||||
{
|
||||
_iconTextureRect.Texture = item.Icon;
|
||||
}
|
||||
|
||||
_item = item;
|
||||
UpdateTooltipText(item);
|
||||
UpdateQuantityLabel(item.Quantity);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var newQuantity = _item.Quantity + item.Quantity;
|
||||
_item.Quantity = newQuantity;
|
||||
UpdateTooltipText(item);
|
||||
UpdateQuantityLabel(newQuantity);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Update item tips</para>
|
||||
/// <para>更新物品的提示内容</para>
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
private void UpdateTooltipText(IItem item)
|
||||
{
|
||||
if (Config.IsDebug())
|
||||
{
|
||||
_control.TooltipText = string.Format(TranslationServer.Translate("item_prompt_debug"), item.Id,
|
||||
TranslationServer.Translate(item.Name),
|
||||
item.Quantity, item.MaxStackQuantity, item.GetType().Name,
|
||||
TranslationServer.Translate(item.Description));
|
||||
}
|
||||
else
|
||||
{
|
||||
_control.TooltipText = TranslationServer.Translate(item.Name) + "\n" +
|
||||
TranslationServer.Translate(item.Description);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Update quantity label</para>
|
||||
/// <para>更新数量标签</para>
|
||||
/// </summary>
|
||||
/// <param name="quantity"></param>
|
||||
private void UpdateQuantityLabel(int? quantity)
|
||||
{
|
||||
switch (quantity)
|
||||
{
|
||||
case null:
|
||||
_quantityLabel.Visible = false;
|
||||
return;
|
||||
case > 1:
|
||||
//When the quantity is greater than 1, we display the quantity.
|
||||
//当数量大于1时,我们显示数量
|
||||
_quantityLabel.Text = quantity.ToString();
|
||||
_quantityLabel.Visible = true;
|
||||
break;
|
||||
default:
|
||||
_quantityLabel.Visible = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_backgroundTexture = GD.Load<Texture2D>("res://sprites/ui/ItemBarEmpty.png");
|
||||
_backgroundTextureWhenSelect = GD.Load<Texture2D>("res://sprites/ui/ItemBarFocus.png");
|
||||
_backgroundTextureRect =
|
||||
GetNode<TextureRect>("BackgroundTexture");
|
||||
_iconTextureRect = GetNode<TextureRect>("BackgroundTexture/CenterContainer/IconTextureRect");
|
||||
_quantityLabel = GetNode<Label>("Control/QuantityLabel");
|
||||
_control = GetNode<Control>("Control");
|
||||
_quantityLabel.Visible = false;
|
||||
}
|
||||
}
|
|
@ -66,7 +66,14 @@ public partial class GameSceneLoader : SceneLoaderTemplate
|
|||
//Register players in the holder
|
||||
//在持有者内注册玩家
|
||||
var node2D = (Node2D)packedScene.Instantiate();
|
||||
GameSceneNodeHolder.Player = node2D as Player;
|
||||
if (node2D is Player player)
|
||||
{
|
||||
GameSceneNodeHolder.Player = player;
|
||||
//Allow the player to pick up items.
|
||||
//使玩家可以捡起物品。
|
||||
player.ItemContainer = GameSceneNodeHolder.HotBar;
|
||||
}
|
||||
|
||||
var gameRoot = GetNode<Node2D>(".");
|
||||
gameRoot.AddChild(node2D);
|
||||
node2D.Position = new Vector2(55, 70);
|
||||
|
|
Loading…
Reference in New Issue
Block a user