diff --git a/.gitignore b/.gitignore
index cbaf961..267c058 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,6 @@
export_presets.cfg
.idea/
.vs/
-*.translation
\ No newline at end of file
+*.translation
+*.user
+*.DotSettings
diff --git a/ColdMint.Traveler.csproj b/ColdMint.Traveler.csproj
index ec53ff3..9ba3342 100644
--- a/ColdMint.Traveler.csproj
+++ b/ColdMint.Traveler.csproj
@@ -10,5 +10,6 @@
+
\ No newline at end of file
diff --git a/data/itemRegs/packsacks.yaml b/data/itemRegs/packsacks.yaml
new file mode 100644
index 0000000..937aea4
--- /dev/null
+++ b/data/itemRegs/packsacks.yaml
@@ -0,0 +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
diff --git a/data/itemRegs/weapons.yaml b/data/itemRegs/weapons.yaml
new file mode 100644
index 0000000..171c341
--- /dev/null
+++ b/data/itemRegs/weapons.yaml
@@ -0,0 +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
diff --git a/locals/Action.csv b/locals/Action.csv
new file mode 100644
index 0000000..9c072c2
--- /dev/null
+++ b/locals/Action.csv
@@ -0,0 +1,8 @@
+id,zh,en,ja
+action_pick_up,拾捡,Pick up ,拾います
+action_move_left,向左移动,Move left,左に移動します
+action_move_right,向右移动,Move right,右に移動します
+action_jump,跳跃,Jump,飛
+action_throw,抛出,Throw a ,ほうしゅつ
+action_use_item,使用,Use,しよう
+action_jump_down,跳下平台,Jump off platform,踊り場から飛び降ります
\ No newline at end of file
diff --git a/locals/Action.csv.import b/locals/Action.csv.import
new file mode 100644
index 0000000..c34e892
--- /dev/null
+++ b/locals/Action.csv.import
@@ -0,0 +1,17 @@
+[remap]
+
+importer="csv_translation"
+type="Translation"
+uid="uid://b0hqoab2n241u"
+
+[deps]
+
+files=["res://locals/Action.zh.translation", "res://locals/Action.en.translation", "res://locals/Action.ja.translation"]
+
+source_file="res://locals/Action.csv"
+dest_files=["res://locals/Action.zh.translation", "res://locals/Action.en.translation", "res://locals/Action.ja.translation"]
+
+[params]
+
+compress=true
+delimiter=0
diff --git a/locals/Log.csv b/locals/Log.csv
index 7a74051..78c2114 100644
--- a/locals/Log.csv
+++ b/locals/Log.csv
@@ -1,28 +1,33 @@
id,zh,en,ja
-map_generator_is_running,地图生成器正在运行中,请稍后重试。,"Map Generator is running, please try again later.",マップ生成器が動作中ですので、後ほどリトライしてください。
-missing_parameters,缺少参数。,Missing parameters.,パラメータが不足しています。
-room_root_node_must_be_node2d,房间根节点必须是 Node2D。,Room root node must be an instance of Node2D.,ルートノードはNode2Dでなければなりません。
-width_or_height_of_room_slot_must_be_1,房间槽的宽度或高度必须为1。,The width or height of the room slot must be 1.,部屋の溝の幅または高さは1でなければなりません。
-connected_room_timeout,连接房间超时。,Timeout when connecting rooms.,接続部屋はタイムアウトです。
-projectiles_is_empty,未设置抛射体。,The projectile is not set.,射出体は設置されていません。
-map_generator_missing_parameters,地图生成器缺少参数。,Map generator missing parameters.,マップジェネレータが不足しています。
-map_generator_attempts_to_parse_empty_layout_diagrams,地图生成器尝试解析空的布局图。,Map generator attempts to parse empty layout diagrams.,マップジェネレータは空のレイアウト図を解析しようとしています。
-map_generator_has_no_starting_room_data,地图生成器没有起点房间数据。,Map generator has no starting room data.,マップ生成器に起点部屋データはありません。
-room_placement_strategy_terminates_map_generation,房间的放置策略终止了地图生成。,The room placement strategy terminates map generation.,部屋の配置ポリシーはマップ作成を終了します。
-start_room_placement_information_returns_empty,起始房间放置信息返回空。,Start room placement information returns empty.,スタートルーム放置情報は空に戻ります。
-start_room_placement_failed,起始房间放置失败。,Start room placement failed.,スタートルーム放置失敗です。
-room_data_missing,房间数据缺失。,Missing room data.,部屋データが欠落しています。
-failed_to_calculate_the_room_location,计算房间{0}位置时失败。,Failed to calculate the location of room {0}.,部屋{0}の位置を計算するのに失敗します。
-place_existing_rooms,放置已存在的房间{0}。,Place existing rooms {0}.,既存の部屋を置きます{0}。
-room_placement_failed,房间{0}放置失败。,Room {0} placement failed.,部屋{0}の放置に失敗します。
-room_placement_information,房间{0}已被成功放置在{1}。,Room {0} has been successfully placed in {1}.,部屋{0}を{1}に配置しました。
-room_injection_processor_does_not_exist,找不到房间注入处理器{0},请检测是否在MapGenerator内注册。,"Room injection processor {0} not found, check to see if it is registered in MapGenerator.",部屋注入プロセッサ{0}が見つかりません、MapGenerator内に登録されているかどうか検出してください。
-time_range_debug,当前时间:{0}起始时间:{1},结束时间{2},是否在范围内{3},"Current time: {0} Start time: {1}, end time {2}, whether in range {3}",現在時間:{0}開始時間:{1}終了時間{2}範囲内かどうか{3}です
-player_spawn_debug,玩家{0}生成在{1}。,"Player {0} spawned at {1}.",プレイヤー{0}が{1}に生成されました。
-player_packed_scene_not_exist,玩家预制场景不存在。,Player packed scene does not exist.,プレイヤーのパックされたシーンが存在しません。
-exit_the_room_debug,节点{0}退出房间{1}。,"Node {0} exits room {1}.",ノード{0}が部屋{1}を退出します。
-enter_the_room_debug,节点{0}进入房间{1}。,"Node {0} enters room {1}.",ノード{0}が部屋{1}に入ります。
-death_info,生物{0}被{1}击败。,"Creature {0} was defeated by {1}.",生物{0}が{1}によって打ち負かされました。
-loot_list_has_no_entries,ID为{0}的战利品表,没有指定条目。,"Loot list with ID {0}, no entry specified.",ID{0}の戦利品テーブルは、エントリ指定されていません。
-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}内にありません。
-loot_data_quantity,有{0}个战利品数据被返回。,{0} loot data was returned.,{0}個の戦利品データが返されます。
\ No newline at end of file
+log_map_generator_is_running,地图生成器正在运行中,请稍后重试。,"Map Generator is running, please try again later.",マップ生成器が動作中ですので、後ほどリトライしてください。
+log_missing_parameters,缺少参数。,Missing parameters.,パラメータが不足しています。
+log_room_root_node_must_be_node2d,房间根节点必须是 Node2D。,Room root node must be an instance of Node2D.,ルートノードはNode2Dでなければなりません。
+log_width_or_height_of_room_slot_must_be_1,房间槽的宽度或高度必须为1。,The width or height of the room slot must be 1.,部屋の溝の幅または高さは1でなければなりません。
+log_connected_room_timeout,连接房间超时。,Timeout when connecting rooms.,接続部屋はタイムアウトです。
+log_projectiles_is_empty,未设置抛射体。,The projectile is not set.,射出体は設置されていません。
+log_map_generator_missing_parameters,地图生成器缺少参数。,Map generator missing parameters.,マップジェネレータが不足しています。
+log_map_generator_attempts_to_parse_empty_layout_diagrams,地图生成器尝试解析空的布局图。,Map generator attempts to parse empty layout diagrams.,マップジェネレータは空のレイアウト図を解析しようとしています。
+log_map_generator_has_no_starting_room_data,地图生成器没有起点房间数据。,Map generator has no starting room data.,マップ生成器に起点部屋データはありません。
+log_room_placement_strategy_terminates_map_generation,房间的放置策略终止了地图生成。,The room placement strategy terminates map generation.,部屋の配置ポリシーはマップ作成を終了します。
+log_start_room_placement_information_returns_empty,起始房间放置信息返回空。,Start room placement information returns empty.,スタートルーム放置情報は空に戻ります。
+log_start_room_placement_failed,起始房间放置失败。,Start room placement failed.,スタートルーム放置失敗です。
+log_room_data_missing,房间数据缺失。,Missing room data.,部屋データが欠落しています。
+log_failed_to_calculate_the_room_location,计算房间{0}位置时失败。,Failed to calculate the location of room {0}.,部屋{0}の位置を計算するのに失敗します。
+log_place_existing_rooms,放置已存在的房间{0}。,Place existing rooms {0}.,既存の部屋を置きます{0}。
+log_room_placement_failed,房间{0}放置失败。,Room {0} placement failed.,部屋{0}の放置に失敗します。
+log_room_placement_information,房间{0}已被成功放置在{1}。,Room {0} has been successfully placed in {1}.,部屋{0}を{1}に配置しました。
+log_room_injection_processor_does_not_exist,找不到房间注入处理器{0},请检测是否在MapGenerator内注册。,"Room injection processor {0} not found, check to see if it is registered in MapGenerator.",部屋注入プロセッサ{0}が見つかりません、MapGenerator内に登録されているかどうか検出してください。
+log_time_range_debug,当前时间:{0}起始时间:{1},结束时间{2},是否在范围内{3},"Current time: {0} Start time: {1}, end time {2}, whether in range {3}",現在時間:{0}開始時間:{1}終了時間{2}範囲内かどうか{3}です
+log_player_spawn_debug,玩家{0}生成在{1}。,"Player {0} spawned at {1}.",プレイヤー{0}が{1}に生成されました。
+log_player_packed_scene_not_exist,玩家预制场景不存在。,Player packed scene does not exist.,プレイヤーのパックされたシーンが存在しません。
+log_exit_the_room_debug,节点{0}退出房间{1}。,"Node {0} exits room {1}.",ノード{0}が部屋{1}を退出します。
+log_enter_the_room_debug,节点{0}进入房间{1}。,"Node {0} enters room {1}.",ノード{0}が部屋{1}に入ります。
+log_death_info,生物{0}被{1}击败。,"Creature {0} was defeated by {1}.",生物{0}が{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}を登録
+log_error_when_open_item_regs_dir,尝试打开物品信息目录时发生错误,Error when opening itemRegs dir,アイテム情報カタログを開こうとしてエラーが発生しました。
\ No newline at end of file
diff --git a/locals/Misc.csv b/locals/Misc.csv
new file mode 100644
index 0000000..1d3370e
--- /dev/null
+++ b/locals/Misc.csv
@@ -0,0 +1,4 @@
+id,zh,en,ja
+de,的,"'s",の
+default_player_name,白纸,blankPaper,しらかみ
+item_prompt_debug,ID:{0}\n名称:{1}\n数量:{2}\n最大叠加数量:{3}\n数据类型:{4}\n描述:{5},ID: {0}\nName: {1}\nQuantity: {2}\nMaximum stacking quantity: {3}\nData type: {4}\nDescription:{5},id:{0}\n名称:{1}\nの数は最大{2}\nシナジー数:{3}\nデータタイプ:{4}\n述べ表わす:{5}
\ No newline at end of file
diff --git a/locals/Misc.csv.import b/locals/Misc.csv.import
new file mode 100644
index 0000000..c2d2d11
--- /dev/null
+++ b/locals/Misc.csv.import
@@ -0,0 +1,17 @@
+[remap]
+
+importer="csv_translation"
+type="Translation"
+uid="uid://bdyf1nkmm3h6c"
+
+[deps]
+
+files=["res://locals/Misc.zh.translation", "res://locals/Misc.en.translation", "res://locals/Misc.ja.translation"]
+
+source_file="res://locals/Misc.csv"
+dest_files=["res://locals/Misc.zh.translation", "res://locals/Misc.en.translation", "res://locals/Misc.ja.translation"]
+
+[params]
+
+compress=true
+delimiter=0
diff --git a/locals/UI.csv b/locals/UI.csv
index 0289d47..7f407b4 100644
--- a/locals/UI.csv
+++ b/locals/UI.csv
@@ -1,37 +1,27 @@
id,zh,en,ja
-product_name,异界旅人,A traveler from another world,異界の旅人です
-start_game,开始游戏,Start game,ゲームを始めます
-settings,设置,Settings,備え付け
-pick_up,拾捡,Pick up ,拾います
-move_left,向左移动,Move left,左に移動します
-move_right,向右移动,Move right,右に移動します
-jump,跳跃,Jump,飛
-throw,抛出,Throw a ,ほうしゅつ
-use_item,使用,Use,しよう
-jump_down,跳下平台,Jump off platform,踊り場から飛び降ります
-de,的,"'s",の
-default_player_name,白纸,blankPaper,しらかみ
-item_prompt_debug,ID:{0}\n名称:{1}\n数量:{2}\n最大叠加数量:{3}\n数据类型:{4}\n描述:{5},ID: {0}\nName: {1}\nQuantity: {2}\nMaximum stacking quantity: {3}\nData type: {4}\nDescription:{5},id:{0}\n名称:{1}\nの数は最大{2}\nシナジー数:{3}\nデータタイプ:{4}\n述べ表わす:{5}
-level_graph_editor,关卡图编辑器,Level graph editor,ステージマップエディター
-create_room,创建房间,Create room,部屋を作ります
-close,关闭,Close,閉じます
-name,名称,Name,めいしょう
-describe,描述,Describe,ないよう
-creation,创建,Creation,創建
-default_room_name,房间{0},Room{0},部屋{0}です
-room_template_collection_prompt,房间模板集(传入路径为文件夹,将选择文件夹内的所有子文件),"Room template set (incoming path is folder, all subfiles in folder will be selected)",部屋テンプレートセット(着信経路をフォルダにして、フォルダ内のすべてのサブファイルを選択します。)
-error_specifying_room_template_line,位于{0}错误,文件或文件夹不存在。,"Located at {0} error, file or folder does not exist.",{0}エラーに位置し、ファイルやフォルダが存在しません。
-line_errors_must_start_with_res,位于{0}错误,必须以res://开头。,"Located at {0} error, must start with res://.",{0}エラーに位置し、res://で始めなければなりません。
-open_the_export_directory,打开导出目录,Open the export directory,エクスポートディレクトリを開きます
-save,保存,Save,保留
-filename,文件名,File name,ファイル名
-cancel,取消,Cancel,キャンセル
-load,加载,Load,ろーど
-delete_selected_node,删除选中的节点,Delete selected node,選択されたノードを削除します
-re_create_map,重新创建地图,Re-create map,地図を再作成します
-seed_info,种子:{0},Seed: {0},シード:{0}
-tags,标签,Tags,と呼ぶ
-room_injection_processor,房间注入处理器,Room injection processor,部屋注入処理器
-game_over_title,游戏结束!,Game Over!,ゲームオーバー!
-death_info_describe,死因,death,死因
-restart,重新开始,Restart,ぶり返す
+ui_product_name,异界旅人,A traveler from another world,異界の旅人です
+ui_start_game,开始游戏,Start game,ゲームを始めます
+ui_settings,设置,Settings,備え付け
+ui_level_graph_editor,关卡图编辑器,Level graph editor,ステージマップエディター
+ui_create_room,创建房间,Create room,部屋を作ります
+ui_close,关闭,Close,閉じます
+ui_name,名称,Name,めいしょう
+ui_describe,描述,Describe,ないよう
+ui_creation,创建,Creation,創建
+ui_default_room_name,房间{0},Room{0},部屋{0}です
+ui_room_template_collection_prompt,房间模板集(传入路径为文件夹,将选择文件夹内的所有子文件),"Room template set (incoming path is folder, all subfiles in folder will be selected)",部屋テンプレートセット(着信経路をフォルダにして、フォルダ内のすべてのサブファイルを選択します。)
+ui_error_specifying_room_template_line,位于{0}错误,文件或文件夹不存在。,"Located at {0} error, file or folder does not exist.",{0}エラーに位置し、ファイルやフォルダが存在しません。
+ui_line_errors_must_start_with_res,位于{0}错误,必须以res://开头。,"Located at {0} error, must start with res://.",{0}エラーに位置し、res://で始めなければなりません。
+ui_open_the_export_directory,打开导出目录,Open the export directory,エクスポートディレクトリを開きます
+ui_save,保存,Save,セーブ
+ui_filename,文件名,File name,ファイル名
+ui_cancel,取消,Cancel,キャンセル
+ui_load,加载,Load,ロード
+ui_delete_selected_node,删除选中的节点,Delete selected node,選択されたノードを削除します
+ui_re_create_map,重新创建地图,Re-create map,地図を再作成します
+ui_seed_info,种子:{0},Seed: {0},シード:{0}
+ui_tags,标签,Tags,と呼ぶ
+ui_room_injection_processor,房间注入处理器,Room injection processor,部屋注入処理器
+ui_game_over_title,游戏结束!,Game Over!,ゲームオーバー!
+ui_death_info_describe,死因,death,死因
+ui_restart,重新开始,Restart,ぶり返す
diff --git a/prefab/packsacks/packsack.tscn b/prefab/packsacks/packsack.tscn
index a6ec43c..8160034 100644
--- a/prefab/packsacks/packsack.tscn
+++ b/prefab/packsacks/packsack.tscn
@@ -10,6 +10,7 @@ size = Vector2(41, 57)
collision_layer = 8
collision_mask = 38
script = ExtResource("1_slakl")
+Id = "packsack"
[node name="Player" type="Sprite2D" parent="."]
texture = ExtResource("2_e1ale")
diff --git a/prefab/ui/RoomNode.tscn b/prefab/ui/RoomNode.tscn
index 89f86c0..ce9b02f 100644
--- a/prefab/ui/RoomNode.tscn
+++ b/prefab/ui/RoomNode.tscn
@@ -18,4 +18,4 @@ script = ExtResource("1_jiu7r")
[node name="DescribeLabel" type="Label" parent="."]
layout_mode = 2
-text = "describe"
+text = "ui_describe"
diff --git a/project.godot b/project.godot
index 0fcb4f3..933865e 100644
--- a/project.godot
+++ b/project.godot
@@ -146,7 +146,7 @@ hotbar_previous={
[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/Item.en.translation", "res://locals/Item.ja.translation", "res://locals/Item.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", "res://locals/Action.en.translation", "res://locals/Action.ja.translation", "res://locals/Action.zh.translation", "res://locals/Misc.en.translation", "res://locals/Misc.ja.translation", "res://locals/Misc.zh.translation")
[layer_names]
diff --git a/scenes/LevelGraphEditor.tscn b/scenes/LevelGraphEditor.tscn
index 2811dd6..a09ba4e 100644
--- a/scenes/LevelGraphEditor.tscn
+++ b/scenes/LevelGraphEditor.tscn
@@ -32,7 +32,7 @@ offset_left = 11.0
offset_top = 7.0
offset_right = 143.0
offset_bottom = 32.0
-text = "level_graph_editor"
+text = "ui_level_graph_editor"
[node name="CreateOrEditorPanel" type="Panel" parent="."]
visible = false
@@ -193,27 +193,27 @@ grow_horizontal = 0
[node name="DeleteSelectedNodeButton" type="Button" parent="HBoxContainer"]
layout_mode = 2
-text = "delete_selected_node"
+text = "ui_delete_selected_node"
[node name="OpenExportFolderButton" type="Button" parent="HBoxContainer"]
layout_mode = 2
-text = "open_the_export_directory"
+text = "ui_open_the_export_directory"
[node name="ShowSavePanelButton" type="Button" parent="HBoxContainer"]
layout_mode = 2
-text = "save"
+text = "ui_save"
[node name="ShowLoadPanelButton" type="Button" parent="HBoxContainer"]
layout_mode = 2
-text = "load"
+text = "ui_load"
[node name="ShowCreateRoomPanelButton" type="Button" parent="HBoxContainer"]
layout_mode = 2
-text = "create_room"
+text = "ui_create_room"
[node name="ReturnButton" type="Button" parent="HBoxContainer"]
layout_mode = 2
-text = "close"
+text = "ui_close"
[node name="SaveOrLoadPanel" type="Panel" parent="."]
visible = false
diff --git a/scenes/game.tscn b/scenes/game.tscn
index b07ed07..7d03926 100644
--- a/scenes/game.tscn
+++ b/scenes/game.tscn
@@ -72,7 +72,7 @@ script = ExtResource("5_dis4v")
layout_mode = 0
offset_right = 8.0
offset_bottom = 8.0
-text = "re_create_map"
+text = "ui_re_create_map"
[node name="SeedLabel" type="Label" parent="CanvasLayer/Control"]
layout_mode = 1
diff --git a/scenes/gameOverMenu.tscn b/scenes/gameOverMenu.tscn
index 5dfefd4..5b8e2a7 100644
--- a/scenes/gameOverMenu.tscn
+++ b/scenes/gameOverMenu.tscn
@@ -37,7 +37,7 @@ layout_mode = 2
[node name="GameOverLabel" type="Label" parent="CenterContainer/VBoxContainer/CenterContainer"]
layout_mode = 2
theme_override_font_sizes/font_size = 30
-text = "game_over_title"
+text = "ui_game_over_title"
[node name="MarginContainer" type="MarginContainer" parent="CenterContainer/VBoxContainer"]
layout_mode = 2
@@ -48,7 +48,7 @@ layout_mode = 2
[node name="DeathInfoLabel" type="Label" parent="CenterContainer/VBoxContainer/MarginContainer/CenterContainer2"]
layout_mode = 2
-text = "death_info_describe"
+text = "ui_death_info_describe"
[node name="MarginContainer2" type="MarginContainer" parent="CenterContainer/VBoxContainer"]
layout_mode = 2
@@ -57,4 +57,4 @@ theme_override_constants/margin_bottom = 150
[node name="RestartButton" type="Button" parent="CenterContainer/VBoxContainer/MarginContainer2"]
layout_mode = 2
-text = "restart"
+text = "ui_restart"
diff --git a/scenes/mainMenu.tscn b/scenes/mainMenu.tscn
index 8b1cf45..9e32f9d 100644
--- a/scenes/mainMenu.tscn
+++ b/scenes/mainMenu.tscn
@@ -23,7 +23,7 @@ offset_top = 170.0
offset_right = 47.5
offset_bottom = 201.0
grow_horizontal = 2
-text = "start_game"
+text = "ui_start_game"
[node name="SettingsButton" type="Button" parent="."]
layout_mode = 1
@@ -35,7 +35,7 @@ offset_top = 215.0
offset_right = 50.5
offset_bottom = 248.0
grow_horizontal = 2
-text = "settings"
+text = "ui_settings"
[node name="levelGraphEditorButton" type="Button" parent="."]
layout_mode = 1
@@ -47,7 +47,7 @@ offset_top = 269.0
offset_right = 50.5
offset_bottom = 302.0
grow_horizontal = 2
-text = "level_graph_editor"
+text = "ui_level_graph_editor"
[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 1
@@ -87,7 +87,7 @@ grow_horizontal = 2
[node name="Label" type="Label" parent="CenterContainer"]
layout_mode = 2
theme_override_font_sizes/font_size = 45
-text = "product_name"
+text = "ui_product_name"
[node name="CenterContainer2" type="CenterContainer" parent="."]
layout_mode = 1
@@ -99,7 +99,7 @@ grow_horizontal = 2
[node name="SloganLabel" type="Label" parent="CenterContainer2"]
layout_mode = 2
-text = "slogan"
+text = "ui_slogan"
[node name="VBoxContainer2" type="VBoxContainer" parent="."]
layout_mode = 1
diff --git a/scripts/character/Player.cs b/scripts/character/Player.cs
index 6a291f0..a965b5c 100644
--- a/scripts/character/Player.cs
+++ b/scripts/character/Player.cs
@@ -82,21 +82,21 @@ public partial class Player : CharacterTemplate
operationTipBuilder.Append(']');
operationTipBuilder.Append(TranslationServerUtils.Translate(InputMap.ActionGetEvents("ui_left")[0].AsText()));
operationTipBuilder.Append("[/color]");
- operationTipBuilder.Append(TranslationServerUtils.Translate("move_left"));
+ operationTipBuilder.Append(TranslationServerUtils.Translate("action_move_left"));
operationTipBuilder.Append(' ');
operationTipBuilder.Append("[color=");
operationTipBuilder.Append(Config.OperationTipActionColor);
operationTipBuilder.Append(']');
operationTipBuilder.Append(TranslationServerUtils.Translate(InputMap.ActionGetEvents("ui_right")[0].AsText()));
operationTipBuilder.Append("[/color]");
- operationTipBuilder.Append(TranslationServerUtils.Translate("move_right"));
+ operationTipBuilder.Append(TranslationServerUtils.Translate("action_move_right"));
operationTipBuilder.Append(' ');
operationTipBuilder.Append("[color=");
operationTipBuilder.Append(Config.OperationTipActionColor);
operationTipBuilder.Append(']');
operationTipBuilder.Append(TranslationServerUtils.Translate(InputMap.ActionGetEvents("ui_up")[0].AsText()));
operationTipBuilder.Append("[/color]");
- operationTipBuilder.Append(TranslationServerUtils.Translate("jump"));
+ operationTipBuilder.Append(TranslationServerUtils.Translate("action_jump"));
if (_collidingWithPlatform)
{
operationTipBuilder.Append(' ');
@@ -106,7 +106,7 @@ public partial class Player : CharacterTemplate
operationTipBuilder.Append(
TranslationServerUtils.Translate(InputMap.ActionGetEvents("ui_down")[0].AsText()));
operationTipBuilder.Append("[/color]");
- operationTipBuilder.Append(TranslationServerUtils.Translate("jump_down"));
+ operationTipBuilder.Append(TranslationServerUtils.Translate("action_jump_down"));
}
//If the PickingRangeBodiesList is not null and the length is greater than 0
@@ -120,7 +120,7 @@ public partial class Player : CharacterTemplate
operationTipBuilder.Append(
TranslationServerUtils.Translate(InputMap.ActionGetEvents("pick_up")[0].AsText()));
operationTipBuilder.Append("[/color]");
- operationTipBuilder.Append(TranslationServerUtils.Translate("pick_up"));
+ operationTipBuilder.Append(TranslationServerUtils.Translate("action_pick_up"));
operationTipLabel.Text = operationTipBuilder.ToString();
}
@@ -132,7 +132,7 @@ public partial class Player : CharacterTemplate
operationTipBuilder.Append(']');
operationTipBuilder.Append(TranslationServerUtils.Translate(InputMap.ActionGetEvents("throw")[0].AsText()));
operationTipBuilder.Append("[/color]");
- operationTipBuilder.Append(TranslationServerUtils.Translate("throw"));
+ operationTipBuilder.Append(TranslationServerUtils.Translate("action_throw"));
if (CurrentItem is IItem item)
{
operationTipBuilder.Append(TranslationServerUtils.Translate(item.Name));
@@ -143,7 +143,7 @@ public partial class Player : CharacterTemplate
operationTipBuilder.Append(
TranslationServerUtils.Translate(InputMap.ActionGetEvents("use_item")[0].AsText()));
operationTipBuilder.Append("[/color]");
- operationTipBuilder.Append(TranslationServerUtils.Translate("use_item"));
+ operationTipBuilder.Append(TranslationServerUtils.Translate("action_use_item"));
operationTipBuilder.Append(TranslationServerUtils.Translate(item.Name));
}
}
diff --git a/scripts/debug/LogCat.cs b/scripts/debug/LogCat.cs
index 66adaa5..08468ab 100644
--- a/scripts/debug/LogCat.cs
+++ b/scripts/debug/LogCat.cs
@@ -70,7 +70,7 @@ public static class LogCat
}
StringBuilder.Append(DateTime.Now.ToString(" yyyy-M-d HH:mm:ss : "));
- StringBuilder.Append(TranslationServerUtils.Translate(message));
+ StringBuilder.Append(TranslationServerUtils.Translate($"log_{message}"));
return StringBuilder;
}
diff --git a/scripts/item/ItemTypeManager.cs b/scripts/item/ItemTypeManager.cs
index 25089f9..5b553a6 100644
--- a/scripts/item/ItemTypeManager.cs
+++ b/scripts/item/ItemTypeManager.cs
@@ -1,8 +1,13 @@
using System.Collections.Generic;
-using ColdMint.scripts.item.weapon;
+
+using ColdMint.scripts.debug;
using ColdMint.scripts.utils;
+
using Godot;
+using YamlDotNet.Serialization;
+using YamlDotNet.Serialization.NamingConventions;
+
namespace ColdMint.scripts.item;
///
@@ -11,26 +16,61 @@ namespace ColdMint.scripts.item;
///
public static class ItemTypeManager
{
+ //Use for yaml deserialization
+ private record struct ItemTypeInfo(string Id, string ScenePath, string IconPath, int MaxStackValue) { }
+
+ ///
+ /// Register items from yaml file
+ /// 从文件注册物品
+ ///
+ public static void RegisterFromFile()
+ {
+ LogCat.Log("start_item_register_from_file");
+
+ // initialize yaml deserializer
+ var deserializer = new DeserializerBuilder()
+ .WithNamingConvention(UnderscoredNamingConvention.Instance) // convent snake_case
+ .Build();
+
+ // initialize file dir
+ string itemRegsDirPath = "res://data/itemRegs/";
+ var itemRegsDir = DirAccess.Open(itemRegsDirPath);
+ if (DirAccess.GetOpenError() is not Error.Ok)
+ {
+ LogCat.LogError("error_when_open_item_regs_dir");
+ }
+
+ // traverse the dir, find files to register
+ foreach (var file in itemRegsDir.GetFiles())
+ {
+ if (file is null) continue;
+ LogCat.LogWithFormat("item_register_from_file", file);
+
+ // read file, parse to an IEnumerable of type infos
+ var yamlFile = FileAccess.Open($"{itemRegsDirPath}/{file}", FileAccess.ModeFlags.Read);
+ var yamlString = yamlFile.GetAsText();
+ var typeInfos = deserializer.Deserialize>(yamlString);
+ yamlFile.Close();
+
+ // traverse type infos and register them.
+ foreach (var typeInfo in typeInfos)
+ {
+ LogCat.LogWithFormat("item_register_find_item_in_file", typeInfo.Id);
+ var scene = ResourceLoader.Load(typeInfo.ScenePath);
+ var icon = ResourceLoader.Load(typeInfo.IconPath);
+ var itemType = new ItemType(typeInfo.Id,
+ () => NodeUtils.InstantiatePackedScene(scene),
+ icon, typeInfo.MaxStackValue);
+ Register(itemType);
+ }
+ }
+ }
+
///
/// Register items here
/// 在这里注册物品
///
- public static void StaticRegister()
- {
- var staffOfTheUndeadScene = ResourceLoader.Load("res://prefab/weapons/staffOfTheUndead.tscn");
- var staffOfTheUndeadIcon = ResourceLoader.Load("res://sprites/weapon/staffOfTheUndead.png");
- var staffOfTheUndead =
- new ItemType("staff_of_the_undead",
- () => NodeUtils.InstantiatePackedScene(staffOfTheUndeadScene), staffOfTheUndeadIcon,
- 1);
- Register(staffOfTheUndead);
-
- var packsackScene = ResourceLoader.Load("res://prefab/packsacks/packsack.tscn");
- var packsackIcon = ResourceLoader.Load("res://sprites/Player.png");
- var packsack = new ItemType("packsack", () => NodeUtils.InstantiatePackedScene(packsackScene),
- packsackIcon, 1);
- Register(packsack);
- }
+ public static void StaticRegister() { }
private static Dictionary Registry { get; } = [];
private static Texture2D DefaultTexture { get; } = new PlaceholderTexture2D();
@@ -49,13 +89,18 @@ public static class ItemTypeManager
///
/// Creates a new instance of the item registered to the given id.
- /// Returns null when the id is not registered.
+ /// 创建给定物品id的新物品实例
///
+ ///
+ /// Returns null when the id is not registered.
+ /// 当物品id没有注册时返回null
+ ///
public static IItem? NewItem(string id) =>
Registry.TryGetValue(id, out var itemType) ? itemType.NewItemFunc() : null;
///
- /// Get the translated default name of the item type for the given id
+ /// Get the translated default name of the item type for the given id
+ /// 获取指定物品id翻译后的物品名
///
///
/// Translated default name of the item id if it exists. Else, return the id itself
@@ -63,7 +108,8 @@ public static class ItemTypeManager
public static string DefaultNameOf(string id) => TranslationServerUtils.Translate($"item_{id}") ?? id;
///
- /// Get the translated default description of the item type for the given id
+ /// Get the translated default description of the item type for the given id
+ /// 获取指定物品id翻译后的描述
///
///
/// Translated default description of the item id if it exists. Else, return null
@@ -71,10 +117,12 @@ public static class ItemTypeManager
public static string? DefaultDescriptionOf(string id) => TranslationServerUtils.Translate($"item_{id}_desc");
///
- /// Get the default icon of the item type for the given id
+ /// Get the default icon of the item type for the given id
+ /// 获取指定物品id的默认图标
///
///
- /// Translated default icon of the item id if it exists. Else, return a placeholder
+ /// Default icon of the item id if it exists. Else, return a
+ /// 当前物品id的默认图标,若无则返回一个
///
public static Texture2D DefaultIconOf(string id) =>
Registry.TryGetValue(id, out var itemType)
diff --git a/scripts/loader/sceneLoader/GameSceneLoader.cs b/scripts/loader/sceneLoader/GameSceneLoader.cs
index dd290f2..6352775 100644
--- a/scripts/loader/sceneLoader/GameSceneLoader.cs
+++ b/scripts/loader/sceneLoader/GameSceneLoader.cs
@@ -84,7 +84,7 @@ public partial class GameSceneLoader : SceneLoaderTemplate
{
//If you have a seedLabel, then set the seed to it.
//如果有seedLabel,那么将种子设置上去。
- var seedInfo = TranslationServerUtils.TranslateWithFormat("seed_info", MapGenerator.Seed);
+ var seedInfo = TranslationServerUtils.TranslateWithFormat("ui_seed_info", MapGenerator.Seed);
_seedLabel.Text = seedInfo ?? $"Seed: {MapGenerator.Seed}";
}
await MapGenerator.GenerateMap();
diff --git a/scripts/loader/uiLoader/LevelGraphEditorLoader.cs b/scripts/loader/uiLoader/LevelGraphEditorLoader.cs
index b10804a..3d20953 100644
--- a/scripts/loader/uiLoader/LevelGraphEditorLoader.cs
+++ b/scripts/loader/uiLoader/LevelGraphEditorLoader.cs
@@ -60,7 +60,7 @@ public partial class LevelGraphEditorLoader : UiLoaderTemplate
{
base.InitializeData();
_roomNodeScene = (PackedScene)GD.Load("res://prefab/ui/RoomNode.tscn");
- _defaultRoomName = TranslationServerUtils.Translate("default_room_name");
+ _defaultRoomName = TranslationServerUtils.Translate("ui_default_room_name");
var folder = Config.GetLevelGraphExportDirectory();
if (!Directory.Exists(folder))
{
@@ -148,7 +148,7 @@ public partial class LevelGraphEditorLoader : UiLoaderTemplate
{
if (!lastLine.StartsWith("res://"))
{
- var lineError = TranslationServer.Translate("line_errors_must_start_with_res");
+ var lineError = TranslationServer.Translate("ui_line_errors_must_start_with_res");
if (lineError == null)
{
return;
@@ -162,7 +162,7 @@ public partial class LevelGraphEditorLoader : UiLoaderTemplate
var dirExists = DirAccess.DirExistsAbsolute(lastLine);
if (!fileExists && !dirExists)
{
- var lineError = TranslationServerUtils.Translate("error_specifying_room_template_line");
+ var lineError = TranslationServerUtils.Translate("ui_error_specifying_room_template_line");
if (lineError == null)
{
return;
@@ -404,7 +404,7 @@ public partial class LevelGraphEditorLoader : UiLoaderTemplate
if (_nodeBinding.ActionButton != null)
{
- _nodeBinding.ActionButton.Text = TranslationServerUtils.Translate("load");
+ _nodeBinding.ActionButton.Text = TranslationServerUtils.Translate("ui_load");
}
if (_nodeBinding.FileNameLineEdit != null)
@@ -414,7 +414,7 @@ public partial class LevelGraphEditorLoader : UiLoaderTemplate
if (_nodeBinding.SaveOrLoadPanelTitleLabel != null)
{
- _nodeBinding.SaveOrLoadPanelTitleLabel.Text = TranslationServerUtils.Translate("load");
+ _nodeBinding.SaveOrLoadPanelTitleLabel.Text = TranslationServerUtils.Translate("ui_load");
}
_saveMode = false;
@@ -432,7 +432,7 @@ public partial class LevelGraphEditorLoader : UiLoaderTemplate
if (_nodeBinding.ActionButton != null)
{
- _nodeBinding.ActionButton.Text = TranslationServerUtils.Translate("save");
+ _nodeBinding.ActionButton.Text = TranslationServerUtils.Translate("ui_save");
}
if (_nodeBinding.FileNameLineEdit != null)
@@ -442,7 +442,7 @@ public partial class LevelGraphEditorLoader : UiLoaderTemplate
if (_nodeBinding.SaveOrLoadPanelTitleLabel != null)
{
- _nodeBinding.SaveOrLoadPanelTitleLabel.Text = TranslationServerUtils.Translate("save");
+ _nodeBinding.SaveOrLoadPanelTitleLabel.Text = TranslationServerUtils.Translate("ui_save");
}
_saveMode = true;
diff --git a/scripts/loader/uiLoader/MainMenuLoader.cs b/scripts/loader/uiLoader/MainMenuLoader.cs
index 4eede2e..5bad091 100644
--- a/scripts/loader/uiLoader/MainMenuLoader.cs
+++ b/scripts/loader/uiLoader/MainMenuLoader.cs
@@ -95,8 +95,11 @@ public partial class MainMenuLoader : UiLoaderTemplate
CampManager.AddCamp(aborigines);
_gameScene = (PackedScene)GD.Load("res://scenes/game.tscn");
- //Temp: Register ItemType
- //临时:注册物品类型
+ //Register ItemTypes from file
+ //从文件注册物品类型
+ ItemTypeManager.RegisterFromFile();
+ //Hardcoded ItemTypes Register
+ //硬编码注册物品类型
ItemTypeManager.StaticRegister();
}