Compare commits

..

No commits in common. "master" and "4.2.2" have entirely different histories.

203 changed files with 3250 additions and 8067 deletions

7
.gitignore vendored
View File

@ -1,13 +1,8 @@
# Godot 4+ specific ignores # Godot 4+ specific ignores
.godot/ .godot/
export_presets.cfg
.idea/ .idea/
.vs/ .vs/
.vscode/
.fleet/
# Ignore the Android build directory
android/
export_presets.cfg
*.translation *.translation
*.user *.user
AppConfig.yaml AppConfig.yaml
ColdMint.Traveler.csproj.old

View File

@ -1,4 +1,4 @@
<Project Sdk="Godot.NET.Sdk/4.3.0"> <Project Sdk="Godot.NET.Sdk/4.2.2">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net7.0</TargetFramework> <TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net7.0</TargetFramework>
@ -9,9 +9,7 @@
<LangVersion>12</LangVersion> <LangVersion>12</LangVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2024.2.0" /> <PackageReference Include="JetBrains.Annotations" Version="2023.3.0" />
<PackageReference Include="YamlDotNet" Version="16.1.3" /> <PackageReference Include="YamlDotNet" Version="15.1.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="6.0.29" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.10" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -10,12 +10,12 @@ A pixel cross-platform roguelite game.
## Recent Development progress ## Recent Development progress
| Task | status | | Task | status |
|------------------------------------------|-------------| | ----------------------------------------------------------- | ------------------ |
| Randomly generated map | complete | | Randomly generated map | complete |
| loot | complete | | loot | complete |
| Support still out of the knapsack system | complete | | Support still out of the knapsack system | complete |
| Add AI agents to creatures | In progress | | Add AI agents to creatures | In progress |
## Screenshot ## Screenshot
@ -30,20 +30,12 @@ Level graph editor
## Run the project locally ## Run the project locally
#### Download engine #### Download engine
1. Download [Godot Engine .Net](https://godotengine.org/). 1. Download [Godot Engine .Net](https://godotengine.org/).
After downloading the engine, you will need to download an additional export template to export as an executable After downloading the engine, you will need to download an additional export template to export as an executable program.
program.
2. Download [.NetSDK](https://dotnet.microsoft.com/download). 2. Download [.NetSDK](https://dotnet.microsoft.com/download).
Ubuntu or Linux Mint install the .net 8.0 Sdk.
```
apt install dotnet-sdk-8.0
```
#### Clone project #### Clone project
Enter the following command in your working directory: Enter the following command in your working directory:
@ -63,29 +55,44 @@ data/*
#### Custom feature #### Custom feature
- **disableVersionIsolation** Disable version isolation. - **disableVersionIsolation** Disable version isolation.
- **enableMod** Experimental feature, the game loads dll files and pck files in the mod directory when the mod is
enabled. Due to the isolation of AssemblyLoadContext, the main game content cannot be accessed from within the Mod for
the time being.
#### Run the console on Linux ## Configuring Openobserve
Enter the following command in the directory where the game is located: > This is optional, and the game will work even if you do not configure Openobserve.
``` openobserve is used to continuously collect logs and alarm information after a game has been released.
./Traveler.sh
``` #### Set up the openobserve server
see[openobserve](https://github.com/openobserve/openobserve)
#### Write configuration
After you have set up an openobserve server, follow the following steps to configure the file:
1. Create a configuration file named **AppConfig.yaml** in the root directory of your project.
2. Fill in the information for the remote server.
```yaml
open_observe:
address: [address]
access_token: [token]
org_id: [org_id]
stream_name: [stream_name]
```
address Indicates the address of the server in the format of http(s)://www.example.com. (Support http and https)
## Participate in translation ## Participate in translation
The project is prepared for localization at the beginning of writing. You can edit the csv file in the locals directory. The project is prepared for localization at the beginning of writing. You can edit the csv file in the locals directory. To modify and add new translations.
To modify and add new translations.
## License ## License
[GPL-3.0 license](LICENSE) [GPL-3.0 license](LICENSE)
Support commercial, anyone can modify, build, and sell or distribute for free. For all derivative versions of this Support commercial, anyone can modify, build, and sell or distribute for free. For all derivative versions of this project, under the GPL, you shall **retain the author copyright** and **publish the modified source code**.
project, under the GPL, you shall **retain the author copyright** and **publish the modified source code**.
> Note: You have the right to sell the modified version, but not the original. > Note: You have the right to sell the modified version, but not the original.
> >

View File

@ -34,13 +34,6 @@
2. ダウンロード [.NetSDK](https://dotnet.microsoft.com/download). 2. ダウンロード [.NetSDK](https://dotnet.microsoft.com/download).
UbuntuやLinux Mintに。net8.0Sdkをインストールします。
```
apt install dotnet-sdk-8.0
```
#### クローンプロジェクトです #### クローンプロジェクトです
作業リストに次の指示を入力します。 作業リストに次の指示を入力します。
@ -60,15 +53,35 @@ data/*
#### 風習特徴 #### 風習特徴
- **disableVersionIsolation** 版孤立を無効化する。 - **disableVersionIsolation** 版孤立を無効化する。
- **enableMod**実験的な機能、modが有効になっている場合、ゲームはmodディレクトリにdllファイルとpckファイルをロードします。assemblyloadcontextが分離されているため、当面の間、mod内からメインゲームのコンテンツにアクセスすることはできません。
#### Linux上でコンソールを動かします ## はいちOpenobserve
ゲームの存在するディレクトリに以下のコマンドを入力します: > これはオプションなので、Openobserveを設定しなくてもゲームは正常に動作します。
openobserveは、リリース後にログやアラームを継続的に収集するために使用されます。
#### 搭建openobserve衣服务器
読み過ごす:[openobserve](https://github.com/openobserve/openobserve)
#### 構成を書きます
openobserveのサーバーを構築したら、次のようにファイルを設定します。
1. プロジェクトのルートディレクトリに**AppConfig.yaml **というプロファイルを作成します。
2. リモートサーバーの情報を入力します。
```yaml
open_observe:
address: [address]
access_token: [token]
org_id: [org_id]
stream_name: [stream_name]
```
address サーバーのアドレス、フォーマットはこうなります http(s)://www.example.com。支持http和https
```
./Traveler.sh
```
## 翻訳に携わります ## 翻訳に携わります
このプロジェクトは、当初からローカライズの準備ができていました。localsディレクトリのcsvファイルを編集することができます。新しい翻訳を加えたり修正したりしています このプロジェクトは、当初からローカライズの準備ができていました。localsディレクトリのcsvファイルを編集することができます。新しい翻訳を加えたり修正したりしています

View File

@ -10,11 +10,11 @@
## 近期研发进度 ## 近期研发进度
| 任务 | 状态 | | 任务 | 状态 |
|-----------|-----| | ----------------------------------------------------------- |----|
| 随机生成地图 | 完成 | | 随机生成地图 | 完成 |
| 战利品 | 完成 | | 战利品 | 完成 |
| 支持仍出的背包系统 | 完成 | | 支持仍出的背包系统 | 完成 |
| 为生物添加AI代理 | 进行中 | | 为生物添加AI代理 | 进行中 |
## 屏幕截图 ## 屏幕截图
@ -30,19 +30,12 @@
## 在本地运行项目 ## 在本地运行项目
#### 下载引擎 #### 下载引擎
1. 下载[Godot Engine .Net](https://godotengine.org/)。 1. 下载[Godot Engine .Net](https://godotengine.org/)。
下载引擎后,您需要额外下载导出模板才能导出为可执行程序。 下载引擎后,您需要额外下载导出模板才能导出为可执行程序。
2. 下载 [.NetSDK](https://dotnet.microsoft.com/download). 2. 下载 [.NetSDK](https://dotnet.microsoft.com/download).
Ubuntu或Linux Mint安装.net8.0Sdk。
```
apt install dotnet-sdk-8.0
```
#### 克隆项目 #### 克隆项目
在您的工作目录输入以下指令: 在您的工作目录输入以下指令:
@ -62,15 +55,34 @@ data/*
#### 自定义特性 #### 自定义特性
- **disableVersionIsolation** 禁用版本隔离。 - **disableVersionIsolation** 禁用版本隔离。
- **enableMod** 实验性功能当启用模组时游戏会在mod目录加载dll文件和pck文件。由于AssemblyLoadContext的隔离性暂时不能从Mod内访问主游戏内容。
#### 在Linux上运行控制台 ## 配置Openobserve
在游戏所在目录输入以下命令: > 这是可选的操作即使您不配置Openobserve游戏也能正常运行。
``` openobserve用于在游戏发布后持续收集日志和报警信息。
./Traveler.sh
``` #### 搭建openobserve服务器
请见:[openobserve](https://github.com/openobserve/openobserve)
#### 编写配置
在您搭建完毕openobserve的服务器后按如下步骤配置文件
1. 在项目的根目录创建名为**AppConfig.yaml**的配置文件。
2. 填入远程服务器的信息。
```yaml
open_observe:
address: [address]
access_token: [token]
org_id: [org_id]
stream_name: [stream_name]
```
address 服务器的地址,格式为 http(s)://www.example.com。支持http和https
## 参与翻译 ## 参与翻译
@ -82,8 +94,7 @@ data/*
查看协议的中文翻译版本:[GPL-3.0 license 简体中文](LICENSE_ZH) 查看协议的中文翻译版本:[GPL-3.0 license 简体中文](LICENSE_ZH)
支持商用任何人可修改构建并用于售卖或免费发布。对于此项目的所有衍生版本根据GPL协议您应当**保留作者版权**,以及* 支持商用任何人可修改构建并用于售卖或免费发布。对于此项目的所有衍生版本根据GPL协议您应当**保留作者版权**,以及**公开修改后的源代码**。
*公开修改后的源代码**。
> 注意:您有权售卖修改后的版本,但不能售卖原版。 > 注意:您有权售卖修改后的版本,但不能售卖原版。

View File

@ -1,10 +0,0 @@
#Register items here.
#在这里注册物品。
#Note: The id must be the same as the item id in the scene. Otherwise, an ArgumentException will be thrown.
#备注id必须和场景内的物品id保持一致。否则会抛出ArgumentException。
#After you declare the id of the item, add the corresponding localized text to the csv file in the locals' folder. For example, if the id is a corresponding name is item_a and the corresponding description is item_a_desc.
#当您声明物品的id后请在locals文件夹中的csv文件中添加相应的本地化文本。例如id为a则对应的名称为item_a对应的描述为item_a_desc。
- id: resignation_certificate
scene_path: res://prefab/items/resignationCertificate.tscn
icon_path: res://sprites/projectile/resignationCertificate.png
max_stack_value: 1

View File

@ -1,26 +0,0 @@
#Register spells used by the projectile here.
#在这里注册抛射体使用的法术。
#Note: The id must be the same as the item id in the scene. Otherwise, an ArgumentException will be thrown.
#备注id必须和场景内的物品id保持一致。否则会抛出ArgumentException。
#After you declare the id of the item, add the corresponding localized text to the csv file in the locals' folder. For example, if the id is a corresponding name is item_a and the corresponding description is item_a_desc.
#当您声明物品的id后请在locals文件夹中的csv文件中添加相应的本地化文本。例如id为a则对应的名称为item_a对应的描述为item_a_desc。
- id: necromancy
scene_path: res://prefab/magics/curseOfTheUndead.tscn
icon_path: res://sprites/projectile/curseOfTheUndead.png
max_stack_value: 1
- id: x3
scene_path: res://prefab/magics/x3.tscn
icon_path: res://sprites/projectile/x3.png
max_stack_value: 1
- id: curse
scene_path: res://prefab/magics/curse.tscn
icon_path: res://sprites/projectile/x3.png
max_stack_value: 1
- id: magic_missile
scene_path: res://prefab/magics/magicMissile.tscn
icon_path: res://sprites/projectile/magicMissile.png
max_stack_value: 1
- id: tracking_spell
scene_path: res://prefab/magics/trackingSpell.tscn
icon_path: res://sprites/projectile/trackingSpell.png
max_stack_value: 1

View File

@ -1,13 +1,4 @@
#Register an item container here. - id: packsack
#在这里注册物品容器。 scene_path: res://prefab/packsacks/packsack.tscn
#Note: The id must be the same as the item id in the scene. Otherwise, an ArgumentException will be thrown. icon_path: res://sprites/packsack.png
#备注id必须和场景内的物品id保持一致。否则会抛出ArgumentException。
#After you declare the id of the item, add the corresponding localized text to the csv file in the locals' folder. For example, if the id is a corresponding name is item_a and the corresponding description is item_a_desc.
#当您声明物品的id后请在locals文件夹中的csv文件中添加相应的本地化文本。例如id为a则对应的名称为item_a对应的描述为item_a_desc。
#portable_backpacks
#便携式背包
- id: portable_backpacks
scene_path: res://prefab/packsacks/PortableBackpacks.tscn
icon_path: res://sprites/PortableBackpacks.png
max_stack_value: 1 max_stack_value: 1

View File

@ -1,25 +1,20 @@
#Register your weapon here. - id: staff_of_the_undead
#在这里注册你的武器。 scene_path: res://prefab/weapons/staffOfTheUndead.tscn
#Note: The id must be the same as the item id in the scene. Otherwise, an ArgumentException will be thrown. icon_path: res://sprites/weapon/staffOfTheUndead_icon.png
#备注id必须和场景内的物品id保持一致。否则会抛出ArgumentException。 max_stack_value: 1
#After you declare the id of the item, add the corresponding localized text to the csv file in the locals' folder. For example, if the id is a corresponding name is item_a and the corresponding description is item_a_desc. custom_args:
#当您声明物品的id后请在locals文件夹中的csv文件中添加相应的本地化文本。例如id为a则对应的名称为item_a对应的描述为item_a_desc。 - name: UniqueName
type: string
value: 爱你!
#staff_necromancy - id: degraded_staff_of_the_undead
#死灵法杖 scene_path: res://prefab/weapons/staffOfTheUndead.tscn
# The Necromancy Staff will act differently on different difficulties. icon_path: res://sprites/weapon/staffOfTheUndead_icon.png
#死灵法杖在不同的难度下会有不同的行为。
#The probability of generating monsters is as follows:Hard mode 100%, Normal mode 75%, easy mode 5%
#以下是在击杀敌人后生成怪物的概率困难模式100%普通模式75%简单模式5%
- id: staff_necromancy
scene_path: res://prefab/weapons/StaffNecromancy.tscn
icon_path: res://sprites/weapon/StaffNecromancy_Icon.png
max_stack_value: 1
- id: iron_axe
scene_path: res://prefab/weapons/IronAxe.tscn
icon_path: res://sprites/weapon/StaffNecromancy_Icon.png
max_stack_value: 1
- id: beginner_staff
scene_path: res://prefab/weapons/BeginnerStaff.tscn
icon_path: res://sprites/weapon/BeginnerStaff_Icon.png
max_stack_value: 1 max_stack_value: 1
custom_args:
- name: FiringIntervalAsMillisecond
type: int
value: 1000
- name: UniqueName
type: string
value: item_staff_of_the_undead_desc

View File

@ -1,181 +1,57 @@
connection_data_list: connection_data_list:
- from_id: 5a284c6f-2ce5-4dba-b32e-f0fcb9e9940d - from_id: c0255eb6-2c75-44f7-9058-0921fe8fb0d8
to_id: 4de20bd2-b557-4c29-9613-d4b35ea1f239 to_id: 4ae948ea-82b7-4b2d-bec2-19ed8a9d4c03
from_port: 0 from_port: 0
to_port: 0 to_port: 0
- from_id: 4de20bd2-b557-4c29-9613-d4b35ea1f239 - from_id: 4ae948ea-82b7-4b2d-bec2-19ed8a9d4c03
to_id: 3053d123-3f71-4cd0-8f05-f821aa95c702 to_id: ba32e05c-0c80-4a79-b5ce-5b8150400e05
from_port: 0 from_port: 0
to_port: 0 to_port: 0
- from_id: 3053d123-3f71-4cd0-8f05-f821aa95c702 - from_id: 4ae948ea-82b7-4b2d-bec2-19ed8a9d4c03
to_id: fcc9333c-e70f-4a28-9029-1b1098502049 to_id: 8b3d645a-96c0-407e-871d-6f4a0b69557b
from_port: 0 from_port: 0
to_port: 0 to_port: 0
- from_id: fcc9333c-e70f-4a28-9029-1b1098502049 - from_id: 8b3d645a-96c0-407e-871d-6f4a0b69557b
to_id: 627b8abc-abb9-4117-bdea-9f818a69f972 to_id: 7e3ae680-3d7e-4ae9-b82f-5bfbe1c2f613
from_port: 0 from_port: 0
to_port: 0 to_port: 0
- from_id: 627b8abc-abb9-4117-bdea-9f818a69f972 - from_id: ba32e05c-0c80-4a79-b5ce-5b8150400e05
to_id: 478eee96-e8f6-4eea-82cd-a2ab3f54e015 to_id: 7e3ae680-3d7e-4ae9-b82f-5bfbe1c2f613
from_port: 0
to_port: 0
- from_id: 478eee96-e8f6-4eea-82cd-a2ab3f54e015
to_id: b2dba7b5-baab-4911-be58-7f54bdf89f86
from_port: 0
to_port: 0
- from_id: fcc9333c-e70f-4a28-9029-1b1098502049
to_id: fb43e864-e7b8-4482-a43a-34612b14aa94
from_port: 0
to_port: 0
- from_id: 627b8abc-abb9-4117-bdea-9f818a69f972
to_id: fab80988-f9b6-4e53-91cd-4c063d9cb1fb
from_port: 0
to_port: 0
- from_id: fb43e864-e7b8-4482-a43a-34612b14aa94
to_id: 89805068-5b2f-4f44-92b4-58d4df704341
from_port: 0
to_port: 0
- from_id: fab80988-f9b6-4e53-91cd-4c063d9cb1fb
to_id: d28a2647-a7f3-4179-a91d-d4a1d38a7438
from_port: 0
to_port: 0
- from_id: 89805068-5b2f-4f44-92b4-58d4df704341
to_id: 53abd2f0-995f-4d37-8b2f-058c70282fbd
from_port: 0
to_port: 0
- from_id: 53abd2f0-995f-4d37-8b2f-058c70282fbd
to_id: c702286c-5f8a-417b-9220-769bdfc1ea8c
from_port: 0
to_port: 0
- from_id: c702286c-5f8a-417b-9220-769bdfc1ea8c
to_id: 310c226b-dbb2-4193-b386-7b018a725228
from_port: 0 from_port: 0
to_port: 0 to_port: 0
room_node_data_list: room_node_data_list:
- id: 5a284c6f-2ce5-4dba-b32e-f0fcb9e9940d - id: c0255eb6-2c75-44f7-9058-0921fe8fb0d8
title: 房间1 title: 起点房间
description: '' description: 测试的起点房间。
room_template_set: room_template_set:
- res://prefab/roomTemplates/tutorials/spellEditor.tscn - 'res://prefab/roomTemplates/dungeon/initialRoom.tscn'
tags: tags:
- StartingRoom - StartingRoom
room_injection_processor_data: '' room_injection_processor_data: null
enter_room_event_handler_id: - id: ba32e05c-0c80-4a79-b5ce-5b8150400e05
exit_room_event_handler_id:
- id: 4de20bd2-b557-4c29-9613-d4b35ea1f239
title: 房间2
description: ''
room_template_set:
- res://prefab/roomTemplates/tutorials/tripleShotSpell.tscn
tags:
room_injection_processor_data: ''
enter_room_event_handler_id:
exit_room_event_handler_id:
- id: 3053d123-3f71-4cd0-8f05-f821aa95c702
title: 房间3 title: 房间3
description: '' description: ''
room_template_set: room_template_set:
- res://prefab/roomTemplates/dungeon/ - 'res://prefab/roomTemplates/dungeon/'
tags: tags: null
room_injection_processor_data: '' - id: 4ae948ea-82b7-4b2d-bec2-19ed8a9d4c03
enter_room_event_handler_id: title: 大厅
exit_room_event_handler_id: description: 比普通房间要大一些的房间,有多个门,用于连接到其他房间。
- id: fcc9333c-e70f-4a28-9029-1b1098502049 room_template_set:
- 'res://prefab/roomTemplates/dungeon/utilityRoom.tscn'
tags: null
room_injection_processor_data: null
- id: 8b3d645a-96c0-407e-871d-6f4a0b69557b
title: 房间4 title: 房间4
description: '' description: ''
room_template_set: room_template_set:
- res://prefab/roomTemplates/dungeon/ - 'res://prefab/roomTemplates/dungeon/'
tags: tags: null
room_injection_processor_data: '' room_injection_processor_data: ''
enter_room_event_handler_id: - id: 7e3ae680-3d7e-4ae9-b82f-5bfbe1c2f613
exit_room_event_handler_id:
- id: 627b8abc-abb9-4117-bdea-9f818a69f972
title: 房间5 title: 房间5
description: '' description: ''
room_template_set: room_template_set:
- res://prefab/roomTemplates/dungeon/ - 'res://prefab/roomTemplates/dungeon/'
tags: tags: null
room_injection_processor_data: '' room_injection_processor_data: ''
enter_room_event_handler_id:
exit_room_event_handler_id:
- id: 478eee96-e8f6-4eea-82cd-a2ab3f54e015
title: 房间6
description: ''
room_template_set:
- res://prefab/roomTemplates/dungeon/
tags:
room_injection_processor_data: ''
enter_room_event_handler_id:
exit_room_event_handler_id:
- id: b2dba7b5-baab-4911-be58-7f54bdf89f86
title: 房间7
description: ''
room_template_set:
- res://prefab/roomTemplates/dungeon/
tags:
room_injection_processor_data: ''
enter_room_event_handler_id:
exit_room_event_handler_id:
- id: fb43e864-e7b8-4482-a43a-34612b14aa94
title: 房间8
description: ''
room_template_set:
- res://prefab/roomTemplates/dungeon/
tags:
room_injection_processor_data: ''
enter_room_event_handler_id:
exit_room_event_handler_id:
- id: fab80988-f9b6-4e53-91cd-4c063d9cb1fb
title: 房间9
description: ''
room_template_set:
- res://prefab/roomTemplates/dungeon/
tags:
room_injection_processor_data: ''
enter_room_event_handler_id:
exit_room_event_handler_id:
- id: d28a2647-a7f3-4179-a91d-d4a1d38a7438
title: 房间11
description: ''
room_template_set:
- res://prefab/roomTemplates/dungeon/
tags:
room_injection_processor_data: ''
enter_room_event_handler_id:
exit_room_event_handler_id:
- id: 89805068-5b2f-4f44-92b4-58d4df704341
title: 房间10
description: ''
room_template_set:
- res://prefab/roomTemplates/dungeon/
tags:
room_injection_processor_data: ''
enter_room_event_handler_id:
exit_room_event_handler_id:
- id: c702286c-5f8a-417b-9220-769bdfc1ea8c
title: 房间13
description: ''
room_template_set:
- res://prefab/roomTemplates/dungeon/
tags:
room_injection_processor_data: ''
enter_room_event_handler_id:
exit_room_event_handler_id:
- id: 53abd2f0-995f-4d37-8b2f-058c70282fbd
title: 房间12
description: ''
room_template_set:
- res://prefab/roomTemplates/dungeon/
tags:
room_injection_processor_data: ''
enter_room_event_handler_id:
exit_room_event_handler_id:
- id: 310c226b-dbb2-4193-b386-7b018a725228
title: 房间14
description: ''
room_template_set:
- res://prefab/roomTemplates/dungeon/
tags:
room_injection_processor_data: ''
enter_room_event_handler_id:
exit_room_event_handler_id:

View File

@ -1,15 +0,0 @@
[gd_resource type="AudioBusLayout" format=3 uid="uid://cdugntqhtcyd"]
[resource]
bus/1/name = &"BGM"
bus/1/solo = false
bus/1/mute = false
bus/1/bypass_fx = false
bus/1/volume_db = 0.0
bus/1/send = &"Master"
bus/2/name = &"SoundEffect"
bus/2/solo = false
bus/2/mute = false
bus/2/bypass_fx = false
bus/2/volume_db = -0.0127316
bus/2/send = &"Master"

View File

@ -15,7 +15,6 @@ dest_files=["res://.godot/imported/ark-pixel-12px-proportional-zh_cn.ttf-478ad47
Rendering=null Rendering=null
antialiasing=1 antialiasing=1
generate_mipmaps=false generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false multichannel_signed_distance_field=false
msdf_pixel_range=8 msdf_pixel_range=8
msdf_size=48 msdf_size=48

View File

@ -1,3 +0,0 @@
id,zh,en,ja
character_necromancer,死灵法师,Necromancer,ネクロマンサー
character_evil_crow,邪恶的乌鸦先生,Evil Mr. Raven,悪のミスター・レイヴン
1 id zh en ja
2 character_necromancer 死灵法师 Necromancer ネクロマンサー
3 character_evil_crow 邪恶的乌鸦先生 Evil Mr. Raven 悪のミスター・レイヴン

View File

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

View File

@ -3,9 +3,6 @@ id,zh,en,ja
#自杀 #自杀
death_info_self_1,{0}误伤了自己。,{0} accidentally shot themself.,{0}誤って自分を傷つけました。 death_info_self_1,{0}误伤了自己。,{0} accidentally shot themself.,{0}誤って自分を傷つけました。
death_info_self_2,{0}忘记了瞄准。,{0} forgot to aim.,{0}照準を忘れました。 death_info_self_2,{0}忘记了瞄准。,{0} forgot to aim.,{0}照準を忘れました。
#Died reading a separation certificate.
#死于阅读离职证明。
death_info_resignation_certificate,{0}阅读冷薄荷的离职证明被毒害了!(你知道的太多了),{0} Read Cold Mint's separation certificate was poisoned!(You know too much),{0}コールドミントの離職証明書を読んで毒されました!(あなたは知りすぎです)
#Default death message #Default death message
#默认死亡信息 #默认死亡信息
death_info_default,{0}被{1}杀死了。,{0} is killed by {1}.,{0}は{1}に殺されました。 death_info_default,{0}被{1}杀死了。,{0} is killed by {1}.,{0}は{1}に殺されました。
1 id,zh,en,ja
3 #自杀
4 death_info_self_1,{0}误伤了自己。,{0} accidentally shot themself.,{0}誤って自分を傷つけました。
5 death_info_self_2,{0}忘记了瞄准。,{0} forgot to aim.,{0}照準を忘れました。
#Died reading a separation certificate.
#死于阅读离职证明。
death_info_resignation_certificate,{0}阅读冷薄荷的离职证明被毒害了!(你知道的太多了),{0} Read Cold Mint's separation certificate was poisoned!(You know too much),{0}コールドミントの離職証明書を読んで毒されました!(あなたは知りすぎです)
6 #Default death message
7 #默认死亡信息
8 death_info_default,{0}被{1}杀死了。,{0} is killed by {1}.,{0}は{1}に殺されました。

View File

@ -1,21 +1,5 @@
id,zh,en,ja id,zh,en,ja
item_staff_necromancy,死灵法杖,staffNecromancy,ネクロポリスの杖です item_staff_of_the_undead,死灵法杖,StaffOfTheUndead,ネクロポリスの杖です
item_staff_necromancy_desc,发射诅咒,可将敌人转化为邪恶的怪物。,Cast a curse that transforms enemies into evil monsters.,呪いを発射して、敵を邪悪な怪物に変えることができます。 item_staff_of_the_undead_desc,发射诅咒,可将敌人转化为邪恶的怪物。,Cast a curse that transforms enemies into evil monsters.,呪いを発射して、敵を邪悪な怪物に変えることができます。
item_portable_backpacks,便携式背包,PortableBackpacks,ポータブルバックパック item_packsack,背包,Packsack,背嚢
item_portable_backpacks_desc,为玩家提供9个物品槽。,Provides 9 item slots for the player.,プレイヤーに9つのアイテムスロットを提供します。 item_packsack_desc,可以装载更多物品的背包。,A backpack that can hold more items.,より多くのアイテムを保持できるバックパックです。
item_necromancy,死灵法术,necromancy,ネクロマンシー
item_necromancy_desc,法术的实体化弹丸。,The materialized projectile of a spell.,術の実体化した弾丸です。
item_x3,三重射击法术,Triple shot spell,三重射撃術です
item_x3_desc,使发射器一次射出三颗弹丸。,Make the launcher shoot three pellets at a time.,発射機から一度に三つの弾丸を発射させます。
item_resignation_certificate,离职证明,Resignation certificate,退職証明書です
item_resignation_certificate_desc,冷薄荷,感谢您在职时为公司做出的贡献。,"Cold Mint, thank you for your service to the company.",コールドミント、現役時代のご貢献ありがとうございました。
item_iron_axe,铁斧子,Iron axe,鉄の斧です
item_iron_axe_desc,铁斧子,Iron axe,鉄の斧です
item_curse,死灵诅咒法术,The curse of the Dead,死霊呪いの術
item_curse_desc,杀死敌人后在生成死灵敌人。,Spawn Undead enemies after killing them.,敵を殺すと死霊敵が発生します。
item_beginner_staff,初学者法杖,Beginner's staff,初心者用の杖です
item_beginner_staff_desc,送给初来乍到的冒险家。,For new adventurers.,初心者の冒険家に贈ります。
item_magic_missile,魔法飞弹,Magic missile,魔法のミサイルです
item_magic_missile_desc,轻快的法术。,A light spell.,軽快な術です。
item_tracking_spell,追踪法术,Tracking spell,追跡術です
item_tracking_spell_desc,使发射的子弹追踪敌人,Let the fired bullets track the enemy,発射した弾丸で敵を追跡させます
1 id zh en ja
2 item_staff_necromancy item_staff_of_the_undead 死灵法杖 staffNecromancy StaffOfTheUndead ネクロポリスの杖です
3 item_staff_necromancy_desc item_staff_of_the_undead_desc 发射诅咒,可将敌人转化为邪恶的怪物。 Cast a curse that transforms enemies into evil monsters. 呪いを発射して、敵を邪悪な怪物に変えることができます。
4 item_portable_backpacks item_packsack 便携式背包 背包 PortableBackpacks Packsack ポータブルバックパック 背嚢
5 item_portable_backpacks_desc item_packsack_desc 为玩家提供9个物品槽。 可以装载更多物品的背包。 Provides 9 item slots for the player. A backpack that can hold more items. プレイヤーに9つのアイテムスロットを提供します。 より多くのアイテムを保持できるバックパックです。
item_necromancy 死灵法术 necromancy ネクロマンシー
item_necromancy_desc 法术的实体化弹丸。 The materialized projectile of a spell. 術の実体化した弾丸です。
item_x3 三重射击法术 Triple shot spell 三重射撃術です
item_x3_desc 使发射器一次射出三颗弹丸。 Make the launcher shoot three pellets at a time. 発射機から一度に三つの弾丸を発射させます。
item_resignation_certificate 离职证明 Resignation certificate 退職証明書です
item_resignation_certificate_desc 冷薄荷,感谢您在职时为公司做出的贡献。 Cold Mint, thank you for your service to the company. コールドミント、現役時代のご貢献ありがとうございました。
item_iron_axe 铁斧子 Iron axe 鉄の斧です
item_iron_axe_desc 铁斧子 Iron axe 鉄の斧です
item_curse 死灵诅咒法术 The curse of the Dead 死霊呪いの術
item_curse_desc 杀死敌人后在生成死灵敌人。 Spawn Undead enemies after killing them. 敵を殺すと死霊敵が発生します。
item_beginner_staff 初学者法杖 Beginner's staff 初心者用の杖です
item_beginner_staff_desc 送给初来乍到的冒险家。 For new adventurers. 初心者の冒険家に贈ります。
item_magic_missile 魔法飞弹 Magic missile 魔法のミサイルです
item_magic_missile_desc 轻快的法术。 A light spell. 軽快な術です。
item_tracking_spell 追踪法术 Tracking spell 追跡術です
item_tracking_spell_desc 使发射的子弹追踪敌人 Let the fired bullets track the enemy 発射した弾丸で敵を追跡させます

View File

@ -4,6 +4,7 @@ log_missing_parameters,缺少参数。,Missing parameters.,パラメータが不
log_room_root_node_must_be_node2d,房间根节点必须是 Node2D。,Room root node must be an instance of Node2D.,ルートードはNode2Dでなければなりません。 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_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_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_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_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_map_generator_has_no_starting_room_data,地图生成器没有起点房间数据。,Map generator has no starting room data.,マップ生成器に起点部屋データはありません。
@ -35,6 +36,10 @@ log_register_item,注册物品类型{0}结果为{1},Registered item type {0}; re
log_error_when_open_item_regs_dir,尝试打开物品信息目录{0}时发生错误,错误代码:{1},"An error occurred when trying to open the item information directory {0}, error code: {1}",アイテム情報ディレクトリ{0}を開こうとしてエラーが発生しました、エラーコード:{1} log_error_when_open_item_regs_dir,尝试打开物品信息目录{0}时发生错误,错误代码:{1},"An error occurred when trying to open the item information directory {0}, error code: {1}",アイテム情報ディレクトリ{0}を開こうとしてエラーが発生しました、エラーコード:{1}
log_wrong_custom_arg,不匹配的参数:类型为{0}而值为{1},Mismatched parameter: type {0} and value {1},パラメータの不一致:型{0}と値{1}。 log_wrong_custom_arg,不匹配的参数:类型为{0}而值为{1},Mismatched parameter: type {0} and value {1},パラメータの不一致:型{0}と値{1}。
log_item_container_is_null,物品容器为空,Item container is null,アイテム・コンテナが空です log_item_container_is_null,物品容器为空,Item container is null,アイテム・コンテナが空です
log_item_has_no_owner,物品没有所有者,Item has no owner,アイテムに所有者がいません
log_no_damage_between_camps,没有阵营之间的伤害,No damage between camps,陣営間のダメージはありません
log_contact_damage_disabled_during_collision,在碰撞期间禁用接触伤害,Contact damage disabled during collision,衝突中に接触ダメージが無効になります
log_owner_of_the_item_is_not_character,物品的所有者不是角色,The owner of the item is not a character,アイテムの所有者はキャラクターではありません
log_try_to_open_state_machine_that_is_on,尝试打开处于运行状态的状态机。,Try to open a state machine that is on.,実行中のステートマシンを開こうとしています。 log_try_to_open_state_machine_that_is_on,尝试打开处于运行状态的状态机。,Try to open a state machine that is on.,実行中のステートマシンを開こうとしています。
log_state_machine_does_not_specify_context,状态机没有指定上下文。,The state machine does not specify a context.,ステートマシンはコンテキストを指定していません。 log_state_machine_does_not_specify_context,状态机没有指定上下文。,The state machine does not specify a context.,ステートマシンはコンテキストを指定していません。
log_state_processor_already_registered,状态处理器已经注册。,State processor already registered.,ステートプロセッサは既に登録されています。 log_state_processor_already_registered,状态处理器已经注册。,State processor already registered.,ステートプロセッサは既に登録されています。
@ -46,7 +51,13 @@ log_patrol_to_next_point,下一个点{0},当前位置{1},偏移量{2},距
log_patrol_arrival_point,到达巡逻点{0}。,Arrival at patrol point {0}.,巡回ポイント{0}に到着します。 log_patrol_arrival_point,到达巡逻点{0}。,Arrival at patrol point {0}.,巡回ポイント{0}に到着します。
log_patrol_origin_position,巡逻路径的起始位置是{0}。,The starting position of the patrol path is {0}.,巡回路の開始位置は{0}です。 log_patrol_origin_position,巡逻路径的起始位置是{0}。,The starting position of the patrol path is {0}.,巡回路の開始位置は{0}です。
log_patrol_not_on_floor,不能将初始路径设置在空中。,The initial path cannot be set in the air.,初期パスを空中に設定できません。 log_patrol_not_on_floor,不能将初始路径设置在空中。,The initial path cannot be set in the air.,初期パスを空中に設定できません。
log_item_container_is_null,物品容器为空。,Item container is null.,アイテム・コンテナが空です。
log_can_add_item,可以添加物品{0}。,Can add item {0}.,アイテム{0}を追加できます。 log_can_add_item,可以添加物品{0}。,Can add item {0}.,アイテム{0}を追加できます。
log_backpack_not_allowed,不允许添加到背包。,Not allowed to add to backpack.,バックパックに追加することは許可されていません。
log_item_is_null,物品为空。,Item is null.,アイテムが空です。
log_item_id_not_same,物品ID不同。,Item ID is different.,アイテムIDが異なります。
log_max_quantity_exceeded,超过最大数量。,Exceeded maximum quantity.,最大数量を超えました。
log_item_slot_is_selected_and_not_allowed,已选择物品槽,不允许添加。,"Item slot is selected, not allowed to add.",アイテムスロットが選択されており、追加は許可されていません。
log_patrol_enemy_detected,检测到敌人。,Enemy detected.,敵を検出しました。 log_patrol_enemy_detected,检测到敌人。,Enemy detected.,敵を検出しました。
log_attacker_or_target_is_null,攻击者或目标为空。,Attacker or target is null.,攻撃者またはターゲットが空です。 log_attacker_or_target_is_null,攻击者或目标为空。,Attacker or target is null.,攻撃者またはターゲットが空です。
log_in_the_same_camp,在同一阵营。,In the same camp.,同じ陣営です。 log_in_the_same_camp,在同一阵营。,In the same camp.,同じ陣営です。
@ -62,6 +73,10 @@ log_owner_is_not_AiCharacter,所有者不是AiCharacter。,Owner is not AiCharac
log_find_nearest_item,查找最近的物品。,Find the nearest item.,最も近いアイテムを見つけます。 log_find_nearest_item,查找最近的物品。,Find the nearest item.,最も近いアイテムを見つけます。
log_float_label_instantiate_failed,浮动标签实例化失败。,Float label instantiation failed.,フロートラベルのインスタンス化に失敗しました。 log_float_label_instantiate_failed,浮动标签实例化失败。,Float label instantiation failed.,フロートラベルのインスタンス化に失敗しました。
log_pickable_picked_up,可拾捡物被捡起了,那么不显示标签。,"If the pickable item is picked up, the label is not displayed.",でも、拾得物が拾い上げられたら、ラベルは表示されません。 log_pickable_picked_up,可拾捡物被捡起了,那么不显示标签。,"If the pickable item is picked up, the label is not displayed.",でも、拾得物が拾い上げられたら、ラベルは表示されません。
log_start_uploading,开始上传{0}条日志。,Start uploading {0} logs.,{0}個のログをアップロードを開始します。
log_upload_successful,上传成功,已上传{0}条日志,剩余{1}条日志待上传。,"Upload successful, {0} logs uploaded, {1} logs remaining.",アップロードが成功しました、{0}個のログがアップロードされ、{1}個のログが残っています。
log_upload_failed,上传失败,错误代码:{0},剩余{1}条日志待上传。,"Upload failed, error code: {0}, {1} logs remaining.",アップロードに失敗しました、エラーコード:{0}、{1}個のログが残っています。
log_upload_status,已记录{0}条日志,上传阈值为{1}。,"{0} logs recorded, upload threshold is {1}.",{0}個のログが記録され、アップロード閾値は{1}です。
log_weapon_detected,检测到武器。,Weapon detected.,武器が検出されました。 log_weapon_detected,检测到武器。,Weapon detected.,武器が検出されました。
log_no_weapon_detected,没有检测到武器。,No weapon detected.,武器が検出されません。 log_no_weapon_detected,没有检测到武器。,No weapon detected.,武器が検出されません。
log_weapon_lost,武器丢失。,Weapon lost.,武器が失われました。 log_weapon_lost,武器丢失。,Weapon lost.,武器が失われました。
@ -71,7 +86,6 @@ log_weapon_not_in_pickup_range,武器不在拾取范围内。,The weapon is not
log_weapon_picked_up,武器被拾取。,Weapon picked up.,武器が拾い取られました。 log_weapon_picked_up,武器被拾取。,Weapon picked up.,武器が拾い取られました。
log_weapon_pickup_failed,武器拾取失败。,Weapon pickup failed.,武器の拾い取りに失敗しました。 log_weapon_pickup_failed,武器拾取失败。,Weapon pickup failed.,武器の拾い取りに失敗しました。
log_enter_the_picking_range_body,进入拾取范围。,Enter the picking range.,拾い取り範囲に入ります。 log_enter_the_picking_range_body,进入拾取范围。,Enter the picking range.,拾い取り範囲に入ります。
log_exit_the_picking_range_body,退出拾取范围。,Exit the picking range.,ピックアップ範囲から外します。
log_search_for_weapon_timeout,搜索武器超时。,Search for weapon timeout.,武器の検索がタイムアウトしました。 log_search_for_weapon_timeout,搜索武器超时。,Search for weapon timeout.,武器の検索がタイムアウトしました。
log_initialize_the_context,初始化上下文环境。,Initialize the context environment.,コンテキスト環境を初期化します。 log_initialize_the_context,初始化上下文环境。,Initialize the context environment.,コンテキスト環境を初期化します。
log_initialize_the_context_failed,初始化上下文环境失败。,Initialize the context environment failed.,コンテキスト環境の初期化に失敗しました。 log_initialize_the_context_failed,初始化上下文环境失败。,Initialize the context environment failed.,コンテキスト環境の初期化に失敗しました。
@ -95,38 +109,3 @@ log_dll_name,已加载{0}。,Loaded {0}.,{0}をロードしました。
log_dll_does_not_register_lifecycle_processor,位于{0}的dll文件未注册生命周期处理器{1}。,"The DLL file located at {0} does not register the lifecycle processor {1}.",{0}にあるDLLファイルは、ライフサイクルプロセッサ{1}を登録していません。 log_dll_does_not_register_lifecycle_processor,位于{0}的dll文件未注册生命周期处理器{1}。,"The DLL file located at {0} does not register the lifecycle processor {1}.",{0}にあるDLLファイルは、ライフサイクルプロセッサ{1}を登録していません。
log_mod_lifecycle_handler_not_implement_interface,位于{0}的dll文件生命周期处理器未实现IModLifecycleHandler接口。,"The DLL file located at {0}, the lifecycle processor does not implement the IModLifecycleHandler interface.",{0}にあるDLLファイル、ライフサイクルプロセッサはIModLifecycleHandlerインターフェースを実装していません。 log_mod_lifecycle_handler_not_implement_interface,位于{0}的dll文件生命周期处理器未实现IModLifecycleHandler接口。,"The DLL file located at {0}, the lifecycle processor does not implement the IModLifecycleHandler interface.",{0}にあるDLLファイル、ライフサイクルプロセッサはIModLifecycleHandlerインターフェースを実装していません。
log_dll_no_parameterless_constructor,位于{0}的dll文件没有无参构造函数。,"The DLL file located at {0} does not have a parameterless constructor.",{0}にあるDLLファイルにはパラメータのないコンストラクタがありません。 log_dll_no_parameterless_constructor,位于{0}的dll文件没有无参构造函数。,"The DLL file located at {0} does not have a parameterless constructor.",{0}にあるDLLファイルにはパラメータのないコンストラクタがありません。
log_dll_type_length,位于{0}的dll文件内共包含{1}个类型。,"The DLL file located at {0} contains a total of {1} types.",{0}にあるDLLファイルには合計{1}個のタイプが含まれています。
log_after_no_longer_in_contact_with_any_tiles,不再与任何瓦片接触后,可以造成伤害。,"After no longer coming into contact with any tiles, it can cause damage",タイルと接触しなくなった後、損傷を引き起こす可能性があります。
log_contact_with_tiles_disables_damage,与瓦片接触禁用伤害。,"Disabling damage on contact with tiles",タイルとの接触によるダメージの無効化
log_hide_all_node,隐藏{0}个节点。,Hide {0} nodes.,{0}ノードを非表示にします。
log_show_all_node,显示{0}个节点。,Show {0} nodes.,{0}ノードが表示されます。
log_enter_the_screen,进入屏幕。,Enter screen,画面に移動。
log_exit_the_screen,退出屏幕。,Exit screen,画面を終了します。
log_failed_to_create_room_preview,创建{0}的房间预览图失败。,Failed to create a room preview of the {0}.,{0}の部屋のプレビューを作成できませんでした。
log_generated_item_is_empty,生成的物品{0}是空的吗{1}。,Generated item {0} is empty {1}.,生成したアイテム{0}は空ですか{1}。
log_projectile_generate_magic_is_null,没有装填可提供抛射体的法术。,There is no reload spell that provides projectiles.,射出体を提供するスペルを装填していません。
log_projectile_scene_is_null,抛射体场景为空。,Projectile scene is empty.,射出体は空です。
log_projectile_is_null,抛射体为空。,Projectile scene is empty.,射出シーンは空です。
log_projectile_weapon_range,加载法术范围{0}顺序模式吗{1}上次发射法术时采用的索引{2}。,Load spell range {0} Sequential mode {1} Index used when the spell was last fired {2}.,スペル範囲{0}順序モードですか{1}前回スペルを送信した時のインデックス{2}。
log_no_platform_detection_raycast_found,缺少必要的平台检测射线。,Lack of necessary platform detection rays.,放射線を検出するのに必要なプラットフォームが不足しています。
log_hide_display_item,项目{0}被隐藏了。,Item {0} is hidden.,アイテム{0}は非表示にされます。
log_add_display_item,添加项目{0}。,Add item {0}.,項目{0}を追加します。
log_update_display_item,更新项目{0}。,Update item {0}.,更新項目{0}です。
log_batch_update_data,批量更新数据开始为{0}结束为{1}.,Batch update data starts with {0} and ends with {1}.,一括更新データの開始を{0}、終了を{1}とします。
log_new_room_node_data_is_incomplete,新房间{0}数据不全。,New room {0} data is incomplete.,新しい部屋{0}はデータが不完全です。
log_parent_room_does_not_exist,放置房间{0}时父级房间不存在。,The parent room does not exist when room {0} is placed.,部屋{0}を置いても親部屋は存在しません。
log_room_template_does_not_exist,放置房间{0}房间模板不存在。,Room template does not exist when placing room {1}.,部屋{0}を置いた時点では部屋テンプレートは存在しません。
log_room_slot_does_not_exist,放置房间{0}房间槽位不存在。,Room slot does not exist when placing room {0}.,置き部屋{0}部屋スロットは存在しません。
log_available_rooms_are_not_available,放置房间{0}时,可用房间不存在。,"When placing room {0}, the available room does not exist.",部屋{0}を置いた場合、利用可能な部屋は存在しません。
log_room_corresponding_to_resource_is_null,放置房间{0}时,资源{1}对应的房间为null.,"When room {0} is placed, the room corresponding to resource {1} is null.",部屋{0}を置く場合、リソース{1}に対応する部屋はnullとなります。
log_slots_do_not_match,放置房间{0}时,槽位不匹配。,"When placing room {0}, the slots do not match.",部屋{0}を置く時、溝の位置が一致しません。
log_slot_incomplete,放置房间{0}时,槽位不完整。,The slot is incomplete when placing room {0}.,部屋{0}を置く場合、溝の位置が不完全です。
log_placement_position_is_empty,房间{0}放置位置为空。,The room {0} position is empty.,部屋{0}を空にします。
log_parameter_inconsistency,参数不齐。,Parameter inconsistency.,パラメーターが不揃いです。
log_room_slot_position_is_empty,房间位置描述为空。,Room location is described as empty.,部屋の位置は空です。
log_room_overlap,房间重叠。,The rooms overlap.,部屋が重なります。
log_game_over_event_is_empty,游戏结束事件为空。,End of game event is empty.,ゲームオーバーでイベントは空です。
log_cannot_resurrect_non_existent_player,不能复活不存在的玩家。,Cannot resurrect non-existent players.,存在しないプレイヤーを復活させることはできません。
log_no_audio_stream_player,没有音频播放器组件。,No audio player component.,オーディオプレーヤーキットはありません。
log_audio_stream_player_is_playing,音频播放器正在播放中。,The audio player is playing.,オーディオプレーヤーが再生中です。
log_play_audio,播放音频BUS为{0}Stream为{1}.,BUS is {0} and Stream is {1}.,再生オーディオはBUSが{0}Streamが{1}です。
1 id zh en ja
4 log_room_root_node_must_be_node2d 房间根节点必须是 Node2D。 Room root node must be an instance of Node2D. ルートノードはNode2Dでなければなりません。
5 log_width_or_height_of_room_slot_must_be_1 房间槽的宽度或高度必须为1。 The width or height of the room slot must be 1. 部屋の溝の幅または高さは1でなければなりません。
6 log_connected_room_timeout 连接房间超时。 Timeout when connecting rooms. 接続部屋はタイムアウトです。
7 log_projectiles_is_empty 未设置抛射体。 The projectile is not set. 射出体は設置されていません。
8 log_map_generator_missing_parameters 地图生成器缺少参数。 Map generator missing parameters. マップジェネレータが不足しています。
9 log_map_generator_attempts_to_parse_empty_layout_diagrams 地图生成器尝试解析空的布局图。 Map generator attempts to parse empty layout diagrams. マップジェネレータは空のレイアウト図を解析しようとしています。
10 log_map_generator_has_no_starting_room_data 地图生成器没有起点房间数据。 Map generator has no starting room data. マップ生成器に起点部屋データはありません。
36 log_error_when_open_item_regs_dir 尝试打开物品信息目录{0}时发生错误,错误代码:{1} An error occurred when trying to open the item information directory {0}, error code: {1} アイテム情報ディレクトリ{0}を開こうとしてエラーが発生しました、エラーコード:{1}
37 log_wrong_custom_arg 不匹配的参数:类型为{0}而值为{1} Mismatched parameter: type {0} and value {1} パラメータの不一致:型{0}と値{1}。
38 log_item_container_is_null 物品容器为空 Item container is null アイテム・コンテナが空です
39 log_item_has_no_owner 物品没有所有者 Item has no owner アイテムに所有者がいません
40 log_no_damage_between_camps 没有阵营之间的伤害 No damage between camps 陣営間のダメージはありません
41 log_contact_damage_disabled_during_collision 在碰撞期间禁用接触伤害 Contact damage disabled during collision 衝突中に接触ダメージが無効になります
42 log_owner_of_the_item_is_not_character 物品的所有者不是角色 The owner of the item is not a character アイテムの所有者はキャラクターではありません
43 log_try_to_open_state_machine_that_is_on 尝试打开处于运行状态的状态机。 Try to open a state machine that is on. 実行中のステートマシンを開こうとしています。
44 log_state_machine_does_not_specify_context 状态机没有指定上下文。 The state machine does not specify a context. ステートマシンはコンテキストを指定していません。
45 log_state_processor_already_registered 状态处理器已经注册。 State processor already registered. ステートプロセッサは既に登録されています。
51 log_patrol_arrival_point 到达巡逻点{0}。 Arrival at patrol point {0}. 巡回ポイント{0}に到着します。
52 log_patrol_origin_position 巡逻路径的起始位置是{0}。 The starting position of the patrol path is {0}. 巡回路の開始位置は{0}です。
53 log_patrol_not_on_floor 不能将初始路径设置在空中。 The initial path cannot be set in the air. 初期パスを空中に設定できません。
54 log_item_container_is_null 物品容器为空。 Item container is null. アイテム・コンテナが空です。
55 log_can_add_item 可以添加物品{0}。 Can add item {0}. アイテム{0}を追加できます。
56 log_backpack_not_allowed 不允许添加到背包。 Not allowed to add to backpack. バックパックに追加することは許可されていません。
57 log_item_is_null 物品为空。 Item is null. アイテムが空です。
58 log_item_id_not_same 物品ID不同。 Item ID is different. アイテムIDが異なります。
59 log_max_quantity_exceeded 超过最大数量。 Exceeded maximum quantity. 最大数量を超えました。
60 log_item_slot_is_selected_and_not_allowed 已选择物品槽,不允许添加。 Item slot is selected, not allowed to add. アイテムスロットが選択されており、追加は許可されていません。
61 log_patrol_enemy_detected 检测到敌人。 Enemy detected. 敵を検出しました。
62 log_attacker_or_target_is_null 攻击者或目标为空。 Attacker or target is null. 攻撃者またはターゲットが空です。
63 log_in_the_same_camp 在同一阵营。 In the same camp. 同じ陣営です。
73 log_find_nearest_item 查找最近的物品。 Find the nearest item. 最も近いアイテムを見つけます。
74 log_float_label_instantiate_failed 浮动标签实例化失败。 Float label instantiation failed. フロートラベルのインスタンス化に失敗しました。
75 log_pickable_picked_up 可拾捡物被捡起了,那么不显示标签。 If the pickable item is picked up, the label is not displayed. でも、拾得物が拾い上げられたら、ラベルは表示されません。
76 log_start_uploading 开始上传{0}条日志。 Start uploading {0} logs. {0}個のログをアップロードを開始します。
77 log_upload_successful 上传成功,已上传{0}条日志,剩余{1}条日志待上传。 Upload successful, {0} logs uploaded, {1} logs remaining. アップロードが成功しました、{0}個のログがアップロードされ、{1}個のログが残っています。
78 log_upload_failed 上传失败,错误代码:{0},剩余{1}条日志待上传。 Upload failed, error code: {0}, {1} logs remaining. アップロードに失敗しました、エラーコード:{0}、{1}個のログが残っています。
79 log_upload_status 已记录{0}条日志,上传阈值为{1}。 {0} logs recorded, upload threshold is {1}. {0}個のログが記録され、アップロード閾値は{1}です。
80 log_weapon_detected 检测到武器。 Weapon detected. 武器が検出されました。
81 log_no_weapon_detected 没有检测到武器。 No weapon detected. 武器が検出されません。
82 log_weapon_lost 武器丢失。 Weapon lost. 武器が失われました。
86 log_weapon_picked_up 武器被拾取。 Weapon picked up. 武器が拾い取られました。
87 log_weapon_pickup_failed 武器拾取失败。 Weapon pickup failed. 武器の拾い取りに失敗しました。
88 log_enter_the_picking_range_body 进入拾取范围。 Enter the picking range. 拾い取り範囲に入ります。
log_exit_the_picking_range_body 退出拾取范围。 Exit the picking range. ピックアップ範囲から外します。
89 log_search_for_weapon_timeout 搜索武器超时。 Search for weapon timeout. 武器の検索がタイムアウトしました。
90 log_initialize_the_context 初始化上下文环境。 Initialize the context environment. コンテキスト環境を初期化します。
91 log_initialize_the_context_failed 初始化上下文环境失败。 Initialize the context environment failed. コンテキスト環境の初期化に失敗しました。
109 log_dll_does_not_register_lifecycle_processor 位于{0}的dll文件,未注册生命周期处理器{1}。 The DLL file located at {0} does not register the lifecycle processor {1}. {0}にあるDLLファイルは、ライフサイクルプロセッサ{1}を登録していません。
110 log_mod_lifecycle_handler_not_implement_interface 位于{0}的dll文件,生命周期处理器未实现IModLifecycleHandler接口。 The DLL file located at {0}, the lifecycle processor does not implement the IModLifecycleHandler interface. {0}にあるDLLファイル、ライフサイクルプロセッサはIModLifecycleHandlerインターフェースを実装していません。
111 log_dll_no_parameterless_constructor 位于{0}的dll文件,没有无参构造函数。 The DLL file located at {0} does not have a parameterless constructor. {0}にあるDLLファイルにはパラメータのないコンストラクタがありません。
log_dll_type_length 位于{0}的dll文件内,共包含{1}个类型。 The DLL file located at {0} contains a total of {1} types. {0}にあるDLLファイルには合計{1}個のタイプが含まれています。
log_after_no_longer_in_contact_with_any_tiles 不再与任何瓦片接触后,可以造成伤害。 After no longer coming into contact with any tiles, it can cause damage タイルと接触しなくなった後、損傷を引き起こす可能性があります。
log_contact_with_tiles_disables_damage 与瓦片接触禁用伤害。 Disabling damage on contact with tiles タイルとの接触によるダメージの無効化
log_hide_all_node 隐藏{0}个节点。 Hide {0} nodes. {0}ノードを非表示にします。
log_show_all_node 显示{0}个节点。 Show {0} nodes. {0}ノードが表示されます。
log_enter_the_screen 进入屏幕。 Enter screen 画面に移動。
log_exit_the_screen 退出屏幕。 Exit screen 画面を終了します。
log_failed_to_create_room_preview 创建{0}的房间预览图失败。 Failed to create a room preview of the {0}. {0}の部屋のプレビューを作成できませんでした。
log_generated_item_is_empty 生成的物品{0}是空的吗{1}。 Generated item {0} is empty {1}. 生成したアイテム{0}は空ですか{1}。
log_projectile_generate_magic_is_null 没有装填可提供抛射体的法术。 There is no reload spell that provides projectiles. 射出体を提供するスペルを装填していません。
log_projectile_scene_is_null 抛射体场景为空。 Projectile scene is empty. 射出体は空です。
log_projectile_is_null 抛射体为空。 Projectile scene is empty. 射出シーンは空です。
log_projectile_weapon_range 加载法术范围{0}顺序模式吗{1}上次发射法术时采用的索引{2}。 Load spell range {0} Sequential mode {1} Index used when the spell was last fired {2}. スペル範囲{0}順序モードですか{1}前回スペルを送信した時のインデックス{2}。
log_no_platform_detection_raycast_found 缺少必要的平台检测射线。 Lack of necessary platform detection rays. 放射線を検出するのに必要なプラットフォームが不足しています。
log_hide_display_item 项目{0}被隐藏了。 Item {0} is hidden. アイテム{0}は非表示にされます。
log_add_display_item 添加项目{0}。 Add item {0}. 項目{0}を追加します。
log_update_display_item 更新项目{0}。 Update item {0}. 更新項目{0}です。
log_batch_update_data 批量更新数据开始为{0}结束为{1}. Batch update data starts with {0} and ends with {1}. 一括更新データの開始を{0}、終了を{1}とします。
log_new_room_node_data_is_incomplete 新房间{0}数据不全。 New room {0} data is incomplete. 新しい部屋{0}はデータが不完全です。
log_parent_room_does_not_exist 放置房间{0}时父级房间不存在。 The parent room does not exist when room {0} is placed. 部屋{0}を置いても親部屋は存在しません。
log_room_template_does_not_exist 放置房间{0}房间模板不存在。 Room template does not exist when placing room {1}. 部屋{0}を置いた時点では部屋テンプレートは存在しません。
log_room_slot_does_not_exist 放置房间{0}房间槽位不存在。 Room slot does not exist when placing room {0}. 置き部屋{0}部屋スロットは存在しません。
log_available_rooms_are_not_available 放置房间{0}时,可用房间不存在。 When placing room {0}, the available room does not exist. 部屋{0}を置いた場合、利用可能な部屋は存在しません。
log_room_corresponding_to_resource_is_null 放置房间{0}时,资源{1}对应的房间为null. When room {0} is placed, the room corresponding to resource {1} is null. 部屋{0}を置く場合、リソース{1}に対応する部屋はnullとなります。
log_slots_do_not_match 放置房间{0}时,槽位不匹配。 When placing room {0}, the slots do not match. 部屋{0}を置く時、溝の位置が一致しません。
log_slot_incomplete 放置房间{0}时,槽位不完整。 The slot is incomplete when placing room {0}. 部屋{0}を置く場合、溝の位置が不完全です。
log_placement_position_is_empty 房间{0}放置位置为空。 The room {0} position is empty. 部屋{0}を空にします。
log_parameter_inconsistency 参数不齐。 Parameter inconsistency. パラメーターが不揃いです。
log_room_slot_position_is_empty 房间位置描述为空。 Room location is described as empty. 部屋の位置は空です。
log_room_overlap 房间重叠。 The rooms overlap. 部屋が重なります。
log_game_over_event_is_empty 游戏结束事件为空。 End of game event is empty. ゲームオーバーでイベントは空です。
log_cannot_resurrect_non_existent_player 不能复活不存在的玩家。 Cannot resurrect non-existent players. 存在しないプレイヤーを復活させることはできません。
log_no_audio_stream_player 没有音频播放器组件。 No audio player component. オーディオプレーヤーキットはありません。
log_audio_stream_player_is_playing 音频播放器正在播放中。 The audio player is playing. オーディオプレーヤーが再生中です。
log_play_audio 播放音频BUS为{0}Stream为{1}. BUS is {0} and Stream is {1}. 再生オーディオはBUSが{0}Streamが{1}です。

View File

@ -1,3 +1,4 @@
id,zh,en,ja id,zh,en,ja
de,的,"'s",の
default_player_name,白纸,blankPaper,しらかみ 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} 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}
1 id zh en ja
2 de 's
3 default_player_name 白纸 blankPaper しらかみ
4 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}

View File

@ -4,8 +4,3 @@ slogan_1,Kawaii!,Kawaii!,Kawaii!
slogan_2,魔法是想象的世界。,Magic is an imaginary world.,魔法は想像の世界です。 slogan_2,魔法是想象的世界。,Magic is an imaginary world.,魔法は想像の世界です。
slogan_3,也试试《Minecraft》,Also try 'Minecraft'!,「Minecraft」もやってみて slogan_3,也试试《Minecraft》,Also try 'Minecraft'!,「Minecraft」もやってみて
slogan_4,也试试《Terraria》,Also try 'Terraria'!,「Terraria」もやってみて slogan_4,也试试《Terraria》,Also try 'Terraria'!,「Terraria」もやってみて
slogan_5,也试试《Terraria》,Also try 'Terraria'!,「Terraria」もやってみて
slogan_6,游戏在bug上运行。,The game runs on a bug.,ゲームはバグで動作します。
slogan_7,こんにちは!,こんにちは!,こんにちは!
slogan_7,你好!,你好!,你好!
slogan_7,Hello,Hello,Hello
1 id zh en ja
4 slogan_2 魔法是想象的世界。 Magic is an imaginary world. 魔法は想像の世界です。
5 slogan_3 也试试《Minecraft》! Also try 'Minecraft'! 「Minecraft」もやってみて!
6 slogan_4 也试试《Terraria》! Also try 'Terraria'! 「Terraria」もやってみて!
slogan_5 也试试《Terraria》! Also try 'Terraria'! 「Terraria」もやってみて!
slogan_6 游戏在bug上运行。 The game runs on a bug. ゲームはバグで動作します。
slogan_7 こんにちは! こんにちは! こんにちは!
slogan_7 你好! 你好! 你好!
slogan_7 Hello! Hello! Hello!

View File

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

View File

@ -1 +0,0 @@
id,zh,en,ja
1 id zh en ja

View File

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

View File

@ -34,9 +34,3 @@ ui_character_voice,角色配音,character_voice,キャラクターボイスで
ui_translator,翻译,translator,翻訳 ui_translator,翻译,translator,翻訳
ui_unordered_list_tip,排名不分先后,Ranking is not in order,順位は関係ありません ui_unordered_list_tip,排名不分先后,Ranking is not in order,順位は関係ありません
ui_loading,正在加载...,Loading...,読み込み中... ui_loading,正在加载...,Loading...,読み込み中...
ui_spell_editor,法术编辑器,Spell editor,スペルエディター
ui_rebuild_the_world,正在重新构建世界...,Is reconstructing the world...,世界を再構築しています…
ui_tutorial_spellEditor,按E捡起地上的武器\n法杖需要搭配法术使用\n靠近工作台\n鼠标左键使用工作台。\n鼠标左键拖动物品\n以实现在不同的容器之间移动它们。,"Press E to pick up the weapon on the ground, \nthe wand needs to be used with the spell, \nclose to the workbench, \nthe left mouse button to use the workbench.\nDrag items with the left mouse button \nto move them between different containers.",Eを押して地面の武器を拾い上げます。\n杖は魔法と組み合わせて使います。\n作業台に近づいて、\nマウスの左ボタンで作業台を使います。\nマウスの左ボタンでモをドラッグすると、\nさまざまな容器の間を移動できます。
ui_tutorial_break_box,鼠标左键使用武器打破箱子->,"Use the left mouse button to \nbreak the box with the weapon->",マウスの左ボタンで箱を破ります->
ui_tutorial_jump_onto_platform,W跳上平台\nS从平台上跳下。,"W jumps onto the platform, \nS jumps off the platform.",Wは踊り場に、\nSは踊り場に飛び降りるのです。
ui_tutorial_combine_more_powerful_spells,组合更强力的法术->,Combine more powerful spells->,より強力な術を組み合わせます->

1 id zh en ja
34 ui_translator 翻译 translator 翻訳
35 ui_unordered_list_tip 排名不分先后 Ranking is not in order 順位は関係ありません
36 ui_loading 正在加载... Loading... 読み込み中...
ui_spell_editor 法术编辑器 Spell editor スペルエディター
ui_rebuild_the_world 正在重新构建世界... Is reconstructing the world... 世界を再構築しています…
ui_tutorial_spellEditor 按E捡起地上的武器,\n法杖需要搭配法术使用,\n靠近工作台,\n鼠标左键使用工作台。\n鼠标左键拖动物品,\n以实现在不同的容器之间移动它们。 Press E to pick up the weapon on the ground, \nthe wand needs to be used with the spell, \nclose to the workbench, \nthe left mouse button to use the workbench.\nDrag items with the left mouse button \nto move them between different containers. Eを押して地面の武器を拾い上げます。\n杖は魔法と組み合わせて使います。\n作業台に近づいて、\nマウスの左ボタンで作業台を使います。\nマウスの左ボタンでモノをドラッグすると、\nさまざまな容器の間を移動できます。
ui_tutorial_break_box 鼠标左键使用武器打破箱子-> Use the left mouse button to \nbreak the box with the weapon-> マウスの左ボタンで箱を破ります->
ui_tutorial_jump_onto_platform W跳上平台,\nS从平台上跳下。 W jumps onto the platform, \nS jumps off the platform. Wは踊り場に、\nSは踊り場に飛び降りるのです。
ui_tutorial_combine_more_powerful_spells 组合更强力的法术-> Combine more powerful spells-> より強力な術を組み合わせます->

View File

@ -1,3 +0,0 @@
[gd_scene format=3 uid="uid://briehpw3eg1i6"]
[node name="Camera2D" type="Camera2D"]

View File

@ -1,104 +0,0 @@
[gd_scene load_steps=11 format=3 uid="uid://dxx1vqpecig7i"]
[ext_resource type="Script" path="res://scripts/character/AiCharacter.cs" id="1_ubaid"]
[ext_resource type="Texture2D" uid="uid://c1yxhtiqrfvvp" path="res://sprites/character/BlackenedAboriginalWarrior.png" id="2_pcmq1"]
[ext_resource type="Script" path="res://scripts/damage/DamageNumberNodeSpawn.cs" id="3_kiam3"]
[ext_resource type="PackedScene" uid="uid://sqqfrmikmk5v" path="res://prefab/ui/HealthBar.tscn" id="4_gt388"]
[ext_resource type="Script" path="res://scripts/bubble/BubbleMarker.cs" id="5_y2fh5"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_f8frw"]
size = Vector2(40, 46)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_a3myh"]
size = Vector2(46, 65)
[sub_resource type="SpriteFrames" id="SpriteFrames_qumby"]
animations = [{
"frames": [{
"duration": 1.0,
"texture": ExtResource("2_pcmq1")
}],
"loop": true,
"name": &"default",
"speed": 5.0
}]
[sub_resource type="CircleShape2D" id="CircleShape2D_c61vr"]
radius = 220.0
[sub_resource type="CircleShape2D" id="CircleShape2D_fowd5"]
radius = 300.0
[node name="BlackenedAboriginalWarrior" type="CharacterBody2D"]
collision_layer = 64
collision_mask = 38
script = ExtResource("1_ubaid")
InitWeaponId = "staff_necromancy"
CharacterName = "character_evil_crow"
CanMutateAfterDeath = false
MaxHp = 50
CampId = "Mazoku"
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(2, 10)
shape = SubResource("RectangleShape2D_f8frw")
[node name="Area2DPickingArea" type="Area2D" parent="."]
collision_layer = 0
collision_mask = 8
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2DPickingArea"]
position = Vector2(0, 5.5)
shape = SubResource("RectangleShape2D_a3myh")
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."]
sprite_frames = SubResource("SpriteFrames_qumby")
[node name="ItemMarker2D" type="Marker2D" parent="."]
position = Vector2(15, 20)
[node name="AttackObstacleDetection" type="RayCast2D" parent="ItemMarker2D"]
collision_mask = 2
[node name="DamageNumber" type="Marker2D" parent="."]
position = Vector2(0, -32)
script = ExtResource("3_kiam3")
[node name="HealthBar" parent="." instance=ExtResource("4_gt388")]
visible = false
offset_left = -46.0
offset_top = 41.0
offset_right = 50.0
offset_bottom = 53.0
[node name="WallDetection" type="RayCast2D" parent="."]
position = Vector2(3, -1)
target_position = Vector2(50, 0)
collision_mask = 6
[node name="AttackArea2D" type="Area2D" parent="."]
collision_layer = 0
collision_mask = 68
[node name="CollisionShape2D" type="CollisionShape2D" parent="AttackArea2D"]
shape = SubResource("CircleShape2D_c61vr")
[node name="NavigationAgent2D" type="NavigationAgent2D" parent="."]
[node name="BubbleMarker" type="Marker2D" parent="."]
position = Vector2(0, -79)
script = ExtResource("5_y2fh5")
[node name="ScoutArea2D" type="Area2D" parent="."]
collision_layer = 0
collision_mask = 76
[node name="CollisionShape2D" type="CollisionShape2D" parent="ScoutArea2D"]
shape = SubResource("CircleShape2D_fowd5")
[node name="TipLabel" type="Label" parent="."]
offset_left = -20.0
offset_top = 46.0
offset_right = 15.0
offset_bottom = 71.0
horizontal_alignment = 1

View File

@ -22,19 +22,19 @@ animations = [{
"speed": 5.0 "speed": 5.0
}] }]
[node name="Player" type="CharacterBody2D" node_paths=PackedStringArray("_platformDetectionRayCast2DList")] [node name="Player" type="CharacterBody2D"]
light_mask = 2
collision_layer = 4 collision_layer = 4
collision_mask = 162 collision_mask = 34
platform_floor_layers = 4294967042
platform_wall_layers = 128
script = ExtResource("1_1dlls") script = ExtResource("1_1dlls")
_platformDetectionRayCast2DList = [NodePath("PlatformDetectionRayCast1"), NodePath("PlatformDetectionRayCast2"), NodePath("PlatformDetectionRayCast3")] metadata/CampId = "Default"
MaxHp = 32 metadata/MaxHp = 32
CampId = "Default"
[node name="CollisionShape2D" type="CollisionShape2D" parent="."] [node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("CapsuleShape2D_bb8wt") shape = SubResource("CapsuleShape2D_bb8wt")
debug_color = Color(0.886275, 0, 0.803922, 0.419608)
[node name="Camera2D" type="Camera2D" parent="."]
position_smoothing_enabled = true
[node name="Area2DPickingArea" type="Area2D" parent="."] [node name="Area2DPickingArea" type="Area2D" parent="."]
collision_layer = 0 collision_layer = 0
@ -50,15 +50,7 @@ sprite_frames = SubResource("SpriteFrames_qumby")
width = 5.0 width = 5.0
default_color = Color(0.858824, 0.65098, 0.682353, 1) default_color = Color(0.858824, 0.65098, 0.682353, 1)
[node name="PlatformDetectionRayCast1" type="RayCast2D" parent="."] [node name="PlatformDetectionRayCast" type="RayCast2D" parent="."]
collision_mask = 32
[node name="PlatformDetectionRayCast2" type="RayCast2D" parent="."]
position = Vector2(20, 0)
collision_mask = 32
[node name="PlatformDetectionRayCast3" type="RayCast2D" parent="."]
position = Vector2(-20, 0)
collision_mask = 32 collision_mask = 32
[node name="ItemMarker2D" type="Marker2D" parent="."] [node name="ItemMarker2D" type="Marker2D" parent="."]
@ -67,5 +59,3 @@ position = Vector2(15, 20)
[node name="DamageNumber" type="Marker2D" parent="."] [node name="DamageNumber" type="Marker2D" parent="."]
position = Vector2(0, -47) position = Vector2(0, -47)
script = ExtResource("3_lrmsw") script = ExtResource("3_lrmsw")
[node name="AudioListener2D" type="AudioListener2D" parent="."]

View File

@ -34,20 +34,17 @@ radius = 172.29
collision_layer = 64 collision_layer = 64
collision_mask = 38 collision_mask = 38
script = ExtResource("1_ubaid") script = ExtResource("1_ubaid")
InitWeaponId = null
CharacterName = "character_necromancer"
CanMutateAfterDeath = false
_initialHp = null
MaxHp = 50
CampId = "Mazoku"
LootListId = "test" LootListId = "test"
metadata/CampId = "Mazoku"
metadata/MaxHp = 50
metadata/Name = "死灵法师"
[node name="CollisionShape2D" type="CollisionShape2D" parent="."] [node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(0, 4) position = Vector2(0, 4)
shape = SubResource("CapsuleShape2D_bb8wt") shape = SubResource("CapsuleShape2D_bb8wt")
[node name="Area2DPickingArea" type="Area2D" parent="."] [node name="Area2DPickingArea" type="Area2D" parent="."]
collision_layer = 64 collision_layer = 0
collision_mask = 8 collision_mask = 8
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2DPickingArea"] [node name="CollisionShape2D" type="CollisionShape2D" parent="Area2DPickingArea"]
@ -92,20 +89,13 @@ shape = SubResource("CircleShape2D_c61vr")
position = Vector2(0, -79) position = Vector2(0, -79)
script = ExtResource("5_y2fh5") script = ExtResource("5_y2fh5")
[node name="VisibleOnScreenEnabler2D" type="VisibleOnScreenEnabler2D" parent="."]
position = Vector2(0, 5.5)
scale = Vector2(2.04, 3.05)
[node name="ScoutArea2D" type="Area2D" parent="."] [node name="ScoutArea2D" type="Area2D" parent="."]
collision_layer = 0 collision_layer = 0
collision_mask = 76 collision_mask = 76
[node name="CollisionShape2D" type="CollisionShape2D" parent="ScoutArea2D"] [node name="CollisionShape2D" type="CollisionShape2D" parent="ScoutArea2D"]
shape = SubResource("CircleShape2D_fowd5") shape = SubResource("CircleShape2D_fowd5")
[node name="TipLabel" type="Label" parent="."]
anchors_preset = 5
anchor_left = 0.5
anchor_right = 0.5
offset_left = -57.0
offset_top = 57.0
offset_right = 61.0
offset_bottom = 82.0
grow_horizontal = 2
horizontal_alignment = 1

View File

@ -1,117 +0,0 @@
[gd_scene load_steps=16 format=3 uid="uid://djsh4unystlf0"]
[ext_resource type="Script" path="res://scripts/furniture/GuiFurniture.cs" id="1_t1qdg"]
[ext_resource type="Texture2D" uid="uid://cyciw4drjvrs8" path="res://sprites/furnitures/SpellEditor.png" id="2_sbshw"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_vx4tg"]
size = Vector2(31, 31)
[sub_resource type="CircleShape2D" id="CircleShape2D_in1f7"]
radius = 52.6118
[sub_resource type="AtlasTexture" id="AtlasTexture_yq6e3"]
atlas = ExtResource("2_sbshw")
region = Rect2(0, 0, 44, 43)
[sub_resource type="AtlasTexture" id="AtlasTexture_ljyfv"]
atlas = ExtResource("2_sbshw")
region = Rect2(44, 0, 44, 43)
[sub_resource type="AtlasTexture" id="AtlasTexture_46j2i"]
atlas = ExtResource("2_sbshw")
region = Rect2(88, 0, 44, 43)
[sub_resource type="AtlasTexture" id="AtlasTexture_q6a2v"]
atlas = ExtResource("2_sbshw")
region = Rect2(132, 0, 44, 43)
[sub_resource type="AtlasTexture" id="AtlasTexture_lyh2i"]
atlas = ExtResource("2_sbshw")
region = Rect2(0, 43, 44, 43)
[sub_resource type="AtlasTexture" id="AtlasTexture_84sml"]
atlas = ExtResource("2_sbshw")
region = Rect2(44, 43, 44, 43)
[sub_resource type="AtlasTexture" id="AtlasTexture_xncbb"]
atlas = ExtResource("2_sbshw")
region = Rect2(88, 43, 44, 43)
[sub_resource type="AtlasTexture" id="AtlasTexture_eaqhr"]
atlas = ExtResource("2_sbshw")
region = Rect2(132, 43, 44, 43)
[sub_resource type="AtlasTexture" id="AtlasTexture_bcdl4"]
atlas = ExtResource("2_sbshw")
region = Rect2(0, 86, 44, 43)
[sub_resource type="AtlasTexture" id="AtlasTexture_a4mgy"]
atlas = ExtResource("2_sbshw")
region = Rect2(44, 86, 44, 43)
[sub_resource type="SpriteFrames" id="SpriteFrames_mppe5"]
animations = [{
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_yq6e3")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ljyfv")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_46j2i")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_q6a2v")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_lyh2i")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_84sml")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_xncbb")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_eaqhr")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_bcdl4")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_a4mgy")
}],
"loop": true,
"name": &"default",
"speed": 5.0
}]
[node name="RigidBody2D" type="RigidBody2D"]
collision_layer = 256
collision_mask = 160
script = ExtResource("1_t1qdg")
Path = "res://prefab/ui/SpellEditorUI.tscn"
_furnitureName = "ui_spell_editor"
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(-0.5, -0.5)
shape = SubResource("RectangleShape2D_vx4tg")
[node name="OperateArea2D" type="Area2D" parent="."]
visible = false
[node name="CollisionShape2D" type="CollisionShape2D" parent="OperateArea2D"]
shape = SubResource("CircleShape2D_in1f7")
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."]
scale = Vector2(0.7, 0.7)
sprite_frames = SubResource("SpriteFrames_mppe5")
autoplay = "default"
frame_progress = 0.717769
[node name="TipLabel" type="Label" parent="."]
offset_left = -17.0
offset_top = 19.0
offset_right = 23.0
offset_bottom = 44.0

View File

@ -1,30 +0,0 @@
[gd_scene load_steps=5 format=3 uid="uid://dld3qttpsdjpe"]
[ext_resource type="Script" path="res://scripts/furniture/Barrier.cs" id="1_hfnuj"]
[ext_resource type="Texture2D" uid="uid://cvlm5tmv43i8t" path="res://sprites/furnitures/wooden_box.png" id="2_24vtp"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_vx4tg"]
size = Vector2(32, 32)
[sub_resource type="CircleShape2D" id="CircleShape2D_in1f7"]
radius = 52.6118
[node name="WoodenBox" type="RigidBody2D"]
collision_layer = 256
collision_mask = 160
script = ExtResource("1_hfnuj")
_initialDurability = null
_maxDurability = 1
_furnitureName = null
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("RectangleShape2D_vx4tg")
[node name="OperateArea2D" type="Area2D" parent="."]
visible = false
[node name="CollisionShape2D" type="CollisionShape2D" parent="OperateArea2D"]
shape = SubResource("CircleShape2D_in1f7")
[node name="WoodenBox" type="Sprite2D" parent="."]
texture = ExtResource("2_24vtp")

View File

@ -1,39 +0,0 @@
[gd_scene load_steps=5 format=3 uid="uid://cj36fjtrlo03t"]
[ext_resource type="Script" path="res://scripts/inventory/ResignationCertificate.cs" id="1_nydte"]
[ext_resource type="AudioStream" uid="uid://cak6chjjsu7wo" path="res://sounds/fire.wav" id="2_ei0j2"]
[ext_resource type="Texture2D" uid="uid://dyfqdpdlq286h" path="res://sprites/projectile/resignationCertificate.png" id="3_jwff2"]
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_xnc20"]
radius = 6.0
height = 21.0
[node name="Resignation certificate" type="RigidBody2D"]
collision_layer = 8
collision_mask = 34
angular_damp = -1.0
script = ExtResource("1_nydte")
FiringIntervalAsMillisecond = 1000
_recoilStrength = null
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(1, 0.5)
shape = SubResource("CapsuleShape2D_xnc20")
[node name="Marker2D" type="Marker2D" parent="."]
position = Vector2(65, 0)
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="Marker2D"]
stream = ExtResource("2_ei0j2")
bus = &"SoundEffect"
[node name="TipLabel" type="Label" parent="."]
offset_left = -19.0
offset_top = 23.0
offset_right = 21.0
offset_bottom = 48.0
[node name="CurseOfTheUndead" type="Sprite2D" parent="."]
[node name="X3" type="Sprite2D" parent="."]
texture = ExtResource("3_jwff2")

View File

@ -1,38 +0,0 @@
[gd_scene load_steps=5 format=3 uid="uid://m3tkjcbrrhfj"]
[ext_resource type="Script" path="res://scripts/spell/NodeSpawnOnKillCharacterSpell.cs" id="1_gg5rs"]
[ext_resource type="AudioStream" uid="uid://cak6chjjsu7wo" path="res://sounds/fire.wav" id="2_83n3c"]
[ext_resource type="Texture2D" uid="uid://mb5yijtw7sw5" path="res://sprites/projectile/x3.png" id="3_thtsv"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_i3lbq"]
size = Vector2(30, 31)
[node name="curse" type="RigidBody2D"]
collision_layer = 8
collision_mask = 34
angular_damp = -1.0
script = ExtResource("1_gg5rs")
_packedScenePath = "res://prefab/entitys/BlackenedAboriginalWarrior.tscn"
_projectilePath = null
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(0, -0.5)
shape = SubResource("RectangleShape2D_i3lbq")
[node name="Marker2D" type="Marker2D" parent="."]
position = Vector2(65, 0)
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="Marker2D"]
stream = ExtResource("2_83n3c")
bus = &"SoundEffect"
[node name="TipLabel" type="Label" parent="."]
offset_left = -19.0
offset_top = 23.0
offset_right = 21.0
offset_bottom = 48.0
[node name="CurseOfTheUndead" type="Sprite2D" parent="."]
[node name="X3" type="Sprite2D" parent="."]
texture = ExtResource("3_thtsv")

View File

@ -1,34 +0,0 @@
[gd_scene load_steps=5 format=3 uid="uid://crthy8a50a4t"]
[ext_resource type="Script" path="res://scripts/spell/SpellPickAble.cs" id="1_v0grp"]
[ext_resource type="AudioStream" uid="uid://cak6chjjsu7wo" path="res://sounds/fire.wav" id="4_ffr2k"]
[ext_resource type="Texture2D" uid="uid://bbcjkyrsx88av" path="res://sprites/projectile/curseOfTheUndead.png" id="4_y6nkf"]
[sub_resource type="CircleShape2D" id="CircleShape2D_akp3k"]
[node name="curseOfTheUndead" type="RigidBody2D"]
collision_layer = 8
collision_mask = 34
angular_damp = -1.0
script = ExtResource("1_v0grp")
_projectilePath = "res://prefab/projectile/curseOfTheUndead.tscn"
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(0, -0.625)
shape = SubResource("CircleShape2D_akp3k")
[node name="Marker2D" type="Marker2D" parent="."]
position = Vector2(65, 0)
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="Marker2D"]
stream = ExtResource("4_ffr2k")
bus = &"SoundEffect"
[node name="TipLabel" type="Label" parent="."]
offset_left = -19.0
offset_top = 23.0
offset_right = 21.0
offset_bottom = 48.0
[node name="CurseOfTheUndead" type="Sprite2D" parent="."]
texture = ExtResource("4_y6nkf")

View File

@ -1,36 +0,0 @@
[gd_scene load_steps=5 format=3 uid="uid://bt3ck8twqowke"]
[ext_resource type="Script" path="res://scripts/spell/SpellPickAble.cs" id="1_xxv2a"]
[ext_resource type="AudioStream" uid="uid://cak6chjjsu7wo" path="res://sounds/fire.wav" id="2_p1csa"]
[ext_resource type="Texture2D" uid="uid://ca3paw31aubkd" path="res://sprites/projectile/magicMissile.png" id="3_ckdw6"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_i3lbq"]
size = Vector2(20, 14)
[node name="MagicMissile" type="RigidBody2D"]
collision_layer = 8
collision_mask = 34
angular_damp = -1.0
script = ExtResource("1_xxv2a")
_projectilePath = "res://prefab/projectile/magicMissile.tscn"
UniqueIcon = ExtResource("3_ckdw6")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("RectangleShape2D_i3lbq")
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="."]
stream = ExtResource("2_p1csa")
bus = &"SoundEffect"
[node name="Marker2D" type="Marker2D" parent="."]
[node name="TipLabel" type="Label" parent="."]
offset_left = -19.0
offset_top = 23.0
offset_right = 21.0
offset_bottom = 48.0
[node name="CurseOfTheUndead" type="Sprite2D" parent="."]
[node name="MagicMissile" type="Sprite2D" parent="."]
texture = ExtResource("3_ckdw6")

View File

@ -1,36 +0,0 @@
[gd_scene load_steps=5 format=3 uid="uid://cg75t3fw5c6er"]
[ext_resource type="Script" path="res://scripts/spell/TrackingSpell.cs" id="1_vhnwx"]
[ext_resource type="AudioStream" uid="uid://cak6chjjsu7wo" path="res://sounds/fire.wav" id="2_3fbv3"]
[ext_resource type="Texture2D" uid="uid://dhgbij2ifphar" path="res://sprites/projectile/trackingSpell.png" id="2_i33g0"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_i3lbq"]
size = Vector2(30, 31)
[node name="trackingSpell" type="RigidBody2D"]
collision_layer = 8
collision_mask = 34
angular_damp = -1.0
script = ExtResource("1_vhnwx")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(0, -0.5)
shape = SubResource("RectangleShape2D_i3lbq")
[node name="Marker2D" type="Marker2D" parent="."]
position = Vector2(65, 0)
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="Marker2D"]
stream = ExtResource("2_3fbv3")
bus = &"SoundEffect"
[node name="TipLabel" type="Label" parent="."]
offset_left = -19.0
offset_top = 23.0
offset_right = 21.0
offset_bottom = 48.0
[node name="CurseOfTheUndead" type="Sprite2D" parent="."]
[node name="TrackingSpell" type="Sprite2D" parent="."]
texture = ExtResource("2_i33g0")

View File

@ -1,38 +0,0 @@
[gd_scene load_steps=5 format=3 uid="uid://cg75t3fw5c6er"]
[ext_resource type="Script" path="res://scripts/spell/MultipleFireSpell.cs" id="1_cnhod"]
[ext_resource type="Texture2D" uid="uid://mb5yijtw7sw5" path="res://sprites/projectile/x3.png" id="3_b3s8h"]
[ext_resource type="AudioStream" uid="uid://cak6chjjsu7wo" path="res://sounds/fire.wav" id="4_ffr2k"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_i3lbq"]
size = Vector2(30, 31)
[node name="x3" type="RigidBody2D"]
collision_layer = 8
collision_mask = 34
angular_damp = -1.0
script = ExtResource("1_cnhod")
RandomAngle = true
UnitRadian = 0.07
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(0, -0.5)
shape = SubResource("RectangleShape2D_i3lbq")
[node name="Marker2D" type="Marker2D" parent="."]
position = Vector2(65, 0)
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="Marker2D"]
stream = ExtResource("4_ffr2k")
bus = &"SoundEffect"
[node name="TipLabel" type="Label" parent="."]
offset_left = -19.0
offset_top = 23.0
offset_right = 21.0
offset_bottom = 48.0
[node name="CurseOfTheUndead" type="Sprite2D" parent="."]
[node name="X3" type="Sprite2D" parent="."]
texture = ExtResource("3_b3s8h")

View File

@ -1,26 +0,0 @@
[gd_scene load_steps=4 format=3 uid="uid://bq5d2w22wnxrf"]
[ext_resource type="Script" path="res://scripts/inventory/Packsack.cs" id="1_slakl"]
[ext_resource type="Texture2D" uid="uid://di0sw4rgd26y0" path="res://sprites/PortableBackpacks.png" id="2_l0fbh"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_xqyue"]
size = Vector2(21, 29)
[node name="RigidBody2D" type="RigidBody2D"]
collision_layer = 8
collision_mask = 38
script = ExtResource("1_slakl")
NumberSlots = 30
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(-2.5, 1.5)
shape = SubResource("RectangleShape2D_xqyue")
[node name="Packsack" type="Sprite2D" parent="."]
scale = Vector2(0.5, 0.5)
texture = ExtResource("2_l0fbh")
[node name="TipLabel" type="Label" parent="."]
offset_top = 31.0
offset_right = 40.0
offset_bottom = 56.0

View File

@ -0,0 +1,37 @@
[gd_scene load_steps=5 format=3 uid="uid://cn10fimoem04m"]
[ext_resource type="Script" path="res://scripts/inventory/Packsack.cs" id="1_slakl"]
[ext_resource type="Texture2D" uid="uid://dvx10dfjctn7t" path="res://sprites/packsack.png" id="2_40jca"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_brthl"]
size = Vector2(21, 29)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_xqyue"]
size = Vector2(21, 29)
[node name="RigidBody2D" type="RigidBody2D"]
collision_layer = 8
collision_mask = 38
script = ExtResource("1_slakl")
NumberSlots = 30
Id = "packsack"
UniqueName = null
UniqueDescription = null
_minContactInjury = null
_maxContactInjury = null
[node name="DamageArea2D" type="Area2D" parent="."]
collision_layer = 8
collision_mask = 102
[node name="CollisionShape2D" type="CollisionShape2D" parent="DamageArea2D"]
position = Vector2(-2.5, 1.5)
shape = SubResource("RectangleShape2D_brthl")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(-2.5, 1.5)
shape = SubResource("RectangleShape2D_xqyue")
[node name="Packsack" type="Sprite2D" parent="."]
scale = Vector2(0.5, 0.5)
texture = ExtResource("2_40jca")

View File

@ -1,21 +1,22 @@
[gd_scene load_steps=4 format=3 uid="uid://c01av43yk1q71"] [gd_scene load_steps=5 format=3 uid="uid://c01av43yk1q71"]
[ext_resource type="Script" path="res://scripts/projectile/Projectile.cs" id="1_ib3qh"] [ext_resource type="Script" path="res://scripts/projectile/Projectile.cs" id="1_ib3qh"]
[ext_resource type="Texture2D" uid="uid://bbcjkyrsx88av" path="res://sprites/projectile/curseOfTheUndead.png" id="1_k8el6"] [ext_resource type="Texture2D" uid="uid://bbcjkyrsx88av" path="res://sprites/projectile/curseOfTheUndead.png" id="1_k8el6"]
[sub_resource type="CircleShape2D" id="CircleShape2D_dgro2"] [sub_resource type="CircleShape2D" id="CircleShape2D_dgro2"]
[sub_resource type="CircleShape2D" id="CircleShape2D_8117d"]
radius = 11.0
[node name="curseOfTheUndead" type="CharacterBody2D"] [node name="curseOfTheUndead" type="CharacterBody2D"]
collision_layer = 0 collision_layer = 0
collision_mask = 0 collision_mask = 0
script = ExtResource("1_ib3qh") script = ExtResource("1_ib3qh")
_life = 5000 metadata/Speed = 500.0
_durability = 1.0 metadata/Durability = 1.0
_maxDamage = 7 metadata/DamageType = 2
_minDamage = 3 metadata/Knockback = Vector2(2, -3)
_damageType = 2 metadata/Life = 5000
Speed = 10.0
_repelStrength = 2.5
[node name="CurseOfTheUndead" type="Sprite2D" parent="."] [node name="CurseOfTheUndead" type="Sprite2D" parent="."]
texture = ExtResource("1_k8el6") texture = ExtResource("1_k8el6")
@ -23,6 +24,9 @@ texture = ExtResource("1_k8el6")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."] [node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("CircleShape2D_dgro2") shape = SubResource("CircleShape2D_dgro2")
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="."] [node name="CollisionDetectionArea" type="Area2D" parent="."]
bus = &"SoundEffect" collision_layer = 16
area_mask = 16 collision_mask = 78
[node name="CollisionShape2D" type="CollisionShape2D" parent="CollisionDetectionArea"]
shape = SubResource("CircleShape2D_8117d")

View File

@ -1,31 +0,0 @@
[gd_scene load_steps=4 format=3 uid="uid://dmt5gpklx8efc"]
[ext_resource type="Script" path="res://scripts/projectile/Projectile.cs" id="1_cp6hg"]
[ext_resource type="Texture2D" uid="uid://ca3paw31aubkd" path="res://sprites/projectile/magicMissile.png" id="2_6mikr"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_vfvxd"]
size = Vector2(20, 14)
[node name="MagicMissile" type="CharacterBody2D"]
collision_layer = 0
collision_mask = 0
script = ExtResource("1_cp6hg")
_life = 5000
_durability = 1.0
_maxDamage = 7
_minDamage = 3
_damageType = 2
Speed = 15.0
_repelStrength = 2.5
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(1, 0)
shape = SubResource("RectangleShape2D_vfvxd")
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="."]
bus = &"SoundEffect"
area_mask = 16
[node name="MagicMissile" type="Sprite2D" parent="."]
position = Vector2(1, 0)
texture = ExtResource("2_6mikr")

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,70 @@
[gd_scene load_steps=8 format=3 uid="uid://b0uurp551pku"]
[ext_resource type="TileSet" uid="uid://c4wpp12rr44hi" path="res://tileSets/dungeon.tres" id="1_a15hy"]
[ext_resource type="Script" path="res://scripts/map/AiCharacterSpawn.cs" id="2_wamhd"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_kiih8"]
size = Vector2(443, 118)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_o85u0"]
size = Vector2(20, 48)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_30r3c"]
size = Vector2(20, 46)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_7tsse"]
size = Vector2(53, 24)
[sub_resource type="NavigationPolygon" id="NavigationPolygon_rh1gx"]
vertices = PackedVector2Array(501, 150, 9, 151, 11, 107, 43, 107, 170, 41, 169, 11, 217, 11, 219, 42, 42, 44, 470, 107, 499, 106, 469, 43)
polygons = Array[PackedInt32Array]([PackedInt32Array(0, 1, 2, 3), PackedInt32Array(4, 5, 6, 7), PackedInt32Array(0, 3, 8, 4, 7, 9), PackedInt32Array(9, 10, 0), PackedInt32Array(9, 7, 11)])
outlines = Array[PackedVector2Array]([PackedVector2Array(479, 34, 228, 32, 226, 1, 159, 1, 160, 31, 32, 35, 33, 97, 1, 97, -1, 162, 512, 160, 509, 96, 480, 97)])
source_geometry_group_name = &"navigation_polygon_source_group"
[node name="InitialRoom" type="Node2D"]
[node name="TileMap" type="TileMap" parent="."]
tile_set = ExtResource("1_a15hy")
format = 2
layer_0/name = "BackgroundWall"
layer_0/navigation_enabled = false
layer_0/tile_data = PackedInt32Array(65550, 393217, 5, 131086, 393217, 5, 196622, 393217, 5, 262158, 393217, 5, 262157, 393217, 5, 196621, 393217, 5, 131085, 393217, 5, 65549, 393217, 5, 65548, 393217, 5, 65547, 393217, 5, 65546, 393217, 5, 65545, 393217, 5, 65544, 393217, 5, 65543, 393217, 5, 65542, 393217, 5, 65541, 393217, 5, 65540, 393217, 5, 65539, 393217, 5, 65538, 393217, 5, 65537, 393217, 5, 131073, 393217, 5, 131074, 393217, 5, 131075, 393217, 5, 131076, 393217, 5, 131077, 393217, 5, 131078, 393217, 5, 131079, 393217, 5, 131080, 393217, 5, 131081, 393217, 5, 131082, 393217, 5, 131083, 393217, 5, 131084, 393217, 5, 196620, 393217, 5, 196619, 393217, 5, 196618, 393217, 5, 196617, 393217, 5, 196616, 262145, 5, 196615, 393217, 5, 196614, 393217, 5, 196613, 262145, 5, 196612, 393217, 5, 196611, 393217, 5, 196610, 393217, 5, 196609, 393217, 5, 262145, 393217, 5, 262146, 393217, 5, 262147, 393217, 5, 262148, 393217, 5, 262149, 393217, 5, 262150, 393217, 5, 262151, 393217, 5, 262152, 393217, 5, 262153, 393217, 5, 262154, 393217, 5, 262155, 393217, 5, 262156, 393217, 5, 196608, 393217, 5, 262144, 393217, 5, 262159, 393217, 5, 196623, 393217, 5, 5, 393217, 5, 6, 393217, 5)
layer_1/name = "BackgroundDecoration"
layer_1/tile_data = PackedInt32Array()
layer_2/name = "Ground"
layer_2/tile_data = PackedInt32Array(0, 1, 3, 65536, 131073, 1, 131072, 131073, 1, 1, 65537, 2, 2, 65537, 2, 3, 65537, 2, 4, 65537, 2, 7, 65537, 2, 8, 65537, 2, 9, 65537, 2, 10, 65537, 2, 11, 65537, 2, 12, 65537, 2, 13, 65537, 2, 14, 65537, 3, 15, 131073, 3, 65551, 131073, 4, 131087, 131073, 4, 327681, 65537, 0, 327682, 65537, 0, 327683, 65537, 0, 327684, 65537, 0, 327685, 65537, 0, 327686, 65537, 0, 327687, 65537, 0, 327688, 65537, 0, 327689, 65537, 0, 327690, 65537, 0, 327691, 65537, 0, 327692, 65537, 0, 327693, 65537, 0, 327694, 65537, 0, 327680, 1, 5, 327695, 131073, 5, 5, 262145, 4, 6, 262145, 4)
[node name="RoomArea" type="Area2D" parent="."]
collision_mask = 0
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomArea"]
position = Vector2(256.5, 95)
shape = SubResource("RectangleShape2D_kiih8")
[node name="RoomSlotList" type="Node2D" parent="."]
[node name="Area2D" type="Area2D" parent="RoomSlotList"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomSlotList/Area2D"]
position = Vector2(17, 129)
shape = SubResource("RectangleShape2D_o85u0")
[node name="Area2D2" type="Area2D" parent="RoomSlotList"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomSlotList/Area2D2"]
position = Vector2(498, 128)
shape = SubResource("RectangleShape2D_30r3c")
[node name="Area2D3" type="Area2D" parent="RoomSlotList"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomSlotList/Area2D3"]
position = Vector2(193, 15)
shape = SubResource("RectangleShape2D_7tsse")
[node name="Marker2D" type="Marker2D" parent="."]
position = Vector2(260, 87)
script = ExtResource("2_wamhd")
metadata/ResPath = "res://prefab/entitys/DelivererOfDarkMagic.tscn"
[node name="NavigationRegion2D" type="NavigationRegion2D" parent="."]
navigation_polygon = SubResource("NavigationPolygon_rh1gx")

View File

@ -0,0 +1,71 @@
[gd_scene load_steps=8 format=3 uid="uid://dslr5tdbp4noq"]
[ext_resource type="TileSet" uid="uid://c4wpp12rr44hi" path="res://tileSets/dungeon.tres" id="1_rn2om"]
[ext_resource type="Script" path="res://scripts/map/AiCharacterSpawn.cs" id="2_7q101"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_kiih8"]
size = Vector2(441, 122)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_o85u0"]
size = Vector2(20, 48)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_x4kt2"]
size = Vector2(46, 20)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_131jn"]
size = Vector2(20, 54)
[sub_resource type="NavigationPolygon" id="NavigationPolygon_db40i"]
vertices = PackedVector2Array(499, 108, 501, 150, 246, 149, 471, 108, 12, 149, 11, 107, 41, 107, 203, 149, 245, 180, 203, 178, 43, 43, 470, 44)
polygons = Array[PackedInt32Array]([PackedInt32Array(0, 1, 2, 3), PackedInt32Array(4, 5, 6, 7), PackedInt32Array(2, 8, 9, 7), PackedInt32Array(10, 11, 3, 2, 7, 6)])
outlines = Array[PackedVector2Array]([PackedVector2Array(34, 33, 31, 97, 1, 98, 2, 159, 193, 159, 193, 188, 255, 191, 256, 159, 512, 161, 509, 98, 481, 98, 480, 35)])
source_geometry_group_name = &"navigation_polygon_source_group"
[node name="InitialRoom" type="Node2D"]
[node name="TileMap" type="TileMap" parent="."]
tile_set = ExtResource("1_rn2om")
format = 2
layer_0/name = "BackgroundWall"
layer_0/navigation_enabled = false
layer_0/tile_data = PackedInt32Array(65550, 393217, 5, 131086, 393217, 5, 196622, 393217, 5, 262158, 393217, 5, 262157, 393217, 5, 196621, 393217, 5, 131085, 393217, 5, 65549, 393217, 5, 65548, 393217, 5, 65547, 393217, 5, 65546, 393217, 5, 65545, 393217, 5, 65544, 393217, 5, 65543, 393217, 5, 65542, 393217, 5, 65541, 393217, 5, 65540, 393217, 5, 65539, 393217, 5, 65538, 393217, 5, 65537, 393217, 5, 131073, 393217, 5, 131074, 393217, 5, 131075, 393217, 5, 131076, 393217, 5, 131077, 393217, 5, 131078, 393217, 5, 131079, 393217, 5, 131080, 393217, 5, 131081, 393217, 5, 131082, 393217, 5, 131083, 393217, 5, 131084, 393217, 5, 196620, 393217, 5, 196619, 393217, 5, 196618, 393217, 5, 196617, 393217, 5, 196616, 262145, 5, 196615, 393217, 5, 196614, 393217, 5, 196613, 262145, 5, 196612, 393217, 5, 196611, 393217, 5, 196610, 393217, 5, 196609, 393217, 5, 262145, 393217, 5, 262146, 393217, 5, 262147, 393217, 5, 262148, 393217, 5, 262149, 393217, 5, 262150, 393217, 5, 262151, 393217, 5, 262152, 393217, 5, 262153, 393217, 5, 262154, 393217, 5, 262155, 393217, 5, 262156, 393217, 5, 196608, 393217, 5, 262144, 393217, 5, 262159, 393217, 5, 196623, 393217, 5, 327686, 393217, 5, 327687, 393217, 5)
layer_1/name = "BackgroundDecoration"
layer_1/tile_data = PackedInt32Array()
layer_2/name = "Ground"
layer_2/tile_data = PackedInt32Array(0, 1, 3, 65536, 131073, 1, 131072, 131073, 1, 1, 65537, 2, 2, 65537, 2, 3, 65537, 2, 4, 65537, 2, 5, 65537, 2, 6, 65537, 2, 7, 65537, 2, 8, 65537, 2, 9, 65537, 2, 10, 65537, 2, 11, 65537, 2, 12, 65537, 2, 13, 65537, 2, 14, 65537, 3, 15, 131073, 3, 65551, 131073, 4, 131087, 131073, 4, 327681, 65537, 0, 327682, 65537, 0, 327683, 65537, 0, 327684, 65537, 0, 327685, 65537, 0, 327688, 65537, 0, 327689, 65537, 0, 327690, 65537, 0, 327691, 65537, 0, 327692, 65537, 0, 327693, 65537, 0, 327694, 65537, 0, 327680, 1, 5, 327695, 131073, 5, 327686, 262145, 4, 327687, 262145, 4)
[node name="RoomArea" type="Area2D" parent="."]
collision_mask = 0
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomArea"]
position = Vector2(255.5, 97)
shape = SubResource("RectangleShape2D_kiih8")
[node name="RoomSlotList" type="Node2D" parent="."]
[node name="Area2D" type="Area2D" parent="RoomSlotList"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomSlotList/Area2D"]
position = Vector2(17, 129)
shape = SubResource("RectangleShape2D_o85u0")
[node name="Area2D3" type="Area2D" parent="RoomSlotList"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomSlotList/Area2D3"]
position = Vector2(224, 178)
shape = SubResource("RectangleShape2D_x4kt2")
[node name="Area2D2" type="Area2D" parent="RoomSlotList"]
position = Vector2(498, 109)
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomSlotList/Area2D2"]
position = Vector2(0, 17)
shape = SubResource("RectangleShape2D_131jn")
[node name="Marker2D" type="Marker2D" parent="."]
position = Vector2(237, 69)
script = ExtResource("2_7q101")
metadata/ResPath = "res://prefab/entitys/DelivererOfDarkMagic.tscn"
[node name="NavigationRegion2D" type="NavigationRegion2D" parent="."]
navigation_polygon = SubResource("NavigationPolygon_db40i")

View File

@ -0,0 +1,63 @@
[gd_scene load_steps=8 format=3 uid="uid://du5ldsp613fei"]
[ext_resource type="TileSet" uid="uid://c4wpp12rr44hi" path="res://tileSets/dungeon.tres" id="1_rn2om"]
[ext_resource type="Script" path="res://scripts/map/PlayerSpawn.cs" id="2_6p8mv"]
[ext_resource type="Script" path="res://scripts/map/ItemSpawn.cs" id="3_v1tlc"]
[ext_resource type="Texture2D" uid="uid://b2blj0yf4ohx3" path="res://icon.svg" id="4_psvpu"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_kiih8"]
size = Vector2(450, 191)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_jxmys"]
size = Vector2(18, 57.75)
[sub_resource type="NavigationPolygon" id="NavigationPolygon_064c7"]
vertices = PackedVector2Array(468, 174, 500, 174, 499, 214, 41, 214, 45, 45, 468, 45)
polygons = Array[PackedInt32Array]([PackedInt32Array(0, 1, 2, 3), PackedInt32Array(0, 3, 4, 5)])
outlines = Array[PackedVector2Array]([PackedVector2Array(35, 35, 31, 224, 509, 225, 510, 164, 478, 164, 478, 35)])
source_geometry_group_name = &"navigation_polygon_source_group"
[node name="InitialRoom" type="Node2D"]
[node name="TileMap" type="TileMap" parent="."]
tile_set = ExtResource("1_rn2om")
format = 2
layer_0/name = "BackgroundWall"
layer_0/navigation_enabled = false
layer_0/tile_data = PackedInt32Array(393230, 393217, 5, 393229, 393217, 5, 393228, 393217, 5, 393227, 393217, 5, 393226, 393217, 5, 393225, 393217, 5, 393224, 393217, 5, 393223, 393217, 5, 393222, 393217, 5, 65550, 393217, 5, 131086, 393217, 5, 196622, 393217, 5, 262158, 393217, 5, 327694, 393217, 5, 327693, 393217, 5, 262157, 393217, 5, 196621, 393217, 5, 131085, 393217, 5, 65549, 393217, 5, 65548, 393217, 5, 65547, 393217, 5, 65546, 393217, 5, 65545, 393217, 5, 65544, 393217, 5, 65543, 393217, 5, 65542, 393217, 5, 65541, 393217, 5, 65540, 393217, 5, 65539, 393217, 5, 65538, 393217, 5, 65537, 393217, 5, 131073, 393217, 5, 131074, 393217, 5, 131075, 393217, 5, 131076, 393217, 5, 131077, 393217, 5, 131078, 393217, 5, 131079, 393217, 5, 131080, 393217, 5, 131081, 393217, 5, 131082, 393217, 5, 131083, 393217, 5, 131084, 393217, 5, 196620, 393217, 5, 196619, 393217, 5, 196618, 393217, 5, 196617, 393217, 5, 196616, 262145, 5, 196615, 393217, 5, 196614, 393217, 5, 196613, 262145, 5, 196612, 393217, 5, 196611, 393217, 5, 196610, 393217, 5, 196609, 393217, 5, 262145, 393217, 5, 262146, 393217, 5, 262147, 393217, 5, 262148, 393217, 5, 262149, 393217, 5, 262150, 393217, 5, 262151, 393217, 5, 262152, 393217, 5, 262153, 393217, 5, 262154, 393217, 5, 262155, 393217, 5, 262156, 393217, 5, 327692, 393217, 5, 327691, 393217, 5, 327690, 393217, 5, 327689, 393217, 5, 327688, 393217, 5, 327687, 393217, 5, 327686, 393217, 5, 327685, 393217, 5, 327684, 393217, 5, 327683, 393217, 5, 327682, 393217, 5, 327681, 393217, 5, 393217, 393217, 5, 393218, 393217, 5, 393219, 393217, 5, 393220, 393217, 5, 393221, 393217, 5, 393231, 393217, 5, 327695, 393217, 5)
layer_1/name = "BackgroundDecoration"
layer_1/tile_data = PackedInt32Array(393218, 458753, 5, 65550, 458753, 4)
layer_2/name = "Ground"
layer_2/tile_data = PackedInt32Array(0, 1, 3, 65536, 131073, 1, 131072, 131073, 1, 196608, 131073, 1, 262144, 131073, 1, 458752, 1, 5, 15, 131073, 3, 65551, 131073, 4, 131087, 131073, 4, 196623, 131073, 4, 262159, 131073, 4, 458767, 131073, 5, 327680, 131073, 1, 393216, 131073, 1, 1, 65537, 2, 2, 65537, 2, 3, 65537, 2, 4, 65537, 2, 5, 65537, 2, 6, 65537, 2, 7, 65537, 2, 8, 65537, 2, 9, 65537, 2, 10, 65537, 2, 11, 65537, 2, 12, 65537, 2, 13, 65537, 2, 14, 65537, 3, 458753, 65537, 0, 458754, 65537, 0, 458755, 65537, 0, 458756, 65537, 0, 458757, 65537, 0, 458758, 65537, 0, 458759, 65537, 0, 458760, 65537, 0, 458761, 65537, 0, 458762, 65537, 0, 458763, 65537, 0, 458764, 65537, 0, 458765, 65537, 0, 458766, 65537, 0)
[node name="RoomArea" type="Area2D" parent="."]
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomArea"]
position = Vector2(253, 130.5)
shape = SubResource("RectangleShape2D_kiih8")
[node name="RoomSlotList" type="Node2D" parent="."]
[node name="Slot1" type="Area2D" parent="RoomSlotList"]
position = Vector2(491, 193)
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomSlotList/Slot1"]
position = Vector2(5, 0)
shape = SubResource("RectangleShape2D_jxmys")
debug_color = Color(0, 0.6, 0.701961, 0.419608)
[node name="Marker2D" type="Marker2D" parent="."]
position = Vector2(221, 134)
script = ExtResource("2_6p8mv")
[node name="ItemMarker2D" type="Marker2D" parent="."]
position = Vector2(142, 84)
script = ExtResource("3_v1tlc")
ItemId = "staff_of_the_undead"
[node name="Icon" type="Sprite2D" parent="ItemMarker2D"]
scale = Vector2(0.3, 0.3)
texture = ExtResource("4_psvpu")
[node name="NavigationRegion2D" type="NavigationRegion2D" parent="."]
navigation_polygon = SubResource("NavigationPolygon_064c7")

View File

@ -1,86 +0,0 @@
[gd_scene load_steps=8 format=4 uid="uid://bo245qin4rl8a"]
[ext_resource type="TileSet" uid="uid://c4wpp12rr44hi" path="res://tileSets/dungeon.tres" id="1_60tbt"]
[ext_resource type="Texture2D" uid="uid://drw45jlmfo0su" path="res://sprites/light/White_100.png" id="2_w0wh3"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_o85u0"]
size = Vector2(20, 48)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_6qg1t"]
size = Vector2(20.9922, 46.5)
[sub_resource type="NavigationPolygon" id="NavigationPolygon_1qloc"]
vertices = PackedVector2Array(630, 138.672, 630, 183.008, 11, 183.977, 11, 138.672, 41.8984, 137.688, 599.203, 137.688, 597.203, 44.0078, 42.8906, 44.9766)
polygons = Array[PackedInt32Array]([PackedInt32Array(0, 1, 2, 3, 4, 5), PackedInt32Array(6, 5, 4, 7)])
outlines = Array[PackedVector2Array]([PackedVector2Array(33, 35, 607, 34, 609, 128, 640, 129, 640, 193, 1, 194, 1, 129, 32, 128)])
source_geometry_group_name = &"navigation_polygon_source_group"
[sub_resource type="RectangleShape2D" id="RectangleShape2D_kiih8"]
size = Vector2(638, 222)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_kfmgh"]
size = Vector2(579, 151.5)
[node name="InitialRoom2" type="Node2D"]
[node name="RoomSlotList" type="Node2D" parent="."]
[node name="Area2D" type="Area2D" parent="RoomSlotList"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomSlotList/Area2D"]
position = Vector2(14, 158)
shape = SubResource("RectangleShape2D_o85u0")
[node name="Area2D5" type="Area2D" parent="RoomSlotList"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomSlotList/Area2D5"]
position = Vector2(624, 157)
shape = SubResource("RectangleShape2D_6qg1t")
[node name="NavigationRegion2D" type="NavigationRegion2D" parent="."]
navigation_polygon = SubResource("NavigationPolygon_1qloc")
[node name="TileMap" type="Node2D" parent="."]
[node name="BackgroundWall" type="TileMapLayer" parent="TileMap"]
use_parent_material = true
tile_map_data = PackedByteArray("AAABAAEAAQAGAAUAAAABAAIAAQAGAAUAAAABAAMAAQAGAAUAAAABAAQAAQAGAAUAAAABAAUAAQAGAAUAAAACAAEAAQAGAAUAAAACAAIAAQAGAAUAAAACAAMAAQAGAAUAAAACAAQAAQAGAAUAAAACAAUAAQAGAAUAAAADAAEAAQAGAAUAAAADAAIAAQAGAAUAAAADAAMAAQAGAAUAAAADAAQAAQAGAAUAAAADAAUAAQAGAAUAAAAEAAEAAQAGAAUAAAAEAAIAAQAGAAUAAAAEAAMAAQAGAAUAAAAEAAQAAQAGAAUAAAAEAAUAAQAGAAUAAAAFAAEAAQAGAAUAAAAFAAIAAQAGAAUAAAAFAAMAAQAGAAUAAAAFAAQAAQAGAAUAAAAFAAUAAQAGAAUAAAAGAAEAAQAGAAUAAAAGAAIAAQAGAAUAAAAGAAMAAQAGAAUAAAAGAAQAAQAGAAUAAAAGAAUAAQAGAAUAAAAHAAEAAQAGAAUAAAAHAAIAAQAGAAUAAAAHAAMAAQAGAAUAAAAHAAQAAQAGAAUAAAAHAAUAAQAGAAUAAAAIAAEAAQAGAAUAAAAIAAIAAQAGAAUAAAAIAAMAAQAGAAUAAAAIAAQAAQAGAAUAAAAIAAUAAQAGAAUAAAAJAAEAAQAGAAUAAAAJAAIAAQAGAAUAAAAJAAMAAQAGAAUAAAAJAAQAAQAGAAUAAAAJAAUAAQAGAAUAAAAKAAEAAQAGAAUAAAAKAAIAAQAGAAUAAAAKAAMAAQAGAAUAAAAKAAQAAQAGAAUAAAAKAAUAAQAGAAUAAAALAAEAAQAGAAUAAAALAAIAAQAGAAUAAAALAAMAAQAGAAUAAAALAAQAAQAGAAUAAAALAAUAAQAGAAUAAAAMAAEAAQAGAAUAAAAMAAIAAQAGAAUAAAAMAAMAAQAGAAUAAAAMAAQAAQAGAAUAAAAMAAUAAQAGAAUAAAANAAEAAQAGAAUAAAANAAIAAQAGAAUAAAANAAMAAQAGAAUAAAANAAQAAQAGAAUAAAANAAUAAQAGAAUAAAAOAAEAAQAGAAUAAAAOAAIAAQAGAAUAAAAOAAMAAQAGAAUAAAAOAAQAAQAGAAUAAAAOAAUAAQAGAAUAAAAPAAEAAQAGAAUAAAAPAAIAAQAGAAUAAAAPAAMAAQAGAAUAAAAPAAQAAQAGAAUAAAAPAAUAAQAGAAUAAAAQAAEAAQAGAAUAAAAQAAIAAQAGAAUAAAAQAAMAAQAGAAUAAAAQAAQAAQAGAAUAAAAQAAUAAQAGAAUAAAARAAEAAQAGAAUAAAARAAIAAQAGAAUAAAARAAMAAQAGAAUAAAARAAQAAQAGAAUAAAARAAUAAQAGAAUAAAASAAEAAQAGAAUAAAASAAIAAQAGAAUAAAASAAMAAQAGAAUAAAASAAQAAQAGAAUAAAASAAUAAQAGAAUAAAAAAAUAAQAGAAUAAAAAAAQAAQAGAAUAAAATAAUAAQAGAAUAAAATAAQAAQAGAAUAAAA=")
tile_set = ExtResource("1_60tbt")
navigation_enabled = false
[node name="BackgroundDecoration" type="TileMapLayer" parent="TileMap"]
use_parent_material = true
tile_map_data = PackedByteArray("AAADAAQAAQAEAAYAAAAEAAQAAQAEAAYAAAAEAAUAAQAEAAYAAAADAAUAAQAEAAYAAAADAAMAAQAEAAYAAAAEAAMAAQAEAAYAAAAGAAMAAQAEAAYAAAAGAAQAAQAEAAYAAAAGAAUAAQAEAAYAAAAHAAUAAQAEAAYAAAAHAAQAAQAEAAYAAAAHAAMAAQAEAAYAAAAJAAMAAQAEAAYAAAAJAAQAAQAEAAYAAAAJAAUAAQAEAAYAAAAKAAUAAQAEAAYAAAAKAAQAAQAEAAYAAAAKAAMAAQAEAAYAAAAOAAUAAQABAAYAAAANAAUAAQAAAAYAAAA=")
tile_set = ExtResource("1_60tbt")
[node name="Ground" type="TileMapLayer" parent="TileMap"]
use_parent_material = true
tile_map_data = PackedByteArray("AAAAAAAAAQAAAAMAAAABAAAAAQABAAIAAAACAAAAAQABAAIAAAADAAAAAQABAAIAAAAEAAAAAQABAAIAAAAFAAAAAQABAAIAAAAGAAAAAQABAAIAAAAHAAAAAQABAAIAAAAIAAAAAQABAAIAAAAJAAAAAQABAAIAAAAKAAAAAQABAAIAAAALAAAAAQABAAIAAAAMAAAAAQABAAIAAAANAAAAAQABAAIAAAAOAAAAAQABAAIAAAAPAAAAAQABAAIAAAAQAAAAAQABAAIAAAARAAAAAQABAAIAAAAAAAEAAQACAAEAAAAAAAIAAQACAAEAAAAAAAMAAQACAAEAAAABAAYAAQABAAAAAAACAAYAAQABAAAAAAADAAYAAQABAAAAAAAEAAYAAQABAAAAAAAFAAYAAQABAAAAAAAGAAYAAQABAAAAAAAHAAYAAQABAAAAAAAIAAYAAQABAAAAAAAJAAYAAQABAAAAAAAKAAYAAQABAAAAAAALAAYAAQABAAAAAAAMAAYAAQABAAAAAAANAAYAAQABAAAAAAAOAAYAAQABAAAAAAAPAAYAAQABAAAAAAAQAAYAAQABAAAAAAARAAYAAQABAAAAAAASAAYAAQABAAAAAAASAAAAAQABAAIAAAATAAEAAQAAAAEAAAATAAIAAQAAAAEAAAATAAMAAQAAAAEAAAATAAYAAQACAAUAAAATAAAAAQACAAMAAAAAAAYAAQAAAAUAAAA=")
tile_set = ExtResource("1_60tbt")
[node name="Barrier" type="TileMapLayer" parent="TileMap"]
use_parent_material = true
tile_map_data = PackedByteArray("AAATAAQAAQAAAAEAAAATAAUAAQAAAAEAAAAAAAQAAQACAAEAAAAAAAUAAQACAAEAAAA=")
tile_set = ExtResource("1_60tbt")
[node name="PointLight2D" type="PointLight2D" parent="."]
visible = false
position = Vector2(320, 111)
scale = Vector2(20.125, 7.06253)
texture = ExtResource("2_w0wh3")
[node name="AutoSpawn" type="Node2D" parent="."]
visible = false
[node name="RoomArea" type="Area2D" parent="."]
collision_mask = 0
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomArea"]
position = Vector2(320, 112)
shape = SubResource("RectangleShape2D_kiih8")
[node name="SpawnArea" type="Area2D" parent="."]
[node name="CollisionShape2D" type="CollisionShape2D" parent="SpawnArea"]
position = Vector2(315.5, 116.25)
shape = SubResource("RectangleShape2D_kfmgh")

File diff suppressed because one or more lines are too long

View File

@ -1,110 +0,0 @@
[gd_scene load_steps=8 format=4 uid="uid://53ssan8hgcyn"]
[ext_resource type="TileSet" uid="uid://c4wpp12rr44hi" path="res://tileSets/dungeon.tres" id="1_kdit4"]
[ext_resource type="Texture2D" uid="uid://drw45jlmfo0su" path="res://sprites/light/White_100.png" id="2_g41lp"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_o85u0"]
size = Vector2(22.5, 48)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_6qg1t"]
size = Vector2(24.5, 59.75)
[sub_resource type="NavigationPolygon" id="NavigationPolygon_1qloc"]
vertices = PackedVector2Array(8, 791.953, 8, 746.922, 42, 749.922, 405.523, 790.039, 403.461, 746, 374.047, 746, 373.32, 109.617, 404.82, 107.648, 404.148, 150.32, 373.969, 151.328, 42, 341.359, 10.1719, 343.344, 10.8438, 301, 41, 301, 41, 86.2891, 11.6719, 88.2969, 10.3203, 45, 29.0078, 45, 371.289, 44.0234, 375.031, 489.672, 372.953, 537.211, 404.141, 533.18, 404.828, 490.656)
polygons = Array[PackedInt32Array]([PackedInt32Array(0, 1, 2, 3), PackedInt32Array(4, 3, 2, 5), PackedInt32Array(6, 7, 8, 9), PackedInt32Array(10, 11, 12, 13), PackedInt32Array(14, 15, 16, 17), PackedInt32Array(14, 17, 18, 6), PackedInt32Array(13, 14, 6, 9, 19, 10), PackedInt32Array(2, 10, 19, 20), PackedInt32Array(20, 5, 2), PackedInt32Array(21, 20, 19, 22)])
outlines = Array[PackedVector2Array]([PackedVector2Array(29, 35, 381, 34, 383, 99, 415, 97, 414, 160, 384, 161, 385, 480, 415, 481, 414, 542, 383, 546, 384, 736, 413, 736, 416, 800, -2, 802, -2, 736, 32, 739, 32, 352, 0, 354, 1, 291, 31, 291, 31, 97, 2, 99, 0, 35)])
source_geometry_group_name = &"navigation_polygon_source_group"
[sub_resource type="RectangleShape2D" id="RectangleShape2D_kiih8"]
size = Vector2(413, 828)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_kfmgh"]
size = Vector2(322, 765)
[node name="InitialRoom2" type="Node2D"]
[node name="RoomSlotList" type="Node2D" parent="."]
[node name="Area2D" type="Area2D" parent="RoomSlotList"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomSlotList/Area2D"]
position = Vector2(15, 322)
shape = SubResource("RectangleShape2D_o85u0")
[node name="Area2D2" type="Area2D" parent="RoomSlotList"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomSlotList/Area2D2"]
position = Vector2(16, 767)
shape = SubResource("RectangleShape2D_o85u0")
[node name="Area2D6" type="Area2D" parent="RoomSlotList"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomSlotList/Area2D6"]
position = Vector2(401, 516)
shape = SubResource("RectangleShape2D_o85u0")
[node name="Area2D4" type="Area2D" parent="RoomSlotList"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomSlotList/Area2D4"]
position = Vector2(14, 65)
shape = SubResource("RectangleShape2D_o85u0")
[node name="Area2D5" type="Area2D" parent="RoomSlotList"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomSlotList/Area2D5"]
position = Vector2(399, 129)
shape = SubResource("RectangleShape2D_o85u0")
[node name="Area2D3" type="Area2D" parent="RoomSlotList"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomSlotList/Area2D3"]
position = Vector2(399.75, 769.875)
shape = SubResource("RectangleShape2D_6qg1t")
[node name="NavigationRegion2D" type="NavigationRegion2D" parent="."]
position = Vector2(0, -1)
navigation_polygon = SubResource("NavigationPolygon_1qloc")
[node name="TileMap" type="Node2D" parent="."]
[node name="BackgroundWall" type="TileMapLayer" parent="TileMap"]
use_parent_material = true
tile_map_data = PackedByteArray("AAABABIAAQAGAAUAAAABABMAAQAGAAUAAAABABQAAQAGAAUAAAABABUAAQAGAAUAAAABABYAAQAGAAUAAAABABcAAQAGAAUAAAABABgAAQAGAAUAAAACABIAAQAGAAUAAAACABMAAQAGAAUAAAACABQAAQAGAAUAAAACABUAAQAGAAUAAAACABYAAQAGAAUAAAACABcAAQAGAAUAAAACABgAAQAGAAUAAAADABIAAQAGAAUAAAADABMAAQAGAAUAAAADABQAAQAGAAUAAAADABUAAQAGAAUAAAADABYAAQAGAAUAAAADABcAAQAGAAUAAAADABgAAQAGAAUAAAAEABIAAQAGAAUAAAAEABMAAQAGAAUAAAAEABQAAQAGAAUAAAAEABUAAQAGAAUAAAAEABYAAQAGAAUAAAAEABcAAQAGAAUAAAAEABgAAQAGAAUAAAAFABIAAQAGAAUAAAAFABMAAQAGAAUAAAAFABQAAQAGAAUAAAAFABUAAQAGAAUAAAAFABYAAQAGAAUAAAAFABcAAQAGAAUAAAAFABgAAQAGAAUAAAAGABIAAQAGAAUAAAAGABMAAQAGAAUAAAAGABQAAQAGAAUAAAAGABUAAQAGAAUAAAAGABYAAQAGAAUAAAAGABcAAQAGAAUAAAAGABgAAQAGAAUAAAAHABIAAQAGAAUAAAAHABMAAQAGAAUAAAAHABQAAQAGAAUAAAAHABUAAQAGAAUAAAAHABYAAQAGAAUAAAAHABcAAQAGAAUAAAAHABgAAQAGAAUAAAAIABIAAQAGAAUAAAAIABMAAQAGAAUAAAAIABQAAQAGAAUAAAAIABUAAQAGAAUAAAAIABYAAQAGAAUAAAAIABcAAQAGAAUAAAAIABgAAQAGAAUAAAAJABIAAQAGAAUAAAAJABMAAQAGAAUAAAAJABQAAQAGAAUAAAAJABUAAQAGAAUAAAAJABYAAQAGAAUAAAAJABcAAQAGAAUAAAAJABgAAQAGAAUAAAAKABIAAQAGAAUAAAAKABMAAQAGAAUAAAAKABQAAQAGAAUAAAAKABUAAQAGAAUAAAAKABYAAQAGAAUAAAAKABcAAQAGAAUAAAAKABgAAQAGAAUAAAALABIAAQAGAAUAAAALABMAAQAGAAUAAAALABQAAQAGAAUAAAALABUAAQAGAAUAAAALABYAAQAGAAUAAAALABcAAQAGAAUAAAALABgAAQAGAAUAAAAAAAEAAQAGAAUAAAAAAAIAAQAGAAUAAAABAAEAAQAGAAUAAAABAAIAAQAGAAUAAAABAAMAAQAGAAUAAAABAAQAAQAGAAUAAAABAAUAAQAGAAUAAAABAAYAAQAGAAUAAAABAAcAAQAGAAUAAAABAAgAAQAGAAUAAAABAAkAAQAGAAUAAAABAAoAAQAGAAUAAAABAAsAAQAGAAUAAAABAAwAAQAGAAUAAAABAA0AAQAGAAUAAAABAA4AAQAGAAUAAAABAA8AAQAGAAUAAAABABAAAQAGAAUAAAABABEAAQAGAAUAAAACAAEAAQAGAAUAAAACAAIAAQAGAAUAAAACAAMAAQAGAAUAAAACAAQAAQAGAAUAAAACAAUAAQAGAAUAAAACAAYAAQAGAAUAAAACAAcAAQAGAAUAAAACAAgAAQAGAAUAAAACAAkAAQAGAAUAAAACAAoAAQAGAAUAAAACAAsAAQAGAAUAAAACAAwAAQAGAAUAAAACAA0AAQAGAAUAAAACAA4AAQAGAAUAAAACAA8AAQAGAAUAAAACABAAAQAGAAUAAAACABEAAQAGAAUAAAADAAEAAQAGAAUAAAADAAIAAQAGAAUAAAADAAMAAQAGAAUAAAADAAQAAQAGAAUAAAADAAUAAQAGAAUAAAADAAYAAQAGAAUAAAADAAcAAQAGAAUAAAADAAgAAQAGAAUAAAADAAkAAQAGAAUAAAADAAoAAQAGAAUAAAADAAsAAQAGAAUAAAADAAwAAQAGAAUAAAADAA0AAQAGAAUAAAADAA4AAQAGAAUAAAADAA8AAQAGAAUAAAADABAAAQAGAAUAAAADABEAAQAGAAUAAAAEAAEAAQAGAAUAAAAEAAIAAQAGAAUAAAAEAAMAAQAGAAUAAAAEAAQAAQAGAAUAAAAEAAUAAQAGAAUAAAAEAAYAAQAGAAUAAAAEAAcAAQAGAAUAAAAEAAgAAQAGAAUAAAAEAAkAAQAGAAUAAAAEAAoAAQAGAAUAAAAEAAsAAQAGAAUAAAAEAAwAAQAGAAUAAAAEAA0AAQAGAAUAAAAEAA4AAQAGAAUAAAAEAA8AAQAGAAUAAAAEABAAAQAGAAUAAAAEABEAAQAGAAUAAAAFAAEAAQAGAAUAAAAFAAIAAQAGAAUAAAAFAAMAAQAGAAUAAAAFAAQAAQAGAAUAAAAFAAUAAQAGAAUAAAAFAAYAAQAGAAUAAAAFAAcAAQAGAAUAAAAFAAgAAQAGAAUAAAAFAAkAAQAGAAUAAAAFAAoAAQAGAAUAAAAFAAsAAQAGAAUAAAAFAAwAAQAGAAUAAAAFAA0AAQAGAAUAAAAFAA4AAQAGAAUAAAAFAA8AAQAGAAUAAAAFABAAAQAGAAUAAAAFABEAAQAGAAUAAAAGAAEAAQAGAAUAAAAGAAIAAQAGAAUAAAAGAAMAAQAGAAUAAAAGAAQAAQAGAAUAAAAGAAUAAQAGAAUAAAAGAAYAAQAGAAUAAAAGAAcAAQAGAAUAAAAGAAgAAQAGAAUAAAAGAAkAAQAGAAUAAAAGAAoAAQAGAAUAAAAGAAsAAQAGAAUAAAAGAAwAAQAGAAUAAAAGAA0AAQAGAAUAAAAGAA4AAQAGAAUAAAAGAA8AAQAGAAUAAAAGABAAAQAGAAUAAAAGABEAAQAGAAUAAAAHAAEAAQAGAAUAAAAHAAIAAQAGAAUAAAAHAAMAAQAGAAUAAAAHAAQAAQAGAAUAAAAHAAUAAQAGAAUAAAAHAAYAAQAGAAUAAAAHAAcAAQAGAAUAAAAHAAgAAQAGAAUAAAAHAAkAAQAGAAUAAAAHAAoAAQAGAAUAAAAHAAsAAQAGAAUAAAAHAAwAAQAGAAUAAAAHAA0AAQAGAAUAAAAHAA4AAQAGAAUAAAAHAA8AAQAGAAUAAAAHABAAAQAGAAUAAAAHABEAAQAGAAUAAAAIAAEAAQAGAAUAAAAIAAIAAQAGAAUAAAAIAAMAAQAGAAUAAAAIAAQAAQAGAAUAAAAIAAUAAQAGAAUAAAAIAAYAAQAGAAUAAAAIAAcAAQAGAAUAAAAIAAgAAQAGAAUAAAAIAAkAAQAGAAUAAAAIAAoAAQAGAAUAAAAIAAsAAQAGAAUAAAAIAAwAAQAGAAUAAAAIAA0AAQAGAAUAAAAIAA4AAQAGAAUAAAAIAA8AAQAGAAUAAAAIABAAAQAGAAUAAAAIABEAAQAGAAUAAAAJAAEAAQAGAAUAAAAJAAIAAQAGAAUAAAAJAAMAAQAGAAUAAAAJAAQAAQAGAAUAAAAJAAUAAQAGAAUAAAAJAAYAAQAGAAUAAAAJAAcAAQAGAAUAAAAJAAgAAQAGAAUAAAAJAAkAAQAGAAUAAAAJAAoAAQAGAAUAAAAJAAsAAQAGAAUAAAAJAAwAAQAGAAUAAAAJAA0AAQAGAAUAAAAJAA4AAQAGAAUAAAAJAA8AAQAGAAUAAAAJABAAAQAGAAUAAAAJABEAAQAGAAUAAAAKAAEAAQAGAAUAAAAKAAIAAQAGAAUAAAAKAAMAAQAGAAUAAAAKAAQAAQAGAAUAAAAKAAUAAQAGAAUAAAAKAAYAAQAGAAUAAAAKAAcAAQAGAAUAAAAKAAgAAQAGAAUAAAAKAAkAAQAGAAUAAAAKAAoAAQAGAAUAAAAKAAsAAQAGAAUAAAAKAAwAAQAGAAUAAAAKAA0AAQAGAAUAAAAKAA4AAQAGAAUAAAAKAA8AAQAGAAUAAAAKABAAAQAGAAUAAAAKABEAAQAGAAUAAAALAAEAAQAGAAUAAAALAAIAAQAGAAUAAAALAAMAAQAGAAUAAAALAAQAAQAGAAUAAAALAAUAAQAGAAUAAAALAAYAAQAGAAUAAAALAAcAAQAGAAUAAAALAAgAAQAGAAUAAAALAAkAAQAGAAUAAAALAAoAAQAGAAUAAAALAAsAAQAGAAUAAAALAAwAAQAGAAUAAAALAA0AAQAGAAUAAAALAA4AAQAGAAUAAAALAA8AAQAGAAUAAAALABAAAQAGAAUAAAALABEAAQAGAAUAAAAMAAMAAQAGAAUAAAAMAAQAAQAGAAUAAAAAAAkAAQAGAAUAAAAAAAoAAQAGAAUAAAAMABAAAQAGAAUAAAAMAA8AAQAGAAUAAAAMABcAAQAGAAUAAAAMABgAAQAGAAUAAAAAABcAAQAGAAUAAAAAABgAAQAGAAUAAAA=")
tile_set = ExtResource("1_kdit4")
navigation_enabled = false
[node name="BackgroundDecoration" type="TileMapLayer" parent="TileMap"]
use_parent_material = true
tile_map_data = PackedByteArray("AAALABEAAQAHAAQAAAABAAsAAQAGAAQAAAALAAEAAQAHAAQAAAADAAoAAQAHAAUAAAAHAAIAAQAHAAUAAAAKABgAAQAHAAUAAAA=")
tile_set = ExtResource("1_kdit4")
[node name="Ground" type="TileMapLayer" parent="TileMap"]
use_parent_material = true
tile_map_data = PackedByteArray("AAAAAAAAAQAAAAMAAAABAAAAAQABAAIAAAACAAAAAQABAAIAAAADAAAAAQABAAIAAAAEAAAAAQABAAIAAAAFAAAAAQABAAIAAAAGAAAAAQABAAIAAAAHAAAAAQABAAIAAAAIAAAAAQABAAIAAAAJAAAAAQABAAIAAAAKAAAAAQABAAIAAAAAAAMAAQACAAEAAAAAAAQAAQACAAEAAAAAAAUAAQACAAEAAAAAAAYAAQACAAEAAAAAAAcAAQACAAEAAAAAAAgAAQACAAEAAAAAAAsAAQACAAEAAAAAAAwAAQACAAEAAAAAAA0AAQACAAEAAAAAAA4AAQACAAEAAAAAAA8AAQACAAEAAAAAABAAAQACAAEAAAAMAA4AAQAAAAEAAAAMAA0AAQAAAAEAAAAMAAwAAQAAAAEAAAAMAAsAAQAAAAEAAAAMAAoAAQAAAAEAAAAMAAkAAQAAAAEAAAAMAAgAAQAAAAEAAAAMAAcAAQAAAAEAAAAMAAYAAQAAAAEAAAAMAAUAAQAAAAEAAAAMAAAAAQACAAMAAAAMAAEAAQAAAAEAAAAMAAIAAQAAAAEAAAALAAAAAQABAAIAAAAAABEAAQACAAEAAAAAABIAAQACAAEAAAAAABMAAQACAAEAAAAAABQAAQACAAEAAAAAABUAAQACAAEAAAAAABYAAQACAAEAAAAMABEAAQAAAAEAAAAMABIAAQAAAAEAAAAMABMAAQAAAAEAAAAMABQAAQAAAAEAAAAMABUAAQAAAAEAAAAMABYAAQAAAAEAAAABABkAAQABAAAAAAACABkAAQABAAAAAAADABkAAQABAAAAAAAEABkAAQABAAAAAAAFABkAAQABAAAAAAAGABkAAQABAAAAAAAHABkAAQABAAAAAAAIABkAAQABAAAAAAAJABkAAQABAAAAAAAKABkAAQABAAAAAAALABkAAQABAAAAAAAAABkAAQAAAAUAAAAMABkAAQACAAUAAAACABgAAQAEAAQAAAADABcAAQAEAAQAAAAEABYAAQAEAAQAAAAFABUAAQAEAAQAAAAGABQAAQAEAAQAAAAHABMAAQAEAAQAAAAIABIAAQAEAAQAAAAJABEAAQAEAAQAAAAKABEAAQAEAAQAAAALABEAAQAEAAQAAAAIABAAAQAEAAQAAAAHAA8AAQAEAAQAAAAGAA4AAQAEAAQAAAAFAA0AAQAEAAQAAAAEAAwAAQAEAAQAAAADAAsAAQAEAAQAAAACAAsAAQAEAAQAAAABAAsAAQAEAAQAAAAEAAoAAQAEAAQAAAAFAAkAAQAEAAQAAAAGAAgAAQAEAAQAAAAHAAcAAQAEAAQAAAAIAAYAAQAEAAQAAAAJAAUAAQAEAAQAAAAKAAUAAQAEAAQAAAALAAUAAQAEAAQAAAAIAAQAAQAEAAQAAAAHAAMAAQAEAAQAAAAGAAMAAQAEAAQAAAAFAAMAAQAEAAQAAAAEAAMAAQAEAAQAAAADAAMAAQAEAAQAAAACAAMAAQAEAAQAAAABAAMAAQAEAAQAAAA=")
tile_set = ExtResource("1_kdit4")
[node name="Barrier" type="TileMapLayer" parent="TileMap"]
use_parent_material = true
tile_map_data = PackedByteArray("AAAMAAMAAQAAAAEAAAAMAAQAAQAAAAEAAAAMAA8AAQAAAAEAAAAMABAAAQAAAAEAAAAMABcAAQAAAAEAAAAMABgAAQAAAAEAAAAAABcAAQACAAEAAAAAABgAAQACAAEAAAAAAAkAAQACAAEAAAAAAAoAAQACAAEAAAAAAAEAAQACAAEAAAAAAAIAAQACAAEAAAA=")
tile_set = ExtResource("1_kdit4")
[node name="PointLight2D" type="PointLight2D" parent="."]
visible = false
position = Vector2(206.5, 414.5)
scale = Vector2(12.9688, 26.0313)
texture = ExtResource("2_g41lp")
[node name="AutoSpawn" type="Node2D" parent="."]
[node name="RoomArea" type="Area2D" parent="."]
collision_mask = 0
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomArea"]
position = Vector2(207.5, 416)
shape = SubResource("RectangleShape2D_kiih8")
[node name="SpawnArea" type="Area2D" parent="."]
[node name="CollisionShape2D" type="CollisionShape2D" parent="SpawnArea"]
position = Vector2(209, 416.5)
shape = SubResource("RectangleShape2D_kfmgh")

View File

@ -1,136 +0,0 @@
[gd_scene load_steps=12 format=4 uid="uid://du5ldsp613fei"]
[ext_resource type="Script" path="res://scripts/map/PlayerSpawn.cs" id="1_q04qt"]
[ext_resource type="TileSet" uid="uid://c4wpp12rr44hi" path="res://tileSets/dungeon.tres" id="2_5bnvh"]
[ext_resource type="Texture2D" uid="uid://drw45jlmfo0su" path="res://sprites/light/White_100.png" id="3_atgj7"]
[ext_resource type="Script" path="res://scripts/map/ItemSpawn.cs" id="4_6ihp7"]
[ext_resource type="PackedScene" uid="uid://djsh4unystlf0" path="res://prefab/furnitures/SpellEditor.tscn" id="5_0kep0"]
[ext_resource type="Texture2D" uid="uid://cdjmfqp854utu" path="res://sprites/tutorials/spellEditor.png" id="6_dbg76"]
[ext_resource type="PackedScene" uid="uid://dld3qttpsdjpe" path="res://prefab/furnitures/WoodenBox.tscn" id="7_jybe6"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_jxmys"]
size = Vector2(23, 54.875)
[sub_resource type="NavigationPolygon" id="NavigationPolygon_064c7"]
vertices = PackedVector2Array(756.172, 267.297, 756.82, 306.008, 45.0312, 306.977, 723.094, 268.297, 45.9688, 42, 721.094, 42)
polygons = Array[PackedInt32Array]([PackedInt32Array(0, 1, 2, 3), PackedInt32Array(3, 2, 4, 5)])
outlines = Array[PackedVector2Array]([PackedVector2Array(36, 32, 731, 32, 733, 258, 766, 257, 767, 316, 35, 317)])
source_geometry_group_name = &"navigation_polygon_source_group"
[sub_resource type="RectangleShape2D" id="RectangleShape2D_kiih8"]
size = Vector2(758, 342)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_u54ac"]
size = Vector2(658, 284)
[node name="InitialRoom3" type="Node2D"]
[node name="RoomSlotList" type="Node2D" parent="."]
[node name="Slot1" type="Area2D" parent="RoomSlotList"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomSlotList/Slot1"]
position = Vector2(751.5, 289.438)
shape = SubResource("RectangleShape2D_jxmys")
debug_color = Color(0, 0.6, 0.701961, 0.419608)
[node name="PlayerSpawn" type="Marker2D" parent="."]
position = Vector2(54, 256)
script = ExtResource("1_q04qt")
[node name="NavigationRegion2D" type="NavigationRegion2D" parent="."]
navigation_polygon = SubResource("NavigationPolygon_064c7")
[node name="TileMap" type="Node2D" parent="."]
[node name="BackgroundWall" type="TileMapLayer" parent="TileMap"]
use_parent_material = true
tile_map_data = PackedByteArray("AAAOAAYAAQAGAAUAAAANAAYAAQAGAAUAAAAMAAYAAQAGAAUAAAALAAYAAQAGAAUAAAAKAAYAAQAGAAUAAAAJAAYAAQAGAAUAAAAIAAYAAQAGAAUAAAAHAAYAAQAGAAUAAAAGAAYAAQAGAAUAAAAOAAEAAQAGAAUAAAAOAAIAAQAGAAUAAAAOAAMAAQAGAAUAAAAOAAQAAQAGAAUAAAAOAAUAAQAGAAUAAAANAAUAAQAGAAUAAAANAAQAAQAGAAUAAAANAAMAAQAGAAUAAAANAAIAAQAGAAUAAAANAAEAAQAGAAUAAAAMAAEAAQAGAAUAAAALAAEAAQAGAAUAAAAKAAEAAQAGAAUAAAAJAAEAAQAGAAUAAAAIAAEAAQAGAAUAAAAHAAEAAQAGAAUAAAAGAAEAAQAGAAUAAAAFAAEAAQAGAAUAAAAEAAEAAQAGAAUAAAADAAEAAQAGAAUAAAACAAEAAQAGAAUAAAABAAEAAQAGAAUAAAABAAIAAQAGAAUAAAACAAIAAQAGAAUAAAADAAIAAQAGAAUAAAAEAAIAAQAGAAUAAAAFAAIAAQAGAAUAAAAGAAIAAQAGAAUAAAAHAAIAAQAGAAUAAAAIAAIAAQAGAAUAAAAJAAIAAQAGAAUAAAAKAAIAAQAGAAUAAAALAAIAAQAGAAUAAAAMAAIAAQAGAAUAAAAMAAMAAQAGAAUAAAALAAMAAQAGAAUAAAAKAAMAAQAGAAUAAAAJAAMAAQAGAAUAAAAIAAMAAQAGAAUAAAAHAAMAAQAGAAUAAAAGAAMAAQAGAAUAAAAFAAMAAQAGAAUAAAAEAAMAAQAGAAUAAAADAAMAAQAGAAUAAAACAAMAAQAGAAUAAAABAAMAAQAGAAUAAAABAAQAAQAGAAUAAAACAAQAAQAGAAUAAAADAAQAAQAGAAUAAAAEAAQAAQAGAAUAAAAFAAQAAQAGAAUAAAAGAAQAAQAGAAUAAAAHAAQAAQAGAAUAAAAIAAQAAQAGAAUAAAAJAAQAAQAGAAUAAAAKAAQAAQAGAAUAAAALAAQAAQAGAAUAAAAMAAQAAQAGAAUAAAAMAAUAAQAGAAUAAAALAAUAAQAGAAUAAAAKAAUAAQAGAAUAAAAJAAUAAQAGAAUAAAAIAAUAAQAGAAUAAAAHAAUAAQAGAAUAAAAGAAUAAQAGAAUAAAAFAAUAAQAGAAUAAAAEAAUAAQAGAAUAAAADAAUAAQAGAAUAAAACAAUAAQAGAAUAAAABAAUAAQAGAAUAAAABAAYAAQAGAAUAAAACAAYAAQAGAAUAAAADAAYAAQAGAAUAAAAEAAYAAQAGAAUAAAAFAAYAAQAGAAUAAAAPAAYAAQAGAAUAAAAPAAUAAQAGAAUAAAABAAcAAQAGAAUAAAABAAgAAQAGAAUAAAABAAkAAQAGAAUAAAACAAkAAQAGAAUAAAACAAgAAQAGAAUAAAACAAcAAQAGAAUAAAADAAcAAQAGAAUAAAADAAgAAQAGAAUAAAADAAkAAQAGAAUAAAAEAAkAAQAGAAUAAAAEAAgAAQAGAAUAAAAEAAcAAQAGAAUAAAAFAAcAAQAGAAUAAAAFAAgAAQAGAAUAAAAFAAkAAQAGAAUAAAAGAAkAAQAGAAUAAAAGAAgAAQAGAAUAAAAGAAcAAQAGAAUAAAAHAAgAAQAGAAUAAAAHAAkAAQAGAAUAAAAHAAcAAQAGAAUAAAAIAAcAAQAGAAUAAAAIAAgAAQAGAAUAAAAIAAkAAQAGAAUAAAAJAAkAAQAGAAUAAAAJAAgAAQAGAAUAAAAJAAcAAQAGAAUAAAAKAAcAAQAGAAUAAAAKAAgAAQAGAAUAAAAKAAkAAQAGAAUAAAALAAkAAQAGAAUAAAALAAgAAQAGAAUAAAALAAcAAQAGAAUAAAAMAAcAAQAGAAUAAAAMAAgAAQAGAAUAAAAMAAkAAQAGAAUAAAANAAkAAQAGAAUAAAANAAgAAQAGAAUAAAANAAcAAQAGAAUAAAAOAAcAAQAGAAUAAAAOAAgAAQAGAAUAAAAOAAkAAQAGAAUAAAAPAAkAAQAGAAUAAAAPAAgAAQAGAAUAAAAPAAcAAQAGAAUAAAAPAAQAAQAGAAUAAAAPAAMAAQAGAAUAAAAPAAIAAQAGAAUAAAAPAAEAAQAGAAUAAAAQAAEAAQAGAAUAAAARAAEAAQAGAAUAAAASAAEAAQAGAAUAAAATAAEAAQAGAAUAAAAUAAEAAQAGAAUAAAAVAAEAAQAGAAUAAAAWAAEAAQAGAAUAAAAWAAIAAQAGAAUAAAAVAAIAAQAGAAUAAAAUAAIAAQAGAAUAAAATAAIAAQAGAAUAAAASAAIAAQAGAAUAAAARAAIAAQAGAAUAAAAQAAIAAQAGAAUAAAAQAAMAAQAGAAUAAAARAAMAAQAGAAUAAAASAAMAAQAGAAUAAAATAAMAAQAGAAUAAAAUAAMAAQAGAAUAAAAVAAMAAQAGAAUAAAAWAAMAAQAGAAUAAAAWAAQAAQAGAAUAAAAVAAQAAQAGAAUAAAAUAAQAAQAGAAUAAAATAAQAAQAGAAUAAAASAAQAAQAGAAUAAAARAAQAAQAGAAUAAAAQAAQAAQAGAAUAAAAQAAUAAQAGAAUAAAARAAUAAQAGAAUAAAASAAUAAQAGAAUAAAATAAUAAQAGAAUAAAAUAAUAAQAGAAUAAAAVAAUAAQAGAAUAAAAWAAUAAQAGAAUAAAAWAAYAAQAGAAUAAAAVAAYAAQAGAAUAAAAUAAYAAQAGAAUAAAATAAYAAQAGAAUAAAASAAYAAQAGAAUAAAARAAYAAQAGAAUAAAAQAAYAAQAGAAUAAAAQAAcAAQAGAAUAAAARAAcAAQAGAAUAAAASAAcAAQAGAAUAAAATAAcAAQAGAAUAAAAUAAcAAQAGAAUAAAAVAAcAAQAGAAUAAAAWAAcAAQAGAAUAAAAWAAgAAQAGAAUAAAAVAAgAAQAGAAUAAAAUAAgAAQAGAAUAAAATAAgAAQAGAAUAAAASAAgAAQAGAAUAAAARAAgAAQAGAAUAAAAQAAgAAQAGAAUAAAAQAAkAAQAGAAUAAAARAAkAAQAGAAUAAAASAAkAAQAGAAUAAAATAAkAAQAGAAUAAAAUAAkAAQAGAAUAAAAVAAkAAQAGAAUAAAAWAAkAAQAGAAUAAAAXAAkAAQAGAAUAAAAXAAgAAQAGAAUAAAA=")
tile_set = ExtResource("2_5bnvh")
navigation_enabled = false
[node name="BackgroundDecoration" type="TileMapLayer" parent="TileMap"]
use_parent_material = true
tile_map_data = PackedByteArray("AAAEAAkAAQAHAAUAAAAWAAEAAQAHAAQAAAA=")
tile_set = ExtResource("2_5bnvh")
[node name="Ground" type="TileMapLayer" parent="TileMap"]
use_parent_material = true
tile_map_data = PackedByteArray("AAAAAAAAAQAAAAMAAAAAAAEAAQACAAEAAAAAAAIAAQACAAEAAAAAAAMAAQACAAEAAAAAAAQAAQACAAEAAAAAAAcAAQACAAEAAAAPAAAAAQABAAIAAAAAAAUAAQACAAEAAAAAAAYAAQACAAEAAAABAAAAAQABAAIAAAACAAAAAQABAAIAAAADAAAAAQABAAIAAAAEAAAAAQABAAIAAAAFAAAAAQABAAIAAAAGAAAAAQABAAIAAAAHAAAAAQABAAIAAAAIAAAAAQABAAIAAAAJAAAAAQABAAIAAAAKAAAAAQABAAIAAAALAAAAAQABAAIAAAAMAAAAAQABAAIAAAANAAAAAQABAAIAAAAOAAAAAQABAAMAAAAAAAgAAQACAAEAAAAAAAkAAQACAAEAAAAAAAoAAQAAAAUAAAABAAoAAQABAAAAAAACAAoAAQABAAAAAAADAAoAAQABAAAAAAAEAAoAAQABAAAAAAAFAAoAAQABAAAAAAAGAAoAAQABAAAAAAAHAAoAAQABAAAAAAAIAAoAAQABAAAAAAAJAAoAAQABAAAAAAAKAAoAAQABAAAAAAALAAoAAQABAAAAAAAMAAoAAQABAAAAAAANAAoAAQABAAAAAAAOAAoAAQABAAAAAAAPAAoAAQABAAAAAAAQAAoAAQABAAAAAAARAAoAAQABAAAAAAASAAoAAQABAAAAAAATAAoAAQABAAAAAAAUAAoAAQABAAAAAAAVAAoAAQABAAAAAAAWAAoAAQABAAAAAAAXAAoAAQACAAUAAAAQAAAAAQABAAIAAAARAAAAAQABAAIAAAASAAAAAQABAAIAAAATAAAAAQABAAIAAAAUAAAAAQABAAIAAAAXAAcAAQAAAAEAAAAXAAYAAQAAAAEAAAAXAAUAAQAAAAEAAAAXAAQAAQAAAAEAAAAXAAMAAQAAAAEAAAAXAAIAAQAAAAEAAAAXAAEAAQAAAAEAAAAXAAAAAQACAAMAAAAVAAAAAQABAAIAAAAWAAAAAQABAAIAAAA=")
tile_set = ExtResource("2_5bnvh")
[node name="Barrier" type="TileMapLayer" parent="TileMap"]
use_parent_material = true
tile_map_data = PackedByteArray("AAAXAAgAAQAAAAEAAAAXAAkAAQAAAAEAAAA=")
tile_set = ExtResource("2_5bnvh")
[node name="PointLight2D" type="PointLight2D" parent="."]
visible = false
position = Vector2(386, 178)
scale = Vector2(23.9375, 11.0625)
texture = ExtResource("3_atgj7")
[node name="Label" type="Label" parent="."]
offset_left = 37.0
offset_top = 46.0
offset_right = 200.0
offset_bottom = 71.0
text = "ui_tutorial_spellEditor"
[node name="Label2" type="Label" parent="."]
offset_left = 391.0
offset_top = 261.0
offset_right = 554.0
offset_bottom = 286.0
text = "ui_tutorial_break_box"
[node name="SpellEditor" type="Sprite2D" parent="."]
position = Vector2(621, 100)
texture = ExtResource("6_dbg76")
[node name="RigidBody2D" parent="." instance=ExtResource("5_0kep0")]
position = Vector2(227, 283)
[node name="WoodenBox" parent="." instance=ExtResource("7_jybe6")]
position = Vector2(715, 244)
_initialDurability = 0
_furnitureName = ""
[node name="WoodenBox2" parent="." instance=ExtResource("7_jybe6")]
position = Vector2(715, 200)
_initialDurability = 0
_furnitureName = ""
[node name="WoodenBox3" parent="." instance=ExtResource("7_jybe6")]
position = Vector2(715, 162)
_initialDurability = 0
_furnitureName = ""
[node name="AutoSpawn" type="Node2D" parent="."]
[node name="beginner_staff" type="Marker2D" parent="AutoSpawn"]
position = Vector2(134, 248)
script = ExtResource("4_6ihp7")
_itemIdList = PackedStringArray("beginner_staff")
[node name="magic_missile" type="Marker2D" parent="AutoSpawn"]
position = Vector2(100, 250)
script = ExtResource("4_6ihp7")
_itemIdList = PackedStringArray("magic_missile")
[node name="tracking_spell" type="Marker2D" parent="AutoSpawn"]
position = Vector2(156, 245)
script = ExtResource("4_6ihp7")
_itemIdList = PackedStringArray("tracking_spell")
[node name="RoomArea" type="Area2D" parent="."]
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomArea"]
position = Vector2(383, 175)
shape = SubResource("RectangleShape2D_kiih8")
[node name="SpawnArea" type="Area2D" parent="."]
[node name="CollisionShape2D" type="CollisionShape2D" parent="SpawnArea"]
position = Vector2(405, 178)
shape = SubResource("RectangleShape2D_u54ac")

View File

@ -1,142 +0,0 @@
[gd_scene load_steps=12 format=4 uid="uid://dodxp4mm0emj3"]
[ext_resource type="TileSet" uid="uid://c4wpp12rr44hi" path="res://tileSets/dungeon.tres" id="2_k54gk"]
[ext_resource type="Texture2D" uid="uid://drw45jlmfo0su" path="res://sprites/light/White_100.png" id="3_d6t7n"]
[ext_resource type="PackedScene" uid="uid://dld3qttpsdjpe" path="res://prefab/furnitures/WoodenBox.tscn" id="4_60glh"]
[ext_resource type="Script" path="res://scripts/map/ItemSpawn.cs" id="4_fh50l"]
[ext_resource type="PackedScene" uid="uid://djsh4unystlf0" path="res://prefab/furnitures/SpellEditor.tscn" id="5_ll4ng"]
[ext_resource type="Texture2D" uid="uid://kgodvs3ilxbs" path="res://sprites/tutorials/tripleShotSpell.png" id="6_2qcf3"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_jxmys"]
size = Vector2(23, 54.875)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_xgxoy"]
size = Vector2(26, 57)
[sub_resource type="NavigationPolygon" id="NavigationPolygon_064c7"]
vertices = PackedVector2Array(728.094, 269, 755.672, 269, 754.328, 309.062, 457.93, 310.93, 621.094, 264.742, 619.094, 45.0781, 726.078, 45.9219, 562.906, 266.273, 456.93, 150.68, 564.898, 43.0078, 42.9531, 43.9766, 404.938, 157.18, 41.9609, 265.109, 405.93, 309.023, 10, 309.969, 10, 268.102)
polygons = Array[PackedInt32Array]([PackedInt32Array(0, 1, 2, 3), PackedInt32Array(4, 5, 6, 0), PackedInt32Array(4, 0, 3, 7), PackedInt32Array(7, 3, 8, 9), PackedInt32Array(10, 9, 8, 11), PackedInt32Array(12, 10, 11, 13), PackedInt32Array(12, 13, 14, 15)])
outlines = Array[PackedVector2Array]([PackedVector2Array(33, 34, 32, 256, 0, 259, 0, 320, 416, 319, 415, 166, 447, 162, 448, 321, 764, 319, 766, 259, 738, 259, 736, 36, 609, 35, 611, 255, 573, 256, 575, 33)])
source_geometry_group_name = &"navigation_polygon_source_group"
[sub_resource type="RectangleShape2D" id="RectangleShape2D_kiih8"]
size = Vector2(755, 340)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_o4dgl"]
size = Vector2(706, 289)
[node name="InitialRoom" type="Node2D"]
[node name="RoomSlotList" type="Node2D" parent="."]
[node name="Slot1" type="Area2D" parent="RoomSlotList"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomSlotList/Slot1"]
position = Vector2(751.5, 289.438)
shape = SubResource("RectangleShape2D_jxmys")
debug_color = Color(0, 0.6, 0.701961, 0.419608)
[node name="Area2D" type="Area2D" parent="RoomSlotList"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomSlotList/Area2D"]
position = Vector2(17, 288)
shape = SubResource("RectangleShape2D_xgxoy")
[node name="NavigationRegion2D" type="NavigationRegion2D" parent="."]
navigation_polygon = SubResource("NavigationPolygon_064c7")
[node name="TileMap" type="Node2D" parent="."]
[node name="BackgroundWall" type="TileMapLayer" parent="TileMap"]
use_parent_material = true
tile_map_data = PackedByteArray("AAAOAAYAAQAGAAUAAAANAAYAAQAGAAUAAAAMAAYAAQAGAAUAAAALAAYAAQAGAAUAAAAKAAYAAQAGAAUAAAAJAAYAAQAGAAUAAAAIAAYAAQAGAAUAAAAHAAYAAQAGAAUAAAAGAAYAAQAGAAUAAAAOAAEAAQAGAAUAAAAOAAIAAQAGAAUAAAAOAAMAAQAGAAUAAAAOAAQAAQAGAAUAAAAOAAUAAQAGAAUAAAANAAUAAQAGAAUAAAANAAQAAQAGAAUAAAANAAMAAQAGAAUAAAANAAIAAQAGAAUAAAANAAEAAQAGAAUAAAAMAAEAAQAGAAUAAAALAAEAAQAGAAUAAAAKAAEAAQAGAAUAAAAJAAEAAQAGAAUAAAAIAAEAAQAGAAUAAAAHAAEAAQAGAAUAAAAGAAEAAQAGAAUAAAAFAAEAAQAGAAUAAAAEAAEAAQAGAAUAAAADAAEAAQAGAAUAAAACAAEAAQAGAAUAAAABAAEAAQAGAAUAAAABAAIAAQAGAAUAAAACAAIAAQAGAAUAAAADAAIAAQAGAAUAAAAEAAIAAQAGAAUAAAAFAAIAAQAGAAUAAAAGAAIAAQAGAAUAAAAHAAIAAQAGAAUAAAAIAAIAAQAGAAUAAAAJAAIAAQAGAAUAAAAKAAIAAQAGAAUAAAALAAIAAQAGAAUAAAAMAAIAAQAGAAUAAAAMAAMAAQAGAAUAAAALAAMAAQAGAAUAAAAKAAMAAQAGAAUAAAAJAAMAAQAGAAUAAAAIAAMAAQAGAAUAAAAHAAMAAQAGAAUAAAAGAAMAAQAGAAUAAAAFAAMAAQAGAAUAAAAEAAMAAQAGAAUAAAADAAMAAQAGAAUAAAACAAMAAQAGAAUAAAABAAMAAQAGAAUAAAABAAQAAQAGAAUAAAACAAQAAQAGAAUAAAADAAQAAQAGAAUAAAAEAAQAAQAGAAUAAAAFAAQAAQAGAAUAAAAGAAQAAQAGAAUAAAAHAAQAAQAGAAUAAAAIAAQAAQAGAAUAAAAJAAQAAQAGAAUAAAAKAAQAAQAGAAUAAAALAAQAAQAGAAUAAAAMAAQAAQAGAAUAAAAMAAUAAQAGAAUAAAALAAUAAQAGAAUAAAAKAAUAAQAGAAUAAAAJAAUAAQAGAAUAAAAIAAUAAQAGAAUAAAAHAAUAAQAGAAUAAAAGAAUAAQAGAAUAAAAFAAUAAQAGAAUAAAAEAAUAAQAGAAUAAAADAAUAAQAGAAUAAAACAAUAAQAGAAUAAAABAAUAAQAGAAUAAAABAAYAAQAGAAUAAAACAAYAAQAGAAUAAAADAAYAAQAGAAUAAAAEAAYAAQAGAAUAAAAFAAYAAQAGAAUAAAAPAAYAAQAGAAUAAAAPAAUAAQAGAAUAAAABAAcAAQAGAAUAAAABAAgAAQAGAAUAAAABAAkAAQAGAAUAAAACAAkAAQAGAAUAAAACAAgAAQAGAAUAAAACAAcAAQAGAAUAAAADAAcAAQAGAAUAAAADAAgAAQAGAAUAAAADAAkAAQAGAAUAAAAEAAkAAQAGAAUAAAAEAAgAAQAGAAUAAAAEAAcAAQAGAAUAAAAFAAcAAQAGAAUAAAAFAAgAAQAGAAUAAAAFAAkAAQAGAAUAAAAGAAkAAQAGAAUAAAAGAAgAAQAGAAUAAAAGAAcAAQAGAAUAAAAHAAgAAQAGAAUAAAAHAAkAAQAGAAUAAAAHAAcAAQAGAAUAAAAIAAcAAQAGAAUAAAAIAAgAAQAGAAUAAAAIAAkAAQAGAAUAAAAJAAkAAQAGAAUAAAAJAAgAAQAGAAUAAAAJAAcAAQAGAAUAAAAKAAcAAQAGAAUAAAAKAAgAAQAGAAUAAAAKAAkAAQAGAAUAAAALAAkAAQAGAAUAAAALAAgAAQAGAAUAAAALAAcAAQAGAAUAAAAMAAcAAQAGAAUAAAAMAAgAAQAGAAUAAAAMAAkAAQAGAAUAAAANAAkAAQAGAAUAAAANAAgAAQAGAAUAAAANAAcAAQAGAAUAAAAOAAcAAQAGAAUAAAAOAAgAAQAGAAUAAAAOAAkAAQAGAAUAAAAPAAkAAQAGAAUAAAAPAAgAAQAGAAUAAAAPAAcAAQAGAAUAAAAPAAQAAQAGAAUAAAAPAAMAAQAGAAUAAAAPAAIAAQAGAAUAAAAPAAEAAQAGAAUAAAAQAAEAAQAGAAUAAAARAAEAAQAGAAUAAAASAAEAAQAGAAUAAAATAAEAAQAGAAUAAAAUAAEAAQAGAAUAAAAVAAEAAQAGAAUAAAAWAAEAAQAGAAUAAAAWAAIAAQAGAAUAAAAVAAIAAQAGAAUAAAAUAAIAAQAGAAUAAAATAAIAAQAGAAUAAAASAAIAAQAGAAUAAAARAAIAAQAGAAUAAAAQAAIAAQAGAAUAAAAQAAMAAQAGAAUAAAARAAMAAQAGAAUAAAASAAMAAQAGAAUAAAATAAMAAQAGAAUAAAAUAAMAAQAGAAUAAAAVAAMAAQAGAAUAAAAWAAMAAQAGAAUAAAAWAAQAAQAGAAUAAAAVAAQAAQAGAAUAAAAUAAQAAQAGAAUAAAATAAQAAQAGAAUAAAASAAQAAQAGAAUAAAARAAQAAQAGAAUAAAAQAAQAAQAGAAUAAAAQAAUAAQAGAAUAAAARAAUAAQAGAAUAAAASAAUAAQAGAAUAAAATAAUAAQAGAAUAAAAUAAUAAQAGAAUAAAAVAAUAAQAGAAUAAAAWAAUAAQAGAAUAAAAWAAYAAQAGAAUAAAAVAAYAAQAGAAUAAAAUAAYAAQAGAAUAAAATAAYAAQAGAAUAAAASAAYAAQAGAAUAAAARAAYAAQAGAAUAAAAQAAYAAQAGAAUAAAAQAAcAAQAGAAUAAAARAAcAAQAGAAUAAAASAAcAAQAGAAUAAAATAAcAAQAGAAUAAAAUAAcAAQAGAAUAAAAVAAcAAQAGAAUAAAAWAAcAAQAGAAUAAAAWAAgAAQAGAAUAAAAVAAgAAQAGAAUAAAAUAAgAAQAGAAUAAAATAAgAAQAGAAUAAAASAAgAAQAGAAUAAAARAAgAAQAGAAUAAAAQAAgAAQAGAAUAAAAQAAkAAQAGAAUAAAARAAkAAQAGAAUAAAASAAkAAQAGAAUAAAATAAkAAQAGAAUAAAAUAAkAAQAGAAUAAAAVAAkAAQAGAAUAAAAWAAkAAQAGAAUAAAAXAAkAAQAGAAUAAAAXAAgAAQAGAAUAAAAAAAkAAQAGAAUAAAAAAAgAAQAGAAUAAAA=")
tile_set = ExtResource("2_k54gk")
navigation_enabled = false
[node name="BackgroundDecoration" type="TileMapLayer" parent="TileMap"]
use_parent_material = true
tile_map_data = PackedByteArray("AAAWAAEAAQAHAAQAAAACAAkAAQAHAAEAAAA=")
tile_set = ExtResource("2_k54gk")
[node name="Ground" type="TileMapLayer" parent="TileMap"]
use_parent_material = true
tile_map_data = PackedByteArray("AAAAAAAAAQAAAAMAAAAAAAEAAQACAAEAAAAAAAIAAQACAAEAAAAAAAMAAQACAAEAAAAAAAQAAQACAAEAAAAAAAcAAQACAAEAAAAPAAAAAQABAAIAAAAAAAUAAQACAAEAAAAAAAYAAQACAAEAAAABAAAAAQABAAIAAAACAAAAAQABAAIAAAADAAAAAQABAAIAAAAEAAAAAQABAAIAAAAFAAAAAQABAAIAAAAGAAAAAQABAAIAAAAHAAAAAQABAAIAAAAIAAAAAQABAAIAAAAJAAAAAQABAAIAAAAKAAAAAQABAAIAAAALAAAAAQABAAIAAAAMAAAAAQABAAIAAAANAAAAAQABAAIAAAAOAAAAAQABAAMAAAAAAAoAAQAAAAUAAAABAAoAAQABAAAAAAACAAoAAQABAAAAAAADAAoAAQABAAAAAAAEAAoAAQABAAAAAAAFAAoAAQABAAAAAAAGAAoAAQABAAAAAAAHAAoAAQABAAAAAAAIAAoAAQABAAAAAAAJAAoAAQABAAAAAAAKAAoAAQABAAAAAAALAAoAAQABAAAAAAAMAAoAAQABAAAAAAANAAoAAQABAAAAAAAOAAoAAQABAAAAAAAPAAoAAQABAAAAAAAQAAoAAQABAAAAAAARAAoAAQABAAAAAAASAAoAAQABAAAAAAATAAoAAQABAAAAAAAUAAoAAQABAAAAAAAVAAoAAQABAAAAAAAWAAoAAQABAAAAAAAXAAoAAQACAAUAAAAQAAAAAQABAAIAAAARAAAAAQABAAIAAAASAAAAAQABAAIAAAATAAAAAQABAAIAAAAUAAAAAQABAAIAAAAXAAcAAQAAAAEAAAAXAAYAAQAAAAEAAAAXAAUAAQAAAAEAAAAXAAQAAQAAAAEAAAAXAAMAAQAAAAEAAAAXAAIAAQAAAAEAAAAXAAEAAQAAAAEAAAAXAAAAAQACAAMAAAAVAAAAAQABAAIAAAAWAAAAAQABAAIAAAAEAAkAAQAEAAQAAAAFAAgAAQAEAAQAAAAGAAcAAQAEAAQAAAAHAAYAAQAEAAQAAAAIAAUAAQAEAAQAAAAKAAUAAQAEAAQAAAAMAAUAAQAEAAQAAAASAAUAAQADAAAAAAAJAAUAAQAEAAQAAAALAAUAAQAEAAQAAAANAAkAAQADAAAAAAANAAgAAQADAAAAAAANAAcAAQADAAAAAAANAAYAAQADAAAAAAANAAUAAQADAAAAAAASAAYAAQADAAAAAAASAAcAAQADAAAAAAASAAQAAQADAAAAAAASAAMAAQADAAAAAAASAAIAAQADAAAAAAASAAEAAQADAAAAAAAOAAUAAQADAAQAAAAPAAYAAQAEAAQAAAAQAAcAAQAEAAQAAAARAAgAAQAEAAQAAAAQAAkAAQAEAAQAAAA=")
tile_set = ExtResource("2_k54gk")
[node name="Barrier" type="TileMapLayer" parent="TileMap"]
use_parent_material = true
tile_map_data = PackedByteArray("AAAXAAgAAQAAAAEAAAAXAAkAAQAAAAEAAAAAAAgAAQACAAEAAAAAAAkAAQACAAEAAAA=")
tile_set = ExtResource("2_k54gk")
[node name="PointLight2D" type="PointLight2D" parent="."]
visible = false
position = Vector2(386, 178)
scale = Vector2(23.9375, 11.0625)
texture = ExtResource("3_d6t7n")
[node name="Label" type="Label" parent="."]
offset_left = 54.0
offset_top = 55.0
offset_right = 277.0
offset_bottom = 80.0
text = "ui_tutorial_jump_onto_platform"
[node name="Label2" type="Label" parent="."]
offset_left = 151.0
offset_top = 126.0
offset_right = 453.0
offset_bottom = 151.0
text = "ui_tutorial_combine_more_powerful_spells"
[node name="WoodenBox" parent="." instance=ExtResource("4_60glh")]
position = Vector2(711, 179)
[node name="WoodenBox4" parent="." instance=ExtResource("4_60glh")]
position = Vector2(676, 179)
[node name="WoodenBox5" parent="." instance=ExtResource("4_60glh")]
position = Vector2(676, 144)
[node name="WoodenBox6" parent="." instance=ExtResource("4_60glh")]
position = Vector2(675, 102)
[node name="WoodenBox7" parent="." instance=ExtResource("4_60glh")]
position = Vector2(641, 180)
[node name="WoodenBox8" parent="." instance=ExtResource("4_60glh")]
position = Vector2(640, 142)
[node name="WoodenBox9" parent="." instance=ExtResource("4_60glh")]
position = Vector2(640, 101)
[node name="WoodenBox2" parent="." instance=ExtResource("4_60glh")]
position = Vector2(712, 138)
[node name="WoodenBox3" parent="." instance=ExtResource("4_60glh")]
position = Vector2(711, 98)
[node name="RigidBody2D" parent="." instance=ExtResource("5_ll4ng")]
position = Vector2(473, 285)
[node name="TripleShotSpell" type="Sprite2D" parent="."]
position = Vector2(637, 85)
texture = ExtResource("6_2qcf3")
[node name="RoomArea" type="Area2D" parent="."]
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomArea"]
position = Vector2(383.5, 176)
shape = SubResource("RectangleShape2D_kiih8")
[node name="SpawnArea" type="Area2D" parent="."]
[node name="CollisionShape2D" type="CollisionShape2D" parent="SpawnArea"]
position = Vector2(385, 177.5)
shape = SubResource("RectangleShape2D_o4dgl")
[node name="AutoSpawn" type="Node2D" parent="."]
[node name="x3" type="Marker2D" parent="AutoSpawn"]
position = Vector2(434, 105)
script = ExtResource("4_fh50l")
_itemIdList = PackedStringArray("x3")

14
prefab/ui/FloatLabel.tscn Normal file
View File

@ -0,0 +1,14 @@
[gd_scene format=3 uid="uid://b7se73tsnlpd6"]
[node name="FloatLabel" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="Label" type="Label" parent="."]
layout_mode = 0
offset_right = 40.0
offset_bottom = 23.0

View File

@ -12,3 +12,8 @@ texture_under = ExtResource("1_sc0v3")
texture_over = ExtResource("2_ay5vh") texture_over = ExtResource("2_ay5vh")
texture_progress = ExtResource("2_s0gle") texture_progress = ExtResource("2_s0gle")
script = ExtResource("4_84gre") script = ExtResource("4_84gre")
[node name="Label" type="Label" parent="."]
layout_mode = 0
offset_right = 40.0
offset_bottom = 23.0

View File

@ -1,53 +0,0 @@
[gd_scene load_steps=3 format=3 uid="uid://h7lvaqqlsi4t"]
[ext_resource type="Script" path="res://scripts/loader/uiLoader/SpellEditorUi.cs" id="1_1pxjs"]
[ext_resource type="PackedScene" uid="uid://d2i4udh0hho41" path="res://prefab/ui/ItemSlot.tscn" id="2_3ut57"]
[node name="SpellEditorUi" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
script = ExtResource("1_1pxjs")
[node name="TitleLabel" type="Label" parent="."]
layout_mode = 1
anchors_preset = 10
anchor_right = 1.0
offset_bottom = 25.0
grow_horizontal = 2
text = "ui_spell_editor"
horizontal_alignment = 1
[node name="ExitButton" type="Button" parent="."]
layout_mode = 1
anchors_preset = 1
anchor_left = 1.0
anchor_right = 1.0
offset_left = -91.0
offset_top = 11.0
offset_right = -24.0
offset_bottom = 44.0
grow_horizontal = 0
text = "ui_close"
[node name="HFlowContainer" type="HFlowContainer" parent="."]
layout_mode = 1
anchors_preset = 10
anchor_right = 1.0
offset_left = 32.0
offset_top = 127.0
offset_right = -20.0
offset_bottom = 629.0
grow_horizontal = 2
mouse_filter = 2
[node name="ItemSlot" parent="." instance=ExtResource("2_3ut57")]
layout_mode = 1
offset_left = 34.0
offset_top = 73.0
offset_right = 72.0
offset_bottom = 111.0

View File

@ -1,40 +0,0 @@
[gd_scene load_steps=6 format=3 uid="uid://cg2jmn7cs8m2c"]
[ext_resource type="Script" path="res://scripts/weapon/ProjectileWeapon.cs" id="1_w4b6p"]
[ext_resource type="Texture2D" uid="uid://pf2ilanjwino" path="res://sprites/weapon/BeginnerStaff_Icon.png" id="2_ip8xd"]
[ext_resource type="Texture2D" uid="uid://b4g1mkvjf7uns" path="res://sprites/weapon/BeginnerStaff.png" id="3_rhhwp"]
[ext_resource type="AudioStream" uid="uid://cak6chjjsu7wo" path="res://sounds/fire.wav" id="4_p12sk"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_14m1g"]
size = Vector2(48, 5)
[node name="BeginnerStaff" type="RigidBody2D"]
collision_layer = 8
collision_mask = 34
script = ExtResource("1_w4b6p")
_numberSlots = 5
_fireSequentially = true
FiringIntervalAsMillisecond = 280
_recoilStrength = 5
UniqueIcon = ExtResource("2_ip8xd")
[node name="StaffOfTheUndead2" type="Sprite2D" parent="."]
position = Vector2(30, 0)
texture = ExtResource("3_rhhwp")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(26, 0.5)
shape = SubResource("RectangleShape2D_14m1g")
[node name="Marker2D" type="Marker2D" parent="."]
position = Vector2(65, 0)
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="Marker2D"]
stream = ExtResource("4_p12sk")
bus = &"SoundEffect"
[node name="TipLabel" type="Label" parent="."]
offset_left = 6.0
offset_top = 48.0
offset_right = 46.0
offset_bottom = 73.0

View File

@ -1,46 +0,0 @@
[gd_scene load_steps=6 format=3 uid="uid://g1jrthe4ojdd"]
[ext_resource type="Script" path="res://scripts/weapon/MeleeWeapon.cs" id="1_snmy1"]
[ext_resource type="Texture2D" uid="uid://wt50kx6bup51" path="res://sprites/weapon/StaffNecromancy.png" id="3_cm7e6"]
[ext_resource type="AudioStream" uid="uid://cak6chjjsu7wo" path="res://sounds/fire.wav" id="4_qimud"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_14m1g"]
size = Vector2(49, 5.25)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_2u0n7"]
size = Vector2(102, 94)
[node name="IronAxe" type="RigidBody2D"]
collision_layer = 8
collision_mask = 34
angular_damp = -1.0
script = ExtResource("1_snmy1")
[node name="StaffOfTheUndead2" type="Sprite2D" parent="."]
position = Vector2(30, 0)
texture = ExtResource("3_cm7e6")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(25.5, 0.375)
shape = SubResource("RectangleShape2D_14m1g")
[node name="Marker2D" type="Marker2D" parent="."]
position = Vector2(65, 0)
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="Marker2D"]
stream = ExtResource("4_qimud")
bus = &"SoundEffect"
[node name="TipLabel" type="Label" parent="."]
offset_left = 6.0
offset_top = 48.0
offset_right = 46.0
offset_bottom = 73.0
[node name="WeaponDamageArea" type="Area2D" parent="."]
collision_layer = 512
collision_mask = 0
[node name="CollisionShape2D" type="CollisionShape2D" parent="WeaponDamageArea"]
position = Vector2(127, 1)
shape = SubResource("RectangleShape2D_2u0n7")

View File

@ -1,41 +0,0 @@
[gd_scene load_steps=6 format=3 uid="uid://dnnn2xyayiehk"]
[ext_resource type="Texture2D" uid="uid://wt50kx6bup51" path="res://sprites/weapon/StaffNecromancy.png" id="1_ms3us"]
[ext_resource type="Script" path="res://scripts/weapon/ProjectileWeapon.cs" id="1_w8hhv"]
[ext_resource type="Texture2D" uid="uid://dg5vwprt66w4j" path="res://sprites/weapon/StaffNecromancy_Icon.png" id="3_31iau"]
[ext_resource type="AudioStream" uid="uid://cak6chjjsu7wo" path="res://sounds/fire.wav" id="4_ffr2k"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_14m1g"]
size = Vector2(49, 5.25)
[node name="StaffOfTheUndead" type="RigidBody2D"]
collision_layer = 8
collision_mask = 34
script = ExtResource("1_w8hhv")
_numberSlots = 1
_spellList = PackedStringArray("necromancy")
_fireSequentially = true
FiringIntervalAsMillisecond = 350
_recoilStrength = 5
UniqueIcon = ExtResource("3_31iau")
[node name="StaffOfTheUndead2" type="Sprite2D" parent="."]
position = Vector2(30, 0)
texture = ExtResource("1_ms3us")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(25.5, 0.375)
shape = SubResource("RectangleShape2D_14m1g")
[node name="Marker2D" type="Marker2D" parent="."]
position = Vector2(65, 0)
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="Marker2D"]
stream = ExtResource("4_ffr2k")
bus = &"SoundEffect"
[node name="TipLabel" type="Label" parent="."]
offset_left = 6.0
offset_top = 48.0
offset_right = 46.0
offset_bottom = 73.0

View File

@ -0,0 +1,43 @@
[gd_scene load_steps=6 format=3 uid="uid://dnnn2xyayiehk"]
[ext_resource type="Texture2D" uid="uid://e6670ykyq145" path="res://sprites/weapon/staffOfTheUndead.png" id="1_ms3us"]
[ext_resource type="Script" path="res://scripts/weapon/ProjectileWeapon.cs" id="1_w8hhv"]
[ext_resource type="PackedScene" uid="uid://c01av43yk1q71" path="res://prefab/projectile/curseOfTheUndead.tscn" id="2_34250"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_obcq2"]
size = Vector2(49, 5)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_14m1g"]
size = Vector2(49, 5.25)
[node name="StaffOfTheUndead" type="RigidBody2D"]
collision_layer = 8
collision_mask = 34
script = ExtResource("1_w8hhv")
ProjectileScenes = [ExtResource("2_34250")]
FiringIntervalAsMillisecond = 300
_recoil = null
Id = "staff_of_the_undead"
UniqueName = null
UniqueDescription = null
_minContactInjury = null
_maxContactInjury = null
[node name="DamageArea2D" type="Area2D" parent="."]
collision_layer = 8
collision_mask = 70
[node name="CollisionShape2D" type="CollisionShape2D" parent="DamageArea2D"]
position = Vector2(25.5, 0.5)
shape = SubResource("RectangleShape2D_obcq2")
[node name="StaffOfTheUndead2" type="Sprite2D" parent="."]
position = Vector2(30, 0)
texture = ExtResource("1_ms3us")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(25.5, 0.375)
shape = SubResource("RectangleShape2D_14m1g")
[node name="Marker2D" type="Marker2D" parent="."]
position = Vector2(65, 0)

View File

@ -13,7 +13,7 @@ config_version=5
config/name="Traveler" config/name="Traveler"
config/version="0.0.1" config/version="0.0.1"
run/main_scene="res://scenes/splashScreen.tscn" run/main_scene="res://scenes/splashScreen.tscn"
config/features=PackedStringArray("4.3", "C#", "Mobile") config/features=PackedStringArray("4.2", "C#", "Mobile")
boot_splash/show_image=false boot_splash/show_image=false
config/icon="res://icon.svg" config/icon="res://icon.svg"
@ -40,141 +40,124 @@ theme/custom_font="res://fonts/ark-pixel-12px-proportional-zh_cn.ttf"
ui_accept={ ui_accept={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":32,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194310,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194310,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":1,"pressure":0.0,"pressed":true,"script":null) , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":1,"pressure":0.0,"pressed":true,"script":null)
] ]
} }
ui_left={ ui_left={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":65,"physical_keycode":0,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":65,"physical_keycode":0,"key_label":0,"unicode":97,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null) , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null) , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
] ]
} }
ui_right={ ui_right={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":68,"physical_keycode":0,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":68,"physical_keycode":0,"key_label":0,"unicode":100,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null) , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null) , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null)
] ]
} }
ui_up={ ui_up={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":87,"physical_keycode":0,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":87,"physical_keycode":0,"key_label":0,"unicode":119,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null) , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null) , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
] ]
} }
ui_down={ ui_down={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":83,"physical_keycode":0,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":83,"physical_keycode":0,"key_label":0,"unicode":115,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null) , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null) , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
] ]
} }
pick_up={ pick_up={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":69,"physical_keycode":0,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":69,"physical_keycode":0,"key_label":0,"unicode":101,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":9,"pressure":0.0,"pressed":true,"script":null)
] ]
} }
throw={ throw={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":81,"physical_keycode":0,"key_label":0,"unicode":113,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":81,"physical_keycode":0,"key_label":0,"unicode":113,"echo":false,"script":null)
] ]
} }
use_item={ use_item={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(206, 22),"global_position":Vector2(215, 68),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null) "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(211, 16),"global_position":Vector2(215, 57),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":10,"pressure":0.0,"pressed":true,"script":null)
] ]
} }
hotbar_1={ hotbar_1={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":49,"physical_keycode":0,"key_label":0,"unicode":49,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":49,"physical_keycode":0,"key_label":0,"unicode":49,"echo":false,"script":null)
] ]
} }
hotbar_2={ hotbar_2={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":50,"physical_keycode":0,"key_label":0,"unicode":50,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":50,"physical_keycode":0,"key_label":0,"unicode":50,"echo":false,"script":null)
] ]
} }
hotbar_3={ hotbar_3={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":51,"physical_keycode":0,"key_label":0,"unicode":51,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":51,"physical_keycode":0,"key_label":0,"unicode":51,"echo":false,"script":null)
] ]
} }
hotbar_4={ hotbar_4={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":52,"physical_keycode":0,"key_label":0,"unicode":52,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":52,"physical_keycode":0,"key_label":0,"unicode":52,"echo":false,"script":null)
] ]
} }
hotbar_5={ hotbar_5={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":53,"physical_keycode":0,"key_label":0,"unicode":53,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":53,"physical_keycode":0,"key_label":0,"unicode":53,"echo":false,"script":null)
] ]
} }
hotbar_6={ hotbar_6={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":54,"physical_keycode":0,"key_label":0,"unicode":54,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":54,"physical_keycode":0,"key_label":0,"unicode":54,"echo":false,"script":null)
] ]
} }
hotbar_7={ hotbar_7={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":55,"physical_keycode":0,"key_label":0,"unicode":55,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":55,"physical_keycode":0,"key_label":0,"unicode":55,"echo":false,"script":null)
] ]
} }
hotbar_8={ hotbar_8={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":56,"physical_keycode":0,"key_label":0,"unicode":56,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":56,"physical_keycode":0,"key_label":0,"unicode":56,"echo":false,"script":null)
] ]
} }
hotbar_9={ hotbar_9={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":57,"physical_keycode":0,"key_label":0,"unicode":57,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":57,"physical_keycode":0,"key_label":0,"unicode":57,"echo":false,"script":null)
] ]
} }
hotbar_next={ hotbar_next={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":16,"position":Vector2(257, 22),"global_position":Vector2(266, 68),"factor":1.0,"button_index":5,"canceled":false,"pressed":true,"double_click":false,"script":null) "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":16,"position":Vector2(241, 17),"global_position":Vector2(245, 58),"factor":1.0,"button_index":5,"canceled":false,"pressed":true,"double_click":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":5,"axis_value":1.0,"script":null)
] ]
} }
hotbar_previous={ hotbar_previous={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":8,"position":Vector2(169, 17),"global_position":Vector2(173, 58),"factor":1.0,"button_index":4,"canceled":false,"pressed":true,"double_click":false,"script":null) "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":8,"position":Vector2(169, 17),"global_position":Vector2(173, 58),"factor":1.0,"button_index":4,"canceled":false,"pressed":true,"double_click":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":4,"axis_value":1.0,"script":null)
]
}
push={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":70,"physical_keycode":0,"key_label":0,"unicode":102,"location":0,"echo":false,"script":null)
] ]
} }
[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/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", "res://locals/Character.en.translation", "res://locals/Character.ja.translation", "res://locals/Character.zh.translation", "res://locals/SloganOnMap.en.translation", "res://locals/SloganOnMap.ja.translation", "res://locals/SloganOnMap.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] [layer_names]
2d_physics/layer_1="RoomArea" 2d_physics/layer_1="RoomArea"
2d_physics/layer_2="Floor" 2d_physics/layer_2="Ground"
2d_physics/layer_3="Player" 2d_physics/layer_3="Player"
2d_physics/layer_4="PickAbleItem" 2d_physics/layer_4="PickAbleItem"
2d_physics/layer_5="Projectile" 2d_physics/layer_5="Projectile"
2d_physics/layer_6="Platform" 2d_physics/layer_6="Platform"
2d_physics/layer_7="Mob" 2d_physics/layer_7="Mob"
2d_physics/layer_8="Wall"
2d_physics/layer_9="Furniture"
2d_physics/layer_10="WeaponDamageArea"
2d_physics/layer_11="Barrier"
[physics] [physics]
2d/default_gravity=480.0 2d/default_gravity=480.0
[rendering]
textures/canvas_textures/default_texture_filter=0

View File

@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://ckl23uwxrjat4"] [gd_scene load_steps=2 format=3 uid="uid://ckl23uwxrjat4"]
[ext_resource type="Script" path="res://scripts/loader/uiLoader/LevelGraphEditorLoader.cs" id="1_qgo7w"] [ext_resource type="Script" path="res://scripts/loader/uiLoader/LevelGraphEditorLoader.cs" id="1_g1axq"]
[node name="LevelGraphEditor" type="Control"] [node name="LevelGraphEditor" type="Control"]
layout_mode = 3 layout_mode = 3
@ -9,7 +9,7 @@ anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
script = ExtResource("1_qgo7w") script = ExtResource("1_g1axq")
[node name="GraphEdit" type="GraphEdit" parent="."] [node name="GraphEdit" type="GraphEdit" parent="."]
layout_mode = 1 layout_mode = 1

View File

@ -1,13 +1,11 @@
[gd_scene load_steps=9 format=3 uid="uid://bnftvkj2cido7"] [gd_scene load_steps=7 format=3 uid="uid://bnftvkj2cido7"]
[ext_resource type="Script" path="res://scripts/loader/sceneLoader/GameSceneLoader.cs" id="1_mqdgt"] [ext_resource type="Script" path="res://scripts/loader/sceneLoader/GameSceneLoader.cs" id="1_mqdgt"]
[ext_resource type="Texture2D" uid="uid://cs6e0af876ss5" path="res://sprites/ui/HeartEmpty.png" id="2_n1yht"] [ext_resource type="Texture2D" uid="uid://cs6e0af876ss5" path="res://sprites/ui/HeartEmpty.png" id="2_n1yht"]
[ext_resource type="Script" path="res://scripts/inventory/HotBar.cs" id="2_owrhq"] [ext_resource type="Script" path="res://scripts/inventory/HotBar.cs" id="2_owrhq"]
[ext_resource type="Script" path="res://scripts/HealthBarUi.cs" id="2_xrm3v"] [ext_resource type="Script" path="res://scripts/HealthBarUi.cs" id="2_xrm3v"]
[ext_resource type="Script" path="res://scripts/FpsLabel.cs" id="5_dis4v"] [ext_resource type="Script" path="res://scripts/FpsLabel.cs" id="5_dis4v"]
[ext_resource type="PackedScene" uid="uid://c74180dtf7j7a" path="res://scenes/mapContainer.tscn" id="6_ljdj4"]
[ext_resource type="PackedScene" uid="uid://bb188382q7btp" path="res://scenes/gameOverMenu.tscn" id="6_yjmrv"] [ext_resource type="PackedScene" uid="uid://bb188382q7btp" path="res://scenes/gameOverMenu.tscn" id="6_yjmrv"]
[ext_resource type="Script" path="res://scripts/utils/UiGroup.cs" id="7_p0u6a"]
[node name="Game" type="Node2D"] [node name="Game" type="Node2D"]
script = ExtResource("1_mqdgt") script = ExtResource("1_mqdgt")
@ -23,7 +21,6 @@ anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
mouse_filter = 2
[node name="VBoxContainer" type="VBoxContainer" parent="CanvasLayer/Control"] [node name="VBoxContainer" type="VBoxContainer" parent="CanvasLayer/Control"]
layout_mode = 1 layout_mode = 1
@ -37,28 +34,28 @@ offset_right = -20.0
offset_bottom = -20.0 offset_bottom = -20.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 0 grow_vertical = 0
mouse_filter = 2
[node name="HealthBarUi" type="HBoxContainer" parent="CanvasLayer/Control/VBoxContainer"] [node name="HealthBarUi" type="HBoxContainer" parent="CanvasLayer/Control/VBoxContainer"]
layout_mode = 2 layout_mode = 2
mouse_filter = 2
script = ExtResource("2_xrm3v") script = ExtResource("2_xrm3v")
[node name="TextureRect3" type="TextureRect" parent="CanvasLayer/Control/VBoxContainer/HealthBarUi"] [node name="TextureRect3" type="TextureRect" parent="CanvasLayer/Control/VBoxContainer/HealthBarUi"]
layout_mode = 2 layout_mode = 2
mouse_filter = 2
texture = ExtResource("2_n1yht") texture = ExtResource("2_n1yht")
[node name="HotBar" type="HBoxContainer" parent="CanvasLayer/Control/VBoxContainer"] [node name="HotBar" type="HBoxContainer" parent="CanvasLayer/Control/VBoxContainer"]
layout_mode = 2 layout_mode = 2
mouse_filter = 2
script = ExtResource("2_owrhq") script = ExtResource("2_owrhq")
[node name="TextureRect3" type="TextureRect" parent="CanvasLayer/Control/VBoxContainer/HotBar"] [node name="TextureRect3" type="TextureRect" parent="CanvasLayer/Control/VBoxContainer/HotBar"]
layout_mode = 2 layout_mode = 2
mouse_filter = 2
texture = ExtResource("2_n1yht") texture = ExtResource("2_n1yht")
[node name="OperationTip" type="RichTextLabel" parent="CanvasLayer/Control/VBoxContainer"]
layout_mode = 2
bbcode_enabled = true
fit_content = true
[node name="FPSLabel" type="Label" parent="CanvasLayer/Control"] [node name="FPSLabel" type="Label" parent="CanvasLayer/Control"]
layout_mode = 1 layout_mode = 1
anchors_preset = 1 anchors_preset = 1
@ -78,21 +75,15 @@ text = "ui_re_create_map"
[node name="SeedLabel" type="Label" parent="CanvasLayer/Control"] [node name="SeedLabel" type="Label" parent="CanvasLayer/Control"]
layout_mode = 1 layout_mode = 1
anchors_preset = 3 anchors_preset = 5
anchor_left = 1.0 anchor_left = 0.5
anchor_top = 1.0 anchor_right = 0.5
anchor_right = 1.0 offset_left = -20.0
anchor_bottom = 1.0 offset_right = 20.0
offset_left = -45.0 offset_bottom = 25.0
offset_top = -16.0 grow_horizontal = 2
grow_horizontal = 0
grow_vertical = 0
theme_override_font_sizes/font_size = 10
[node name="MapContainer" parent="CanvasLayer/Control" instance=ExtResource("6_ljdj4")] [node name="BackpackUIContainer" type="Control" parent="CanvasLayer"]
layout_mode = 1
[node name="DynamicUiGroup" type="Control" parent="CanvasLayer"]
visible = false visible = false
layout_mode = 3 layout_mode = 3
anchors_preset = 15 anchors_preset = 15
@ -101,7 +92,6 @@ anchor_bottom = 1.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
mouse_filter = 2 mouse_filter = 2
script = ExtResource("7_p0u6a")
[node name="GameOverMenu" parent="CanvasLayer" instance=ExtResource("6_yjmrv")] [node name="GameOverMenu" parent="CanvasLayer" instance=ExtResource("6_yjmrv")]
visible = false visible = false
@ -112,15 +102,8 @@ visible = false
[node name="WeaponContainer" type="Node2D" parent="."] [node name="WeaponContainer" type="Node2D" parent="."]
[node name="SpellContainer" type="Node2D" parent="."]
[node name="PickAbleContainer" type="Node2D" parent="."]
[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="."] [node name="PacksackContainer" type="Node2D" parent="."]
[node name="CanvasModulate" type="CanvasModulate" parent="."]
color = Color(0, 0, 0, 1)

View File

@ -9,7 +9,6 @@ anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
mouse_filter = 2
script = ExtResource("1_vj6du") script = ExtResource("1_vj6du")
[node name="ColorRect" type="ColorRect" parent="."] [node name="ColorRect" type="ColorRect" parent="."]
@ -19,7 +18,6 @@ anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
mouse_filter = 2
color = Color(0.941176, 0.243137, 0.243137, 0.258824) color = Color(0.941176, 0.243137, 0.243137, 0.258824)
[node name="CenterContainer" type="CenterContainer" parent="."] [node name="CenterContainer" type="CenterContainer" parent="."]
@ -29,15 +27,12 @@ anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
mouse_filter = 2
[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer"] [node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer"]
layout_mode = 2 layout_mode = 2
mouse_filter = 2
[node name="CenterContainer" type="CenterContainer" parent="CenterContainer/VBoxContainer"] [node name="CenterContainer" type="CenterContainer" parent="CenterContainer/VBoxContainer"]
layout_mode = 2 layout_mode = 2
mouse_filter = 2
[node name="GameOverLabel" type="Label" parent="CenterContainer/VBoxContainer/CenterContainer"] [node name="GameOverLabel" type="Label" parent="CenterContainer/VBoxContainer/CenterContainer"]
layout_mode = 2 layout_mode = 2
@ -46,12 +41,10 @@ text = "ui_game_over_title"
[node name="MarginContainer" type="MarginContainer" parent="CenterContainer/VBoxContainer"] [node name="MarginContainer" type="MarginContainer" parent="CenterContainer/VBoxContainer"]
layout_mode = 2 layout_mode = 2
mouse_filter = 2
theme_override_constants/margin_top = 18 theme_override_constants/margin_top = 18
[node name="CenterContainer2" type="CenterContainer" parent="CenterContainer/VBoxContainer/MarginContainer"] [node name="CenterContainer2" type="CenterContainer" parent="CenterContainer/VBoxContainer/MarginContainer"]
layout_mode = 2 layout_mode = 2
mouse_filter = 2
[node name="DeathInfoLabel" type="Label" parent="CenterContainer/VBoxContainer/MarginContainer/CenterContainer2"] [node name="DeathInfoLabel" type="Label" parent="CenterContainer/VBoxContainer/MarginContainer/CenterContainer2"]
layout_mode = 2 layout_mode = 2
@ -59,13 +52,9 @@ text = "ui_death_info_describe"
[node name="MarginContainer2" type="MarginContainer" parent="CenterContainer/VBoxContainer"] [node name="MarginContainer2" type="MarginContainer" parent="CenterContainer/VBoxContainer"]
layout_mode = 2 layout_mode = 2
mouse_filter = 2
theme_override_constants/margin_top = 10 theme_override_constants/margin_top = 10
theme_override_constants/margin_bottom = 150 theme_override_constants/margin_bottom = 150
[node name="CenterContainer" type="CenterContainer" parent="CenterContainer/VBoxContainer/MarginContainer2"] [node name="RestartButton" type="Button" parent="CenterContainer/VBoxContainer/MarginContainer2"]
layout_mode = 2 layout_mode = 2
text = "ui_restart"
[node name="Label" type="Label" parent="CenterContainer/VBoxContainer/MarginContainer2/CenterContainer"]
layout_mode = 2
text = "ui_rebuild_the_world"

View File

@ -35,7 +35,6 @@ offset_top = 215.0
offset_right = 50.5 offset_right = 50.5
offset_bottom = 248.0 offset_bottom = 248.0
grow_horizontal = 2 grow_horizontal = 2
disabled = true
text = "ui_settings" text = "ui_settings"
[node name="levelGraphEditorButton" type="Button" parent="."] [node name="levelGraphEditorButton" type="Button" parent="."]

View File

@ -1,150 +0,0 @@
[gd_scene load_steps=8 format=3 uid="uid://c74180dtf7j7a"]
[ext_resource type="Texture2D" uid="uid://c35bsle7thcnh" path="res://sprites/ui/MiniMapBg.png" id="1_h88bi"]
[ext_resource type="Script" path="res://scripts/map/miniMap/MiniMap.cs" id="2_ltp8b"]
[ext_resource type="Texture2D" uid="uid://cfpcm0hkmpu38" path="res://sprites/ui/mark.png" id="3_x80y0"]
[sub_resource type="Animation" id="Animation_dkx17"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Control/MiniMap:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(983, 480)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Control/MiniMap:visible")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [true]
}
[sub_resource type="Animation" id="Animation_jdj6o"]
resource_name = "hide"
length = 0.3
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Control/MiniMap:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.3),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector2(0, 0), Vector2(0, 300)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Control/MiniMap:visible")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.3),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [true, false]
}
[sub_resource type="Animation" id="Animation_icaqa"]
resource_name = "show"
length = 0.3
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Control/MiniMap:visible")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [true]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Control/MiniMap:position")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.3),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector2(0, 300), Vector2(0, 0)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_d5o4b"]
_data = {
"RESET": SubResource("Animation_dkx17"),
"hide": SubResource("Animation_jdj6o"),
"show": SubResource("Animation_icaqa")
}
[node name="MapContainer" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[node name="MiniMapAnimationPlayer" type="AnimationPlayer" parent="."]
libraries = {
"": SubResource("AnimationLibrary_d5o4b")
}
[node name="ColorRect" type="ColorRect" parent="."]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[node name="Control" type="Control" parent="."]
layout_mode = 1
anchors_preset = 3
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = -163.0
offset_top = -163.0
offset_right = -123.0
offset_bottom = -123.0
grow_horizontal = 0
grow_vertical = 0
[node name="MiniMap" type="NinePatchRect" parent="Control"]
layout_mode = 1
offset_right = 150.0
offset_bottom = 150.0
texture = ExtResource("1_h88bi")
patch_margin_left = 7
patch_margin_top = 7
patch_margin_right = 7
patch_margin_bottom = 7
script = ExtResource("2_ltp8b")
[node name="RoomPreviewContainer" type="Node2D" parent="Control/MiniMap"]
[node name="Mark" type="Sprite2D" parent="Control/MiniMap"]
position = Vector2(75, 75)
texture = ExtResource("3_x80y0")

92
scripts/AppConfig.cs Normal file
View File

@ -0,0 +1,92 @@
using ColdMint.scripts.debug;
using ColdMint.scripts.openObserve;
using ColdMint.scripts.serialization;
using Godot;
namespace ColdMint.scripts;
public class AppConfig
{
/// <summary>
/// <para>Load configuration from file</para>
/// <para>从文件加载配置</para>
/// </summary>
public static AppConfigData? LoadFromFile()
{
var appConfigExists = FileAccess.FileExists(Config.AppConfigPath);
if (!appConfigExists)
{
LogCat.LogWarning("appConfig_not_exist");
return null;
}
var appConfigFileAccess = FileAccess.Open(Config.AppConfigPath, FileAccess.ModeFlags.Read);
var yamlData = appConfigFileAccess.GetAsText();
appConfigFileAccess.Close();
return YamlSerialization.Deserialize<AppConfigData>(yamlData);
}
/// <summary>
/// <para>ApplyAppConfig</para>
/// <para>应用配置</para>
/// </summary>
/// <param name="appConfigData"></param>
public static void ApplyAppConfig(AppConfigData appConfigData)
{
if (appConfigData.OpenObserve != null)
{
LogCollector.UpdateHttpClient(appConfigData.OpenObserve);
}
}
}
public class AppConfigData
{
/// <summary>
/// <para>OpenObserve configuration information</para>
/// <para>OpenObserve的配置信息</para>
/// </summary>
// ReSharper disable UnusedAutoPropertyAccessor.Global
public OpenObserve? OpenObserve { get; set; }
// ReSharper restore UnusedAutoPropertyAccessor.Global
}
/// <summary>
/// <para>OpenObserve Configuration information</para>
/// <para>OpenObserve配置信息</para>
/// </summary>
public class OpenObserve
{
/// <summary>
/// <para>server address</para>
/// <para>服务器地址</para>
/// </summary>
// ReSharper disable UnusedAutoPropertyAccessor.Global
public string? Address { get; set; }
// ReSharper restore UnusedAutoPropertyAccessor.Global
/// <summary>
/// <para>Access Token</para>
/// <para>访问密匙</para>
/// </summary>
// ReSharper disable UnusedAutoPropertyAccessor.Global
public string? AccessToken { get; set; }
// ReSharper restore UnusedAutoPropertyAccessor.Global
/// <summary>
/// <para>Organization ID</para>
/// <para>组织ID</para>
/// </summary>
// ReSharper disable UnusedAutoPropertyAccessor.Global
public string? OrgId { get; set; }
// ReSharper restore UnusedAutoPropertyAccessor.Global
/// <summary>
/// <para>Stream Name</para>
/// <para>流名称</para>
/// </summary>
// ReSharper disable UnusedAutoPropertyAccessor.Global
public string? StreamName { get; set; }
// ReSharper restore UnusedAutoPropertyAccessor.Global
}

View File

@ -1,23 +0,0 @@
using Godot;
namespace ColdMint.scripts;
/// <summary>
/// <para>AssetHolder</para>
/// <para>资产持有者</para>
/// </summary>
public static class AssetHolder
{
public static Texture2D? White25;
public static Texture2D? White100;
/// <summary>
/// <para>Loading the game's static assets</para>
/// <para>加载游戏的静态资产</para>
/// </summary>
public static void LoadStaticAsset()
{
White25 = ResourceLoader.Load<Texture2D>("res://sprites/light/White_25.png");
White100 = ResourceLoader.Load<Texture2D>("res://sprites/light/White_100.png");
}
}

View File

@ -21,31 +21,6 @@ public static class Config
public const string Test = "test"; public const string Test = "test";
} }
/// <summary>
/// <para>Difficulty</para>
/// <para>游戏难度</para>
/// </summary>
public static class Difficulty
{
/// <summary>
/// <para>Simple mode</para>
/// <para>简单模式</para>
/// </summary>
public const int Easy = 0;
/// <summary>
/// <para>Normal mode</para>
/// <para>正常模式</para>
/// </summary>
public const int Normal = 1;
/// <summary>
/// <para>Hard mode</para>
/// <para>困难模式</para>
/// </summary>
public const int Hard = 2;
}
/// <summary> /// <summary>
/// <para>Camp ID</para> /// <para>Camp ID</para>
@ -84,12 +59,6 @@ public static class Config
/// </summary> /// </summary>
public const float ThrownItemsHitEnemiesReduceSpeedByPercentage = 0.5f; public const float ThrownItemsHitEnemiesReduceSpeedByPercentage = 0.5f;
/// <summary>
/// <para>Scale of the room preview view</para>
/// <para>房间预览图的缩放</para>
/// </summary>
public const float RoomPreviewScale = 3f;
/// <summary> /// <summary>
/// <para>How much blood does a heart represent</para> /// <para>How much blood does a heart represent</para>
/// <para>一颗心代表多少血量</para> /// <para>一颗心代表多少血量</para>
@ -102,12 +71,25 @@ public static class Config
/// </summary> /// </summary>
public const string ModManifestFileName = "ModManifest.yaml"; public const string ModManifestFileName = "ModManifest.yaml";
/// <summary>
/// <para>The maximum number of stacked items in a single inventory</para>
/// <para>单个物品栏最大堆叠的物品数量</para>
/// </summary>
public const int MaxStackQuantity = 99;
/// <summary> /// <summary>
/// <para>Text change buffering Time How long does it take to execute the actual event after an event with a text change listener is triggered? (Anti-shake processing time), unit: milliseconds</para> /// <para>Text change buffering Time How long does it take to execute the actual event after an event with a text change listener is triggered? (Anti-shake processing time), unit: milliseconds</para>
/// <para>当添加了文本改变监听器的事件被触发后,多长时间后执行实际事件?(防抖处理时长),单位:毫秒</para> /// <para>当添加了文本改变监听器的事件被触发后,多长时间后执行实际事件?(防抖处理时长),单位:毫秒</para>
/// </summary> /// </summary>
public const long TextChangesBuffetingDuration = 300; public const long TextChangesBuffetingDuration = 300;
/// <summary>
/// <para>Operation prompts, function key text color</para>
/// <para>操作提示内,功能键文本颜色</para>
/// </summary>
public const string OperationTipActionColor = "#2b8a3e";
/// <summary> /// <summary>
/// <para>Company/Creator name</para> /// <para>Company/Creator name</para>
/// <para>公司/创作者名字</para> /// <para>公司/创作者名字</para>
@ -133,6 +115,12 @@ public static class Config
public const int HotBarSize = 9; public const int HotBarSize = 9;
/// <summary>
/// <para>UserID</para>
/// <para>用户ID</para>
/// </summary>
public const string UserId = "DefaultUser";
/// <summary> /// <summary>
/// <para>Whether version isolation is enabled</para> /// <para>Whether version isolation is enabled</para>
/// <para>是否启用版本隔离</para> /// <para>是否启用版本隔离</para>
@ -144,16 +132,6 @@ public static class Config
return !OS.HasFeature("disableVersionIsolation"); return !OS.HasFeature("disableVersionIsolation");
} }
/// <summary>
/// <para>Whether to enable Mod</para>
/// <para>是否启用Mod</para>
/// </summary>
/// <returns></returns>
public static bool EnableMod()
{
return OS.HasFeature("enableMod");
}
/// <summary> /// <summary>
/// <para>Default version name</para> /// <para>Default version name</para>
/// <para>默认的版本名称</para> /// <para>默认的版本名称</para>
@ -164,18 +142,6 @@ public static class Config
/// </remarks> /// </remarks>
public const string DefaultVersionName = "Default"; public const string DefaultVersionName = "Default";
/// <summary>
/// <para>EmptyVariant</para>
/// <para>空变量</para>
/// </summary>
public static readonly Variant EmptyVariant = new();
/// <summary>
/// <para>Blank string</para>
/// <para>空白字符串</para>
/// </summary>
public static readonly string? EmptyString = null;
/// <summary> /// <summary>
/// <para>IsDebug</para> /// <para>IsDebug</para>
@ -197,51 +163,6 @@ public static class Config
return OS.HasFeature("editor"); return OS.HasFeature("editor");
} }
/// <summary>
/// <para>ItemType</para>
/// <para>物品类型</para>
/// </summary>
public static class ItemType
{
/// <summary>
/// <para>Unknown</para>
/// <para>未知的</para>
/// </summary>
public const int Unknown = 0;
/// <summary>
/// <para>Placeholder</para>
/// <para>占位符</para>
/// </summary>
public const int Placeholder = 1;
/// <summary>
/// <para>Packsack</para>
/// <para>背包</para>
/// </summary>
public const int Packsack = 2;
/// <summary>
/// <para>ProjectileWeapon</para>
/// <para>远程武器</para>
/// </summary>
public const int ProjectileWeapon = 3;
/// <summary>
/// <para>Spell</para>
/// <para>法术</para>
/// </summary>
/// <remarks>
///<para>Type of special item used in Projectile weapons</para>
///<para>用于远程武器内的特殊物品类型</para>
/// </remarks>
public const int Spell = 4;
/// <summary>
/// <para>Common item types</para>
/// <para>普通的物品类型</para>
/// </summary>
public const int Item = 5;
}
/// <summary> /// <summary>
/// <para>Room Injector ID</para> /// <para>Room Injector ID</para>
/// <para>房间注入器ID</para> /// <para>房间注入器ID</para>
@ -261,49 +182,6 @@ public static class Config
public const string TimeInterval = "TimeInterval"; public const string TimeInterval = "TimeInterval";
} }
public class ZIndexManager
{
/// <summary>
/// <para>Floating icon</para>
/// <para>悬浮图标</para>
/// </summary>
public const int FloatingIcon = 1;
}
/// <summary>
/// <para>Item data changes the event type</para>
/// <para>物品数据改变事件类型</para>
/// </summary>
public enum ItemDataChangeEventType
{
/// <summary>
/// <para>add</para>
/// <para>添加</para>
/// </summary>
Add,
/// <summary>
/// <para>Quantity Added</para>
/// <para>物品数量增加</para>
/// </summary>
QuantityAdded,
/// <summary>
/// <para>remove</para>
/// <para>移除</para>
/// </summary>
Remove,
/// <summary>
/// <para>Replace</para>
/// <para>被替换</para>
/// </summary>
Replace,
/// <summary>
/// <para>Clear</para>
/// <para>被清空</para>
/// </summary>
Clear
}
public enum OsEnum public enum OsEnum
{ {
//unknown //unknown
@ -411,27 +289,17 @@ public static class Config
if (EnableVersionIsolation()) if (EnableVersionIsolation())
{ {
return Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), CompanyName, return Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), CompanyName,
ProjectSettings.GetSetting("application/config/name").AsString(), ProjectSettings.GetSetting("application/config/name").AsString(), UserId,
ProjectSettings.GetSetting("application/config/version").AsString()); ProjectSettings.GetSetting("application/config/version").AsString());
} }
else else
{ {
return Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), CompanyName, return Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), CompanyName,
ProjectSettings.GetSetting("application/config/name").AsString(), ProjectSettings.GetSetting("application/config/name").AsString(), UserId,
DefaultVersionName); DefaultVersionName);
} }
} }
/// <summary>
/// <para>GetDataBaseDirectory</para>
/// <para>获取数据库文件夹</para>
/// </summary>
/// <returns></returns>
public static string GetDataBaseDirectory()
{
return Path.Join(GetGameDataDirectory(), "Databases");
}
/// <summary> /// <summary>
/// <para>GetModDataDirectory</para> /// <para>GetModDataDirectory</para>
/// <para>获取模组文件夹</para> /// <para>获取模组文件夹</para>
@ -470,12 +338,6 @@ public static class Config
/// </summary> /// </summary>
public const int DefaultMaxHp = 100; public const int DefaultMaxHp = 100;
/// <summary>
/// <para>The default durability of furniture</para>
/// <para>家具的默认耐久度</para>
/// </summary>
public const int DefaultMaxDurability = 50;
/// <summary> /// <summary>
/// <para>When a creature takes damage, how long to hide the bloodline again</para> /// <para>When a creature takes damage, how long to hide the bloodline again</para>
/// <para>生物受到伤害时,要在多长时间后再次隐藏血条</para> /// <para>生物受到伤害时,要在多长时间后再次隐藏血条</para>
@ -519,27 +381,6 @@ public static class Config
public const int VerticalVelocityOfDamageNumbers = 5; public const int VerticalVelocityOfDamageNumbers = 5;
public static class OffsetAngleMode
{
/// <summary>
/// <para>Random(Default)</para>
/// <para>随机的(默认)</para>
/// </summary>
public const int Random = 0;
/// <summary>
/// <para>AlwaysSame</para>
/// <para>永远不变的偏移角度</para>
/// </summary>
public const int AlwaysSame = 1;
/// <summary>
/// <para>Cross</para>
/// <para>交叉变换</para>
/// </summary>
public const int Cross = 2;
}
/// <summary> /// <summary>
/// <para>Physical collision layer number</para> /// <para>Physical collision layer number</para>
/// <para>物理碰撞层 序号</para> /// <para>物理碰撞层 序号</para>
@ -547,71 +388,12 @@ public static class Config
public static class LayerNumber public static class LayerNumber
{ {
public const int RoomArea = 1; public const int RoomArea = 1;
/// <summary> public const int Ground = 2;
/// <para>Floor</para>
/// <para>地板</para>
/// </summary>
public const int Floor = 2;
public const int Player = 3; public const int Player = 3;
public const int PickAbleItem = 4; public const int PickAbleItem = 4;
public const int Projectile = 5; public const int Projectile = 5;
/// <summary>
/// <para>Platform</para>
/// <para>平台</para>
/// </summary>
public const int Platform = 6; public const int Platform = 6;
public const int Mob = 7; public const int Mob = 7;
/// <summary>
/// <para>Wall</para>
/// <para>墙壁</para>
/// </summary>
public const int Wall = 8;
/// <summary>
/// <para>Furniture</para>
/// <para>家具</para>
/// </summary>
public const int Furniture = 9;
/// <summary>
/// <para>WeaponDamageArea</para>
/// <para>武器伤害区域</para>
/// </summary>
public const int WeaponDamageArea = 10;
public const int Barrier = 11;
}
/// <summary>
/// <para>TileMapLayerName</para>
/// <para>瓦片节点名称</para>
/// </summary>
public static class TileMapLayerName
{
/// <summary>
/// <para>Ground Layer</para>
/// <para>地面层</para>
/// </summary>
/// <remarks>
///<para>There are collision nodes on which players and creatures can stand.</para>
///<para>拥有碰撞节点,玩家和生物可以站在上面。</para>
/// </remarks>
public const string Ground = "Ground";
/// <summary>
/// <para>Barrier</para>
/// <para>屏障</para>
/// </summary>
public const string Barrier = "Barrier";
/// <summary>
/// <para>Background decorative layer</para>
/// <para>背景装饰层</para>
/// </summary>
public const string BackgroundDecoration = "BackgroundDecoration";
/// <summary>
/// <para>Background wall layer</para>
/// <para>背景墙</para>
/// </summary>
public const string BackgroundWall = "BackgroundWall";
} }
public static class RoomDataTag public static class RoomDataTag

View File

@ -4,11 +4,17 @@ using ColdMint.scripts.map.events;
namespace ColdMint.scripts; namespace ColdMint.scripts;
/// <summary> /// <summary>
/// <para>EventBus</para> /// <para>EventManager</para>
/// <para>事件总线</para> /// <para>事件管理器</para>
/// </summary> /// </summary>
public static class EventBus public static class EventManager
{ {
/// <summary>
/// <para>Event when the AI character is generated</para>
/// <para>AI角色生成事件</para>
/// </summary>
public static Action<AiCharacterGenerateEvent>? AiCharacterGenerateEvent;
/// <summary> /// <summary>
/// <para>Game Over Event</para> /// <para>Game Over Event</para>
/// <para>游戏结束事件</para> /// <para>游戏结束事件</para>
@ -32,4 +38,10 @@ public static class EventBus
/// <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,165 +0,0 @@
using ColdMint.scripts.character;
using ColdMint.scripts.inventory;
using ColdMint.scripts.map.miniMap;
using ColdMint.scripts.utils;
using Godot;
namespace ColdMint.scripts;
/// <summary>
/// <para>Dependencies on the runtime of the game scene</para>
/// <para>游戏场景运行时的依赖</para>
/// </summary>
public static class GameSceneDepend
{
/// <summary>
/// <para>MiniMap</para>
/// <para>迷你地图</para>
/// </summary>
public static MiniMap? MiniMap { get; set; }
/// <summary>
/// <para>MiniMapAnimationPlayer</para>
/// <para>迷你地图的动画节点</para>
/// </summary>
public static AnimationPlayer? MiniMapAnimationPlayer { get; set; }
private static Player? _player;
/// <summary>
/// <para>Player instances within the game scene</para>
/// <para>游戏场景内的玩家实例</para>
/// </summary>
public static Player? Player
{
get => _player;
set
{
_player = value;
if (MiniMap != null)
{
MiniMap.OwnerNode = _player;
}
}
}
/// <summary>
/// <para>When the mouse enters the scope of a character, it is considered a target</para>
/// <para>鼠标进入到某个角色的范围内时,会将其视作目标</para>
/// </summary>
public static Node2D? TemporaryTargetNode { get; set; }
/// <summary>
/// <para>ProjectileContainer</para>
/// <para>抛射体容器</para>
/// </summary>
public static Node2D? ProjectileContainer { get; set; }
/// <summary>
/// <para>SpellContainer</para>
/// <para>法术容器</para>
/// </summary>
public static Node2D? SpellContainer { get; set; }
/// <summary>
/// <para>WeaponContainer</para>
/// <para>武器容器</para>
/// </summary>
public static Node2D? WeaponContainer { get; set; }
/// <summary>
/// <para>PacksackContainer</para>
/// <para>背包容器</para>
/// </summary>
public static Node2D? PacksackContainer { get; set; }
/// <summary>
/// <para>PlayerContainer</para>
/// <para>玩家容器</para>
/// </summary>
public static Node2D? PlayerContainer { get; set; }
/// <summary>
/// <para>PickAbleContainer</para>
/// <para>可拾捡物容器</para>
/// </summary>
public static Node2D? PickAbleContainer { get; set; }
/// <summary>
/// <para>AICharacterContainer</para>
/// <para>AICharacter角色</para>
/// </summary>
public static Node2D? AiCharacterContainer { get; set; }
/// <summary>
/// <para>HotBar</para>
/// <para>快捷栏</para>
/// </summary>
public static HotBar? HotBar { get; set; }
/// <summary>
/// <para>Health Bar UI</para>
/// <para>健康条UI</para>
/// </summary>
public static HealthBarUi? HealthBarUi { get; set; }
/// <summary>
/// <para>DynamicUiGroup</para>
/// <para>动态生成的Ui组</para>
/// </summary>
/// <remarks>
///<para>Dynamically generated Ui objects will be placed under this node</para>
///<para>动态生成的Ui对象将放置在此节点下</para>
/// </remarks>
public static UiGroup? DynamicUiGroup { get; set; }
/// <summary>
/// <para>Whether the player's mouse is hovering over GUI furniture</para>
/// <para>玩家的鼠标是否悬浮在GUI家具上</para>
/// </summary>
public static bool IsMouseOverFurnitureGui;
/// <summary>
/// <para>Whether the mouse is suspended over the item slot</para>
/// <para>鼠标是否悬浮在物品槽上</para>
/// </summary>
public static bool IsMouseOverItemSlotNode;
/// <summary>
/// <para>ShowMiniMap</para>
/// <para>显示迷你地图</para>
/// </summary>
public static void ShowMiniMap()
{
if (MiniMap == null)
{
return;
}
if (MiniMap.Visible)
{
return;
}
MiniMapAnimationPlayer?.Play(name: "show");
}
/// <summary>
/// <para>HideMiniMap</para>
/// <para>隐藏迷你地图</para>
/// </summary>
public static void HideMiniMap()
{
if (MiniMap == null)
{
return;
}
if (MiniMap.Visible)
{
MiniMapAnimationPlayer?.Play(name: "hide");
}
}
}

View File

@ -0,0 +1,128 @@
using ColdMint.scripts.character;
using ColdMint.scripts.inventory;
using ColdMint.scripts.loader.uiLoader;
using ColdMint.scripts.map.events;
using ColdMint.scripts.utils;
using Godot;
namespace ColdMint.scripts;
/// <summary>
/// <para>The node holder within the game scene</para>
/// <para>游戏场景内的节点持有者</para>
/// </summary>
public static class GameSceneNodeHolder
{
private static Player? _player;
/// <summary>
/// <para>Player instances within the game scene</para>
/// <para>游戏场景内的玩家实例</para>
/// </summary>
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>
/// <para>ProjectileContainer</para>
/// <para>抛射体容器</para>
/// </summary>
public static Node2D? ProjectileContainer { get; set; }
/// <summary>
/// <para>WeaponContainer</para>
/// <para>武器容器</para>
/// </summary>
public static Node2D? WeaponContainer { get; set; }
/// <summary>
/// <para>PacksackContainer</para>
/// <para>背包容器</para>
/// </summary>
public static Node2D? PacksackContainer { get; set; }
/// <summary>
/// <para>PlayerContainer</para>
/// <para>玩家容器</para>
/// </summary>
public static Node2D? PlayerContainer { get; set; }
/// <summary>
/// <para>AICharacterContainer</para>
/// <para>AICharacter角色</para>
/// </summary>
public static Node2D? AiCharacterContainer { get; set; }
/// <summary>
/// <para>HotBar</para>
/// <para>快捷栏</para>
/// </summary>
public static HotBar? HotBar { get; set; }
/// <summary>
/// <para>Health Bar UI</para>
/// <para>健康条UI</para>
/// </summary>
public static HealthBarUi? HealthBarUi { get; set; }
/// <summary>
/// <para>operation tip</para>
/// <para>操作提示</para>
/// </summary>
public static RichTextLabel? OperationTipLabel { get; set; }
/// <summary>
/// <para>BackpackUiContainer</para>
/// <para>背包Ui容器</para>
/// </summary>
/// <remarks>
///<para>The knapsack Ui container houses the container of the knapsack ui node. When a user uses a backpack, the node to which his backpack is attached is displayed from within the backpack ui container.</para>
///<para>背包Ui容器内存放的是背包ui节点的容器。当用户使用背包时会从背包ui容器内将其背包对于的节点展示出来。</para>
/// </remarks>
public static Control? BackpackUiContainer { get; set; }
/// <summary>
/// <para>Hide the knapsack node in the knapsack Ui if the knapsack UI is displayed</para>
/// <para>如果背包Ui处于显示状态那么隐藏背包UI内的背包节点</para>
/// </summary>
public static void HideBackpackUiContainerIfVisible()
{
if (BackpackUiContainer == null)
{
return;
}
if (!BackpackUiContainer.Visible)
{
return;
}
NodeUtils.ForEachNode<PacksackUi>(BackpackUiContainer, node =>
{
//If the child node is not visible, the traversal continues.
//如果子节点不可见,则继续遍历。
if (!node.Visible)
return false;
//Until you find a visible node, hide it, and return true, ending the loop.
//直到找到可见的节点隐藏该节点然后返回true结束遍历。
node.Hide();
return true;
});
}
}

View File

@ -153,10 +153,10 @@ public partial class HealthBarUi : HBoxContainer
{ {
base._Ready(); base._Ready();
NodeUtils.DeleteAllChild(this); NodeUtils.DeleteAllChild(this);
_heartEmpty = ResourceLoader.Load<Texture2D>("res://sprites/ui/HeartEmpty.png"); _heartEmpty = GD.Load<Texture2D>("res://sprites/ui/HeartEmpty.png");
_heartQuarter = ResourceLoader.Load<Texture2D>("res://sprites/ui/HeartQuarter.png"); _heartQuarter = GD.Load<Texture2D>("res://sprites/ui/HeartQuarter.png");
_heartHalf = ResourceLoader.Load<Texture2D>("res://sprites/ui/HeartHalf.png"); _heartHalf = GD.Load<Texture2D>("res://sprites/ui/HeartHalf.png");
_heartThreeFourths = ResourceLoader.Load<Texture2D>("res://sprites/ui/HeartThreeFourths.png"); _heartThreeFourths = GD.Load<Texture2D>("res://sprites/ui/HeartThreeFourths.png");
_heartFull = ResourceLoader.Load<Texture2D>("res://sprites/ui/HeartFull.png"); _heartFull = GD.Load<Texture2D>("res://sprites/ui/HeartFull.png");
} }
} }

View File

@ -45,7 +45,7 @@ public partial class BubbleMarker : Marker2D
{ {
if (!_bubbleDictionary.TryGetValue(id, out var value)) if (!_bubbleDictionary.TryGetValue(id, out var value))
{ {
LogCat.LogErrorWithFormat("bubble_not_found", LogCat.LogLabel.BubbleMarker,id); LogCat.LogErrorWithFormat("bubble_not_found", LogCat.LogLabel.BubbleMarker, LogCat.UploadFormat,id);
return; return;
} }
@ -60,7 +60,7 @@ public partial class BubbleMarker : Marker2D
{ {
if (!_bubbleDictionary.TryGetValue(id, out var value)) if (!_bubbleDictionary.TryGetValue(id, out var value))
{ {
LogCat.LogErrorWithFormat("bubble_not_found", LogCat.LogLabel.BubbleMarker,id); LogCat.LogErrorWithFormat("bubble_not_found", LogCat.LogLabel.BubbleMarker, LogCat.UploadFormat,id);
return; return;
} }

View File

@ -9,7 +9,7 @@ namespace ColdMint.scripts.camp;
/// </summary> /// </summary>
public static class CampManager public static class CampManager
{ {
private static readonly Dictionary<string, Camp?> Camps = new(); private static readonly Dictionary<string, Camp?> Camps = new Dictionary<string, Camp?>();
/// <summary> /// <summary>
/// <para>The default camp is returned if no corresponding camp is obtained</para> /// <para>The default camp is returned if no corresponding camp is obtained</para>
@ -40,7 +40,7 @@ public static class CampManager
if (camp.Id != Config.CampId.Default) return false; if (camp.Id != Config.CampId.Default) return false;
_defaultCamp = camp; _defaultCamp = camp;
AddCamp(camp); AddCamp(camp);
LogCat.LogWithFormat("set_default_camp", label: LogCat.LogLabel.CampManager, camp.Id); LogCat.LogWithFormat("set_default_camp", label: LogCat.LogLabel.CampManager, LogCat.UploadFormat, camp.Id);
return true; return true;
} }

View File

@ -62,6 +62,9 @@ public sealed partial class AiCharacter : CharacterTemplate
/// </remarks> /// </remarks>
private RayCast2D? _attackObstacleDetection; private RayCast2D? _attackObstacleDetection;
private VisibleOnScreenEnabler2D? _screenEnabler2D;
/// <summary> /// <summary>
/// <para>Navigation agent</para> /// <para>Navigation agent</para>
/// <para>导航代理</para> /// <para>导航代理</para>
@ -106,29 +109,42 @@ public sealed partial class AiCharacter : CharacterTemplate
private BubbleMarker? _bubbleMarker; private BubbleMarker? _bubbleMarker;
/// <summary> /// <summary>
/// <para>Initial weapon ID</para> /// <para>The initial weapons scene</para>
/// <para>初始的武器ID</para> /// <para>初始的武器场景</para>
/// </summary> /// </summary>
[Export] public string? InitWeaponId; [Export] public string? InitWeaponRes;
public override void _Ready() public override void _Ready()
{ {
base._Ready(); base._Ready();
_enemyInTheAttackRange = []; _enemyInTheAttackRange = new List<CharacterTemplate>();
_enemyInTheScoutRange = []; _enemyInTheScoutRange = new List<CharacterTemplate>();
_weaponInTheScoutRange = []; _weaponInTheScoutRange = new List<WeaponTemplate>();
_screenEnabler2D = GetNode<VisibleOnScreenEnabler2D>("VisibleOnScreenEnabler2D");
_screenEnabler2D.ScreenEntered += () =>
{
//When the character enters the screen.
//当角色进入屏幕。
ProcessMode = ProcessModeEnum.Disabled;
};
_screenEnabler2D.ScreenExited += () =>
{
//When the character leaves the screen.
//当角色离开屏幕。
ProcessMode = ProcessModeEnum.Inherit;
};
_bubbleMarker = GetNode<BubbleMarker>("BubbleMarker"); _bubbleMarker = GetNode<BubbleMarker>("BubbleMarker");
if (_bubbleMarker != null) if (_bubbleMarker != null)
{ {
using var plaintScene = ResourceLoader.Load<PackedScene>("res://prefab/ui/plaint.tscn"); using var plaintScene = GD.Load<PackedScene>("res://prefab/ui/plaint.tscn");
var plaint = NodeUtils.InstantiatePackedScene<Control>(plaintScene); var plaint = NodeUtils.InstantiatePackedScene<Control>(plaintScene);
if (plaint != null) if (plaint != null)
{ {
_bubbleMarker.AddBubble(PlaintBubbleId, plaint); _bubbleMarker.AddBubble(PlaintBubbleId, plaint);
} }
using var queryScene = ResourceLoader.Load<PackedScene>("res://prefab/ui/query.tscn"); using var queryScene = GD.Load<PackedScene>("res://prefab/ui/query.tscn");
var query = NodeUtils.InstantiatePackedScene<Control>(queryScene); var query = NodeUtils.InstantiatePackedScene<Control>(queryScene);
if (query != null) if (query != null)
{ {
@ -179,31 +195,36 @@ public sealed partial class AiCharacter : CharacterTemplate
//You must create an item container for the character before you can pick up the item. //You must create an item container for the character before you can pick up the item.
//必须为角色创建物品容器后才能拾起物品。 //必须为角色创建物品容器后才能拾起物品。
var universalItemContainer = new UniversalItemContainer(1); var universalItemContainer = new UniversalItemContainer();
universalItemContainer.AllowAddingItemByType(Config.ItemType.ProjectileWeapon); var itemSlotNode = universalItemContainer.AddItemSlot(this);
itemSlotNode?.Hide();
ProtectedItemContainer = universalItemContainer; ProtectedItemContainer = universalItemContainer;
//Add initial weapon //Add initial weapon
//添加初始武器 //添加初始武器
AddInitialWeapon(InitWeaponId); AddInitialWeapon(InitWeaponRes);
} }
/// <summary> /// <summary>
/// <para>Adds an initial weapon to the character</para> /// <para>Adds an initial weapon to the character</para>
/// <para>为角色添加初始的武器</para> /// <para>为角色添加初始的武器</para>
/// </summary> /// </summary>
private void AddInitialWeapon(string? initWeaponId) private void AddInitialWeapon(string? initWeaponRes)
{ {
if (string.IsNullOrEmpty(initWeaponId)) if (initWeaponRes == null)
{ {
return; return;
} }
var item = ItemTypeManager.CreateItem(initWeaponId, this); //Set the resource path of the initial weapon and try to create the object of the initial weapon.
if (item is not WeaponTemplate weaponTemplate) //设置了初始武器的资源路径,尝试创建初始武器的对象。
var packedScene = GD.Load<PackedScene>(initWeaponRes);
var weaponTemplate = NodeUtils.InstantiatePackedScene<WeaponTemplate>(packedScene);
if (weaponTemplate == null)
{ {
return; return;
} }
NodeUtils.CallDeferredReparent(this, weaponTemplate);
NodeUtils.CallDeferredAddChild(this, weaponTemplate);
PickItem(weaponTemplate); PickItem(weaponTemplate);
} }
@ -320,7 +341,7 @@ public sealed partial class AiCharacter : CharacterTemplate
if (NavigationAgent2D != null && IsOnFloor()) if (NavigationAgent2D != null && IsOnFloor())
{ {
var nextPathPosition = NavigationAgent2D.GetNextPathPosition(); var nextPathPosition = NavigationAgent2D.GetNextPathPosition();
var direction = GlobalPosition.DirectionTo(nextPathPosition); var direction = (nextPathPosition - GlobalPosition).Normalized();
velocity = direction * Config.CellSize * Speed * ProtectedSpeedScale; velocity = direction * Config.CellSize * Speed * ProtectedSpeedScale;
} }
} }

View File

@ -9,7 +9,6 @@ using ColdMint.scripts.inventory;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;
using ColdMint.scripts.loot; using ColdMint.scripts.loot;
using ColdMint.scripts.pickable; using ColdMint.scripts.pickable;
using ColdMint.scripts.weapon;
using Godot; using Godot;
using WeaponTemplate = ColdMint.scripts.weapon.WeaponTemplate; using WeaponTemplate = ColdMint.scripts.weapon.WeaponTemplate;
@ -70,16 +69,13 @@ public partial class CharacterTemplate : CharacterBody2D
} }
protected const float JumpVelocity = -240; protected const float JumpVelocity = -240;
public string? ReadOnlyCharacterName => TranslationServerUtils.Translate(CharacterName);
[Export] public string? CharacterName; //物品被扔出后多长时间恢复与地面和平台的碰撞(单位:秒)
private readonly double _itemCollisionRecoveryTime = 0.045f;
/// <summary> public string? ReadOnlyCharacterName => CharacterName;
/// <para>Can mutate after death</para>
/// <para>是否允许死后变异</para> protected string? CharacterName;
/// </summary>
[Export]
public bool CanMutateAfterDeath { get; set; } = true;
protected IItemContainer? ProtectedItemContainer; protected IItemContainer? ProtectedItemContainer;
@ -160,29 +156,21 @@ public partial class CharacterTemplate : CharacterBody2D
//The initial health of the character after creation //The initial health of the character after creation
//角色创建后的初始血量 //角色创建后的初始血量
[Export] private int _initialHp; private int _initialHp;
[Export] protected int MaxHp; public int MaxHp;
/// <summary> /// <summary>
/// <para>The camp ID of the role</para> /// <para>The camp ID of the role</para>
/// <para>角色的阵营ID</para> /// <para>角色的阵营ID</para>
/// </summary> /// </summary>
[Export] public string? CampId; public string CampId = null!;
private DamageNumberNodeSpawn? _damageNumber; private DamageNumberNodeSpawn? _damageNumber;
/// <summary>
/// <para>indestructible</para>
/// <para>是否为无敌的</para>
/// </summary>
[Export]
private bool _indestructible;
[Export] public string LootListId { get; private set; } = ""; [Export] public string LootListId { get; private set; } = "";
private HealthBar? _healthBar; private HealthBar? _healthBar;
private Label? _tipLabel;
private DateTime _lastDamageTime; private DateTime _lastDamageTime;
/// <summary> /// <summary>
@ -193,16 +181,6 @@ public partial class CharacterTemplate : CharacterBody2D
public Node[] PickingRangeBodies => PickingRangeBodiesList?.ToArray() ?? []; public Node[] PickingRangeBodies => PickingRangeBodiesList?.ToArray() ?? [];
/// <summary>
/// <para>Full Hp Revive</para>
/// <para>满血复活</para>
/// </summary>
public void FullHpRevive()
{
Revive(MaxHp);
}
/// <summary> /// <summary>
/// <para>Resurrected character</para> /// <para>Resurrected character</para>
/// <para>复活角色</para> /// <para>复活角色</para>
@ -266,23 +244,27 @@ public partial class CharacterTemplate : CharacterBody2D
{ {
continue; continue;
} }
weaponTemplates.Add(weaponTemplate); weaponTemplates.Add(weaponTemplate);
} }
return weaponTemplates.ToArray(); return weaponTemplates.ToArray();
} }
public override void _Ready() public override void _Ready()
{ {
base._Ready(); base._Ready();
PickingRangeBodiesList = []; PickingRangeBodiesList = new List<Node>();
CharacterName = GetMeta("Name", Name).AsString();
CampId = GetMeta("CampId", Config.CampId.Default).AsString();
MaxHp = GetMeta("MaxHp", Config.DefaultMaxHp).AsInt32();
if (MaxHp <= 0) if (MaxHp <= 0)
{ {
//If Max blood volume is 0 or less, set Max blood volume to 10
//若最大血量为0或小于0则将最大血量设置为10
MaxHp = Config.DefaultMaxHp; MaxHp = Config.DefaultMaxHp;
} }
_initialHp = GetMeta("InitialHp", "0").AsInt32();
if (_initialHp <= 0 || _initialHp > MaxHp) if (_initialHp <= 0 || _initialHp > MaxHp)
{ {
//If the initial health is less than or equal to 0 or greater than the maximum health, then set it to the maximum health //If the initial health is less than or equal to 0 or greater than the maximum health, then set it to the maximum health
@ -299,12 +281,12 @@ public partial class CharacterTemplate : CharacterBody2D
_healthBar.MaxValue = MaxHp; _healthBar.MaxValue = MaxHp;
} }
ItemMarker2D = GetNode<Marker2D>("ItemMarker2D"); ItemMarker2D = GetNode<Marker2D>("ItemMarker2D");
_itemMarkerOriginalX = ItemMarker2D.Position.X; _itemMarkerOriginalX = ItemMarker2D.Position.X;
_animatedSprite2D = GetNode<AnimatedSprite2D>("AnimatedSprite2D"); _animatedSprite2D = GetNode<AnimatedSprite2D>("AnimatedSprite2D");
_pickingArea = GetNode<Area2D>("Area2DPickingArea"); _pickingArea = GetNode<Area2D>("Area2DPickingArea");
_damageNumber = GetNode<Marker2D>("DamageNumber") as DamageNumberNodeSpawn; _damageNumber = GetNode<Marker2D>("DamageNumber") as DamageNumberNodeSpawn;
_tipLabel = GetNodeOrNull<Label>("TipLabel");
if (_pickingArea != null) if (_pickingArea != null)
{ {
//If true, the zone will detect objects or areas entering and leaving the zone. //If true, the zone will detect objects or areas entering and leaving the zone.
@ -316,55 +298,6 @@ public partial class CharacterTemplate : CharacterBody2D
_pickingArea.BodyEntered += EnterThePickingRangeBody; _pickingArea.BodyEntered += EnterThePickingRangeBody;
_pickingArea.BodyExited += ExitThePickingRangeBody; _pickingArea.BodyExited += ExitThePickingRangeBody;
} }
//The character cannot pass through the wall and floor
//角色不能穿过墙壁和地板
SetCollisionMaskValue(Config.LayerNumber.Wall, true);
SetCollisionMaskValue(Config.LayerNumber.Floor, true);
SetCollisionMaskValue(Config.LayerNumber.Barrier, true);
InputPickable = true;
}
public override void _ExitTree()
{
base._ExitTree();
if (GameSceneDepend.TemporaryTargetNode == this)
{
GameSceneDepend.TemporaryTargetNode = null;
}
}
public override void _MouseEnter()
{
if (GameSceneDepend.Player != null)
{
var targetCamp = CampManager.GetCamp(CampId);
var playerCamp = CampManager.GetCamp(GameSceneDepend.Player.CampId);
if (CampManager.CanCauseHarm(targetCamp, playerCamp))
{
GameSceneDepend.TemporaryTargetNode = this;
}
}
if (_tipLabel != null)
{
_tipLabel.Visible = true;
_tipLabel.Text = CharacterName;
//Vertical Centering Tip
//垂直居中提示
var oldPosition = _tipLabel.Position;
oldPosition.X = -_tipLabel.Size.X / 2;
_tipLabel.Position = oldPosition;
}
}
public override void _MouseExit()
{
if (_tipLabel != null)
{
_tipLabel.Visible = false;
}
} }
/// <summary> /// <summary>
@ -410,6 +343,7 @@ public partial class CharacterTemplate : CharacterBody2D
return false; return false;
} }
//The item store is marked null, or the item container is null. //The item store is marked null, or the item container is null.
//物品存放的标记为null或者物品容器为null。 //物品存放的标记为null或者物品容器为null。
if (ItemMarker2D == null || ItemContainer == null) if (ItemMarker2D == null || ItemContainer == null)
@ -417,6 +351,14 @@ public partial class CharacterTemplate : CharacterBody2D
return false; return false;
} }
//Get the currently selected node
//拿到当前选择的节点
var selectItemSlotNode = ItemContainer.GetSelectItemSlotNode();
if (selectItemSlotNode == null)
{
return false;
}
//Check to see if you can fit the item into the container first. //Check to see if you can fit the item into the container first.
//先检查是否能将物品放入容器。 //先检查是否能将物品放入容器。
var canAddItem = ItemContainer.CanAddItem(item); var canAddItem = ItemContainer.CanAddItem(item);
@ -427,8 +369,8 @@ public partial class CharacterTemplate : CharacterBody2D
//Is it successfully added to the container? //Is it successfully added to the container?
//再检查是否成功的添加到容器内了? //再检查是否成功的添加到容器内了?
var addSuccessNumber = ItemContainer.AddItem(item); var addSuccess = ItemContainer.AddItem(item);
if (addSuccessNumber <= 0) if (!addSuccess)
{ {
return false; return false;
} }
@ -439,19 +381,16 @@ public partial class CharacterTemplate : CharacterBody2D
//您可以在这里补充更多类型对象的捡起状态处理。 //您可以在这里补充更多类型对象的捡起状态处理。
if (pickAbleItemNode2D is PickAbleTemplate pickAbleTemplate) if (pickAbleItemNode2D is PickAbleTemplate pickAbleTemplate)
{ {
pickAbleTemplate.LoadResource();
pickAbleTemplate.Owner = this; pickAbleTemplate.Owner = this;
pickAbleTemplate.Picked = true; pickAbleTemplate.Picked = true;
pickAbleTemplate.Freeze = true; pickAbleTemplate.SetCollisionMaskValue(Config.LayerNumber.Platform, false);
pickAbleTemplate.DisabledCollisionShape2D(); pickAbleTemplate.SetCollisionMaskValue(Config.LayerNumber.Ground, false);
pickAbleTemplate.EnableContactInjury = false;
pickAbleTemplate.Sleeping = true;
} }
if (pickAbleItemNode2D is ProjectileWeapon projectileWeapon)
{
projectileWeapon.UpdateSpellCache();
}
if (_currentItem == null && ItemContainer.GetSelectItem() == item) if (_currentItem == null && selectItemSlotNode.GetItem() == item)
{ {
//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. //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.
//如果物品容器内选中的物品槽是刚刚捡到的物品,且手里没有物品持有,那么我们将选中的物品放到手上。 //如果物品容器内选中的物品槽是刚刚捡到的物品,且手里没有物品持有,那么我们将选中的物品放到手上。
@ -464,6 +403,7 @@ public partial class CharacterTemplate : CharacterBody2D
} }
NodeUtils.CallDeferredReparent(ItemMarker2D, pickAbleItemNode2D); NodeUtils.CallDeferredReparent(ItemMarker2D, pickAbleItemNode2D);
pickAbleItemNode2D.Position = Vector2.Zero;
return true; return true;
} }
@ -481,10 +421,10 @@ public partial class CharacterTemplate : CharacterBody2D
if (_currentItem is IItem item) if (_currentItem is IItem item)
{ {
return item.Use(this, position); item.Use(this, position);
} }
return false; return true;
} }
public override void _Process(double delta) public override void _Process(double delta)
@ -514,7 +454,7 @@ public partial class CharacterTemplate : CharacterBody2D
return; return;
} }
if (GameSceneDepend.Player == null) if (GameSceneNodeHolder.Player == null)
{ {
//We didn't know who the player was, so we showed it as a hostile color //We didn't know who the player was, so we showed it as a hostile color
//我们不知道玩家是谁,所以我们将其显示为敌对颜色 //我们不知道玩家是谁,所以我们将其显示为敌对颜色
@ -525,7 +465,7 @@ public partial class CharacterTemplate : CharacterBody2D
//If we set up a player node, then compare the injured party ID to the player's party ID //If we set up a player node, then compare the injured party ID to the player's party ID
//如果我们设置了玩家节点那么将受伤者的阵营ID与玩家的阵营ID进行比较 //如果我们设置了玩家节点那么将受伤者的阵营ID与玩家的阵营ID进行比较
var targetCamp = CampManager.GetCamp(CampId); var targetCamp = CampManager.GetCamp(CampId);
var playerCamp = CampManager.GetCamp(GameSceneDepend.Player.CampId); var playerCamp = CampManager.GetCamp(GameSceneNodeHolder.Player.CampId);
if (CampManager.CanCauseHarm(targetCamp, playerCamp)) if (CampManager.CanCauseHarm(targetCamp, playerCamp))
{ {
if (targetCamp != null && playerCamp != null) if (targetCamp != null && playerCamp != null)
@ -563,15 +503,11 @@ public partial class CharacterTemplate : CharacterBody2D
///<para>伤害模板</para> ///<para>伤害模板</para>
/// </param> /// </param>
/// <returns> /// <returns>
///<para>Return whether the character is dead</para> ///<para>Return whether the damage was done successfully</para>
///<para>返回本次伤害是否导致角色死亡。</para> ///<para>返回是否成功造成了伤害</para>
/// </returns> /// </returns>
public bool Damage(DamageTemplate damageTemplate) public bool Damage(DamageTemplate damageTemplate)
{ {
if (_indestructible)
{
return false;
}
_lastDamageTime = DateTime.Now; _lastDamageTime = DateTime.Now;
_damageNumber?.Display(damageTemplate); _damageNumber?.Display(damageTemplate);
CurrentHp -= damageTemplate.Damage; CurrentHp -= damageTemplate.Damage;
@ -581,11 +517,13 @@ public partial class CharacterTemplate : CharacterBody2D
//Character death //Character death
//角色死亡 //角色死亡
OnDie(damageTemplate); OnDie(damageTemplate);
ThrowAllItemOnDie();
return true; return true;
} }
UpDataHealthBar(); UpDataHealthBar();
return false; return true;
} }
/// <summary> /// <summary>
@ -624,11 +562,6 @@ public partial class CharacterTemplate : CharacterBody2D
/// <param name="force"></param> /// <param name="force"></param>
public void AddForce(Vector2 force) public void AddForce(Vector2 force)
{ {
if (_additionalForce != Vector2.Zero)
{
return;
}
_additionalForce = force; _additionalForce = force;
} }
@ -650,16 +583,16 @@ public partial class CharacterTemplate : CharacterBody2D
if (damageTemplate.Attacker is CharacterTemplate characterTemplate && if (damageTemplate.Attacker is CharacterTemplate characterTemplate &&
!string.IsNullOrEmpty(characterTemplate.CharacterName)) !string.IsNullOrEmpty(characterTemplate.CharacterName))
{ {
LogCat.LogWithFormat("death_info", LogCat.LogLabel.Default, CharacterName, LogCat.LogWithFormat("death_info", LogCat.LogLabel.Default, LogCat.UploadFormat, CharacterName,
characterTemplate.CharacterName); characterTemplate.CharacterName);
} }
else else
{ {
LogCat.LogWithFormat("death_info", LogCat.LogLabel.Default, CharacterName, LogCat.LogWithFormat("death_info", LogCat.LogLabel.Default, LogCat.UploadFormat, CharacterName,
damageTemplate.Attacker.Name); damageTemplate.Attacker.Name);
} }
} }
ThrowAllItemOnDie();
CreateLootObject(); CreateLootObject();
QueueFree(); QueueFree();
return Task.CompletedTask; return Task.CompletedTask;
@ -693,7 +626,6 @@ public partial class CharacterTemplate : CharacterBody2D
return; return;
} }
LogCat.Log("exit_the_picking_range_body");
PickingRangeBodiesList?.Remove(node); PickingRangeBodiesList?.Remove(node);
} }
@ -724,7 +656,7 @@ public partial class CharacterTemplate : CharacterBody2D
return; return;
} }
var len = ItemContainer.GetTotalCapacity(); var len = ItemContainer.GetItemSlotCount();
if (len == 0) if (len == 0)
{ {
return; return;
@ -763,19 +695,21 @@ public partial class CharacterTemplate : CharacterBody2D
/// </param> /// </param>
protected void ThrowItem(int index, int number, Vector2 velocity) protected void ThrowItem(int index, int number, Vector2 velocity)
{ {
if (number == 0) var itemSlotNode = ItemContainer?.GetItemSlotNode(index);
if (itemSlotNode is null) return;
if (number < 0)
{ {
return; while (!itemSlotNode.IsEmpty())
{
ThrowOneItem(itemSlotNode, velocity);
}
} }
else
var item = ItemContainer?.GetItem(index);
if (item is null) return;
//Less than 0, throw everything
//小于0,扔出所有物品
var actualQuantity = number < 0 ? item.Quantity : Math.Min(item.Quantity, number);
for (var i = 0; i < actualQuantity; i++)
{ {
ThrowOneItem(index, item, velocity); for (var i = 0; i < number && !itemSlotNode.IsEmpty(); i++)
{
ThrowOneItem(itemSlotNode, velocity);
}
} }
} }
@ -783,39 +717,50 @@ public partial class CharacterTemplate : CharacterBody2D
/// <para>Throw item</para> /// <para>Throw item</para>
/// <para>抛出物品</para> /// <para>抛出物品</para>
/// </summary> /// </summary>
/// <param name="index"></param> /// <param name="itemSlotNode"></param>
/// <param name="originalItem"></param>
/// <param name="velocity"> /// <param name="velocity">
/// <para>The speed to be applied to the item</para> /// <para>The speed to be applied to the item</para>
/// <para>要施加到物品上的速度</para> /// <para>要施加到物品上的速度</para>
/// </param> /// </param>
private void ThrowOneItem(int index, IItem originalItem, Vector2 velocity) private void ThrowOneItem(ItemSlotNode itemSlotNode, Vector2 velocity)
{ {
//Remove the item from the item container //Remove the item from the item container
//从物品容器内取出物品 //从物品容器内取出物品
originalItem.OnThrow(velocity); var item = itemSlotNode.CreateItemInstance(1);
var item = originalItem.CreateItem(1);
if (item is not Node2D node2D) if (item is not Node2D node2D)
{ {
return; return;
} }
item.ItemContainer = null;
NodeUtils.CallDeferredAddChild(NodeUtils.FindContainerNode(node2D, GetNode("/root")), node2D); NodeUtils.CallDeferredAddChild(NodeUtils.FindContainerNode(node2D, GetNode("/root")), node2D);
switch (item) switch (item)
{ {
case PickAbleTemplate pickAbleTemplate: case PickAbleTemplate pickAbleTemplate:
if (GameSceneDepend.WeaponContainer == null) if (GameSceneNodeHolder.WeaponContainer == null)
{ {
return; return;
} }
pickAbleTemplate.LoadResource();
pickAbleTemplate.Sleeping = false;
pickAbleTemplate.Owner = this; pickAbleTemplate.Owner = this;
pickAbleTemplate.Picked = false; pickAbleTemplate.Picked = false;
var timer = new Timer();
pickAbleTemplate.AddChild(timer);
timer.WaitTime = _itemCollisionRecoveryTime;
timer.Autostart = true;
timer.OneShot = true;
timer.Timeout += () =>
{
//We cannot immediately resume the physical collision when the weapon is discharged, which will cause the weapon to collide with the ground and platform earlier, preventing the weapon from flying.
//仍出武器时,我们不能立即恢复物理碰撞,立即恢复会导致武器更早的与地面和平台碰撞,阻止武器的飞行。
pickAbleTemplate.EnableContactInjury = true;
pickAbleTemplate.SetCollisionMaskValue(Config.LayerNumber.Ground, true);
pickAbleTemplate.SetCollisionMaskValue(Config.LayerNumber.Platform, true);
timer.QueueFree();
};
//Setting an initial speed of 0 for items here prevents the problem of throwing items too fast. //Setting an initial speed of 0 for items here prevents the problem of throwing items too fast.
//在这里给物品设置一个为0的初始速度可防止扔出物品时速度过快的问题。 //在这里给物品设置一个为0的初始速度可防止扔出物品时速度过快的问题。
pickAbleTemplate.LinearVelocity = Vector2.Zero; pickAbleTemplate.LinearVelocity = Vector2.Zero;
pickAbleTemplate.EnabledCollisionShape2D();
pickAbleTemplate.Freeze = false;
break; break;
} }
@ -833,8 +778,7 @@ public partial class CharacterTemplate : CharacterBody2D
break; break;
} }
ProtectedItemContainer?.RemoveItem(index, 1); itemSlotNode.RemoveItem(1);
originalItem.QueueFreeSelf();
} }

View File

@ -1,3 +1,5 @@
using System;
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;
@ -15,6 +17,8 @@ namespace ColdMint.scripts.character;
/// </summary> /// </summary>
public partial class Player : CharacterTemplate public partial class Player : CharacterTemplate
{ {
private Control? _floatLabel;
//Empty object projectile //Empty object projectile
//空的物品抛射线 //空的物品抛射线
private readonly Vector2[] _emptyVector2Array = [Vector2.Zero]; private readonly Vector2[] _emptyVector2Array = [Vector2.Zero];
@ -23,7 +27,11 @@ public partial class Player : CharacterTemplate
private Line2D? _parabola; private Line2D? _parabola;
//用于检测玩家是否站在平台上的射线 //用于检测玩家是否站在平台上的射线
[Export] private RayCast2D[]? _platformDetectionRayCast2DList; private RayCast2D? _platformDetectionRayCast2D;
private const float PromptTextDistance = 50;
//抛出物品的飞行速度 //抛出物品的飞行速度
private float _throwingVelocity = Config.CellSize * 13; private float _throwingVelocity = Config.CellSize * 13;
@ -31,8 +39,6 @@ public partial class Player : CharacterTemplate
//射线是否与平台碰撞 //射线是否与平台碰撞
private bool _collidingWithPlatform; private bool _collidingWithPlatform;
private bool _canUseItem;
//How long does it take for the character to recover from a collision with the platform after jumping off the platform (in seconds) //How long does it take for the character to recover from a collision with the platform after jumping off the platform (in seconds)
//角色从平台上跳下后,多少时间后恢复与平台的碰撞(单位:秒) //角色从平台上跳下后,多少时间后恢复与平台的碰撞(单位:秒)
private double _platformCollisionRecoveryTime = 0.2f; private double _platformCollisionRecoveryTime = 0.2f;
@ -41,30 +47,29 @@ public partial class Player : CharacterTemplate
public override void _Ready() public override void _Ready()
{ {
base._Ready(); base._Ready();
if (_platformDetectionRayCast2DList == null || _platformDetectionRayCast2DList.Length == 0)
{
LogCat.LogError("no_platform_detection_raycast_found");
return;
}
CharacterName = TranslationServerUtils.Translate("default_player_name"); CharacterName = TranslationServerUtils.Translate("default_player_name");
LogCat.LogWithFormat("player_spawn_debug", LogCat.LogLabel.Default, ReadOnlyCharacterName, LogCat.LogWithFormat("player_spawn_debug", LogCat.LogLabel.Default, LogCat.UploadFormat, ReadOnlyCharacterName,
GlobalPosition); GlobalPosition);
var floatLabelPackedScene = GD.Load<PackedScene>("res://prefab/ui/FloatLabel.tscn");
//Initializes the float label.
//初始化悬浮标签。
_floatLabel = NodeUtils.InstantiatePackedScene<Control>(floatLabelPackedScene);
if (_floatLabel == null)
{
throw new NullReferenceException(TranslationServer.Translate("float_label_instantiate_failed"));
}
_floatLabel.Hide();
NodeUtils.CallDeferredAddChild(this, _floatLabel);
_parabola = GetNode<Line2D>("Parabola"); _parabola = GetNode<Line2D>("Parabola");
var healthBarUi = GameSceneDepend.HealthBarUi; _platformDetectionRayCast2D = GetNode<RayCast2D>("PlatformDetectionRayCast");
UpdateOperationTip();
var healthBarUi = GameSceneNodeHolder.HealthBarUi;
if (healthBarUi != null) if (healthBarUi != null)
{ {
healthBarUi.MaxHp = MaxHp; healthBarUi.MaxHp = MaxHp;
healthBarUi.CurrentHp = CurrentHp; healthBarUi.CurrentHp = CurrentHp;
} }
//Mount the camera.
//挂载相机。
var mainCameraPackedScene = ResourceLoader.Load<PackedScene>("res://prefab/MainCamera.tscn");
var camera2D = NodeUtils.InstantiatePackedScene<Camera2D>(mainCameraPackedScene);
if (camera2D != null)
{
NodeUtils.CallDeferredAddChild(this, camera2D);
}
} }
protected override void WhenBindItemContainer(IItemContainer? itemContainer) protected override void WhenBindItemContainer(IItemContainer? itemContainer)
@ -76,7 +81,7 @@ public partial class Player : CharacterTemplate
//Subscribe to events when the item container is bound to the player. //Subscribe to events when the item container is bound to the player.
//在物品容器与玩家绑定时订阅事件。 //在物品容器与玩家绑定时订阅事件。
itemContainer.SelectedItemChangeEvent += SelectedItemChangeEvent; itemContainer.SelectedItemSlotChangeEvent += SelectedItemSlotChangeEvent;
} }
public override void _ExitTree() public override void _ExitTree()
@ -86,13 +91,14 @@ public partial class Player : CharacterTemplate
{ {
//Unsubscribe to events when this object is destroyed. //Unsubscribe to events when this object is destroyed.
//此节点被销毁时,取消订阅事件。 //此节点被销毁时,取消订阅事件。
ProtectedItemContainer.SelectedItemChangeEvent -= SelectedItemChangeEvent; ProtectedItemContainer.SelectedItemSlotChangeEvent -= SelectedItemSlotChangeEvent;
} }
} }
private void SelectedItemChangeEvent(SelectedItemChangeEvent selectedItemChangeEvent) private void SelectedItemSlotChangeEvent(SelectedItemSlotChangeEvent selectedItemSlotChangeEvent)
{ {
var item = selectedItemChangeEvent.NewItem; var item = selectedItemSlotChangeEvent.NewItemSlotNode?.GetItem();
GameSceneNodeHolder.HideBackpackUiContainerIfVisible();
if (item is Node2D node2D) if (item is Node2D node2D)
{ {
CurrentItem = node2D; CurrentItem = node2D;
@ -103,35 +109,111 @@ public partial class Player : CharacterTemplate
} }
} }
public override void _MouseEnter()
{
}
public override void _MouseExit()
{
}
/// <summary> /// <summary>
/// <para>UpdateCollidingWithPlatform</para> /// <para>Update operation prompt</para>
/// <para>更新与平台发生碰撞的状态</para> /// <para>更新操作提示</para>
/// </summary> /// </summary>
private void UpdateCollidingWithPlatform() private void UpdateOperationTip()
{ {
//When the collision state between the platform detection ray and the platform changes var operationTipLabel = GameSceneNodeHolder.OperationTipLabel;
//在平台检测射线与平台碰撞状态改变时 if (operationTipLabel == null)
if (_platformDetectionRayCast2DList is not { Length: > 0 }) return;
foreach (var rayCast2D in _platformDetectionRayCast2DList)
{ {
if (!rayCast2D.IsColliding()) continue;
_collidingWithPlatform = true;
return; return;
} }
_collidingWithPlatform = false;
var operationTipBuilder = new StringBuilder();
operationTipBuilder.Append("[color=");
operationTipBuilder.Append(Config.OperationTipActionColor);
operationTipBuilder.Append(']');
operationTipBuilder.Append(TranslationServerUtils.Translate(InputMap.ActionGetEvents("ui_left")[0].AsText()));
operationTipBuilder.Append("[/color]");
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("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("action_jump"));
if (_collidingWithPlatform)
{
operationTipBuilder.Append(' ');
operationTipBuilder.Append("[color=");
operationTipBuilder.Append(Config.OperationTipActionColor);
operationTipBuilder.Append(']');
operationTipBuilder.Append(
TranslationServerUtils.Translate(InputMap.ActionGetEvents("ui_down")[0].AsText()));
operationTipBuilder.Append("[/color]");
operationTipBuilder.Append(TranslationServerUtils.Translate("action_jump_down"));
}
var nearestItem = FindTheNearestItem();
if (nearestItem != null)
{
operationTipBuilder.Append(' ');
operationTipBuilder.Append("[color=");
operationTipBuilder.Append(Config.OperationTipActionColor);
operationTipBuilder.Append(']');
operationTipBuilder.Append(
TranslationServerUtils.Translate(InputMap.ActionGetEvents("pick_up")[0].AsText()));
operationTipBuilder.Append("[/color]");
operationTipBuilder.Append(TranslationServerUtils.Translate("action_pick_up"));
if (nearestItem is IItem item)
{
operationTipBuilder.Append(item.Name);
}
operationTipLabel.Text = operationTipBuilder.ToString();
}
if (CurrentItem != null)
{
operationTipBuilder.Append(' ');
operationTipBuilder.Append("[color=");
operationTipBuilder.Append(Config.OperationTipActionColor);
operationTipBuilder.Append(']');
operationTipBuilder.Append(TranslationServerUtils.Translate(InputMap.ActionGetEvents("throw")[0].AsText()));
operationTipBuilder.Append("[/color]");
operationTipBuilder.Append(TranslationServerUtils.Translate("action_throw"));
if (CurrentItem is IItem item)
{
operationTipBuilder.Append(TranslationServerUtils.Translate(item.Name));
operationTipBuilder.Append(' ');
operationTipBuilder.Append("[color=");
operationTipBuilder.Append(Config.OperationTipActionColor);
operationTipBuilder.Append(']');
operationTipBuilder.Append(
TranslationServerUtils.Translate(InputMap.ActionGetEvents("use_item")[0].AsText()));
operationTipBuilder.Append("[/color]");
operationTipBuilder.Append(TranslationServerUtils.Translate("action_use_item"));
operationTipBuilder.Append(TranslationServerUtils.Translate(item.Name));
}
}
operationTipLabel.Text = operationTipBuilder.ToString();
} }
protected override void HookPhysicsProcess(ref Vector2 velocity, double delta) protected override void HookPhysicsProcess(ref Vector2 velocity, double delta)
{ {
UpdateCollidingWithPlatform(); //When the collision state between the platform detection ray and the platform changes
//在平台检测射线与平台碰撞状态改变时
if (_platformDetectionRayCast2D != null && _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 the character is on the ground, give an upward velocity when the jump button is pressed
//如果角色正在地面上,按下跳跃键时,给予一个向上的速度 //如果角色正在地面上,按下跳跃键时,给予一个向上的速度
if (Input.IsActionJustPressed("ui_up") && IsOnFloor()) if (Input.IsActionJustPressed("ui_up") && IsOnFloor())
@ -142,20 +224,13 @@ public partial class Player : CharacterTemplate
var axis = Input.GetAxis("ui_left", "ui_right"); var axis = Input.GetAxis("ui_left", "ui_right");
velocity.X = axis * Speed * Config.CellSize * ProtectedSpeedScale; velocity.X = axis * Speed * Config.CellSize * ProtectedSpeedScale;
if (Input.IsActionJustPressed("use_item"))
{
_canUseItem = !GameSceneDepend.IsMouseOverFurnitureGui && !GameSceneDepend.IsMouseOverItemSlotNode;
}
//Use items //Use items
//使用物品 //使用物品
if (Input.IsActionPressed("use_item")) if (Input.IsActionPressed("use_item"))
{ {
if (_canUseItem) UseItem(GetGlobalMousePosition());
{
UseItem(GetGlobalMousePosition());
}
} }
//Pick up an item //Pick up an item
//捡起物品 //捡起物品
if (Input.IsActionJustPressed("pick_up")) if (Input.IsActionJustPressed("pick_up"))
@ -168,6 +243,8 @@ public partial class Player : CharacterTemplate
{ {
PickingRangeBodiesList?.Remove(pickAbleItem); PickingRangeBodiesList?.Remove(pickAbleItem);
} }
RecycleFloatLabel();
} }
} }
@ -229,10 +306,16 @@ public partial class Player : CharacterTemplate
} }
ThrowItem(ItemContainer.GetSelectIndex(), 1, GetThrowVelocity()); ThrowItem(ItemContainer.GetSelectIndex(), 1, GetThrowVelocity());
GameSceneNodeHolder.HideBackpackUiContainerIfVisible();
CurrentItem = null; CurrentItem = null;
} }
} }
protected override void WhenUpdateCurrentItem(Node2D? currentItem)
{
UpdateOperationTip();
}
/// <summary> /// <summary>
/// <para>当玩家手动抛出物品时,施加到物品上的速度值</para> /// <para>当玩家手动抛出物品时,施加到物品上的速度值</para>
/// </summary> /// </summary>
@ -305,15 +388,13 @@ public partial class Player : CharacterTemplate
public override void Revive(int newHp) public override void Revive(int newHp)
{ {
base.Revive(newHp); base.Revive(newHp);
var healthBarUi = GameSceneDepend.HealthBarUi; var healthBarUi = GameSceneNodeHolder.HealthBarUi;
if (healthBarUi != null) if (healthBarUi != null)
{ {
//The purpose of setting Hp to the current Hp is to cause the life bar to refresh. //The purpose of setting Hp to the current Hp is to cause the life bar to refresh.
//将Hp设置为当前Hp的目的是使生命条刷新。 //将Hp设置为当前Hp的目的是使生命条刷新。
healthBarUi.CurrentHp = CurrentHp; healthBarUi.CurrentHp = CurrentHp;
} }
ProcessMode = ProcessModeEnum.Inherit;
Show();
} }
/// <summary> /// <summary>
@ -325,10 +406,8 @@ public partial class Player : CharacterTemplate
{ {
Hide(); Hide();
ProcessMode = ProcessModeEnum.Disabled; ProcessMode = ProcessModeEnum.Disabled;
ProtectedItemContainer?.ClearAllItems(); if (EventManager.GameOverEvent == null)
if (EventBus.GameOverEvent == null)
{ {
LogCat.Log("game_over_event_is_empty");
return; return;
} }
@ -338,14 +417,95 @@ public partial class Player : CharacterTemplate
gameOverEvent.DeathInfo = await DeathInfoGenerator.GenerateDeathInfo(this, damageTemplate.Attacker); gameOverEvent.DeathInfo = await DeathInfoGenerator.GenerateDeathInfo(this, damageTemplate.Attacker);
} }
EventBus.GameOverEvent.Invoke(gameOverEvent); EventManager.GameOverEvent.Invoke(gameOverEvent);
} }
protected override void EnterThePickingRangeBody(Node node)
{
base.EnterThePickingRangeBody(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 node2D)
{
return;
}
if (_floatLabel != null)
{
if (node is not PickAbleTemplate pickAbleTemplate)
{
return;
}
if (pickAbleTemplate.Picked)
{
//If the pickables are picked up, the label is not displayed.
//如果可拾捡物被捡起了,那么不显示标签。
LogCat.LogWarning("pickable_picked_up");
return;
}
NodeUtils.CallDeferredReparent(node, _floatLabel);
var rotationDegreesNode2D = node2D.RotationDegrees;
var rotationDegreesNode2DAbs = Math.Abs(rotationDegreesNode2D);
_floatLabel.GlobalPosition = node2D.GlobalPosition;
_floatLabel.Position = rotationDegreesNode2DAbs > 90
? new Vector2(0, PromptTextDistance)
: new Vector2(0, -PromptTextDistance);
_floatLabel.RotationDegrees = 0 - rotationDegreesNode2D;
var label = _floatLabel.GetNode<Label>("Label");
var stringBuilder = new StringBuilder();
if (pickAbleTemplate.Owner is CharacterTemplate characterTemplate)
{
stringBuilder.Append(characterTemplate.ReadOnlyCharacterName);
stringBuilder.Append(TranslationServerUtils.Translate("de"));
}
stringBuilder.Append(TranslationServerUtils.Translate(pickAbleTemplate.Name));
label.Text = stringBuilder.ToString();
_floatLabel.Show();
}
UpdateOperationTip();
}
protected override void ExitThePickingRangeBody(Node node)
{
base.ExitThePickingRangeBody(node);
if (node is not Node2D)
{
return;
}
RecycleFloatLabel();
UpdateOperationTip();
}
/// <summary>
/// <para>Recycle Float Label</para>
/// <para>回收悬浮标签</para>
/// </summary>
private void RecycleFloatLabel()
{
if (_floatLabel == null)
{
return;
}
_floatLabel.Hide();
NodeUtils.CallDeferredReparent(this, _floatLabel);
}
protected override void OnHit(DamageTemplate damageTemplate) protected override void OnHit(DamageTemplate damageTemplate)
{ {
base.OnHit(damageTemplate); base.OnHit(damageTemplate);
var healthBarUi = GameSceneDepend.HealthBarUi; var healthBarUi = GameSceneNodeHolder.HealthBarUi;
if (healthBarUi != null) if (healthBarUi != null)
{ {
healthBarUi.CurrentHp = CurrentHp; healthBarUi.CurrentHp = CurrentHp;

View File

@ -14,37 +14,31 @@ public static class ContributorDataManager
private static readonly ContributorData[] ContributorArray = private static readonly ContributorData[] ContributorArray =
[ [
new() new ContributorData
{ {
Name = "Cold-Mint", Name = "Cold-Mint",
Url = "https://github.com/Cold-Mint", Url = "https://github.com/Cold-Mint",
ContributorTypes = [ContributorType.Coder], ContributorTypes = [ContributorType.Coder],
}, },
new() new ContributorData
{ {
Name = "霧雨烨", Name = "霧雨烨",
Url = "https://github.com/Web13234", Url = "https://github.com/Web13234",
ContributorTypes = [ContributorType.Coder] ContributorTypes = [ContributorType.Coder]
}, },
new() new ContributorData
{ {
Name = "[HYPERLINK BLOCKED]", Name = "[HYPERLINK BLOCKED]",
Url = "https://www.pixiv.net/users/74412798", Url = "https://www.pixiv.net/users/74412798",
ContributorTypes = [ContributorType.Artist], ContributorTypes = [ContributorType.Artist],
ToolTip = "贡献死灵法杖和背包的贴图。" ToolTip = "贡献死灵法杖和背包的贴图。"
}, },
new() new ContributorData
{ {
Name = "\u2605如爱生", Name = "\u2605如爱生",
Url = "https://space.bilibili.com/425243934", Url = "https://space.bilibili.com/425243934",
ContributorTypes = [ContributorType.Artist], ContributorTypes = [ContributorType.Artist],
ToolTip = "贡献了一些枪械贴图。" ToolTip = "贡献了一些枪械贴图。"
},
new()
{
Name = "Ride-A-Pig",
Url = "https://github.com/Ride-A-Pig",
ContributorTypes = [ContributorType.Coder],
} }
]; ];

View File

@ -27,7 +27,7 @@ public partial class DamageNumber : CharacterBody2D
private bool _enableGravity; private bool _enableGravity;
public new void SetVelocity(Vector2 velocity) public void SetVelocity(Vector2 velocity)
{ {
Velocity = velocity; Velocity = velocity;
_enableGravity = true; _enableGravity = true;

View File

@ -46,7 +46,7 @@ public partial class DamageNumberNodeSpawn : Marker2D
public override void _Ready() public override void _Ready()
{ {
base._Ready(); base._Ready();
_damageNumberPackedScene = ResourceLoader.Load("res://prefab/ui/DamageNumber.tscn") as PackedScene; _damageNumberPackedScene = GD.Load("res://prefab/ui/DamageNumber.tscn") as PackedScene;
_rootNode = GetNode<Node2D>("/root/Game/DamageNumberContainer"); _rootNode = GetNode<Node2D>("/root/Game/DamageNumberContainer");
//The horizontal velocity is in the X positive direction //The horizontal velocity is in the X positive direction
//水平速度的X正方向 //水平速度的X正方向

View File

@ -1,48 +0,0 @@
using System;
using System.IO;
namespace ColdMint.scripts.database;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
/// <summary>
/// <para>Game database manager</para>
/// <para>游戏数据库管理器</para>
/// </summary>
public class DataBaseManager
{
private static ServiceProvider? _serviceProvider;
/// <summary>
/// <para>Initialize database</para>
/// <para>初始化数据库</para>
/// </summary>
public static void InitDataBases(string databasePath)
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddDbContext<GameDbContext>(options =>
options.UseSqlite($"Data Source={Path.Join(databasePath, Config.SolutionName + ".db")}"));
_serviceProvider = serviceCollection.BuildServiceProvider();
var dataPackDbContext = GetRequiredService<GameDbContext>();
dataPackDbContext.Database.EnsureCreated();
}
/// <summary>
/// <para>Get database service</para>
/// <para>获取数据库服务</para>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T GetRequiredService<T>() where T : notnull
{
if (_serviceProvider == null)
{
throw new NullReferenceException("service provider is null");
}
var scope = _serviceProvider.CreateScope();
return scope.ServiceProvider.GetRequiredService<T>();
}
}

View File

@ -1,42 +0,0 @@
using ColdMint.scripts.database.gameDbTables;
using Microsoft.EntityFrameworkCore;
namespace ColdMint.scripts.database;
/// <summary>
/// <para>Game database</para>
/// <para>游戏数据库</para>
/// </summary>
public class GameDbContext(DbContextOptions<GameDbContext> options) : DbContext(options)
{
// ReSharper disable UnusedAutoPropertyAccessor.Global
public DbSet<ErrorRecord> ErrorRecords { get; set; }
// ReSharper restore UnusedAutoPropertyAccessor.Global
/// <summary>
/// <para>Async add error record</para>
/// <para>异步添加错误信息</para>
/// </summary>
/// <param name="errorRecord"></param>
public async void AddOrUpdateErrorRecordAsync(ErrorRecord errorRecord)
{
if (errorRecord.Message == null)
{
return;
}
var oldErrorRecord = await ErrorRecords.FindAsync(errorRecord.Message);
if (oldErrorRecord == null)
{
ErrorRecords.Add(errorRecord);
}
else
{
oldErrorRecord.Count++;
oldErrorRecord.LastDateTime = errorRecord.LastDateTime;
ErrorRecords.Update(oldErrorRecord);
}
await SaveChangesAsync();
}
}

View File

@ -1,33 +0,0 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace ColdMint.scripts.database.gameDbTables;
/// <summary>
/// <para>Error record</para>
/// <para>错误记录</para>
/// </summary>
public class ErrorRecord
{
/// <summary>
/// <para>Message</para>
/// <para>错误消息</para>
/// </summary>
[Key]
[MaxLength(255)]
// ReSharper disable UnusedAutoPropertyAccessor.Global
public string? Message { get; set; }
// ReSharper restore UnusedAutoPropertyAccessor.Global
/// <summary>
/// <para>Count</para>
/// <para>出现次数</para>
/// </summary>
public int Count { get; set; } = 1;
/// <summary>
/// <para>DateTime</para>
/// <para>时间</para>
/// </summary>
public DateTime LastDateTime { get; set; } = DateTime.Now;
}

View File

@ -1,20 +0,0 @@
using System.Threading.Tasks;
using ColdMint.scripts.character;
using ColdMint.scripts.inventory;
using ColdMint.scripts.utils;
using Godot;
namespace ColdMint.scripts.deathInfo;
public class ResignationCertificateDeathInfoHandler: IDeathInfoHandler
{
public Task<string?> GenerateDeathInfo(string victimName, string killerName, Player victim, Node killer)
{
if (killer is ResignationCertificate)
{
return Task.FromResult(
TranslationServerUtils.TranslateWithFormat("death_info_resignation_certificate", victimName));
}
return Task.FromResult(Config.EmptyString);
}
}

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using ColdMint.scripts.openObserve;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;
using Godot; using Godot;
@ -15,14 +16,6 @@ public static class LogCat
/// <para>默认的日志标签</para> /// <para>默认的日志标签</para>
/// </summary> /// </summary>
public const string Default = "Default"; public const string Default = "Default";
public const string Debug = "Debug";
public const string PatchworkRoomPlacementStrategy = "PatchworkRoomPlacementStrategy";
/// <summary>
/// <para>ItemContainerDisplay</para>
/// <para>项目容器显示器</para>
/// </summary>
public const string ItemContainerDisplay = "ItemContainerDisplay";
/// <summary> /// <summary>
/// <para>LookForWeaponProcessor</para> /// <para>LookForWeaponProcessor</para>
@ -71,42 +64,11 @@ public static class LogCat
/// <para>日志收集器</para> /// <para>日志收集器</para>
/// </summary> /// </summary>
public const string LogCollector = "LogCollector"; public const string LogCollector = "LogCollector";
/// <summary> /// <summary>
/// <para>Mod Loader</para> /// <para>Mod Loader</para>
/// <para>模组加载器</para> /// <para>模组加载器</para>
/// </summary> /// </summary>
public const string ModLoader = "ModLoader"; public const string ModLoader = "ModLoader";
/// <summary>
/// <para>PickAble Template</para>
/// <para>可拾取物模板</para>
/// </summary>
public const string PickAbleTemplate = "PickAbleTemplate";
/// <summary>
/// <para>ContactInjury</para>
/// <para>物品碰撞伤害</para>
/// </summary>
public const string ContactInjury = "ContactInjury";
/// <summary>
/// <para>Room</para>
/// <para>房间</para>
/// </summary>
public const string Room = "Room";
/// <summary>
/// <para>ItemSpawn</para>
/// <para>物品生成器</para>
/// </summary>
public const string ItemSpawn = "ItemSpawn";
/// <summary>
/// <para>MeleeWeapon</para>
/// <para>近战武器</para>
/// </summary>
public const string MeleeWeapon = "MeleeWeapon";
} }
@ -150,6 +112,11 @@ public static class LogCat
set => _minLogLevel = value; set => _minLogLevel = value;
} }
/// <summary>
/// <para>Whether to upload logs that need to be formatted by default</para>
/// <para>是否默认上传需要格式化的日志</para>
/// </summary>
public static bool UploadFormat { get; set; } = true;
private static readonly StringBuilder StringBuilder = new StringBuilder(); private static readonly StringBuilder StringBuilder = new StringBuilder();
@ -251,12 +218,14 @@ public static class LogCat
/// </param> /// </param>
/// <param name="label"> /// <param name="label">
/// </param> /// </param>
public static void Log(string message, string label = LogLabel.Default) /// <param name="upload">
/// </param>
public static void Log(string message, string label = LogLabel.Default, bool upload = true)
{ {
PrintLog(InfoLogLevel, HandleMessage(InfoLogLevel, message, label).ToString(), label); PrintLog(InfoLogLevel, HandleMessage(InfoLogLevel, message, label).ToString(), label, upload);
} }
private static void PrintLog(int level, string concreteLog, string label) private static void PrintLog(int level, string concreteLog, string label, bool upload)
{ {
if (!IsEnabledLogLabel(label)) if (!IsEnabledLogLabel(label))
{ {
@ -268,16 +237,28 @@ public static class LogCat
return; return;
} }
if (LogCollector.CanUploadLog && upload)
{
var logData = new LogData
{
Level = level,
Message = concreteLog
};
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
LogCollector.Push(logData);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
switch (level) switch (level)
{ {
case WarningLogLevel: case WarningLogLevel:
GD.Print(concreteLog); GD.PrintRich("[color=#FFDE66]"+concreteLog+"[/color]");
break; break;
case ErrorLogLevel: case ErrorLogLevel:
GD.PrintErr(concreteLog); GD.PrintRich("[color=#FF4E39]"+concreteLog+"[/color]");
break; break;
default: default:
GD.Print(concreteLog); GD.PrintRich("[color=#CCCED1]"+concreteLog+"[/color]");
break; break;
} }
} }
@ -293,30 +274,34 @@ public static class LogCat
/// <para>这个消息支持本地化输出假设已存在翻译keyHello = 你好传入Hello则会输出你好。</para> /// <para>这个消息支持本地化输出假设已存在翻译keyHello = 你好传入Hello则会输出你好。</para>
/// </param> /// </param>
/// <param name="label"></param> /// <param name="label"></param>
public static void LogError(string message, string label = LogLabel.Default) /// <param name="upload"></param>
public static void LogError(string message, string label = LogLabel.Default, bool upload = true)
{ {
PrintLog(ErrorLogLevel, HandleMessage(ErrorLogLevel, message, label).ToString(), label); PrintLog(ErrorLogLevel, HandleMessage(ErrorLogLevel, message, label).ToString(), label, upload);
} }
public static void LogWarning(string message, string label = LogLabel.Default) public static void LogWarning(string message, string label = LogLabel.Default, bool upload = true)
{ {
PrintLog(WarningLogLevel, HandleMessage(WarningLogLevel, message, label).ToString(), label); PrintLog(WarningLogLevel, HandleMessage(WarningLogLevel, message, label).ToString(), label, upload);
} }
public static void LogErrorWithFormat(string message, string label, params object?[] args) public static void LogErrorWithFormat(string message, string label, bool upload, params object?[] args)
{ {
PrintLog(ErrorLogLevel, string.Format(HandleMessage(ErrorLogLevel, message, label).ToString(), args), label); PrintLog(ErrorLogLevel, string.Format(HandleMessage(ErrorLogLevel, message, label).ToString(), args), label,
upload);
} }
public static void LogWithFormat(string message, string label, params object?[] args) public static void LogWithFormat(string message, string label, bool upload, params object?[] args)
{ {
PrintLog(InfoLogLevel, string.Format(HandleMessage(InfoLogLevel, message, label).ToString(), args), label); PrintLog(InfoLogLevel, string.Format(HandleMessage(InfoLogLevel, message, label).ToString(), args), label,
upload);
} }
public static void LogWarningWithFormat(string message, string label, params object?[] args) public static void LogWarningWithFormat(string message, string label, bool upload, params object?[] args)
{ {
PrintLog(WarningLogLevel, string.Format(HandleMessage(WarningLogLevel, message, label).ToString(), args), label); PrintLog(WarningLogLevel, string.Format(HandleMessage(WarningLogLevel, message, label).ToString(), args), label,
upload);
} }
/// <summary> /// <summary>
@ -335,6 +320,6 @@ public static class LogCat
//Log an exception here or send it to the server. //Log an exception here or send it to the server.
//请在这里记录异常或将异常发送至服务器。 //请在这里记录异常或将异常发送至服务器。
PrintLog(ErrorLogLevel, PrintLog(ErrorLogLevel,
HandleMessage(ErrorLogLevel, e.Message, label).Append('\n').Append(e.StackTrace).ToString(), label); HandleMessage(ErrorLogLevel, e.Message, label).Append('\n').Append(e.StackTrace).ToString(), label, true);
} }
} }

View File

@ -1,18 +0,0 @@
namespace ColdMint.scripts.furniture;
/// <summary>
/// <para>Barrier</para>
/// <para>屏障型家具</para>
/// </summary>
public partial class Barrier : Furniture
{
public override void _Ready()
{
base._Ready();
CanSleep = false;
SetCollisionLayerValue(Config.LayerNumber.Barrier, true);
SetCollisionLayerValue(Config.LayerNumber.Furniture, false);
SetCollisionMaskValue(Config.LayerNumber.Furniture, true);
SetCollisionMaskValue(Config.LayerNumber.Barrier, true);
}
}

View File

@ -1,108 +0,0 @@
using ColdMint.scripts.damage;
using ColdMint.scripts.utils;
using Godot;
namespace ColdMint.scripts.furniture;
/// <summary>
/// <para>FurnitureTemplate</para>
/// <para>家具模板</para>
/// </summary>
public partial class Furniture : RigidBody2D
{
[Export] private int _initialDurability;
[Export] private int _maxDurability;
[Export]
private string? _furnitureName;
private Label? _tipLabel;
public override void _MouseEnter()
{
if (_tipLabel == null || string.IsNullOrEmpty(_furnitureName))
{
return;
}
var translation = TranslationServerUtils.Translate(_furnitureName);
if (string.IsNullOrEmpty(translation))
{
return;
}
_tipLabel.Visible = true;
_tipLabel.Text = translation;
//Vertical Centering Tip
//垂直居中提示
var oldPosition = _tipLabel.Position;
oldPosition.X = -_tipLabel.Size.X / 2;
_tipLabel.Rotation = -Rotation;
_tipLabel.Position = oldPosition;
}
public override void _MouseExit()
{
if (_tipLabel == null)
{
return;
}
_tipLabel.Visible = false;
}
/// <summary>
/// <para></para>
/// <para>家具的耐久度</para>
/// </summary>
private int _durability;
public override void _Ready()
{
if (_maxDurability <= 0)
{
_maxDurability = Config.DefaultMaxDurability;
}
if (_initialDurability <= 0 || _initialDurability > _maxDurability)
{
_initialDurability = _maxDurability;
}
_tipLabel = GetNodeOrNull<Label>("TipLabel");
InputPickable = true;
_durability = _initialDurability;
SetCollisionLayerValue(Config.LayerNumber.Furniture, true);
SetCollisionMaskValue(Config.LayerNumber.Wall, true);
SetCollisionMaskValue(Config.LayerNumber.Platform, true);
SetCollisionMaskValue(Config.LayerNumber.Floor, true);
}
public override void _PhysicsProcess(double delta)
{
if (Input.IsActionJustReleased("push"))
{
SetCollisionMaskValue(Config.LayerNumber.Player, false);
}
if (Input.IsActionJustPressed("push"))
{
SetCollisionMaskValue(Config.LayerNumber.Player, true);
}
}
/// <summary>
/// <para>This method is called when furniture is damaged</para>
/// <para>当家具损害时调用此方法</para>
/// </summary>
/// <param name="damageTemplate"></param>
/// <returns>
///<para>Return whether the damage completely destroyed the furniture</para>
///<para>返回本次伤害是否彻底破坏了家具</para>
/// </returns>
public bool Damage(DamageTemplate damageTemplate)
{
_durability -= damageTemplate.Damage;
if (_durability <= 0)
{
QueueFree();
}
return true;
}
}

View File

@ -1,124 +0,0 @@
using ColdMint.scripts.character;
using ColdMint.scripts.loader.uiLoader;
using ColdMint.scripts.utils;
using Godot;
namespace ColdMint.scripts.furniture;
/// <summary>
/// <para>GUIFurnitureTemplate</para>
/// <para>带有图形用户页面的家居模板</para>
/// </summary>
public partial class GuiFurniture : Furniture
{
/// <summary>
/// <para>Operating range of furniture</para>
/// <para>家具的操作范围</para>
/// </summary>
/// <remarks>
///<para>For furniture with graphical user pages, the player must enter the action range and press the shortcut key to display the UI page.</para>
///<para>对于带有图形用户页面的家具来说玩家必须进入操作范围内按下快捷键才能显示UI页面。</para>
/// </remarks>
private Area2D? _operateArea2D;
/// <summary>
/// <para>Whether the player is within range of the operation</para>
/// <para>玩家是否在操作范围内</para>
/// </summary>
private bool _playerInRange;
[Export]
public string? Path;
/// <summary>
/// <para>There's a mouse hover</para>
/// <para>有鼠标悬停</para>
/// </summary>
private bool _hasMouseOver;
public override void _Ready()
{
base._Ready();
_operateArea2D = GetNode<Area2D>("OperateArea2D");
_operateArea2D.BodyEntered += OnBodyEntered;
_operateArea2D.BodyExited += OnBodyExited;
_operateArea2D.SetCollisionMaskValue(Config.LayerNumber.Player, true);
if (Path != null)
{
GameSceneDepend.DynamicUiGroup?.RegisterControl(Path, () =>
{
var packedScene = ResourceLoader.Load<PackedScene>(Path);
return NodeUtils.InstantiatePackedScene<SpellEditorUi>(packedScene);
});
}
}
/// <summary>
/// <para>Use furniture</para>
/// <para>使用家具</para>
/// </summary>
/// <param name="player"></param>
private void Use(Player player)
{
if (Path == null)
{
return;
}
GameSceneDepend.DynamicUiGroup?.ShowControl(Path);
}
public override void _MouseEnter()
{
base._MouseEnter();
_hasMouseOver = true;
GameSceneDepend.IsMouseOverFurnitureGui = true;
}
public override void _MouseExit()
{
base._MouseExit();
_hasMouseOver = false;
GameSceneDepend.IsMouseOverFurnitureGui = false;
}
private void OnBodyEntered(Node node)
{
if (node is Player)
{
_playerInRange = true;
}
}
public override void _PhysicsProcess(double delta)
{
base._PhysicsProcess(delta);
if (GameSceneDepend.Player == null || !_playerInRange || !_hasMouseOver)
{
return;
}
if (Input.IsActionJustPressed("use_item"))
{
Use(GameSceneDepend.Player);
}
}
private void OnBodyExited(Node2D node2D)
{
if (node2D is Player)
{
_playerInRange = false;
if (Path != null)
{
GameSceneDepend.DynamicUiGroup?.HideControl(Path);
}
}
}
public override void _ExitTree()
{
if (_operateArea2D != null)
{
_operateArea2D.BodyEntered -= OnBodyEntered;
_operateArea2D.BodyExited -= OnBodyExited;
}
}
}

View File

@ -10,18 +10,22 @@ namespace ColdMint.scripts.inventory;
public partial class HotBar : HBoxContainer public partial class HotBar : HBoxContainer
{ {
private IItemContainer? _itemContainer; private IItemContainer? _itemContainer;
private IItemContainerDisplay? _itemContainerDisplay;
public override void _Ready() public override void _Ready()
{ {
base._Ready(); base._Ready();
var universalItemContainer = new UniversalItemContainer(Config.HotBarSize); _itemContainer = new UniversalItemContainer();
_itemContainer = universalItemContainer;
universalItemContainer.AllowItemTypesExceptPlaceholder();
_itemContainer.SupportSelect = true; _itemContainer.SupportSelect = true;
_itemContainerDisplay = new ItemSlotContainerDisplay(this);
_itemContainerDisplay.BindItemContainer(_itemContainer);
NodeUtils.DeleteAllChild(this); NodeUtils.DeleteAllChild(this);
for (var i = 0; i < Config.HotBarSize; i++)
{
var itemSlotNode = _itemContainer.AddItemSlot(this);
if (itemSlotNode != null)
{
itemSlotNode.BackpackAllowed = true;
}
}
} }
@ -32,14 +36,14 @@ public partial class HotBar : HBoxContainer
{ {
//Mouse wheel down //Mouse wheel down
//鼠标滚轮向下 //鼠标滚轮向下
_itemContainer?.SelectNextItem(); _itemContainer?.SelectTheNextItemSlot();
} }
if (Input.IsActionJustPressed("hotbar_previous")) if (Input.IsActionJustPressed("hotbar_previous"))
{ {
//Mouse wheel up //Mouse wheel up
//鼠标滚轮向上 //鼠标滚轮向上
_itemContainer?.SelectPreviousItem(); _itemContainer?.SelectThePreviousItemSlot();
} }
if (Input.IsActionJustPressed("hotbar_1")) if (Input.IsActionJustPressed("hotbar_1"))
@ -102,7 +106,7 @@ public partial class HotBar : HBoxContainer
return; return;
} }
_itemContainer.SelectItem(shortcutKeyIndex); _itemContainer.SelectItemSlot(shortcutKeyIndex);
} }
public IItemContainer? GetItemContainer() public IItemContainer? GetItemContainer()

View File

@ -4,34 +4,11 @@ namespace ColdMint.scripts.inventory;
public interface IItem public interface IItem
{ {
/// <summary>
/// <para>The position of the item in the container</para>
/// <para>物品在容器内的位置</para>
/// </summary>
public int Index { get; set; }
/// <summary> /// <summary>
/// <para>ID of current item</para> /// <para>ID of current item</para>
/// <para>当前物品的ID</para> /// <para>当前项目的ID</para>
/// </summary> /// </summary>
string Id { get; set; } string Id { get; }
/// <summary>
/// <para>ShowSelf</para>
/// <para>显示自身</para>
/// </summary>
void ShowSelf();
/// <summary>
/// <para>QueueFreeSelf</para>
/// <para>销毁自身</para>
/// </summary>
void QueueFreeSelf();
/// <summary>
/// <para>HideSelf</para>
/// <para>隐藏自身</para>
/// </summary>
void HideSelf();
/// <summary> /// <summary>
/// <para>Icon of current item</para> /// <para>Icon of current item</para>
@ -63,79 +40,11 @@ public interface IItem
/// </summary> /// </summary>
int MaxQuantity { get; } int MaxQuantity { get; }
/// <summary>
/// <para>ItemType</para>
/// <para>获取物品类型</para>
/// </summary>
int ItemType { get; }
/// <summary>
/// <para>Check or not</para>
/// <para>是否选中</para>
/// </summary>
bool IsSelect { get; set; }
/// <summary>
/// <para>The container in which the item is located</para>
/// <para>物品所在的物品容器</para>
/// </summary>
IItemContainer? ItemContainer { get; set; }
/// <summary>
/// <para>Its own container of items</para>
/// <para>自身的物品容器</para>
/// </summary>
/// <remarks>
/// <para>Returns a non-null value if the item itself can hold other items</para>
/// <para>物品本身可容纳其他物品,则返回非空值</para>
/// </remarks>
public IItemContainer? SelfItemContainer { get; set; }
/// <summary>
/// <para>Calculate how many items can be merged with other items</para>
/// <para>计算当前物品可与其他物品合并多少个</para>
/// </summary>
/// <param name="other"></param>
/// <param name="unallocatedQuantity">
///<para>The amount yet to be allocated(This method doesn't actually change the number of iitems, so you need to allocate an int variable to keep track of how many items remain unallocated.)</para>
///<para>尚未分配的数量在此方法并不会实际改变IItem的数量故您需要分配一个int型变量记录还有多少个物品尚未分配</para>
/// </param>
/// <returns>
///<para>Number of mergable numbers. 0 indicates that the number cannot be merged. Greater than 0 indicates that the number can be merged.</para>
///<para>可合并的数量0为不能合并大于0可合并。</para>
/// </returns>
int MergeableItemCount(IItem other, int unallocatedQuantity);
/// <summary>
/// <para>Create a new item instance</para>
/// <para>创建新的物品实例</para>
/// </summary>
/// <param name="number">
///<para>Quantity (pass in a value less than 0 to create an instance using all the quantities of built-in items)</para>
///<para>数量传入小于0的值使用内置物品的所有数量创建实例</para>
/// </param>
/// <returns>
///<para>Newly created item</para>
///<para>新创建的物品</para>
/// </returns>
IItem? CreateItem(int number);
/// <summary> /// <summary>
/// <para>Execute when current item is used <br/> e.g. when player clicks left mouse button with current item in hand</para> /// <para>Execute when current item is used <br/> e.g. when player clicks left mouse button with current item in hand</para>
/// <para>当前项被使用时执行 <br/> e.g. 当玩家用鼠标左键点击当前物品时</para> /// <para>当前项被使用时执行 <br/> e.g. 当玩家用鼠标左键点击当前物品时</para>
/// </summary> /// </summary>
/// <param name="owner">Owner of current item, if any</param> /// <param name="owner">Owner of current item, if any</param>
/// <param name="targetGlobalPosition">Target position, such as the position of the cursor when used by the player</param> /// <param name="targetGlobalPosition">Target position, such as the position of the cursor when used by the player</param>
/// <returns> void Use(Node2D? owner, Vector2 targetGlobalPosition);
///<para>Whether it was successfully executed</para>
///<para>是否成功被执行了</para>
/// </returns>
bool Use(Node2D? owner, Vector2 targetGlobalPosition);
/// <summary>
/// <para>When the item is thrown</para>
/// <para>当物品被抛出时</para>
/// </summary>
/// <param name="velocity"></param>
void OnThrow(Vector2 velocity);
} }

View File

@ -1,5 +1,7 @@
using System; using System;
using System.Collections.Generic;
using ColdMint.scripts.map.events; using ColdMint.scripts.map.events;
using Godot;
namespace ColdMint.scripts.inventory; namespace ColdMint.scripts.inventory;
@ -7,33 +9,17 @@ namespace ColdMint.scripts.inventory;
/// <para>item container</para> /// <para>item container</para>
/// <para>物品容器</para> /// <para>物品容器</para>
/// </summary> /// </summary>
public interface IItemContainer /// <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 : IEnumerable<ItemSlotNode>
{ {
/// <summary> /// <summary>
/// <para>This event is triggered when the selected item changes</para> /// <para>This event is triggered when the selected item slot changes</para>
/// <para>当选中的物品改变时,触发此事件</para> /// <para>当选中的物品改变时,触发此事件</para>
/// </summary> /// </summary>
Action<SelectedItemChangeEvent>? SelectedItemChangeEvent { get; set; } Action<SelectedItemSlotChangeEvent>? SelectedItemSlotChangeEvent { get; set; }
/// <summary>
/// <para>This event is triggered when the item's data changes, such as the number increases, decreases, or new items are added to the container</para>
/// <para>当物品的数据发生改变时,例如数量增加,减少,或者新物品被添加到容器内触发此事件</para>
/// </summary>
Action<ItemDataChangeEvent>? ItemDataChangeEvent { get; set; }
/// <summary>
/// <para>Allow Adding Item By Type</para>
/// <para>允许添加指定类型的物品</para>
/// </summary>
/// <param name="itemType"></param>
void AllowAddingItemByType(int itemType);
/// <summary>
/// <para>Disallow Adding Item By Type</para>
/// <para>禁止添加指定类型的物品</para>
/// </summary>
/// <param name="itemType"></param>
void DisallowAddingItemByType(int itemType);
/// <summary> /// <summary>
/// <para>Can the specified item be added to the container?</para> /// <para>Can the specified item be added to the container?</para>
@ -48,28 +34,15 @@ public interface IItemContainer
/// <para>实现添加物品的方法</para> /// <para>实现添加物品的方法</para>
/// </summary> /// </summary>
/// <param name="item"></param> /// <param name="item"></param>
/// <returns> /// <returns></returns>
///<para>How many items were successfully added. The addition failed, and 0 was returned.</para> bool AddItem(IItem item);
///<para>有多少个物品被成功添加了。添加失败返回0</para>
/// </returns>
int AddItem(IItem item);
/// <summary> /// <summary>
/// <para>Whether this item container supports checking</para> /// <para>Whether this item container supports checking</para>
/// <para>此物品容器是否支持选中</para> /// <para>此物品容器是否支持选中</para>
/// </summary> /// </summary>
bool SupportSelect { get; set; } public bool SupportSelect { get; set; }
/// <summary>
/// <para>Gets a placeholder object</para>
/// <para>获取占位符对象</para>
/// </summary>
/// <param name="index">
///<para>index</para>
///<para>占位符代替的索引</para>
/// </param>
/// <returns></returns>
IItem GetPlaceHolderItem(int index);
/// <summary> /// <summary>
/// <para>Gets the selected location</para> /// <para>Gets the selected location</para>
@ -79,127 +52,104 @@ public interface IItemContainer
int GetSelectIndex(); int GetSelectIndex();
/// <summary> /// <summary>
/// <para>Gets the currently selected item</para> /// <para>Gets the currently selected node</para>
/// <para>获取当前选中的物品</para> /// <para>获取当前选中的节点</para>
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
IItem? GetSelectItem(); ItemSlotNode? GetSelectItemSlotNode();
/// <summary>
/// <para>Gets the item in the specified location</para>
/// <para>获取指定位置的物品</para>
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
IItem? GetItem(int index);
/// <summary>
/// <para>ReplaceItem</para>
/// <para>替换物品</para>
/// </summary>
/// <remarks>
///<para>Even if the item corresponding to the index is null, it can be successfully replaced.</para>
///<para>即使索引对应的物品为null也可以成功的替换。</para>
/// </remarks>
/// <param name="index"></param>
/// <param name="item"></param>
/// <returns></returns>
bool ReplaceItem(int index, IItem item);
/// <summary>
/// <para>Whether items are replaceable</para>
/// <para>是否可替换物品</para>
/// </summary>
/// <param name="index"></param>
/// <param name="item"></param>
/// <returns></returns>
bool CanReplaceItem(int index, IItem item);
/// <summary>
/// <para>ClearItem</para>
/// <para>清理物品</para>
/// </summary>
/// <param name="index"></param>
/// <returns>
///<para>Returns the item to be cleaned, or null if the item to be cleaned cannot be found</para>
///<para>返回要清理的物品如果找不到要清理的物品则返回null</para>
/// </returns>
IItem? ClearItem(int index);
/// <summary>
/// <para>ClearAllItems</para>
/// <para>清理全部物品</para>
/// </summary>
void ClearAllItems();
/// <summary>
/// <para>Gets the item in the specified location, equivalent to <see cref="GetItem"/></para>
/// <para>获取指定位置的物品,等同于<see cref="GetItem"/></para>
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
IItem? this[int index] => GetItem(index);
/// <summary> /// <summary>
/// <para>Removes the item from the currently selected location</para> /// <para>Removes an item from the inventory at the currently selected location</para>
/// <para>移除当前选中位置的物品</para> /// <para>移除当前选中位置物品栏内的物品</para>
/// </summary> /// </summary>
/// <param name="number"> /// <param name="number">
/// <para>Quantity to be removed, inputs below zero represent all items</para> /// <para>Quantity to be removed, inputs below zero represent all items</para>
/// <para>要删除的数量小于0的输入代表全部物品</para> /// <para>要删除的数量小于0的输入代表全部物品</para>
/// </param> /// </param>
/// <returns> /// <returns>
///<para>How many items were actually removed</para> /// <para>The remaining number, if the number of items in the current item stack is less than the specified number. Otherwise,0</para>
///<para>实际移除了多少个物品</para> /// <para>若物品槽内物品少于指定的数量返回相差的数量。否则返回0</para>
/// </returns> /// </returns>
int RemoveSelectItem(int number); int RemoveItemFromItemSlotBySelectIndex(int number);
/// <summary> /// <summary>
/// <para>Deduct the number of items in the specified location</para> /// <para>Gets the number of item slots</para>
/// <para>扣除指定位置的物品数量</para> /// <para>获取物品槽的数量</para>
/// </summary> /// </summary>
/// <param name="itemIndex"></param> /// <returns></returns>
int GetItemSlotCount();
/// <summary>
/// <para>Gets the item slot for the specified location</para>
/// <para>获取指定位置的物品槽</para>
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
ItemSlotNode? GetItemSlotNode(int index);
/// <summary>
/// <para>Gets the item slot for the specified location, equals to <see cref="GetItemSlotNode"/></para>
/// <para>获取指定位置的物品槽,等同于<see cref="GetItemSlotNode"/></para>
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
ItemSlotNode? this[int index] => GetItemSlotNode(index);
/// <summary>
/// <para>Removes an item from the item slot in the specified location</para>
/// <para>在指定位置的物品槽内移除物品</para>
/// </summary>
/// <param name="itemSlotIndex"></param>
/// <param name="number"> /// <param name="number">
/// <para>Quantity to be removed, inputs below zero represent all items</para> /// <para>Quantity to be removed, inputs below zero represent all items</para>
/// <para>要删除的数量小于0的输入代表全部物品</para> /// <para>要删除的数量小于0的输入代表全部物品</para>
/// </param> /// </param>
/// <returns> /// <returns>
///<para>How many items were actually removed</para> /// <para>The remaining number, if the number of items in the current item stack is less than the specified number. Otherwise,0</para>
///<para>实际移除了多少个物品</para> /// <para>若物品槽内物品少于指定的数量返回相差的数量。否则返回0</para>
/// </returns> /// </returns>
int RemoveItem(int itemIndex, int number); int RemoveItemFromItemSlot(int itemSlotIndex, int number);
/// <summary> /// <summary>
/// <para>Gets the used capacity of the item container</para> /// <para>Based on the given item, match the item slots where it can be added to </para>
/// <para>获取物品容器已使用的容量</para> /// <para>根据给定的物品,匹配可放置它的物品槽</para>
/// </summary> /// </summary>
/// <returns></returns> /// <param name="item"></param>
int GetUsedCapacity(); /// <returns>
/// <para>Return null if there is no slot to place the item in</para>
/// <para>若没有槽可放置此物品则返回null</para>
/// </returns>
ItemSlotNode? Match(IItem item);
/// <summary> /// <summary>
/// <para>Gets the total capacity of the item container</para> /// <para>AddItemSlot</para>
/// <para>获取物品容器的总容量</para> /// <para>添加物品槽</para>
/// </summary> /// </summary>
/// <returns></returns> /// <param name="rootNode"></param>
int GetTotalCapacity(); ItemSlotNode? AddItemSlot(Node rootNode);
/// <summary> /// <summary>
/// <para>Select the next item</para> /// <para>SelectTheNextItemSlot</para>
/// <para>选择下一个物品</para> /// <para>选择下一个物品</para>
/// </summary> /// </summary>
void SelectNextItem(); void SelectTheNextItemSlot();
/// <summary> /// <summary>
/// <para>Select the previous item</para> /// <para>SelectThePreviousItemSlot</para>
/// <para>选择上一个物品</para> /// <para>选择上一个物品</para>
/// </summary> /// </summary>
void SelectPreviousItem(); void SelectThePreviousItemSlot();
/// <summary> /// <summary>
/// <para>选择物品</para> /// <para>选择物品</para>
/// <para>Select item</para> /// <para>SelectItemSlot</para>
/// </summary> /// </summary>
/// <param name="index"></param> /// <param name="newSelectIndex"></param>
void SelectItem(int index); void SelectItemSlot(int newSelectIndex);
} }

View File

@ -1,13 +0,0 @@
using System.Collections.Generic;
namespace ColdMint.scripts.inventory;
public interface IItemContainerDisplay : IEnumerable<IItemDisplay>
{
/// <summary>
/// <para>Bind an item container to the item container display</para>
/// <para>为物品容器显示器绑定物品容器</para>
/// </summary>
/// <param name="itemContainer"></param>
void BindItemContainer(IItemContainer? itemContainer);
}

View File

@ -1,40 +0,0 @@
namespace ColdMint.scripts.inventory;
/// <summary>
/// <para>IItemDisplay</para>
/// <para>物品显示器</para>
/// </summary>
public interface IItemDisplay
{
/// <summary>
/// <para>Call this method to refresh the display when the item's information changes</para>
/// <para>物品的信息发生变更时,调用此方法刷新显示器</para>
/// </summary>
/// <remarks>
///<param name="item">
///<para>New data for items after changes</para>
///<para>发生改变后的物品新数据</para>
/// </param>
/// </remarks>
void Update(IItem? item);
/// <summary>
/// <para>Gets the item that is being displayed</para>
/// <para>获取正在显示的物品</para>
/// </summary>
IItem? Item { get; }
/// <summary>
/// <para>Show item Display</para>
/// <para>显示物品显示器</para>
/// </summary>
void ShowSelf();
/// <summary>
/// <para>Hide item Display</para>
/// <para>隐藏物品显示器</para>
/// </summary>
void HideSelf();
}

View File

@ -1,165 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using ColdMint.scripts.debug;
using ColdMint.scripts.map.events;
namespace ColdMint.scripts.inventory;
public abstract class ItemContainerDisplayTemplate : IItemContainerDisplay
{
protected readonly List<IItemDisplay> ItemDisplayList = [];
private IItemContainer? _itemContainer;
public async void BindItemContainer(IItemContainer? itemContainer)
{
if (_itemContainer == itemContainer)
{
return;
}
if (_itemContainer != null)
{
_itemContainer.SelectedItemChangeEvent -= OnSelectedItemChangeEvent;
_itemContainer.ItemDataChangeEvent -= OnItemDataChangeEvent;
}
_itemContainer = itemContainer;
if (itemContainer == null)
{
//Set empty items container to hide all ui.
//设置空物品容器隐藏全部ui。
for (var i = 0; i < ItemDisplayList.Count; i++)
{
var itemDisplay = ItemDisplayList[i];
LogCat.LogWithFormat("hide_display_item", LogCat.LogLabel.ItemContainerDisplay, i);
itemDisplay.Update(null);
itemDisplay.HideSelf();
}
return;
}
itemContainer.SelectedItemChangeEvent += OnSelectedItemChangeEvent;
itemContainer.ItemDataChangeEvent += OnItemDataChangeEvent;
var totalCapacity = itemContainer.GetTotalCapacity();
var currentCapacity = ItemDisplayList.Count;
var capacityDifference = totalCapacity - currentCapacity;
if (capacityDifference > 0)
{
//There are those that need to be added, and we create them.
//有需要添加的,我们创建他们。
for (var i = 0; i < capacityDifference; i++)
{
LogCat.LogWithFormat("add_display_item", LogCat.LogLabel.ItemContainerDisplay, i);
AddItemDisplay();
}
}
else if (capacityDifference < 0)
{
//There are things that need to be hidden
//有需要被隐藏的
for (var i = currentCapacity - 1; i >= totalCapacity; i--)
{
LogCat.LogWithFormat("hide_display_item", LogCat.LogLabel.ItemContainerDisplay, i);
var itemDisplay = ItemDisplayList[i];
itemDisplay.Update(null);
itemDisplay.HideSelf();
}
}
await Task.Yield();
UpdateData(itemContainer, totalCapacity);
}
private void OnItemDataChangeEvent(ItemDataChangeEvent itemDataChangeEvent)
{
if (_itemContainer == null)
{
return;
}
UpdateDataForSingleLocation(_itemContainer, itemDataChangeEvent.NewIndex);
}
private void OnSelectedItemChangeEvent(SelectedItemChangeEvent selectedItemChangeEvent)
{
if (_itemContainer == null)
{
return;
}
UpdateDataForSingleLocation(_itemContainer, selectedItemChangeEvent.OldIndex);
UpdateDataForSingleLocation(_itemContainer, selectedItemChangeEvent.NewIndex);
}
/// <summary>
/// <para>Update data</para>
/// <para>更新数据</para>
/// </summary>
/// <remarks>
///<para>Used to batch update the Item data in itemContainer to the display.</para>
///<para>用于将itemContainer内的Item数据批量更新到显示器内。</para>
/// </remarks>
/// <param name="itemContainer">
///<para>Item container data</para>
///<para>物品容器数据</para>
/// </param>
/// <param name="endIndex">
///<para>endIndex</para>
///<para>结束位置</para>
/// </param>
/// <param name="startIndex">
///<para>startIndex</para>
///<para>起始位置</para>
/// </param>
private void UpdateData(IItemContainer itemContainer, int endIndex, int startIndex = 0)
{
LogCat.LogWithFormat("batch_update_data", LogCat.LogLabel.ItemContainerDisplay, startIndex, endIndex);
for (var i = startIndex; i < endIndex; i++)
{
UpdateDataForSingleLocation(itemContainer, i);
}
}
/// <summary>
/// <para>Update data for a single location</para>
/// <para>更新单个位置的数据</para>
/// </summary>
/// <param name="itemContainer"></param>
/// <param name="index"></param>
private void UpdateDataForSingleLocation(IItemContainer itemContainer, int index)
{
LogCat.LogWithFormat("update_display_item", LogCat.LogLabel.ItemContainerDisplay, index);
var itemDisplay = ItemDisplayList[index];
var item = itemContainer.GetItem(index);
if (item == null)
{
item = itemContainer.GetPlaceHolderItem(index);
}
if (itemContainer.SupportSelect)
{
item.IsSelect = index == itemContainer.GetSelectIndex();
}
else
{
item.IsSelect = false;
}
itemDisplay.Update(item);
itemDisplay.ShowSelf();
}
/// <summary>
/// <para>Add item display</para>
/// <para>添加物品显示器</para>
/// </summary>
protected abstract void AddItemDisplay();
public IEnumerator<IItemDisplay> GetEnumerator()
{
return ItemDisplayList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}

View File

@ -1,26 +0,0 @@
using ColdMint.scripts.utils;
using Godot;
namespace ColdMint.scripts.inventory;
public class ItemSlotContainerDisplay(Node rootNode) : ItemContainerDisplayTemplate
{
private readonly PackedScene? _packedScene = ResourceLoader.Load<PackedScene>("res://prefab/ui/ItemSlot.tscn");
protected override void AddItemDisplay()
{
if (_packedScene == null)
{
return;
}
var itemSlotNode = NodeUtils.InstantiatePackedScene<ItemSlotNode>(_packedScene);
if (itemSlotNode == null)
{
return;
}
ItemDisplayList.Add(itemSlotNode);
NodeUtils.CallDeferredAddChild(rootNode, itemSlotNode);
}
}

View File

@ -1,3 +1,5 @@
using System;
using ColdMint.scripts.debug;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;
using Godot; using Godot;
@ -7,197 +9,280 @@ namespace ColdMint.scripts.inventory;
/// <para>A slot in the inventory</para> /// <para>A slot in the inventory</para>
/// <para>物品栏内的一个插槽</para> /// <para>物品栏内的一个插槽</para>
/// </summary> /// </summary>
public partial class ItemSlotNode : MarginContainer, IItemDisplay public partial class ItemSlotNode : MarginContainer
{ {
private TextureRect? _backgroundTextureRect; private TextureRect? _backgroundTextureRect;
private TextureRect? _iconTextureRect; private TextureRect? _iconTextureRect;
private Label? _quantityLabel; private Label? _quantityLabel;
private Control? _control; private Control? _control;
private bool _isSelect;
private Texture2D? _backgroundTexture; private Texture2D? _backgroundTexture;
private Texture2D? _backgroundTextureWhenSelect; private Texture2D? _backgroundTextureWhenSelect;
public IItem? Item { get; private set; } private IItem? _item;
public IItem? Item
{
set
{
//Set item
//设置物品
_item = value;
UpdateAllDisplay();
}
}
public override void _Ready() public override void _Ready()
{ {
_backgroundTexture = ResourceLoader.Load<Texture2D>("res://sprites/ui/ItemBarEmpty.png"); _backgroundTexture = GD.Load<Texture2D>("res://sprites/ui/ItemBarEmpty.png");
_backgroundTextureWhenSelect = ResourceLoader.Load<Texture2D>("res://sprites/ui/ItemBarFocus.png"); _backgroundTextureWhenSelect = GD.Load<Texture2D>("res://sprites/ui/ItemBarFocus.png");
_backgroundTextureRect = _backgroundTextureRect =
GetNode<TextureRect>("BackgroundTexture"); GetNode<TextureRect>("BackgroundTexture");
_iconTextureRect = GetNode<TextureRect>("BackgroundTexture/IconTextureRect"); _iconTextureRect = GetNode<TextureRect>("BackgroundTexture/IconTextureRect");
_quantityLabel = GetNode<Label>("Control/QuantityLabel"); _quantityLabel = GetNode<Label>("Control/QuantityLabel");
_control = GetNode<Control>("Control"); _control = GetNode<Control>("Control");
_quantityLabel.Hide(); _quantityLabel.Hide();
} UpdateBackground(_isSelect);
public override void _EnterTree()
{
MouseEntered += OnMouseEntered;
MouseExited += OnMouseExited;
}
public override void _ExitTree()
{
MouseEntered -= OnMouseEntered;
MouseExited -= OnMouseExited;
}
private void OnMouseExited()
{
GameSceneDepend.IsMouseOverItemSlotNode = false;
}
private void OnMouseEntered()
{
GameSceneDepend.IsMouseOverItemSlotNode = true;
} }
public override Variant _GetDragData(Vector2 atPosition) public override Variant _GetDragData(Vector2 atPosition)
{ {
switch (Item) if (_isSelect || _iconTextureRect == null)
{ {
case null: //Drag is not allowed if there is no icon or no pile of items.
return Config.EmptyVariant; //如果没有图标或者没有物品堆,那么不允许拖动。
case PlaceholderItem: return new Variant();
return Config.EmptyVariant;
}
if (_iconTextureRect == null)
{
return Config.EmptyVariant;
} }
var textureRect = new TextureRect(); var textureRect = new TextureRect();
textureRect.ExpandMode = _iconTextureRect.ExpandMode; textureRect.ExpandMode = _iconTextureRect.ExpandMode;
textureRect.Size = _iconTextureRect.Size; textureRect.Size = _iconTextureRect.Size;
textureRect.Texture = _iconTextureRect.Texture; textureRect.Texture = _iconTextureRect.Texture;
textureRect.ZIndex = Config.ZIndexManager.FloatingIcon;
SetDragPreview(textureRect); SetDragPreview(textureRect);
return Variant.CreateFrom(this); return Variant.CreateFrom(this);
} }
public override bool _CanDropData(Vector2 atPosition, Variant data) public override bool _CanDropData(Vector2 atPosition, Variant data)
{ {
if (_isSelect)
{
//Do not place items in the selected item slot, even if the item slot is empty.
//禁止在已选中的物品槽内放置物品,即使物品槽是空的。
LogCat.Log("item_slot_is_selected_and_not_allowed");
return false;
}
//If the preplaced slot does not have an icon, the preplaced slot is not allowed.
//如果预放置的槽位没有图标,那么不允许放置。
if (_iconTextureRect == null)
{
return false;
}
var type = data.VariantType; var type = data.VariantType;
if (type == Variant.Type.Nil) if (type == Variant.Type.Nil)
{ {
//The preplaced data is null.
//预放置的数据为null。
return false; return false;
} }
var itemSlotNode = data.As<ItemSlotNode>(); var itemSlotNode = data.As<ItemSlotNode>();
var sourceItem = itemSlotNode.Item; var item = itemSlotNode.GetItem();
if (sourceItem == null) if (item == null)
{ {
//Return null when trying to get the source item.
//尝试获取源物品时返回null。
return false; return false;
} }
switch (Item)
if (item is Packsack packsack)
{ {
case null: if (_item == null)
return true; {
case PlaceholderItem placeholderItem: //If the dragged item is a backpack and there are no items in the current slot, return whether the backpack is allowed.
var placeholderItemContainer = placeholderItem.ItemContainer; //如果拖拽的物品是背包,且当前槽位没有物品,那么返回是否允许放置背包。
if (placeholderItemContainer == null) return BackpackAllowed;
{ }
return true;
} if (packsack.ItemContainer == null)
return placeholderItemContainer.CanReplaceItem(placeholderItem.Index, sourceItem); {
default: LogCat.Log("item_container_is_null");
var sourceItemSelfContainer = sourceItem.SelfItemContainer; return false;
if (sourceItemSelfContainer != null) }
{
//Place the container on the item. return packsack.ItemContainer.CanAddItem(_item);
//将容器放在物品上。
return sourceItemSelfContainer.CanAddItem(Item);
}
var itemSelfContainer = Item.SelfItemContainer;
if (itemSelfContainer != null)
{
//Drag the item onto the container.
//将物品拖到容器上。
return itemSelfContainer.CanAddItem(sourceItem);
}
return Item.MergeableItemCount(sourceItem, sourceItem.Quantity) > 0;
} }
if (_item is Packsack currentPacksack)
{
if (currentPacksack.ItemContainer == null)
{
LogCat.Log("item_container_is_null");
return false;
}
return currentPacksack.ItemContainer.CanAddItem(item);
}
return CanAddItem(item);
}
/// <summary>
/// <para>Get the items in the item container</para>
/// <para>获取物品容器内的物品</para>
/// </summary>
/// <returns>
///<para>There may be multiple quantities</para>
///<para>数量可能有多个</para>
/// </returns>
public IItem? GetItem()
{
return _item;
}
/// <summary>
/// <para>CreateItemInstance</para>
/// <para>创建物品槽内的物品实例</para>
/// </summary>
/// <param name="number">
///<para>Quantity (pass in a value less than 0 to create an instance using all the quantities of built-in items)</para>
///<para>数量传入小于0的值使用内置物品的所有数量创建实例</para>
/// </param>
/// <returns>
///<para>Newly created item</para>
///<para>新创建的物品</para>
/// </returns>
public IItem? CreateItemInstance(int number)
{
if (number == 0)
{
return null;
}
if (_item is not Node2D node2D)
{
return null;
}
var duplicate = node2D.Duplicate();
if (duplicate is not Node2D newNode2D)
{
return null;
}
newNode2D.GlobalPosition = node2D.GlobalPosition;
if (duplicate is not IItem newItem)
{
return null;
}
if (number < 0)
{
newItem.Quantity = _item.Quantity;
}
else
{
newItem.Quantity = number >= _item.Quantity ? _item.Quantity : number;
}
return newItem;
}
/// <summary>
/// <para>Clean out the items in the item slot</para>
/// <para>清理物品槽内的物品</para>
/// </summary>
/// <param name="queueFree">
///<para>Whether to release a node</para>
///<para>是否释放节点</para>
/// </param>
/// <remarks>
///<para>Clean up item object references in item slots.</para>
///<para>清理物品槽内的物品对象引用。</para>
/// </remarks>
public void ClearItem(bool queueFree = true)
{
if (_item == null)
{
return;
}
if (queueFree && _item is Node node)
{
node.QueueFree();
}
_item = null;
UpdateAllDisplay();
} }
public override void _DropData(Vector2 atPosition, Variant data) public override void _DropData(Vector2 atPosition, Variant data)
{ {
//The item is empty and the corresponding item container cannot be retrieved. if (_iconTextureRect == null)
//物品为空,无法获取对应的物品容器。
if (Item is null)
{ {
return; return;
} }
var type = data.VariantType; var type = data.VariantType;
if (type == Variant.Type.Nil) if (type == Variant.Type.Nil)
{ {
//The passed variable is null.
//传入的变量为null。
return; return;
} }
var itemSlotNode = data.As<ItemSlotNode>(); var itemSlotNode = data.As<ItemSlotNode>();
var sourceItem = itemSlotNode.Item; var sourceItem = itemSlotNode.GetItem();
if (sourceItem == null) if (sourceItem == null)
{ {
//Return null when trying to get the source item.
//尝试获取源物品时返回null。
return; return;
} }
if (Item.SelfItemContainer != null && Item.SelfItemContainer.CanAddItem(sourceItem)) if (sourceItem is Packsack packsack)
{ {
//Use items and place them on the container. //If the source item is a backpack.
//用物品,在物品容器上放置。 //如果源物品是背包。
var oldIndex = sourceItem.Index; if (packsack.ItemContainer != null && _item != null)
var oldItemContainer = sourceItem.ItemContainer;
var addNumber = Item.SelfItemContainer.AddItem(sourceItem);
if (addNumber >= 0)
{ {
if (addNumber == sourceItem.Quantity) packsack.ItemContainer.AddItem(_item);
{ ClearItem(false);
oldItemContainer?.ClearItem(oldIndex); return;
}
else
{
oldItemContainer?.RemoveItem(oldIndex, addNumber);
}
} }
}
if (_item is Packsack customPacksack)
{
if (customPacksack.ItemContainer == null)
{
return;
}
customPacksack.ItemContainer.AddItem(sourceItem);
itemSlotNode.ClearItem(false);
return; return;
} }
if (sourceItem.SelfItemContainer != null && sourceItem.SelfItemContainer.CanAddItem(Item)) AddItem(sourceItem);
{ itemSlotNode.ClearItem(false);
//Use containers and place on top of items.
//用容器物品,在物品上放置。
var oldIndex = Item.Index;
var oldItemContainer = Item.ItemContainer;
var addNumber = sourceItem.SelfItemContainer.AddItem(Item);
if (addNumber >= 0)
{
if (addNumber == Item.Quantity)
{
oldItemContainer?.ClearItem(oldIndex);
}
else
{
oldItemContainer?.RemoveItem(oldIndex, addNumber);
}
}
return;
}
if (Item is PlaceholderItem placeholderItem)
{
var placeholderItemContainer = placeholderItem.ItemContainer;
var sourceItemContainer = sourceItem.ItemContainer;
var sourceItemIndex = sourceItem.Index;
var replaceResult = false;
if (placeholderItemContainer != null)
{
replaceResult = placeholderItemContainer.ReplaceItem(placeholderItem.Index, sourceItem);
}
if (replaceResult && sourceItemContainer != null)
{
sourceItemContainer.ClearItem(sourceItemIndex);
}
}
} }
/// <summary>
/// <para>Whether to place a backpack in the current slot</para>
/// <para>当前槽位是否允许放置背包</para>
/// </summary>
public bool BackpackAllowed { get; set; }
public bool IsSelect
{
get => _isSelect;
set
{
UpdateBackground(value);
_isSelect = value;
}
}
private void UpdateBackground(bool isSelect) private void UpdateBackground(bool isSelect)
{ {
@ -211,6 +296,24 @@ public partial class ItemSlotNode : MarginContainer, IItemDisplay
public TextureRect? BackgroundTextureRect => _backgroundTextureRect; public TextureRect? BackgroundTextureRect => _backgroundTextureRect;
/// <summary>
/// <para>Whether the item in this node is empty</para>
/// <para>此节点内的物品是否为空的</para>
/// </summary>
/// <returns>
///<para>Return true if the number of items is 0 or the item object does not exist</para>
///<para>当物品数量为0或物品对象不存在时返回true</para>
/// </returns>
public bool IsEmpty()
{
if (_item == null || _item.Quantity == 0)
{
return true;
}
return false;
}
/// <summary> /// <summary>
/// <para>Update all displays of this slot</para> /// <para>Update all displays of this slot</para>
@ -229,7 +332,7 @@ public partial class ItemSlotNode : MarginContainer, IItemDisplay
/// </summary> /// </summary>
private void UpdateTooltipText() private void UpdateTooltipText()
{ {
if (Item is PlaceholderItem or null) if (_item == null)
{ {
TooltipText = null; TooltipText = null;
return; return;
@ -240,16 +343,16 @@ public partial class ItemSlotNode : MarginContainer, IItemDisplay
var debugText = TranslationServerUtils.Translate("item_prompt_debug"); var debugText = TranslationServerUtils.Translate("item_prompt_debug");
if (debugText != null) if (debugText != null)
{ {
TooltipText = string.Format(debugText, Item.Id, TooltipText = string.Format(debugText, _item.Id,
TranslationServerUtils.Translate(Item.Name), TranslationServerUtils.Translate(_item.Name),
Item.Quantity, Item.MaxQuantity, Item.GetType().Name, _item.Quantity, _item.MaxQuantity, _item.GetType().Name,
TranslationServerUtils.Translate(Item.Description)); TranslationServerUtils.Translate(_item.Description));
} }
} }
else else
{ {
TooltipText = TranslationServerUtils.Translate(Item.Name) + "\n" + TooltipText = TranslationServerUtils.Translate(_item.Name) + "\n" +
TranslationServerUtils.Translate(Item.Description); TranslationServerUtils.Translate(_item.Description);
} }
} }
@ -264,13 +367,7 @@ public partial class ItemSlotNode : MarginContainer, IItemDisplay
return; return;
} }
if (Item is PlaceholderItem or null) switch (_item?.Quantity)
{
_quantityLabel.Hide();
return;
}
switch (Item?.Quantity)
{ {
case null or 1: case null or 1:
_quantityLabel.Hide(); _quantityLabel.Hide();
@ -278,7 +375,7 @@ public partial class ItemSlotNode : MarginContainer, IItemDisplay
default: default:
//When the quantity is not null or 1, we display the quantity. //When the quantity is not null or 1, we display the quantity.
//当数量不为null或1时我们显示数量 //当数量不为null或1时我们显示数量
_quantityLabel.Text = Item?.Quantity.ToString(); _quantityLabel.Text = _item?.Quantity.ToString();
_quantityLabel.Show(); _quantityLabel.Show();
break; break;
} }
@ -293,24 +390,94 @@ public partial class ItemSlotNode : MarginContainer, IItemDisplay
{ {
if (_iconTextureRect != null) if (_iconTextureRect != null)
{ {
_iconTextureRect.Texture = Item?.Icon; _iconTextureRect.Texture = _item?.Icon;
} }
} }
public void Update(IItem? item) public bool CanAddItem(IItem item)
{ {
Item = item; if (!BackpackAllowed && item is Packsack)
UpdateAllDisplay(); {
UpdateBackground(item is { IsSelect: true }); //如果禁止放置背包,且新物品是背包
LogCat.Log("backpack_not_allowed");
return false;
}
if (_item == null)
{
//If there is no item in the current item slot, it is allowed to add.
//如果当前物品槽内没物品,那么允许添加。
LogCat.Log("item_is_null");
return true;
}
if (item.Id != _item.Id)
{
//If the item ID you want to add is different from the current item ID, disable.
//如果要添加的物品ID和当前的物品ID不一样那么禁止。
LogCat.Log("item_id_not_same");
return false;
}
var newQuantity = item.Quantity + _item.Quantity;
if (newQuantity > _item.MaxQuantity)
{
//The maximum number is exceeded and items cannot be added.
//超过了最大数量,无法添加物品。
LogCat.Log("max_quantity_exceeded");
return false;
}
return true;
} }
public void ShowSelf() /// <summary>
/// <para>Remove items from the item slot</para>
/// <para>从物品槽内移除物品</para>
/// </summary>
/// <param name="number">
///<para>number(Less than 0, remove all items)</para>
///<para>物品数量(小于0则移除全部物品)</para>
/// </param>
/// <returns>
///<para>How many items were actually removed</para>
///<para>实际移除了多少个物品</para>
/// </returns>
public int RemoveItem(int number)
{ {
Show(); if (_item == null)
{
return 0;
}
//The number of actual removals
//实际移除的数量
var removeNumber = number < 0 ? _item.Quantity : number;
_item.Quantity -= removeNumber;
if (_item.Quantity <= 0)
{
ClearItem();
}
return removeNumber;
} }
public void HideSelf() public bool AddItem(IItem item)
{ {
Hide(); if (_item == null)
{
Item = item;
return true;
}
var newQuantity = item.Quantity + _item.Quantity;
_item.Quantity = Math.Min(newQuantity, _item.MaxQuantity);
if (item is Node2D node2D)
{
node2D.QueueFree();
}
UpdateQuantityLabel();
return true;
} }
} }

View File

@ -5,10 +5,9 @@ namespace ColdMint.scripts.inventory;
public readonly struct ItemType( public readonly struct ItemType(
string id, string id,
Func<Node?,IItem?> createItemFunc,
Texture2D? icon, Texture2D? icon,
int maxStackQuantity, int maxStackQuantity)
Func<Node?, IItem?> createItemFunc
)
{ {
/// <summary> /// <summary>
/// <para>Item id of this type</para> /// <para>Item id of this type</para>
@ -20,7 +19,7 @@ public readonly struct ItemType(
/// <para>A function returns a new item instance of this type</para> /// <para>A function returns a new item instance of this type</para>
/// <para>用于创建该类型的物品实例的函数</para> /// <para>用于创建该类型的物品实例的函数</para>
/// </summary> /// </summary>
public Func<Node?, IItem?> CreateItemFunc { get; init; } = createItemFunc; public Func<Node?,IItem?> CreateItemFunc { get; init; } = createItemFunc;
/// <summary> /// <summary>
/// <para>Default icon of items of this type</para> /// <para>Default icon of items of this type</para>

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using ColdMint.scripts.utils;
using Godot; using Godot;
namespace ColdMint.scripts.inventory; namespace ColdMint.scripts.inventory;
@ -48,7 +49,7 @@ public static class ItemTypeManager
/// <summary> /// <summary>
/// <para>Create multiple new item instances for the given item ID</para> /// <para>Create multiple new item instances for the given item Id</para>
/// <para>创建多个给定物品Id的新物品实例</para> /// <para>创建多个给定物品Id的新物品实例</para>
/// </summary> /// </summary>
/// <param name="id"></param> /// <param name="id"></param>
@ -84,6 +85,23 @@ public static class ItemTypeManager
return items.ToArray(); return items.ToArray();
} }
/// <summary>
/// <para>Get the translated default name of the item type for the given id</para>
/// <para>获取指定物品id翻译后的物品名</para>
/// </summary>
/// <returns>
/// Translated default name of the item id if it exists. Else, return the id itself
/// </returns>
public static string DefaultNameOf(string id) => TranslationServerUtils.Translate($"item_{id}") ?? id;
/// <summary>
/// <para>Get the translated default description of the item type for the given id</para>
/// <para>获取指定物品id翻译后的描述</para>
/// </summary>
/// <returns>
/// Translated default description of the item id if it exists. Else, return null
/// </returns>
public static string? DefaultDescriptionOf(string id) => TranslationServerUtils.Translate($"item_{id}_desc");
/// <summary> /// <summary>
/// <para>Get the default icon of the item type for the given id</para> /// <para>Get the default icon of the item type for the given id</para>
@ -97,4 +115,16 @@ public static class ItemTypeManager
Registry.TryGetValue(id, out var itemType) Registry.TryGetValue(id, out var itemType)
? itemType.Icon ?? DefaultTexture ? itemType.Icon ?? DefaultTexture
: DefaultTexture; : DefaultTexture;
/// <summary>
/// <para>Gets the maximum number of stacks for an item</para>
/// <para>获取某个物品的最大堆叠数量</para>
/// </summary>
/// <param name="id">
///<para>id</para>
///<para>物品ID</para>
/// </param>
/// <returns></returns>
public static int MaxStackQuantityOf(string id) =>
Registry.TryGetValue(id, out var itemType) ? itemType.MaxStackQuantity : 0;
} }

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using ColdMint.scripts.debug; using ColdMint.scripts.debug;
using ColdMint.scripts.serialization; using ColdMint.scripts.serialization;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;
@ -29,12 +30,12 @@ public static class ItemTypeRegister
LogCat.Log("start_item_register_from_file"); LogCat.Log("start_item_register_from_file");
//初始化文件目录 //初始化文件目录
//initialize file dir //initialize file dir
const string itemRegsDirPath = "res://data/itemRegs"; var itemRegsDirPath = "res://data/itemRegs";
var itemRegsDir = DirAccess.Open(itemRegsDirPath); var itemRegsDir = DirAccess.Open(itemRegsDirPath);
var error = DirAccess.GetOpenError(); var error = DirAccess.GetOpenError();
if (error is not Error.Ok) if (error is not Error.Ok)
{ {
LogCat.LogErrorWithFormat("error_when_open_item_regs_dir", LogCat.LogLabel.Default, itemRegsDirPath, LogCat.LogErrorWithFormat("error_when_open_item_regs_dir", LogCat.LogLabel.Default, true, itemRegsDirPath,
error.ToString()); error.ToString());
return; return;
} }
@ -44,11 +45,11 @@ public static class ItemTypeRegister
var files = itemRegsDir.GetFiles(); var files = itemRegsDir.GetFiles();
if (files == null) if (files == null)
{ {
LogCat.LogWithFormat("found_files", LogCat.LogLabel.Default, 0); LogCat.LogWithFormat("found_files", LogCat.LogLabel.Default, LogCat.UploadFormat, 0);
return; return;
} }
LogCat.LogWithFormat("found_files", LogCat.LogLabel.Default, files.Length); LogCat.LogWithFormat("found_files", LogCat.LogLabel.Default, LogCat.UploadFormat, files.Length);
//将文件解析为项目类型信息 //将文件解析为项目类型信息
//parse files to item type infos //parse files to item type infos
var count = 0; var count = 0;
@ -68,7 +69,7 @@ public static class ItemTypeRegister
count++; count++;
} }
LogCat.LogWithFormat("found_item_types", LogCat.LogLabel.Default, count); LogCat.LogWithFormat("found_item_types", LogCat.LogLabel.Default, LogCat.UploadFormat, count);
} }
/// <summary> /// <summary>
@ -102,10 +103,24 @@ public static class ItemTypeRegister
//加载场景和图标 //加载场景和图标
var scene = ResourceLoader.Load<PackedScene>(typeInfo.ScenePath); var scene = ResourceLoader.Load<PackedScene>(typeInfo.ScenePath);
var icon = ResourceLoader.Load<Texture2D>(typeInfo.IconPath); var icon = ResourceLoader.Load<Texture2D>(typeInfo.IconPath);
//Create init delegate
//创建初始化委托
Action<Node?>? setArgs = null;
if (typeInfo.CustomArgs != null && typeInfo.CustomArgs.Count > 0)
{
foreach (var arg in typeInfo.CustomArgs)
{
setArgs +=
node => node?.SetDeferred(arg.Name, arg.ParseValue());
}
}
//构造项目类型,寄存器 //构造项目类型,寄存器
//construct item type, register //construct item type, register
var itemType = new ItemType(typeInfo.Id, var itemType = new ItemType(typeInfo.Id,
icon, typeInfo.MaxStackValue, defaultParentNode => defaultParentNode =>
{ {
var newItem = NodeUtils.InstantiatePackedScene<IItem>(scene); var newItem = NodeUtils.InstantiatePackedScene<IItem>(scene);
if (newItem is not Node node) return newItem; if (newItem is not Node node) return newItem;
@ -115,12 +130,13 @@ public static class ItemTypeRegister
return null; return null;
} }
newItem.Id = typeInfo.Id; setArgs?.Invoke(node);
NodeUtils.CallDeferredAddChild(NodeUtils.FindContainerNode(node, defaultParentNode), node); NodeUtils.CallDeferredAddChild(NodeUtils.FindContainerNode(node, defaultParentNode), node);
return newItem; return newItem;
}); },
icon, typeInfo.MaxStackValue);
var succeed = ItemTypeManager.Register(itemType); var succeed = ItemTypeManager.Register(itemType);
LogCat.LogWithFormat("register_item", label: LogCat.LogLabel.Default, itemType.Id, LogCat.LogWithFormat("register_item", label: LogCat.LogLabel.Default, LogCat.UploadFormat, itemType.Id,
succeed); succeed);
} }
@ -130,5 +146,44 @@ public static class ItemTypeRegister
string Id, string Id,
string ScenePath, string ScenePath,
string IconPath, string IconPath,
int MaxStackValue); int MaxStackValue,
IList<CustomArg>? CustomArgs);
private readonly record struct CustomArg(string Name, CustomArgType Type, string Value)
{
public Variant ParseValue() =>
Type switch
{
CustomArgType.String => Value,
CustomArgType.Int => int.Parse(Value),
CustomArgType.Float => double.Parse(Value),
CustomArgType.Vector2 => ParseVector2FromString(Value),
CustomArgType.Bool => bool.Parse(Value),
CustomArgType.Texture => ResourceLoader.Load<Texture2D>("res://sprites/" + Value),
_ => throw new ArgumentOutOfRangeException($"Unknown Arg Type {Type}")
};
private Vector2 ParseVector2FromString(string s)
{
var ss = s.Split(',');
if (ss.Length != 2)
{
LogCat.LogErrorWithFormat("wrong_custom_arg", LogCat.LogLabel.Default, LogCat.UploadFormat, "Vector2",
s);
return Vector2.Zero;
}
return new Vector2(float.Parse(ss[0]), float.Parse(ss[1]));
}
}
private enum CustomArgType
{
String,
Int,
Float,
Vector2,
Texture,
Bool,
}
} }

View File

@ -1,4 +1,4 @@
using ColdMint.scripts.pickable; using ColdMint.scripts.pickable;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;
using Godot; using Godot;
using PacksackUi = ColdMint.scripts.loader.uiLoader.PacksackUi; using PacksackUi = ColdMint.scripts.loader.uiLoader.PacksackUi;
@ -11,59 +11,66 @@ namespace ColdMint.scripts.inventory;
/// </summary> /// </summary>
public partial class Packsack : PickAbleTemplate public partial class Packsack : PickAbleTemplate
{ {
private const string Path = "res://prefab/ui/packsackUI.tscn"; private PackedScene? _packedScene;
private PacksackUi? _packsackUi;
public override int ItemType
{
get => Config.ItemType.Packsack;
}
[Export] public int NumberSlots { get; set; } [Export] public int NumberSlots { get; set; }
public override bool Use(Node2D? owner, Vector2 targetGlobalPosition)
{
if (GameSceneDepend.DynamicUiGroup == null)
{
return false;
}
return GameSceneDepend.DynamicUiGroup.ShowControl(Path, control =>
{
if (control is PacksackUi packsackUi)
{
packsackUi.Title = Name;
packsackUi.ItemContainer = SelfItemContainer;
}
});
}
protected override void OnSelectChange(bool isSelected) /// <summary>
/// <para>Whether to allow backpacks</para>
/// <para>是否允许放置背包</para>
/// </summary>
/// <remarks>
///<para>Can a new backpack be placed in the slot of the backpack?</para>
///<para>即此背包的槽位内是否可以再放置新的背包?</para>
/// </remarks>
[Export] public bool BackpackAllowed { get; set; }
public override bool CanPutInPack => false;
public override void Use(Node2D? owner, Vector2 targetGlobalPosition)
{ {
if (isSelected) if (_packedScene == null)
{ {
return; return;
} }
GameSceneDepend.DynamicUiGroup?.HideControl(Path);
}
public override void OnThrow(Vector2 velocity) if (_packsackUi == null)
{
GameSceneDepend.DynamicUiGroup?.HideControl(Path);
}
public override void LoadResource()
{
base.LoadResource();
if (SelfItemContainer == null)
{ {
var universalItemContainer = new UniversalItemContainer(NumberSlots); _packsackUi = NodeUtils.InstantiatePackedScene<PacksackUi>(_packedScene);
universalItemContainer.AllowItemTypesExceptPlaceholder(); if (_packsackUi != null)
universalItemContainer.DisallowAddingItemByType(Config.ItemType.Packsack); {
SelfItemContainer = universalItemContainer; NodeUtils.CallDeferredAddChild(NodeUtils.FindContainerNode(_packsackUi, this), _packsackUi);
SelfItemContainer.SupportSelect = false; _packsackUi.Title = Name;
_packsackUi.ItemContainer = ItemContainer;
}
} }
GameSceneDepend.DynamicUiGroup?.RegisterControl(Path, () =>
GameSceneNodeHolder.BackpackUiContainer?.Show();
_packsackUi?.Show();
}
public IItemContainer? ItemContainer { get; private set; }
public override void _Ready()
{
base._Ready();
ItemContainer = new UniversalItemContainer();
ItemContainer.SupportSelect = false;
//When the backpack is created, the item slot is generated.
//当背包被创建时,物品槽就被生成出来了。
for (var i = 0; i < NumberSlots; i++)
{ {
var packedScene = ResourceLoader.Load<PackedScene>(Path); var itemSlotNode = ItemContainer.AddItemSlot(this);
return NodeUtils.InstantiatePackedScene<PacksackUi>(packedScene); if (itemSlotNode == null)
}); {
continue;
}
itemSlotNode.BackpackAllowed = BackpackAllowed;
itemSlotNode.Hide();
}
_packedScene = GD.Load<PackedScene>("res://prefab/ui/packsackUI.tscn");
} }
} }

View File

@ -1,61 +0,0 @@
using Godot;
namespace ColdMint.scripts.inventory;
/// <summary>
/// <para>PlaceholderItem</para>
/// <para>占位物品</para>
/// </summary>
public class PlaceholderItem : IItem
{
public int Index { get; set; }
public string Id { get; set; }
public void ShowSelf()
{
}
public void QueueFreeSelf()
{
}
public void HideSelf()
{
}
public Texture2D Icon { get; }
public string Name { get; }
public string? Description { get; } = null;
public int Quantity { get; set; } = 1;
public int MaxQuantity { get; } = 1;
public int ItemType
{
get => Config.ItemType.Placeholder;
}
public bool IsSelect { get; set; }
public bool CanContainItems { get; set; } = false;
public IItemContainer? ItemContainer { get; set; }
public IItemContainer? SelfItemContainer { get; set; }
public int MergeableItemCount(IItem other, int unallocatedQuantity)
{
return 0;
}
public IItem? CreateItem(int number)
{
return null;
}
public bool Use(Node2D? owner, Vector2 targetGlobalPosition)
{
return false;
}
public void OnThrow(Vector2 velocity)
{
}
}

View File

@ -1,40 +0,0 @@
using ColdMint.scripts.character;
using ColdMint.scripts.damage;
using ColdMint.scripts.weapon;
using Godot;
namespace ColdMint.scripts.inventory;
/// <summary>
/// <para>ResignationCertificate</para>
/// <para>离职证明</para>
/// </summary>
public partial class ResignationCertificate : WeaponTemplate
{
private readonly Damage _damage = new()
{
MaxDamage = 1,
MinDamage = 1,
Type = Config.DamageType.Magic
};
public override void LoadResource()
{
base.LoadResource();
_damage.CreateDamage();
_damage.Attacker = this;
}
public override int ItemType
{
get => Config.ItemType.Item;
}
protected override bool DoFire(Node2D? owner, Vector2 enemyGlobalPosition)
{
if (Owner is CharacterTemplate characterTemplate)
{
return characterTemplate.Damage(_damage);
}
return false;
}
}

View File

@ -1,7 +1,11 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Linq;
using ColdMint.scripts.map.events; using ColdMint.scripts.map.events;
using ColdMint.scripts.utils;
using Godot;
using JetBrains.Annotations;
namespace ColdMint.scripts.inventory; namespace ColdMint.scripts.inventory;
@ -9,9 +13,11 @@ namespace ColdMint.scripts.inventory;
/// <para>UniversalItemContainer</para> /// <para>UniversalItemContainer</para>
/// <para>通用的物品容器</para> /// <para>通用的物品容器</para>
/// </summary> /// </summary>
public class UniversalItemContainer(int totalCapacity) : IItemContainer public class UniversalItemContainer : IItemContainer
{ {
private readonly Dictionary<int, IItem> _itemDictionary = []; private readonly List<ItemSlotNode>? _itemSlotNodes = [];
private readonly PackedScene? _itemSlotPackedScene = GD.Load<PackedScene>("res://prefab/ui/ItemSlot.tscn");
/// <summary> /// <summary>
/// <para>UnknownIndex</para> /// <para>UnknownIndex</para>
@ -19,401 +25,167 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
/// </summary> /// </summary>
private const int UnknownIndex = -1; private const int UnknownIndex = -1;
//_selectIndex defaults to 0.
//_selectIndex默认为0. //_selectIndex默认为0.
private int _selectIndex; private int _selectIndex;
/// <summary> [MustDisposeResource]
/// <para>The type of item that can be added to the item container</para> public IEnumerator<ItemSlotNode> GetEnumerator()
/// <para>物品容器允许添加的物品类型</para>
/// </summary>
private readonly HashSet<int> _allowedItemTypes = new();
public Action<SelectedItemChangeEvent>? SelectedItemChangeEvent { get; set; }
public Action<ItemDataChangeEvent>? ItemDataChangeEvent { get; set; }
/// <summary>
/// <para>Allow Item Types Except Placeholder</para>
/// <para>允许添加除占位符以外的所有物品类型</para>
/// </summary>
public void AllowItemTypesExceptPlaceholder()
{ {
var itemTypeType = typeof(Config.ItemType); return _itemSlotNodes?.GetEnumerator() ?? Enumerable.Empty<ItemSlotNode>().GetEnumerator();
//Get all fields
//获取所有字段
var fields = itemTypeType.GetFields(BindingFlags.Public | BindingFlags.Static);
//Traversal field
//遍历字段
foreach (var field in fields)
{
//Gets the value of the field
//获取字段的值
var value = field.GetValue(null);
if (value == null)
{
continue;
}
var intValue = (int)value;
if (intValue == Config.ItemType.Placeholder)
{
continue;
}
_allowedItemTypes.Add(intValue);
}
} }
public void AllowAddingItemByType(int itemType) [MustDisposeResource]
IEnumerator IEnumerable.GetEnumerator()
{ {
_allowedItemTypes.Add(itemType); return GetEnumerator();
} }
public void DisallowAddingItemByType(int itemType) public Action<SelectedItemSlotChangeEvent>? SelectedItemSlotChangeEvent { get; set; }
{
_allowedItemTypes.Remove(itemType);
}
public bool CanAddItem(IItem item) public bool CanAddItem(IItem item)
{ {
if (!_allowedItemTypes.Contains(item.ItemType)) return Match(item) != null;
}
public bool AddItem(IItem item)
{
var itemSlotNode = Match(item);
if (itemSlotNode == null)
{ {
return false; return false;
} }
//If the capacity is not full, directly return to add items
//如果未占满容量,直接返回可添加物品
if (GetUsedCapacity() < totalCapacity)
{
return true;
}
if (item.MaxQuantity == 1) return itemSlotNode.AddItem(item);
{
//New items do not support overlay, capacity is full, return cannot add.
//新物品不支持叠加,容量已满,返回不能添加。
return false;
}
//If the capacity is full, we calculate whether we can spread the new items evenly among the existing items.
//如果容量占满了,我们计算是否能将新物品均摊在已有的物品内。
var unallocatedQuantity = item.Quantity;
foreach (var unitItem in _itemDictionary.Values)
{
var number = unitItem.MergeableItemCount(item, unallocatedQuantity);
if (number == 0)
{
continue;
}
unallocatedQuantity -= number;
if (unallocatedQuantity < 1)
{
return true;
}
}
return unallocatedQuantity < 1;
}
private void UpdateSelectStatus(int index, IItem item)
{
item.IsSelect = index == _selectIndex;
}
/// <summary>
/// <para>Update the next available index location</para>
/// <para>更新下个可用的索引位置</para>
/// </summary>
/// <remarks>
///<para>For example, the variable [1,2,3,5,6] represents 4, or the variable [1,2,3,4,5,6,7] represents 8.</para>
///<para>例如[1,2,3,5,6]这个变量表示4再或者[1,2,3,4,5,6,7]这个变量表示8。</para>
/// </remarks>
/// <returns>
///<para>The next available index is returned after obtaining failure<see cref="UnknownIndex"/></para>
///<para>下次可用的索引,获取失败返回<see cref="UnknownIndex"/></para>
/// </returns>
private int GetNextAvailableIndex()
{
if (totalCapacity <= 0)
{
return UnknownIndex;
}
for (var i = 0; i < totalCapacity; i++)
{
var contains = _itemDictionary.ContainsKey(i);
if (!contains)
{
return i;
}
}
return UnknownIndex;
}
public int AddItem(IItem item)
{
var nextAvailableIndex = GetNextAvailableIndex();
if (item.MaxQuantity == 1)
{
if (nextAvailableIndex == UnknownIndex)
{
return 0;
}
_itemDictionary[nextAvailableIndex] = item;
item.Index = nextAvailableIndex;
item.ItemContainer = this;
if (nextAvailableIndex != _selectIndex)
{
item.HideSelf();
}
UpdateSelectStatus(nextAvailableIndex, item);
ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent
{
NewItem = item,
NewIndex = nextAvailableIndex,
Type = Config.ItemDataChangeEventType.Add
});
return item.Quantity;
}
//There can be more than one item, try to share equally.
//物品可有多个,尝试均摊。
var originalQuantity = item.Quantity;
var temporarilyQuantity = item.Quantity;
var index = 0;
foreach (var unitItem in _itemDictionary.Values)
{
var number = unitItem.MergeableItemCount(item, temporarilyQuantity);
if (number == 0)
{
continue;
}
temporarilyQuantity -= number;
unitItem.Quantity += number;
ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent
{
NewItem = unitItem,
NewIndex = index,
Type = Config.ItemDataChangeEventType.QuantityAdded
});
if (item.Quantity < 1)
{
//New items are fully shared.
//新物品完全被均摊。
item.HideSelf();
return originalQuantity;
}
index++;
}
//New items have some left over.
//新物品有一些剩余。
if (GetUsedCapacity() >= totalCapacity)
{
//The capacity is full. The remaining capacity cannot be stored.
//容量已满,无法存放剩余。
return originalQuantity - temporarilyQuantity;
}
//Add the rest to the container.
//添加剩余到容器内。
if (nextAvailableIndex == UnknownIndex)
{
return 0;
}
_itemDictionary[nextAvailableIndex] = item;
item.Index = nextAvailableIndex;
item.ItemContainer = this;
if (nextAvailableIndex != _selectIndex)
{
item.HideSelf();
}
UpdateSelectStatus(nextAvailableIndex, item);
ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent
{
NewItem = item,
NewIndex = nextAvailableIndex,
Type = Config.ItemDataChangeEventType.Add
});
return originalQuantity;
} }
public bool SupportSelect { get; set; } public bool SupportSelect { get; set; }
public IItem GetPlaceHolderItem(int index)
{
var placeholderItem = new PlaceholderItem
{
Index = index,
ItemContainer = this
};
return placeholderItem;
}
public int GetSelectIndex() public int GetSelectIndex()
{ {
return _selectIndex; return _selectIndex;
} }
public IItem? GetSelectItem() public ItemSlotNode? GetSelectItemSlotNode()
{ {
return _itemDictionary.TryGetValue(_selectIndex, out var item) ? item : null; if (_itemSlotNodes == null || _itemSlotNodes.Count == 0)
}
public IItem? GetItem(int index)
{
return _itemDictionary.TryGetValue(index, out var item) ? item : null;
}
public bool ReplaceItem(int index, IItem item)
{
var oldItem = GetItem(index);
_itemDictionary[index] = item;
item.Index = index;
item.ItemContainer = this;
ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent
{
NewItem = item,
NewIndex = index,
OldIndex = index,
OldItem = oldItem,
Type = Config.ItemDataChangeEventType.Replace
});
if (SupportSelect && index == _selectIndex)
{
oldItem?.HideSelf();
item.ShowSelf();
SelectedItemChangeEvent?.Invoke(new SelectedItemChangeEvent
{
NewIndex = index,
OldIndex = index,
NewItem = item,
OldItem = oldItem
});
}
return true;
}
public bool CanReplaceItem(int index, IItem item)
{
if (!_allowedItemTypes.Contains(item.ItemType))
{
return false;
}
return true;
}
public IItem? ClearItem(int index)
{
if (!_itemDictionary.TryGetValue(index, out var item))
{ {
return null; return null;
} }
if (!_itemDictionary.Remove(index))
if (_selectIndex < _itemSlotNodes.Count)
{ {
return null; //Prevent subscripts from going out of bounds.
//防止下标越界。
return _itemSlotNodes[_selectIndex];
} }
ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent
{ return null;
NewItem = null,
NewIndex = index,
OldIndex = index,
OldItem = null,
Type = Config.ItemDataChangeEventType.Clear
});
if (SupportSelect && index == _selectIndex)
{
item.HideSelf();
SelectedItemChangeEvent?.Invoke(new SelectedItemChangeEvent
{
NewIndex = index,
OldIndex = index,
NewItem = null,
OldItem = null
});
}
return item;
} }
public void ClearAllItems() public int RemoveItemFromItemSlotBySelectIndex(int number) => RemoveItemFromItemSlot(_selectIndex, number);
{
foreach (var itemDictionaryKey in _itemDictionary.Keys)
{
var item = ClearItem(itemDictionaryKey);
if (item == null)
{
continue;
}
item.SelfItemContainer?.ClearAllItems();
item.QueueFreeSelf();
}
}
public int GetItemSlotCount()
public int RemoveSelectItem(int number)
{ {
return RemoveItem(_selectIndex, number); if (_itemSlotNodes == null)
}
public int RemoveItem(int itemIndex, int number)
{
if (number == 0)
{ {
return 0; return 0;
} }
if (!_itemDictionary.TryGetValue(itemIndex, out var item)) return _itemSlotNodes.Count;
{
return 0;
}
var originalQuantity = item.Quantity;
if (number < 0)
{
//If the number entered is less than 0, all items are removed.
//输入的数量小于0,则移除全部物品。
item.Quantity = 0;
_itemDictionary.Remove(itemIndex);
ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent
{
NewItem = item,
NewIndex = itemIndex,
Type = Config.ItemDataChangeEventType.Remove
});
return originalQuantity;
}
var removed = Math.Min(number, item.Quantity);
item.Quantity -= removed;
if (item.Quantity < 1)
{
_itemDictionary.Remove(itemIndex);
ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent
{
NewItem = item,
NewIndex = itemIndex,
Type = Config.ItemDataChangeEventType.Remove
});
}
return removed;
} }
public int GetUsedCapacity() public ItemSlotNode? GetItemSlotNode(int index)
{ {
return _itemDictionary.Count; if (_itemSlotNodes == null)
{
return null;
}
var safeIndex = GetSafeIndex(index);
return _itemSlotNodes[safeIndex];
} }
public int GetTotalCapacity() public int RemoveItemFromItemSlot(int itemSlotIndex, int number)
{ {
return totalCapacity; if (_itemSlotNodes == null) return number;
var safeIndex = GetSafeIndex(itemSlotIndex);
if (safeIndex == UnknownIndex)
{
return number;
}
var itemSlot = _itemSlotNodes[safeIndex];
return itemSlot.RemoveItem(number);
} }
/// <summary>
public void SelectNextItem() /// <para>Gets a secure subscript index</para>
/// <para>获取安全的下标索引</para>
/// </summary>
/// <param name="itemSlotIndex"></param>
/// <returns>
/// <para>-1 is returned on failure, and the index that does not result in an out-of-bounds subscript is returned on success</para>
/// <para>失败返回-1成功返回不会导致下标越界的索引</para>
/// </returns>
private int GetSafeIndex(int itemSlotIndex)
{ {
var count = totalCapacity; if (_itemSlotNodes == null)
{
return UnknownIndex;
}
var count = _itemSlotNodes.Count;
if (count == 0)
{
//Prevents the dividend from being 0
//防止被除数为0
return UnknownIndex;
}
return itemSlotIndex % count;
}
public ItemSlotNode? Match(IItem item)
{
//Find and return the first slot that can hold this item, if the list is null or not found, return null
//寻找并返回第一个遇到的可放置此物品的物品槽若列表为空或不存在将返回null
return _itemSlotNodes?.FirstOrDefault(itemSlotNode => itemSlotNode.CanAddItem(item));
}
public ItemSlotNode? AddItemSlot(Node rootNode)
{
if (_itemSlotNodes == null || _itemSlotPackedScene == null)
{
return null;
}
var itemSlotNode = NodeUtils.InstantiatePackedScene<ItemSlotNode>(_itemSlotPackedScene);
if (itemSlotNode == null)
{
return null;
}
NodeUtils.CallDeferredAddChild(rootNode, itemSlotNode);
if (SupportSelect)
{
itemSlotNode.IsSelect = _itemSlotNodes.Count == _selectIndex;
}
else
{
itemSlotNode.IsSelect = false;
}
_itemSlotNodes.Add(itemSlotNode);
return itemSlotNode;
}
public void SelectTheNextItemSlot()
{
if (_itemSlotNodes == null)
{
return;
}
var count = _itemSlotNodes.Count;
if (count == 0) if (count == 0)
{ {
return; return;
@ -426,12 +198,17 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
newSelectIndex = 0; newSelectIndex = 0;
} }
PrivateSelectItem(oldSelectIndex, newSelectIndex); PrivateSelectItemSlot(oldSelectIndex, newSelectIndex);
} }
public void SelectPreviousItem() public void SelectThePreviousItemSlot()
{ {
var count = totalCapacity; if (_itemSlotNodes == null)
{
return;
}
var count = _itemSlotNodes.Count;
if (count == 0) if (count == 0)
{ {
return; return;
@ -444,57 +221,77 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
newSelectIndex = count - 1; newSelectIndex = count - 1;
} }
PrivateSelectItem(oldSelectIndex, newSelectIndex); PrivateSelectItemSlot(oldSelectIndex, newSelectIndex);
} }
/// <summary> /// <summary>
/// <para>Private methods for selecting items</para> /// <para>Select an item slot</para>
/// <para>选择物品的私有方法</para> /// <para>选中某个物品槽</para>
/// </summary> /// </summary>
/// <param name="oldIndex"></param> private void PrivateSelectItemSlot(int oldSelectIndex, int newSelectIndex)
/// <param name="newIndex"></param>
private void PrivateSelectItem(int oldIndex, int newIndex)
{ {
if (!SupportSelect || oldIndex == newIndex) if (!SupportSelect || _itemSlotNodes == null || oldSelectIndex == newSelectIndex)
{ {
return; return;
} }
//There is no need to broadcast placeholders when an event is invoked. var oldItemSlotNode = _itemSlotNodes[oldSelectIndex];
//在调用事件时,无需广播占位符。 oldItemSlotNode.IsSelect = false;
var oldItem = GetItem(oldIndex); var newItemSlotNode = _itemSlotNodes[newSelectIndex];
if (oldItem != null) newItemSlotNode.IsSelect = true;
HideItem(oldSelectIndex);
DisplayItem(newSelectIndex);
SelectedItemSlotChangeEvent?.Invoke(new SelectedItemSlotChangeEvent
{ {
oldItem.HideSelf(); NewItemSlotNode = newItemSlotNode,
oldItem.IsSelect = false; OldItemSlotNode = oldItemSlotNode
}
//There is no need to broadcast placeholders when an event is invoked.
//在调用事件时,无需广播占位符。
var newItem = GetItem(newIndex);
if (newItem != null)
{
newItem.ShowSelf();
newItem.IsSelect = true;
}
_selectIndex = newIndex;
SelectedItemChangeEvent?.Invoke(new SelectedItemChangeEvent
{
NewIndex = newIndex,
OldIndex = oldIndex,
NewItem = newItem,
OldItem = oldItem
}); });
_selectIndex = newSelectIndex;
} }
/// <summary>
public void SelectItem(int index) /// <para>HideItem</para>
/// <para>隐藏某个物品</para>
/// </summary>
/// <param name="index"></param>
private void HideItem(int index)
{ {
if (totalCapacity == 0 || index < 0) var oldItem = _itemSlotNodes?[index].GetItem();
if (oldItem is not Node2D oldNode2D) return;
oldNode2D.ProcessMode = Node.ProcessModeEnum.Disabled;
oldNode2D.Hide();
}
/// <summary>
/// <para>Displays the items in an item slot</para>
/// <para>显示某个物品槽内的物品</para>
/// </summary>
/// <remarks>
///<para>This method can also be used to refresh items held by the character, for example when a new item is dragged to the current display location, then call this method to refresh items held by the character.</para>
///<para>此方法也可用于刷新角色手上持有的物品,例如当新的物品被拖动到当前显示位置,那么请调用此方法刷新角色持有的物品。</para>
/// </remarks>
/// <param name="index"></param>
private void DisplayItem(int index)
{
var item = _itemSlotNodes?[index].GetItem();
if (item is not Node2D newNode2D) return;
newNode2D.ProcessMode = Node.ProcessModeEnum.Inherit;
newNode2D.Show();
}
public void SelectItemSlot(int newSelectIndex)
{
if (newSelectIndex == _selectIndex)
{ {
return; return;
} }
PrivateSelectItem(_selectIndex, index % totalCapacity);
var safeIndex = GetSafeIndex(newSelectIndex);
if (safeIndex == UnknownIndex)
{
return;
}
PrivateSelectItemSlot(_selectIndex, newSelectIndex);
} }
} }

View File

@ -1,10 +1,8 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using ColdMint.scripts.inventory; using ColdMint.scripts.inventory;
using ColdMint.scripts.map; using ColdMint.scripts.map;
using ColdMint.scripts.map.events;
using ColdMint.scripts.map.LayoutParsingStrategy; using ColdMint.scripts.map.LayoutParsingStrategy;
using ColdMint.scripts.map.layoutStrategy; using ColdMint.scripts.map.layoutStrategy;
using ColdMint.scripts.map.miniMap;
using ColdMint.scripts.map.RoomPlacer; using ColdMint.scripts.map.RoomPlacer;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;
using Godot; using Godot;
@ -21,55 +19,42 @@ public partial class GameSceneLoader : SceneLoaderTemplate
public override Task InitializeData() public override Task InitializeData()
{ {
RenderingServer.SetDefaultClearColor(Color.FromHsv(0, 0, 0));
//Loading the blood bar scene //Loading the blood bar scene
//加载血条场景 //加载血条场景
var healthBarUi = GetNode<HealthBarUi>("CanvasLayer/Control/VBoxContainer/HealthBarUi"); var healthBarUi = GetNode<HealthBarUi>("CanvasLayer/Control/VBoxContainer/HealthBarUi");
GameSceneDepend.HealthBarUi = healthBarUi; GameSceneNodeHolder.HealthBarUi = healthBarUi;
//Load HotBar //Load HotBar
//加载HotBar //加载HotBar
var hotBar = GetNode<HotBar>("CanvasLayer/Control/VBoxContainer/HotBar"); var hotBar = GetNode<HotBar>("CanvasLayer/Control/VBoxContainer/HotBar");
GameSceneDepend.HotBar = hotBar; GameSceneNodeHolder.HotBar = hotBar;
//Backpack Ui container //Backpack Ui container
//背包Ui容器 //背包Ui容器
var backpackUiContainer = GetNode<UiGroup>("CanvasLayer/DynamicUiGroup"); var backpackUiContainer = GetNode<Control>("CanvasLayer/BackpackUIContainer");
GameSceneDepend.DynamicUiGroup = backpackUiContainer; GameSceneNodeHolder.BackpackUiContainer = backpackUiContainer;
//Load operation prompt
//加载操作提示
var operationTip = GetNode<RichTextLabel>("CanvasLayer/Control/VBoxContainer/OperationTip");
GameSceneNodeHolder.OperationTipLabel = operationTip;
//Loaded weapon container //Loaded weapon container
//加载武器容器 //加载武器容器
var weaponContainer = GetNode<Node2D>("WeaponContainer"); var weaponContainer = GetNode<Node2D>("WeaponContainer");
GameSceneDepend.WeaponContainer = weaponContainer; GameSceneNodeHolder.WeaponContainer = weaponContainer;
//Load projectile container //Load projectile container
//加载抛射体容器 //加载抛射体容器
var projectileContainer = GetNode<Node2D>("ProjectileContainer"); var projectileContainer = GetNode<Node2D>("ProjectileContainer");
GameSceneDepend.ProjectileContainer = projectileContainer; GameSceneNodeHolder.ProjectileContainer = projectileContainer;
//Load magic container
//加载魔术容器
var magicContainer = GetNode<Node2D>("SpellContainer");
GameSceneDepend.SpellContainer = magicContainer;
//Load Packsack container //Load Packsack container
//加载背包容器 //加载背包容器
var packsackContainer = GetNode<Node2D>("PacksackContainer"); var packsackContainer = GetNode<Node2D>("PacksackContainer");
GameSceneDepend.PacksackContainer = packsackContainer; GameSceneNodeHolder.PacksackContainer = packsackContainer;
//Load AICharacter container //Load AICharacter container
//加载AICharacter容器 //加载AICharacter容器
var aiCharacterContainer = GetNode<Node2D>("AICharacterContainer"); var aiCharacterContainer = GetNode<Node2D>("AICharacterContainer");
GameSceneDepend.AiCharacterContainer = aiCharacterContainer; GameSceneNodeHolder.AiCharacterContainer = aiCharacterContainer;
//Load player container //Load player container
//加载玩家容器 //加载玩家容器
var playerContainer = GetNode<Node2D>("PlayerContainer"); var playerContainer = GetNode<Node2D>("PlayerContainer");
GameSceneDepend.PlayerContainer = playerContainer; GameSceneNodeHolder.PlayerContainer = playerContainer;
//Load the pickable container
//加载可拾捡物容器
var pickAbleContainer = GetNode<Node2D>("PickAbleContainer");
GameSceneDepend.PickAbleContainer = pickAbleContainer;
//Setting up the mini map
//设置迷你地图
var miniMap = GetNode<MiniMap>("CanvasLayer/Control/MapContainer/Control/MiniMap");
GameSceneDepend.MiniMap = miniMap;
//Set the mini map animation
//设置迷你地图动画
var miniMapAnimationPlayer = GetNode<AnimationPlayer>("CanvasLayer/Control/MapContainer/MiniMapAnimationPlayer");
GameSceneDepend.MiniMapAnimationPlayer = miniMapAnimationPlayer;
return Task.CompletedTask; return Task.CompletedTask;
} }
@ -93,34 +78,9 @@ public partial class GameSceneLoader : SceneLoaderTemplate
MapGenerator.LayoutStrategy = new TestLayoutStrategy(); MapGenerator.LayoutStrategy = new TestLayoutStrategy();
MapGenerator.LayoutParsingStrategy = new SequenceLayoutParsingStrategy(); MapGenerator.LayoutParsingStrategy = new SequenceLayoutParsingStrategy();
MapGenerator.RoomPlacementStrategy = new PatchworkRoomPlacementStrategy(); MapGenerator.RoomPlacementStrategy = new PatchworkRoomPlacementStrategy();
EventBus.GameOverEvent += OnGameOverEvent;
await GenerateMap(); await GenerateMap();
} }
private async void OnGameOverEvent(GameOverEvent gameOverEvent)
{
if (GameSceneDepend.WeaponContainer != null)
{
NodeUtils.DeleteAllChild(GameSceneDepend.WeaponContainer);
}
if (GameSceneDepend.PacksackContainer != null)
{
NodeUtils.DeleteAllChild(GameSceneDepend.PacksackContainer);
}
if (GameSceneDepend.SpellContainer != null)
{
NodeUtils.DeleteAllChild(GameSceneDepend.SpellContainer);
}
await GenerateMap();
var replayEvent = new GameReplayEvent();
EventBus.GameReplayEvent?.Invoke(replayEvent);
}
public override void _ExitTree()
{
EventBus.GameOverEvent -= OnGameOverEvent;
}
/// <summary> /// <summary>
/// <para>Generate map</para> /// <para>Generate map</para>
/// <para>生成地图</para> /// <para>生成地图</para>
@ -135,7 +95,6 @@ public partial class GameSceneLoader : SceneLoaderTemplate
var seedInfo = TranslationServerUtils.TranslateWithFormat("ui_seed_info", MapGenerator.Seed); var seedInfo = TranslationServerUtils.TranslateWithFormat("ui_seed_info", MapGenerator.Seed);
_seedLabel.Text = seedInfo ?? $"Seed: {MapGenerator.Seed}"; _seedLabel.Text = seedInfo ?? $"Seed: {MapGenerator.Seed}";
} }
await MapGenerator.GenerateMap(); await MapGenerator.GenerateMap();
} }
} }

Some files were not shown because too many files have changed in this diff Show More