Add a backpack for testing.

加入测试使用的背包。
This commit is contained in:
Cold-Mint 2024-06-12 23:42:35 +08:00
parent 856a957c6a
commit f219380a5f
Signed by: Cold-Mint
GPG Key ID: C5A9BF8A98E0CE99
24 changed files with 197 additions and 50 deletions

View File

@ -1,3 +1,5 @@
id,zh,en,ja id,zh,en,ja
staff_of_the_undead,死灵法杖,StaffOfTheUndead,ネクロポリスの杖です staff_of_the_undead,死灵法杖,StaffOfTheUndead,ネクロポリスの杖です
staff_of_the_undead_desc,发射诅咒,可将敌人转化为邪恶的怪物。,Cast a curse that transforms enemies into evil monsters.,呪いを発射して、敵を邪悪な怪物に変えることができます。 staff_of_the_undead_desc,发射诅咒,可将敌人转化为邪恶的怪物。,Cast a curse that transforms enemies into evil monsters.,呪いを発射して、敵を邪悪な怪物に変えることができます。
packsack,背包,Packsack,背嚢
packsack_desc,可以装载更多物品的背包。,A backpack that can hold more items.,より多くのアイテムを保持できるバックパックです。
1 id zh en ja
2 staff_of_the_undead 死灵法杖 StaffOfTheUndead ネクロポリスの杖です
3 staff_of_the_undead_desc 发射诅咒,可将敌人转化为邪恶的怪物。 Cast a curse that transforms enemies into evil monsters. 呪いを発射して、敵を邪悪な怪物に変えることができます。
4 packsack 背包 Packsack 背嚢
5 packsack_desc 可以装载更多物品的背包。 A backpack that can hold more items. より多くのアイテムを保持できるバックパックです。

17
locals/Item.csv.import Normal file
View File

@ -0,0 +1,17 @@
[remap]
importer="csv_translation"
type="Translation"
uid="uid://dydilbm2stxr4"
[deps]
files=["res://locals/Item.zh.translation", "res://locals/Item.en.translation", "res://locals/Item.ja.translation"]
source_file="res://locals/Item.csv"
dest_files=["res://locals/Item.zh.translation", "res://locals/Item.en.translation", "res://locals/Item.ja.translation"]
[params]
compress=true
delimiter=0

BIN
locals/Item.en.translation Normal file

Binary file not shown.

BIN
locals/Item.ja.translation Normal file

Binary file not shown.

BIN
locals/Item.zh.translation Normal file

Binary file not shown.

View File

@ -1,17 +0,0 @@
[remap]
importer="csv_translation"
type="Translation"
uid="uid://ci3wou75hhj6e"
[deps]
files=["res://locals/Weapon.zh.translation", "res://locals/Weapon.en.translation", "res://locals/Weapon.ja.translation"]
source_file="res://locals/Weapon.csv"
dest_files=["res://locals/Weapon.zh.translation", "res://locals/Weapon.en.translation", "res://locals/Weapon.ja.translation"]
[params]
compress=true
delimiter=0

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,24 @@
[gd_scene load_steps=4 format=3 uid="uid://cn10fimoem04m"]
[ext_resource type="Script" path="res://scripts/inventory/Packsack.cs" id="1_8ehup"]
[ext_resource type="Texture2D" uid="uid://b1twcink38sh0" path="res://sprites/Player.png" id="2_e1ale"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_xqyue"]
size = Vector2(41, 57)
[node name="RigidBody2D" type="RigidBody2D"]
collision_layer = 8
collision_mask = 38
script = ExtResource("1_8ehup")
metadata/Id = "Packsack"
metadata/MaxStackQuantity = 1
metadata/Icon = ExtResource("2_e1ale")
metadata/Name = "packsack"
metadata/Description = "packsack_desc"
[node name="Player" type="Sprite2D" parent="."]
texture = ExtResource("2_e1ale")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(-0.5, 3.5)
shape = SubResource("RectangleShape2D_xqyue")

View File

@ -146,7 +146,7 @@ hotbar_previous={
[internationalization] [internationalization]
locale/translations=PackedStringArray("res://locals/DeathInfo.en.translation", "res://locals/DeathInfo.ja.translation", "res://locals/DeathInfo.zh.translation", "res://locals/InputMapping.en.translation", "res://locals/InputMapping.ja.translation", "res://locals/InputMapping.zh.translation", "res://locals/Log.en.translation", "res://locals/Log.ja.translation", "res://locals/Log.zh.translation", "res://locals/Slogan.en.translation", "res://locals/Slogan.ja.translation", "res://locals/Slogan.zh.translation", "res://locals/UI.en.translation", "res://locals/UI.ja.translation", "res://locals/UI.zh.translation", "res://locals/Weapon.en.translation", "res://locals/Weapon.ja.translation", "res://locals/Weapon.zh.translation") locale/translations=PackedStringArray("res://locals/DeathInfo.en.translation", "res://locals/DeathInfo.ja.translation", "res://locals/DeathInfo.zh.translation", "res://locals/InputMapping.en.translation", "res://locals/InputMapping.ja.translation", "res://locals/InputMapping.zh.translation", "res://locals/Log.en.translation", "res://locals/Log.ja.translation", "res://locals/Log.zh.translation", "res://locals/Slogan.en.translation", "res://locals/Slogan.ja.translation", "res://locals/Slogan.zh.translation", "res://locals/UI.en.translation", "res://locals/UI.ja.translation", "res://locals/UI.zh.translation", "res://locals/Item.en.translation", "res://locals/Item.ja.translation", "res://locals/Item.zh.translation")
[layer_names] [layer_names]

View File

@ -96,3 +96,5 @@ visible = false
[node name="PlayerContainer" type="Node2D" parent="."] [node name="PlayerContainer" type="Node2D" parent="."]
[node name="AICharacterContainer" type="Node2D" parent="."] [node name="AICharacterContainer" type="Node2D" parent="."]
[node name="PacksackContainer" type="Node2D" parent="."]

View File

@ -38,4 +38,10 @@ public static class EventManager
/// <para>地图生成完成事件</para> /// <para>地图生成完成事件</para>
/// </summary> /// </summary>
public static Action<MapGenerationCompleteEvent>? MapGenerationCompleteEvent; public static Action<MapGenerationCompleteEvent>? MapGenerationCompleteEvent;
/// <summary>
/// <para>Player Instance Change Event</para>
/// <para>玩家实例改变事件</para>
/// </summary>
public static Action<PlayerInstanceChangeEvent>? PlayerInstanceChangeEvent;
} }

View File

@ -1,5 +1,6 @@
using ColdMint.scripts.character; using ColdMint.scripts.character;
using ColdMint.scripts.inventory; using ColdMint.scripts.inventory;
using ColdMint.scripts.map.events;
using Godot; using Godot;
namespace ColdMint.scripts; namespace ColdMint.scripts;
@ -10,11 +11,27 @@ namespace ColdMint.scripts;
/// </summary> /// </summary>
public static class GameSceneNodeHolder public static class GameSceneNodeHolder
{ {
private static Player? _player;
/// <summary> /// <summary>
/// <para>Player instances within the game scene</para> /// <para>Player instances within the game scene</para>
/// <para>游戏场景内的玩家实例</para> /// <para>游戏场景内的玩家实例</para>
/// </summary> /// </summary>
public static Player? Player { get; set; } public static Player? Player
{
get => _player;
set
{
_player = value;
//Broadcast the event to the outside when the player instance changes.
//当玩家实例改变时,向外广播事件。
var playerInstanceChangeEvent = new PlayerInstanceChangeEvent
{
PlayerInstance = _player
};
EventManager.PlayerInstanceChangeEvent?.Invoke(playerInstanceChangeEvent);
}
}
/// <summary> /// <summary>
/// <para>WeaponContainer</para> /// <para>WeaponContainer</para>
@ -22,6 +39,12 @@ public static class GameSceneNodeHolder
/// </summary> /// </summary>
public static Node2D? WeaponContainer { get; set; } public static Node2D? WeaponContainer { get; set; }
/// <summary>
/// <para>PacksackContainer</para>
/// <para>背包容器</para>
/// </summary>
public static Node2D? PacksackContainer { get; set; }
/// <summary> /// <summary>
/// <para>PlayerContainer</para> /// <para>PlayerContainer</para>
/// <para>玩家容器</para> /// <para>玩家容器</para>

View File

@ -662,6 +662,7 @@ public partial class CharacterTemplate : CharacterBody2D
return; return;
} }
CallDeferred("NodeReparent", node2D);
switch (item) switch (item)
{ {
case WeaponTemplate weaponTemplate: case WeaponTemplate weaponTemplate:
@ -671,7 +672,6 @@ public partial class CharacterTemplate : CharacterBody2D
} }
weaponTemplate.Picked = false; weaponTemplate.Picked = false;
CallDeferred("WeaponTemplateReparent", weaponTemplate);
var timer = new Timer(); var timer = new Timer();
weaponTemplate.AddChild(timer); weaponTemplate.AddChild(timer);
timer.WaitTime = _itemCollisionRecoveryTime; timer.WaitTime = _itemCollisionRecoveryTime;
@ -720,13 +720,13 @@ public partial class CharacterTemplate : CharacterBody2D
} }
/// <summary> /// <summary>
/// <para>Replace the parent node of the weapon</para> /// <para>Replace the parent node of a node</para>
/// <para>替换武器的父节点</para> /// <para>替换节点的父节点</para>
/// </summary> /// </summary>
/// <param name="weaponTemplate"></param> /// <param name="node"></param>
private void WeaponTemplateReparent(WeaponTemplate weaponTemplate) private void NodeReparent(Node node)
{ {
weaponTemplate.Reparent(GameSceneNodeHolder.WeaponContainer); node.Reparent(NodeUtils.FindContainerNode(node, GetNode("/root")));
} }
public sealed override void _PhysicsProcess(double delta) public sealed override void _PhysicsProcess(double delta)

View File

@ -3,6 +3,8 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using ColdMint.scripts.damage; using ColdMint.scripts.damage;
using ColdMint.scripts.deathInfo; using ColdMint.scripts.deathInfo;
using ColdMint.scripts.debug;
using ColdMint.scripts.inventory;
using ColdMint.scripts.map.events; using ColdMint.scripts.map.events;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;
using ColdMint.scripts.weapon; using ColdMint.scripts.weapon;
@ -130,10 +132,9 @@ public partial class Player : CharacterTemplate
operationTipBuilder.Append(TranslationServerUtils.Translate(InputMap.ActionGetEvents("throw")[0].AsText())); operationTipBuilder.Append(TranslationServerUtils.Translate(InputMap.ActionGetEvents("throw")[0].AsText()));
operationTipBuilder.Append("[/color]"); operationTipBuilder.Append("[/color]");
operationTipBuilder.Append(TranslationServerUtils.Translate("throw")); operationTipBuilder.Append(TranslationServerUtils.Translate("throw"));
if (CurrentItem is WeaponTemplate weaponTemplate) if (CurrentItem is IItem item)
{ {
operationTipBuilder.Append(TranslationServerUtils.Translate(weaponTemplate.Name)); operationTipBuilder.Append(TranslationServerUtils.Translate(item.Name));
//提示武器攻击
operationTipBuilder.Append(' '); operationTipBuilder.Append(' ');
operationTipBuilder.Append("[color="); operationTipBuilder.Append("[color=");
operationTipBuilder.Append(Config.OperationTipActionColor); operationTipBuilder.Append(Config.OperationTipActionColor);
@ -142,7 +143,7 @@ public partial class Player : CharacterTemplate
TranslationServerUtils.Translate(InputMap.ActionGetEvents("use_item")[0].AsText())); TranslationServerUtils.Translate(InputMap.ActionGetEvents("use_item")[0].AsText()));
operationTipBuilder.Append("[/color]"); operationTipBuilder.Append("[/color]");
operationTipBuilder.Append(TranslationServerUtils.Translate("use_item")); operationTipBuilder.Append(TranslationServerUtils.Translate("use_item"));
operationTipBuilder.Append(TranslationServerUtils.Translate(weaponTemplate.Name)); operationTipBuilder.Append(TranslationServerUtils.Translate(item.Name));
} }
} }

View File

@ -1,4 +1,4 @@
using ColdMint.scripts.character; using ColdMint.scripts.map.events;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;
using Godot; using Godot;
@ -10,19 +10,31 @@ namespace ColdMint.scripts.inventory;
/// </summary> /// </summary>
public partial class HotBar : HBoxContainer public partial class HotBar : HBoxContainer
{ {
private UniversalItemContainer? _universalItemContainer; private IItemContainer? _itemContainer;
public override void _Ready() public override void _Ready()
{ {
base._Ready(); base._Ready();
_universalItemContainer = new UniversalItemContainer _itemContainer = new UniversalItemContainer();
{ EventManager.PlayerInstanceChangeEvent += PlayerInstanceChangeEvent;
CharacterTemplate = new Player()
};
NodeUtils.DeleteAllChild(this); NodeUtils.DeleteAllChild(this);
for (var i = 0; i < Config.HotBarSize; i++) for (var i = 0; i < Config.HotBarSize; i++)
{ {
_universalItemContainer.AddItemSlot(this, i); _itemContainer.AddItemSlot(this, i);
}
}
/// <summary>
/// <para>When the player instance changes, we update the binding of the item container</para>
/// <para>当玩家实例改变时,我们更新物品容器的绑定</para>
/// </summary>
/// <param name="playerInstanceChangeEvent"></param>
private void PlayerInstanceChangeEvent(PlayerInstanceChangeEvent playerInstanceChangeEvent)
{
if (_itemContainer is UniversalItemContainer universalItemContainer)
{
universalItemContainer.CharacterTemplate = GameSceneNodeHolder.Player;
} }
} }
@ -33,14 +45,14 @@ public partial class HotBar : HBoxContainer
{ {
//Mouse wheel down //Mouse wheel down
//鼠标滚轮向下 //鼠标滚轮向下
_universalItemContainer?.SelectTheNextItemSlot(); _itemContainer?.SelectTheNextItemSlot();
} }
if (Input.IsActionJustPressed("hotbar_previous")) if (Input.IsActionJustPressed("hotbar_previous"))
{ {
//Mouse wheel up //Mouse wheel up
//鼠标滚轮向上 //鼠标滚轮向上
_universalItemContainer?.SelectThePreviousItemSlot(); _itemContainer?.SelectThePreviousItemSlot();
} }
if (Input.IsActionJustPressed("hotbar_1")) if (Input.IsActionJustPressed("hotbar_1"))
@ -98,15 +110,22 @@ public partial class HotBar : HBoxContainer
/// <param name="shortcutKeyIndex"></param> /// <param name="shortcutKeyIndex"></param>
private void SelectItemSlotByHotBarShortcutKey(int shortcutKeyIndex) private void SelectItemSlotByHotBarShortcutKey(int shortcutKeyIndex)
{ {
if (_universalItemContainer == null) if (_itemContainer == null)
{ {
return; return;
} }
_universalItemContainer.SelectItemSlot(shortcutKeyIndex);
_itemContainer.SelectItemSlot(shortcutKeyIndex);
} }
public IItemContainer? GetItemContainer() public IItemContainer? GetItemContainer()
{ {
return _universalItemContainer; return _itemContainer;
}
public override void _ExitTree()
{
base._ExitTree();
EventManager.PlayerInstanceChangeEvent -= PlayerInstanceChangeEvent;
} }
} }

View File

@ -0,0 +1,40 @@
using System;
using ColdMint.scripts.debug;
using Godot;
namespace ColdMint.scripts.inventory;
/// <summary>
/// <para>packsack</para>
/// <para>背包</para>
/// </summary>
public partial class Packsack : RigidBody2D, IItem
{
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; }
private IItemContainer? _itemContainer;
public override void _Ready()
{
base._Ready();
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();
_itemContainer = new UniversalItemContainer();
}
public IItemContainer? GetItemContainer()
{
return _itemContainer;
}
}

View File

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using ColdMint.scripts.character; using ColdMint.scripts.character;
using ColdMint.scripts.debug;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;
using Godot; using Godot;

View File

@ -35,6 +35,10 @@ public partial class GameSceneLoader : SceneLoaderTemplate
//加载武器容器 //加载武器容器
var weaponContainer = GetNode<Node2D>("WeaponContainer"); var weaponContainer = GetNode<Node2D>("WeaponContainer");
GameSceneNodeHolder.WeaponContainer = weaponContainer; GameSceneNodeHolder.WeaponContainer = weaponContainer;
//Load Packsack container
//加载背包容器
var packsackContainer = GetNode<Node2D>("PacksackContainer");
GameSceneNodeHolder.PacksackContainer = packsackContainer;
//Load AICharacter container //Load AICharacter container
//加载AICharacter容器 //加载AICharacter容器
var aiCharacterContainer = GetNode<Node2D>("AICharacterContainer"); var aiCharacterContainer = GetNode<Node2D>("AICharacterContainer");

View File

@ -47,14 +47,22 @@ public partial class MainMenuLoader : UiLoaderTemplate
{ {
Id = Config.LootListId.Test Id = Config.LootListId.Test
}; };
var lootEntry = new LootEntry var staffOfTheUndead = new LootEntry
{ {
Chance = 1f, Chance = 0.05f,
MaxQuantity = 5, MaxQuantity = 5,
MinQuantity = 1, MinQuantity = 1,
ResPath = "res://prefab/weapons/staffOfTheUndead.tscn" ResPath = "res://prefab/weapons/staffOfTheUndead.tscn"
}; };
testLootList.AddLootEntry(lootEntry); testLootList.AddLootEntry(staffOfTheUndead);
var packsack = new LootEntry
{
Chance = 1f,
MaxQuantity = 1,
MinQuantity = 1,
ResPath = "res://prefab/packsacks/packsack.tscn"
};
testLootList.AddLootEntry(packsack);
LootListManager.RegisterLootList(testLootList); LootListManager.RegisterLootList(testLootList);
} }
DeathInfoGenerator.RegisterDeathInfoHandler(new SelfDeathInfoHandler()); DeathInfoGenerator.RegisterDeathInfoHandler(new SelfDeathInfoHandler());

View File

@ -300,7 +300,6 @@ public static class MapGenerator
{ {
Tag = AiCharacterGenerateEvent.TagMapGenerationComplete Tag = AiCharacterGenerateEvent.TagMapGenerationComplete
}; };
LogCat.Log("触发事件" + (EventManager.AiCharacterGenerateEvent == null));
EventManager.AiCharacterGenerateEvent?.Invoke(aiCharacterGenerateEvent); EventManager.AiCharacterGenerateEvent?.Invoke(aiCharacterGenerateEvent);
} }

View File

@ -0,0 +1,12 @@
using ColdMint.scripts.character;
namespace ColdMint.scripts.map.events;
/// <summary>
/// <para>Player instance change event</para>
/// <para>玩家实例改变事件</para>
/// </summary>
public class PlayerInstanceChangeEvent
{
public Player? PlayerInstance { get; set; }
}

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using ColdMint.scripts.debug; using ColdMint.scripts.debug;
using ColdMint.scripts.inventory;
using ColdMint.scripts.weapon; using ColdMint.scripts.weapon;
using Godot; using Godot;
@ -122,6 +123,11 @@ public static class NodeUtils
{ {
return GameSceneNodeHolder.WeaponContainer; return GameSceneNodeHolder.WeaponContainer;
} }
if (GameSceneNodeHolder.PacksackContainer!= null && childNode is Packsack)
{
return GameSceneNodeHolder.PacksackContainer;
}
return defaultParentNode; return defaultParentNode;
} }