diff --git a/data/itemRegs/packsacks.yaml b/data/itemRegs/packsacks.yaml
index 937aea4..20b9eff 100644
--- a/data/itemRegs/packsacks.yaml
+++ b/data/itemRegs/packsacks.yaml
@@ -1,4 +1,4 @@
- id: packsack
scene_path: res://prefab/packsacks/packsack.tscn
icon_path: res://sprites/Player.png
- max_stack_value: 1
\ No newline at end of file
+ max_stack_value: 1
diff --git a/data/itemRegs/weapons.yaml b/data/itemRegs/weapons.yaml
index 171c341..9637a34 100644
--- a/data/itemRegs/weapons.yaml
+++ b/data/itemRegs/weapons.yaml
@@ -1,4 +1,4 @@
- id: staff_of_the_undead
scene_path: res://prefab/weapons/staffOfTheUndead.tscn
icon_path: res://sprites/weapon/staffOfTheUndead.png
- max_stack_value: 1
\ No newline at end of file
+ max_stack_value: 1
diff --git a/locals/Log.csv b/locals/Log.csv
index 78c2114..63924a5 100644
--- a/locals/Log.csv
+++ b/locals/Log.csv
@@ -26,7 +26,6 @@ log_death_info,生物{0}被{1}击败。,"Creature {0} was defeated by {1}.",生
log_loot_list_has_no_entries,ID为{0}的战利品表,没有指定条目。,"Loot list with ID {0}, no entry specified.",ID{0}の戦利品テーブルは、エントリ指定されていません。
log_not_within_the_loot_spawn_range,给定的数值{0}没有在战利品{1}的生成范围{2}内。,The given value {0} is not within the spawn range {2} of loot {1}.,与えられた数値{0}は戦利品{1}の生成範囲{2}内にありません。
log_loot_data_quantity,有{0}个战利品数据被返回。,{0} loot data was returned.,{0}個の戦利品データが返されます。
-
log_start_item_register_from_file,开始从文件注册物品信息,Start registering item information from files,アイテム情報をファイルから登録開始
log_item_register_from_file,从文件{0}中注册物品信息,Registering item information from file {0},ファイル{0}からアイテム情報を登録する
log_item_register_find_item_in_file,注册发现的物品{0},Register discovered item {0},見つかったアイテム{0}を登録
diff --git a/locals/UI.csv b/locals/UI.csv
index 7f407b4..caa5fee 100644
--- a/locals/UI.csv
+++ b/locals/UI.csv
@@ -25,3 +25,11 @@ ui_room_injection_processor,房间注入处理器,Room injection processor,部
ui_game_over_title,游戏结束!,Game Over!,ゲームオーバー!
ui_death_info_describe,死因,death,死因
ui_restart,重新开始,Restart,ぶり返す
+ui_contributor_tips,由{0}位贡献者共同打造,Built by {0} contributors,{0}のコントリビューターが共同で作り上げました
+ui_contributor,贡献者,contributor,貢献者です
+ui_coder,编程,coder,程序设计
+ui_artist,美术,artist,びじゅつ
+ui_musician,音乐,musician,音楽
+ui_character_voice,角色配音,character_voice,キャラクターボイスです
+ui_translator,翻译,translator,翻訳
+ui_unordered_list_tip,排名不分先后,Ranking is not in order,順位は関係ありません
diff --git a/prefab/roomTemplates/dungeon/initialRoom.tscn b/prefab/roomTemplates/dungeon/initialRoom.tscn
index 06fa45b..c313f04 100644
--- a/prefab/roomTemplates/dungeon/initialRoom.tscn
+++ b/prefab/roomTemplates/dungeon/initialRoom.tscn
@@ -45,18 +45,42 @@ script = ExtResource("2_6p8mv")
[node name="StaffOfTheUndead" parent="." instance=ExtResource("3_ud0w8")]
position = Vector2(231, 116)
+_minContactInjury = null
+_maxContactInjury = null
+_firingIntervalAsMillisecond = null
+_recoil = null
[node name="StaffOfTheUndead2" parent="." instance=ExtResource("3_ud0w8")]
position = Vector2(113, 149)
+_minContactInjury = null
+_maxContactInjury = null
+_firingIntervalAsMillisecond = null
+_recoil = null
[node name="StaffOfTheUndead5" parent="." instance=ExtResource("3_ud0w8")]
position = Vector2(213, 177)
+_minContactInjury = null
+_maxContactInjury = null
+_firingIntervalAsMillisecond = null
+_recoil = null
[node name="StaffOfTheUndead6" parent="." instance=ExtResource("3_ud0w8")]
position = Vector2(290, 167)
+_minContactInjury = null
+_maxContactInjury = null
+_firingIntervalAsMillisecond = null
+_recoil = null
[node name="StaffOfTheUndead3" parent="." instance=ExtResource("3_ud0w8")]
position = Vector2(70, 88)
+_minContactInjury = null
+_maxContactInjury = null
+_firingIntervalAsMillisecond = null
+_recoil = null
[node name="StaffOfTheUndead4" parent="." instance=ExtResource("3_ud0w8")]
position = Vector2(367, 85)
+_minContactInjury = null
+_maxContactInjury = null
+_firingIntervalAsMillisecond = null
+_recoil = null
diff --git a/prefab/ui/contributorGroup.tscn b/prefab/ui/contributorGroup.tscn
new file mode 100644
index 0000000..8f30514
--- /dev/null
+++ b/prefab/ui/contributorGroup.tscn
@@ -0,0 +1,32 @@
+[gd_scene load_steps=2 format=3 uid="uid://6i7rgx3sdu1k"]
+
+[ext_resource type="Script" path="res://scripts/loader/uiLoader/ContributorGroupLoader.cs" id="1_xwjh1"]
+
+[node name="ContributorGroup" type="Control"]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+script = ExtResource("1_xwjh1")
+
+[node name="TitleLabel" type="Label" parent="."]
+layout_mode = 1
+anchors_preset = 10
+anchor_right = 1.0
+offset_bottom = 39.0
+grow_horizontal = 2
+theme_override_font_sizes/font_size = 25
+text = "组名"
+
+[node name="HFlowContainer" type="HFlowContainer" parent="."]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+offset_top = 51.0
+grow_horizontal = 2
+grow_vertical = 2
diff --git a/prefab/weapons/staffOfTheUndead.tscn b/prefab/weapons/staffOfTheUndead.tscn
index d4732bf..29cebc9 100644
--- a/prefab/weapons/staffOfTheUndead.tscn
+++ b/prefab/weapons/staffOfTheUndead.tscn
@@ -16,6 +16,10 @@ collision_mask = 34
script = ExtResource("1_w8hhv")
ProjectileScenes = [ExtResource("2_34250")]
Id = "staff_of_the_undead"
+_minContactInjury = null
+_maxContactInjury = null
+_firingIntervalAsMillisecond = null
+_recoil = null
metadata/Projectiles = PackedStringArray("res://prefab/projectile/curseOfTheUndead.tscn")
[node name="DamageArea2D" type="Area2D" parent="."]
diff --git a/scenes/contributor.tscn b/scenes/contributor.tscn
new file mode 100644
index 0000000..da7f898
--- /dev/null
+++ b/scenes/contributor.tscn
@@ -0,0 +1,68 @@
+[gd_scene load_steps=2 format=3 uid="uid://ljvmhhrk1d6j"]
+
+[ext_resource type="Script" path="res://scripts/loader/uiLoader/ContributorLoader.cs" id="1_ia4x6"]
+
+[node name="Contributor" type="Control"]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+script = ExtResource("1_ia4x6")
+
+[node name="Panel" type="Panel" parent="."]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+
+[node name="CenterContainer" type="CenterContainer" parent="."]
+layout_mode = 1
+anchors_preset = 10
+anchor_right = 1.0
+offset_bottom = 45.0
+grow_horizontal = 2
+
+[node name="Label" type="Label" parent="CenterContainer"]
+layout_mode = 2
+theme_override_font_sizes/font_size = 30
+text = "ui_contributor"
+
+[node name="ExitButton" type="Button" parent="."]
+layout_mode = 1
+anchors_preset = 1
+anchor_left = 1.0
+anchor_right = 1.0
+offset_left = -86.0
+offset_top = 6.0
+offset_right = -19.0
+offset_bottom = 39.0
+grow_horizontal = 0
+text = "ui_close"
+
+[node name="VBoxContainer" type="VBoxContainer" parent="."]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+offset_left = 20.0
+offset_top = 59.0
+offset_right = -18.0
+offset_bottom = -20.0
+grow_horizontal = 2
+grow_vertical = 2
+
+[node name="Label" type="Label" parent="."]
+layout_mode = 1
+anchors_preset = 2
+anchor_top = 1.0
+anchor_bottom = 1.0
+offset_left = 16.0
+offset_top = -36.0
+offset_right = 168.0
+offset_bottom = -11.0
+grow_vertical = 0
+text = "ui_unordered_list_tip"
diff --git a/scenes/mainMenu.tscn b/scenes/mainMenu.tscn
index 9e32f9d..6fb0a0a 100644
--- a/scenes/mainMenu.tscn
+++ b/scenes/mainMenu.tscn
@@ -119,6 +119,12 @@ grow_vertical = 0
layout_mode = 2
horizontal_alignment = 2
+[node name="ContributorButton" type="LinkButton" parent="VBoxContainer2"]
+layout_direction = 3
+layout_mode = 2
+text = "ui_contributor_tips"
+underline = 1
+
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer2"]
layout_mode = 2
diff --git a/scripts/contribute/ContributorData.cs b/scripts/contribute/ContributorData.cs
new file mode 100644
index 0000000..7857a6e
--- /dev/null
+++ b/scripts/contribute/ContributorData.cs
@@ -0,0 +1,26 @@
+namespace ColdMint.scripts.contribute;
+
+///
+/// Contributor information
+/// 贡献者数据
+///
+public class ContributorData
+{
+ ///
+ /// Contributor's name
+ /// 贡献者的名字
+ ///
+ public string? Name { get; set; }
+
+ ///
+ /// Links to contributors' home pages
+ /// 贡献者的主页链接
+ ///
+ public string? Url { get; set; }
+
+ ///
+ /// Type of contribution
+ /// 贡献的类型
+ ///
+ public ContributorType[]? ContributorTypes { get; set; }
+}
\ No newline at end of file
diff --git a/scripts/contribute/ContributorDataManager.cs b/scripts/contribute/ContributorDataManager.cs
new file mode 100644
index 0000000..e8af8d2
--- /dev/null
+++ b/scripts/contribute/ContributorDataManager.cs
@@ -0,0 +1,151 @@
+using System;
+using System.Collections.Generic;
+using ColdMint.scripts.utils;
+
+namespace ColdMint.scripts.contribute;
+
+///
+/// Contributor data Manager
+/// 贡献者数据管理器
+///
+public static class ContributorDataManager
+{
+ private static Dictionary>? _contributorTypeDictionary;
+
+ private static readonly ContributorData[] ContributorArray =
+ [
+ new ContributorData
+ {
+ Name = "Cold-Mint",
+ Url = "https://github.com/Cold-Mint",
+ ContributorTypes = [ContributorType.Coder]
+ },
+ new ContributorData
+ {
+ Name = "Web13234",
+ Url = "https://github.com/Web13234",
+ ContributorTypes = [ContributorType.Coder]
+ },
+ new ContributorData
+ {
+ Name = "HYPERLINK BLOCKED",
+ Url = "https://www.pixiv.net/users/74412798",
+ ContributorTypes = [ContributorType.Artist]
+ }
+ ];
+
+ ///
+ /// Get contributor totals
+ /// 获取贡献者总数
+ ///
+ ///
+ public static int GetContributorTotals()
+ {
+ return ContributorArray.Length;
+ }
+
+ ///
+ /// Gets a dictionary of contribution types to the contributor array
+ /// 获取贡献类型到贡献者数组的字典
+ ///
+ ///
+ ///Cache the results after calling this method, as it is very expensive to generate results.
+ ///调用此方法后请将结果缓存起来,因为生成结果是非常昂贵的。
+ ///
+ ///
+ ///
+ public static Dictionary? GetContributorTypeToContributorDataArray()
+ {
+ if (_contributorTypeDictionary == null)
+ {
+ return null;
+ }
+
+ var result = new Dictionary();
+ foreach (var contributorType in _contributorTypeDictionary.Keys)
+ {
+ result[contributorType] = _contributorTypeDictionary[contributorType].ToArray();
+ }
+
+ return result;
+ }
+
+ ///
+ /// Register all contributor data
+ /// 注册所有的贡献者数据
+ ///
+ public static void RegisterAllContributorData()
+ {
+ if (_contributorTypeDictionary!= null)
+ {
+ return;
+ }
+ foreach (var contributorData in ContributorArray)
+ {
+ RegisterContributorData(contributorData);
+ }
+ }
+
+ ///
+ /// Gets a string description of a contribution type
+ /// 获取某个贡献类型的字符串描述
+ ///
+ ///
+ ///
+ ///
+ public static string? ContributorTypeToString(ContributorType contributorType)
+ {
+ return contributorType switch
+ {
+ ContributorType.Coder => TranslationServerUtils.Translate("ui_coder"),
+ ContributorType.Artist => TranslationServerUtils.Translate("ui_artist"),
+ ContributorType.Musician => TranslationServerUtils.Translate("ui_musician"),
+ ContributorType.CharacterVoice => TranslationServerUtils.Translate("ui_character_voice"),
+ ContributorType.Translator => TranslationServerUtils.Translate("ui_translator"),
+ _ => throw new ArgumentOutOfRangeException(nameof(contributorType), contributorType, null)
+ };
+ }
+
+ ///
+ /// Register contributor data to the type dictionary
+ /// 注册贡献者数据到类型字典
+ ///
+ ///
+ ///
+ private static void AddContributorDataToTypeDictionary(ContributorType contributorType,
+ ContributorData contributorData)
+ {
+ if (_contributorTypeDictionary == null)
+ {
+ return;
+ }
+
+ if (_contributorTypeDictionary.ContainsKey(contributorType))
+ {
+ _contributorTypeDictionary[contributorType].Add(contributorData);
+ }
+ else
+ {
+ _contributorTypeDictionary[contributorType] = [contributorData];
+ }
+ }
+
+ ///
+ /// Register Contributor data
+ /// 注册贡献者数据
+ ///
+ ///
+ private static void RegisterContributorData(ContributorData contributorData)
+ {
+ if (contributorData.Name == null || contributorData.ContributorTypes == null)
+ {
+ return;
+ }
+
+ _contributorTypeDictionary ??= new Dictionary>();
+ foreach (var contributorDataContributorType in contributorData.ContributorTypes)
+ {
+ AddContributorDataToTypeDictionary(contributorDataContributorType, contributorData);
+ }
+ }
+}
\ No newline at end of file
diff --git a/scripts/contribute/ContributorType.cs b/scripts/contribute/ContributorType.cs
new file mode 100644
index 0000000..57bbfb4
--- /dev/null
+++ b/scripts/contribute/ContributorType.cs
@@ -0,0 +1,54 @@
+namespace ColdMint.scripts.contribute;
+
+///
+/// Contribution type
+/// 贡献类型
+///
+public enum ContributorType
+{
+ ///
+ /// Coder
+ /// 程序员
+ ///
+ ///
+ ///Contributed code to the project
+ ///为项目贡献了代码
+ ///
+ Coder,
+ ///
+ /// Artist
+ /// 美术
+ ///
+ ///
+ ///Contributed art assets to the project
+ ///为项目贡献了美术资产
+ ///
+ Artist,
+ ///
+ /// Musician
+ /// 音乐家
+ ///
+ ///
+ ///Contributed music, sound assets to the project
+ ///为项目贡献了音乐,音效资产
+ ///
+ Musician,
+ ///
+ /// CharacterVoice
+ /// 角色配音
+ ///
+ ///
+ ///Contributed voice to the game character
+ ///为游戏角色贡献了语音
+ ///
+ CharacterVoice,
+ ///
+ /// Translator
+ /// 翻译者
+ ///
+ ///
+ ///Contribute to localization of the project(specified language)
+ ///为项目的本地化做出贡献(指定的语言)
+ ///
+ Translator
+}
\ No newline at end of file
diff --git a/scripts/inventory/IItemContainer.cs b/scripts/inventory/IItemContainer.cs
index 1a5a36b..81b2778 100644
--- a/scripts/inventory/IItemContainer.cs
+++ b/scripts/inventory/IItemContainer.cs
@@ -210,7 +210,6 @@ public interface IItemContainer : IEnumerable
/// IEnumerable for the item slot matched to, will be empty if there's no slot satisfies the predicate
/// 包含匹配到的槽位的IEnumerable,当没有满足条件的槽位时为空
///
- ///
IEnumerable MatchAll(Func predicate);
diff --git a/scripts/item/Packsack.cs b/scripts/item/Packsack.cs
index 6ac8e91..5d70057 100644
--- a/scripts/item/Packsack.cs
+++ b/scripts/item/Packsack.cs
@@ -1,6 +1,5 @@
using ColdMint.scripts.inventory;
using ColdMint.scripts.item.itemStacks;
-
using Godot;
namespace ColdMint.scripts.item;
@@ -37,7 +36,7 @@ public partial class Packsack : RigidBody2D, IItem
public bool CanStackWith(IItem item) => false;
- public IItemStack? SpecialStack()
+ public IItemStack SpecialStack()
{
return new PacksackStack(this);
}
@@ -49,8 +48,5 @@ public partial class Packsack : RigidBody2D, IItem
{
base._Ready();
ItemContainer = new UniversalItemContainer();
-
- //Test: Add one ItemSlot for pack
- ItemContainer.AddItemSlot(this);
}
}
\ No newline at end of file
diff --git a/scripts/loader/uiLoader/ContributorGroupLoader.cs b/scripts/loader/uiLoader/ContributorGroupLoader.cs
new file mode 100644
index 0000000..4c35f58
--- /dev/null
+++ b/scripts/loader/uiLoader/ContributorGroupLoader.cs
@@ -0,0 +1,102 @@
+using ColdMint.scripts.contribute;
+using ColdMint.scripts.utils;
+using Godot;
+
+namespace ColdMint.scripts.loader.uiLoader;
+
+///
+/// Contributor group loader
+/// 贡献者组加载器
+///
+public partial class ContributorGroupLoader : UiLoaderTemplate
+{
+ private string? _title;
+ private ContributorData[]? _contributorDataArray;
+
+ ///
+ /// Contributor array
+ /// 贡献者数组
+ ///
+ public ContributorData[]? ContributorDataArray
+ {
+ get => _contributorDataArray;
+ set
+ {
+ _contributorDataArray = value;
+ SetContributorData(value);
+ }
+ }
+
+ ///
+ /// The title of the contribution group
+ /// 贡献组的标题
+ ///
+ public string? Title
+ {
+ get => _title;
+ set
+ {
+ _title = value;
+ SetTitle(value);
+ }
+ }
+
+ private Label? _titleLabel;
+ private HFlowContainer? _flowContainer;
+
+ public override void InitializeUi()
+ {
+ _titleLabel = GetNode