Level graphs migrated to yaml.

关卡图迁移到yaml。
This commit is contained in:
Cold-Mint 2024-06-16 22:44:50 +08:00
parent 7f55bd7d53
commit 8391396191
Signed by: Cold-Mint
GPG Key ID: C5A9BF8A98E0CE99
26 changed files with 195 additions and 171 deletions

View File

@ -13,4 +13,4 @@
value: 1000 value: 1000
- name: UniqueName - name: UniqueName
type: string type: string
value: 劣化的死灵法杖 value: item_staff_of_the_undead_desc

View File

@ -1,88 +0,0 @@
{
"ConnectionDataList": [
{
"FromId": "c0255eb6-2c75-44f7-9058-0921fe8fb0d8",
"ToId": "4ae948ea-82b7-4b2d-bec2-19ed8a9d4c03",
"FromPort": 0,
"ToPort": 0
},
{
"FromId": "4ae948ea-82b7-4b2d-bec2-19ed8a9d4c03",
"ToId": "ba32e05c-0c80-4a79-b5ce-5b8150400e05",
"FromPort": 0,
"ToPort": 0
},
{
"FromId": "4ae948ea-82b7-4b2d-bec2-19ed8a9d4c03",
"ToId": "8b3d645a-96c0-407e-871d-6f4a0b69557b",
"FromPort": 0,
"ToPort": 0
},
{
"FromId": "8b3d645a-96c0-407e-871d-6f4a0b69557b",
"ToId": "7e3ae680-3d7e-4ae9-b82f-5bfbe1c2f613",
"FromPort": 0,
"ToPort": 0
},
{
"FromId": "ba32e05c-0c80-4a79-b5ce-5b8150400e05",
"ToId": "7e3ae680-3d7e-4ae9-b82f-5bfbe1c2f613",
"FromPort": 0,
"ToPort": 0
}
],
"RoomNodeDataList": [
{
"Id": "c0255eb6-2c75-44f7-9058-0921fe8fb0d8",
"Title": "起点房间",
"Description": "测试的起点房间。",
"RoomTemplateSet": [
"res://prefab/roomTemplates/dungeon/initialRoom.tscn"
],
"Tags": [
"StartingRoom"
],
"RoomInjectionProcessorData": null
},
{
"Id": "ba32e05c-0c80-4a79-b5ce-5b8150400e05",
"Title": "房间3",
"Description": "",
"RoomTemplateSet": [
"res://prefab/roomTemplates/dungeon/"
],
"Tags": null,
"RoomInjectionProcessorData": "[\n {\n \"Id\": \"TimeInterval\",\n \"Config\": \"{\\\"DateSpecifiesLevel\\\":0,\\\"StartTime\\\":\\\"2024/1/1 20:34:23\\\",\\\"EndTime\\\":\\\"2025/1/1 20:34:23\\\"}\"\n }\n]"
},
{
"Id": "4ae948ea-82b7-4b2d-bec2-19ed8a9d4c03",
"Title": "大厅",
"Description": "比普通房间要大一些的房间,有多个门,用于连接到其他房间。",
"RoomTemplateSet": [
"res://prefab/roomTemplates/dungeon/utilityRoom.tscn"
],
"Tags": null,
"RoomInjectionProcessorData": null
},
{
"Id": "8b3d645a-96c0-407e-871d-6f4a0b69557b",
"Title": "房间4",
"Description": "",
"RoomTemplateSet": [
"res://prefab/roomTemplates/dungeon/"
],
"Tags": null,
"RoomInjectionProcessorData": ""
},
{
"Id": "7e3ae680-3d7e-4ae9-b82f-5bfbe1c2f613",
"Title": "房间5",
"Description": "",
"RoomTemplateSet": [
"res://prefab/roomTemplates/dungeon/"
],
"Tags": null,
"RoomInjectionProcessorData": ""
}
]
}

View File

@ -0,0 +1,57 @@
connection_data_list:
- from_id: c0255eb6-2c75-44f7-9058-0921fe8fb0d8
to_id: 4ae948ea-82b7-4b2d-bec2-19ed8a9d4c03
from_port: 0
to_port: 0
- from_id: 4ae948ea-82b7-4b2d-bec2-19ed8a9d4c03
to_id: ba32e05c-0c80-4a79-b5ce-5b8150400e05
from_port: 0
to_port: 0
- from_id: 4ae948ea-82b7-4b2d-bec2-19ed8a9d4c03
to_id: 8b3d645a-96c0-407e-871d-6f4a0b69557b
from_port: 0
to_port: 0
- from_id: 8b3d645a-96c0-407e-871d-6f4a0b69557b
to_id: 7e3ae680-3d7e-4ae9-b82f-5bfbe1c2f613
from_port: 0
to_port: 0
- from_id: ba32e05c-0c80-4a79-b5ce-5b8150400e05
to_id: 7e3ae680-3d7e-4ae9-b82f-5bfbe1c2f613
from_port: 0
to_port: 0
room_node_data_list:
- id: c0255eb6-2c75-44f7-9058-0921fe8fb0d8
title: 起点房间
description: 测试的起点房间。
room_template_set:
- 'res://prefab/roomTemplates/dungeon/initialRoom.tscn'
tags:
- StartingRoom
room_injection_processor_data: null
- id: ba32e05c-0c80-4a79-b5ce-5b8150400e05
title: 房间3
description: ''
room_template_set:
- 'res://prefab/roomTemplates/dungeon/'
tags: null
- id: 4ae948ea-82b7-4b2d-bec2-19ed8a9d4c03
title: 大厅
description: 比普通房间要大一些的房间,有多个门,用于连接到其他房间。
room_template_set:
- 'res://prefab/roomTemplates/dungeon/utilityRoom.tscn'
tags: null
room_injection_processor_data: null
- id: 8b3d645a-96c0-407e-871d-6f4a0b69557b
title: 房间4
description: ''
room_template_set:
- 'res://prefab/roomTemplates/dungeon/'
tags: null
room_injection_processor_data: ''
- id: 7e3ae680-3d7e-4ae9-b82f-5bfbe1c2f613
title: 房间5
description: ''
room_template_set:
- 'res://prefab/roomTemplates/dungeon/'
tags: null
room_injection_processor_data: ''

View File

@ -147,6 +147,7 @@ hotbar_previous={
[internationalization] [internationalization]
locale/translations=PackedStringArray("res://locals/DeathInfo.en.translation", "res://locals/DeathInfo.ja.translation", "res://locals/DeathInfo.zh.translation", "res://locals/InputMapping.en.translation", "res://locals/InputMapping.ja.translation", "res://locals/InputMapping.zh.translation", "res://locals/Log.en.translation", "res://locals/Log.ja.translation", "res://locals/Log.zh.translation", "res://locals/Slogan.en.translation", "res://locals/Slogan.ja.translation", "res://locals/Slogan.zh.translation", "res://locals/UI.en.translation", "res://locals/UI.ja.translation", "res://locals/UI.zh.translation", "res://locals/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") 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")
locale/test="ja"
[layer_names] [layer_names]

View File

@ -238,7 +238,7 @@ offset_top = 15.0
offset_right = 21.5 offset_right = 21.5
offset_bottom = 40.0 offset_bottom = 40.0
grow_horizontal = 2 grow_horizontal = 2
text = "save" text = "ui_save"
[node name="FileNameLineEdit" type="LineEdit" parent="SaveOrLoadPanel"] [node name="FileNameLineEdit" type="LineEdit" parent="SaveOrLoadPanel"]
layout_mode = 1 layout_mode = 1
@ -263,7 +263,7 @@ offset_top = -38.0
offset_right = 80.0 offset_right = 80.0
offset_bottom = -13.0 offset_bottom = -13.0
grow_vertical = 2 grow_vertical = 2
text = "filename" text = "ui_filename"
[node name="HBoxContainer" type="HBoxContainer" parent="SaveOrLoadPanel"] [node name="HBoxContainer" type="HBoxContainer" parent="SaveOrLoadPanel"]
layout_mode = 1 layout_mode = 1
@ -281,8 +281,8 @@ grow_vertical = 0
[node name="CancelButton" type="Button" parent="SaveOrLoadPanel/HBoxContainer"] [node name="CancelButton" type="Button" parent="SaveOrLoadPanel/HBoxContainer"]
layout_mode = 2 layout_mode = 2
text = "cancel" text = "ui_cancel"
[node name="ActionButton" type="Button" parent="SaveOrLoadPanel/HBoxContainer"] [node name="ActionButton" type="Button" parent="SaveOrLoadPanel/HBoxContainer"]
layout_mode = 2 layout_mode = 2
text = "save" text = "ui_save"

View File

@ -54,7 +54,6 @@ texture = ExtResource("2_n1yht")
[node name="OperationTip" type="RichTextLabel" parent="CanvasLayer/Control/VBoxContainer"] [node name="OperationTip" type="RichTextLabel" parent="CanvasLayer/Control/VBoxContainer"]
layout_mode = 2 layout_mode = 2
bbcode_enabled = true bbcode_enabled = true
text = "OperationTip"
fit_content = true fit_content = true
[node name="FPSLabel" type="Label" parent="CanvasLayer/Control"] [node name="FPSLabel" type="Label" parent="CanvasLayer/Control"]
@ -85,6 +84,7 @@ offset_bottom = 25.0
grow_horizontal = 2 grow_horizontal = 2
[node name="BackpackUIContainer" type="Control" parent="CanvasLayer"] [node name="BackpackUIContainer" type="Control" parent="CanvasLayer"]
visible = false
layout_mode = 3 layout_mode = 3
anchors_preset = 15 anchors_preset = 15
anchor_right = 1.0 anchor_right = 1.0

View File

@ -127,6 +127,7 @@ underline = 1
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer2"] [node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer2"]
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 8
[node name="GodotLabel" type="Label" parent="VBoxContainer2/HBoxContainer"] [node name="GodotLabel" type="Label" parent="VBoxContainer2/HBoxContainer"]
layout_mode = 2 layout_mode = 2

View File

@ -205,7 +205,7 @@ public partial class CharacterTemplate : CharacterBody2D
CharacterName = GetMeta("Name", Name).AsString(); CharacterName = GetMeta("Name", Name).AsString();
CampId = GetMeta("CampId", Config.CampId.Default).AsString(); CampId = GetMeta("CampId", Config.CampId.Default).AsString();
MaxHp = GetMeta("MaxHp", Config.DefaultMaxHp).AsInt32(); MaxHp = GetMeta("MaxHp", Config.DefaultMaxHp).AsInt32();
var lootListId = GetMeta("LootListId", string.Empty).AsString(); // var lootListId = GetMeta("LootListId", string.Empty).AsString();
if (MaxHp <= 0) if (MaxHp <= 0)
{ {

View File

@ -4,7 +4,6 @@ using System.Threading.Tasks;
using ColdMint.scripts.damage; using ColdMint.scripts.damage;
using ColdMint.scripts.deathInfo; using ColdMint.scripts.deathInfo;
using ColdMint.scripts.debug;
using ColdMint.scripts.item; using ColdMint.scripts.item;
using ColdMint.scripts.map.events; using ColdMint.scripts.map.events;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;

View File

@ -1,15 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using ColdMint.scripts.debug; using ColdMint.scripts.debug;
using ColdMint.scripts.serialization;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;
using Godot; using Godot;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
namespace ColdMint.scripts.item; namespace ColdMint.scripts.item;
/// <summary> /// <summary>
@ -21,7 +17,9 @@ public static class ItemTypeRegister
/// <para>Register items here</para> /// <para>Register items here</para>
/// <para>在这里注册物品</para> /// <para>在这里注册物品</para>
/// </summary> /// </summary>
public static void StaticRegister() { } public static void StaticRegister()
{
}
/// <summary> /// <summary>
/// <para>Register items from yaml file</para> /// <para>Register items from yaml file</para>
@ -30,43 +28,51 @@ public static class ItemTypeRegister
public static void RegisterFromFile() public static void RegisterFromFile()
{ {
LogCat.Log("start_item_register_from_file"); LogCat.Log("start_item_register_from_file");
//初始化文件目录
// initialize yaml deserializer //initialize file dir
var deserializer = new DeserializerBuilder() var itemRegsDirPath = "res://data/itemRegs/";
.WithNamingConvention(UnderscoredNamingConvention.Instance) // convent snake_case
.Build();
// initialize file dir
string itemRegsDirPath = "res://data/itemRegs/";
var itemRegsDir = DirAccess.Open(itemRegsDirPath); var itemRegsDir = DirAccess.Open(itemRegsDirPath);
if (DirAccess.GetOpenError() is not Error.Ok) if (DirAccess.GetOpenError() is not Error.Ok)
{ {
LogCat.LogError("error_when_open_item_regs_dir"); LogCat.LogError("error_when_open_item_regs_dir");
} }
// find files //找到文件
//find files
var files = itemRegsDir.GetFiles(); var files = itemRegsDir.GetFiles();
if (files == null)
{
LogCat.LogWithFormat("found_files", 0);
return;
}
LogCat.LogWithFormat("found_files", files.Length); LogCat.LogWithFormat("found_files", files.Length);
//将文件解析为项目类型信息
// parse files to item type infos //parse files to item type infos
IEnumerable<ItemTypeInfo> typeInfos = IEnumerable<ItemTypeInfo> typeInfos =
files.SelectMany(file => ParseFile(deserializer, $"{itemRegsDirPath}/{file}")).ToList(); files.SelectMany(file => ParseFile( $"{itemRegsDirPath}/{file}")).ToList();
LogCat.LogWithFormat("found_item_types", typeInfos.Count()); LogCat.LogWithFormat("found_item_types", typeInfos.Count());
// traverse type infos and register them. //遍历类型信息并注册它们。
//traverse type infos and register them.
foreach (var typeInfo in typeInfos) foreach (var typeInfo in typeInfos)
{ {
RegisterTypeInfo(typeInfo); RegisterTypeInfo(typeInfo);
} }
} }
private static IList<ItemTypeInfo> ParseFile(IDeserializer deserializer, string filePath) /// <summary>
/// <para>ParseFile</para>
/// <para>解析文件</para>
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
private static IList<ItemTypeInfo> ParseFile(string filePath)
{ {
var yamlFile = FileAccess.Open(filePath, FileAccess.ModeFlags.Read); var yamlFile = FileAccess.Open(filePath, FileAccess.ModeFlags.Read);
//阅读和反序列化
//Read & deserialize //Read & deserialize
var yamlString = yamlFile.GetAsText(); var yamlString = yamlFile.GetAsText();
var typeInfos = deserializer.Deserialize<IList<ItemTypeInfo>>(yamlString); var typeInfos = YamlSerialization.Deserialize<IList<ItemTypeInfo>>(yamlString);
yamlFile.Close(); yamlFile.Close();
return typeInfos; return typeInfos;
} }
@ -102,28 +108,33 @@ public static class ItemTypeRegister
//construct item type, register //construct item type, register
var itemType = new ItemType(typeInfo.Id, var itemType = new ItemType(typeInfo.Id,
newItemFunc, newItemFunc,
icon, typeInfo.MaxStackValue); icon, typeInfo.MaxStackValue);
var succeed = ItemTypeManager.Register(itemType); var succeed = ItemTypeManager.Register(itemType);
LogCat.LogWithFormat("register_item", itemType.Id, succeed); LogCat.LogWithFormat("register_item", itemType.Id, succeed);
} }
//Use for yaml deserialization //Use for yaml deserialization
private record struct ItemTypeInfo( private record struct ItemTypeInfo(
string Id, string ScenePath, string IconPath, int MaxStackValue, string Id,
IList<CustomArg>? CustomArgs) { } string ScenePath,
string IconPath,
int MaxStackValue,
IList<CustomArg>? CustomArgs)
{
}
private readonly record struct CustomArg(string Name, CustomArgType Type, string Value) private readonly record struct CustomArg(string Name, CustomArgType Type, string Value)
{ {
public Variant ParseValue() => public Variant ParseValue() =>
Type switch Type switch
{ {
CustomArgType.String => Value, CustomArgType.String => Value,
CustomArgType.Int => int.Parse(Value), CustomArgType.Int => int.Parse(Value),
CustomArgType.Float => double.Parse(Value), CustomArgType.Float => double.Parse(Value),
CustomArgType.Vector2 => ParseVector2FromString(Value), CustomArgType.Vector2 => ParseVector2FromString(Value),
CustomArgType.Texture => ResourceLoader.Load<Texture2D>("res://sprites/" + Value), CustomArgType.Texture => ResourceLoader.Load<Texture2D>("res://sprites/" + Value),
_ => throw new ArgumentOutOfRangeException($"Unknown Arg Type {Type}") _ => throw new ArgumentOutOfRangeException($"Unknown Arg Type {Type}")
}; };
private Vector2 ParseVector2FromString(string s) private Vector2 ParseVector2FromString(string s)

View File

@ -2,8 +2,6 @@ using System;
using ColdMint.scripts.character; using ColdMint.scripts.character;
using ColdMint.scripts.pickable; using ColdMint.scripts.pickable;
using ColdMint.scripts.damage;
using Godot; using Godot;
namespace ColdMint.scripts.item.weapon; namespace ColdMint.scripts.item.weapon;

View File

@ -583,7 +583,7 @@ public partial class LevelGraphEditorLoader : UiLoaderTemplate
} }
var filePath = Path.Join(Config.GetLevelGraphExportDirectory(), FileNameToActualName(fileName)); var filePath = Path.Join(Config.GetLevelGraphExportDirectory(), FileNameToActualName(fileName));
await File.WriteAllTextAsync(filePath, JsonSerialization.Serialize(levelGraphEditorSaveData)); await File.WriteAllTextAsync(filePath, YamlSerialization.Serialize(levelGraphEditorSaveData));
} }
/// <summary> /// <summary>
@ -598,13 +598,13 @@ public partial class LevelGraphEditorLoader : UiLoaderTemplate
private string FileNameToActualName(string fileName) private string FileNameToActualName(string fileName)
{ {
string actualName; string actualName;
if (fileName.EndsWith(".json")) if (fileName.EndsWith(".yaml"))
{ {
actualName = fileName; actualName = fileName;
} }
else else
{ {
actualName = fileName + ".json"; actualName = fileName + ".yaml";
} }
return actualName; return actualName;
@ -627,7 +627,7 @@ public partial class LevelGraphEditorLoader : UiLoaderTemplate
} }
var levelGraphEditorSaveData = var levelGraphEditorSaveData =
await JsonSerialization.ReadJsonFileToObj<LevelGraphEditorSaveData>(filePath); await YamlSerialization.ReadYamlFileToObj<LevelGraphEditorSaveData>(filePath);
if (levelGraphEditorSaveData == null) if (levelGraphEditorSaveData == null)
{ {
//Deserialization failed. //Deserialization failed.

View File

@ -6,7 +6,6 @@ using ColdMint.scripts.camp;
using ColdMint.scripts.contribute; using ColdMint.scripts.contribute;
using ColdMint.scripts.deathInfo; using ColdMint.scripts.deathInfo;
using ColdMint.scripts.debug; using ColdMint.scripts.debug;
using ColdMint.scripts.inventory;
using ColdMint.scripts.item; using ColdMint.scripts.item;
using ColdMint.scripts.loot; using ColdMint.scripts.loot;
using ColdMint.scripts.map; using ColdMint.scripts.map;
@ -132,7 +131,6 @@ public partial class MainMenuLoader : UiLoaderTemplate
{ {
_startGameButton.Pressed += () => _startGameButton.Pressed += () =>
{ {
LogCat.Log("start_game");
if (_gameScene == null) if (_gameScene == null)
{ {
return; return;

View File

@ -1,5 +1,4 @@
using ColdMint.scripts.debug; using ColdMint.scripts.inventory;
using ColdMint.scripts.inventory;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;
using Godot; using Godot;

View File

@ -1,6 +1,4 @@
using Godot; namespace ColdMint.scripts.loot;
namespace ColdMint.scripts.loot;
public readonly record struct LootDatum(string ItemId, int Quantity) public readonly record struct LootDatum(string ItemId, int Quantity)
{ {

View File

@ -1,5 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;

View File

@ -4,8 +4,6 @@ using System.Collections.Generic;
using ColdMint.scripts.debug; using ColdMint.scripts.debug;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;
using Godot;
namespace ColdMint.scripts.loot; namespace ColdMint.scripts.loot;
/// <summary> /// <summary>

View File

@ -1,9 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using ColdMint.scripts.utils;
using Godot;
namespace ColdMint.scripts.loot; namespace ColdMint.scripts.loot;
/// <summary> /// <summary>

View File

@ -178,7 +178,6 @@ public static class MapGenerator
var roomDictionary = new Dictionary<string, Room>(); var roomDictionary = new Dictionary<string, Room>();
var randomNumberGenerator = new RandomNumberGenerator(); var randomNumberGenerator = new RandomNumberGenerator();
randomNumberGenerator.Seed = _seed; randomNumberGenerator.Seed = _seed;
LogCat.LogWithFormat("seed_info", _seed);
var startRoomNodeData = await _layoutParsingStrategy.GetStartRoomNodeData(); var startRoomNodeData = await _layoutParsingStrategy.GetStartRoomNodeData();
if (startRoomNodeData == null || string.IsNullOrEmpty(startRoomNodeData.Id)) if (startRoomNodeData == null || string.IsNullOrEmpty(startRoomNodeData.Id))
{ {
@ -223,8 +222,8 @@ public static class MapGenerator
if (_roomInjectionProcessorsDictionary != null && !string.IsNullOrEmpty(roomInjectionProcessorData)) if (_roomInjectionProcessorsDictionary != null && !string.IsNullOrEmpty(roomInjectionProcessorData))
{ {
var roomInjectionProcessorDataArray = var roomInjectionProcessorDataArray =
JsonSerialization.Deserialize<RoomInjectionProcessorData[]>(roomInjectionProcessorData); YamlSerialization.Deserialize<RoomInjectionProcessorData[]>(roomInjectionProcessorData);
if (roomInjectionProcessorDataArray != null && roomInjectionProcessorDataArray.Length > 0) if (roomInjectionProcessorDataArray.Length > 0)
{ {
foreach (var injectionProcessorData in roomInjectionProcessorDataArray) foreach (var injectionProcessorData in roomInjectionProcessorDataArray)
{ {

View File

@ -24,10 +24,10 @@ public interface IRoomInjectionProcessor
///<para>Random probability generator based on world seed</para> ///<para>Random probability generator based on world seed</para>
///<para>根据世界种子确定的随机概率生成器</para> ///<para>根据世界种子确定的随机概率生成器</para>
/// </param> /// </param>
/// <param name="jsonConfigData"> /// <param name="yamlConfigData">
///<para>Inject data into the processor</para> ///<para>Inject data into the processor</para>
///<para>注入处理器的数据</para> ///<para>注入处理器的数据</para>
/// </param> /// </param>
/// <returns></returns> /// <returns></returns>
public Task<bool> CanBePlaced(RandomNumberGenerator randomNumberGenerator, string? jsonConfigData); public Task<bool> CanBePlaced(RandomNumberGenerator randomNumberGenerator, string? yamlConfigData);
} }

View File

@ -11,7 +11,7 @@ namespace ColdMint.scripts.map.layoutStrategy;
/// </summary> /// </summary>
public class TestLayoutStrategy : ILayoutStrategy public class TestLayoutStrategy : ILayoutStrategy
{ {
private const string Path = "res://data/levelGraphs/test.json"; private const string Path = "res://data/levelGraphs/test.yaml";
public Task<LevelGraphEditorSaveData?> GetLayout() public Task<LevelGraphEditorSaveData?> GetLayout()
{ {
@ -27,6 +27,6 @@ public class TestLayoutStrategy : ILayoutStrategy
return Task.FromResult<LevelGraphEditorSaveData?>(null); return Task.FromResult<LevelGraphEditorSaveData?>(null);
} }
return Task.FromResult(JsonSerialization.Deserialize<LevelGraphEditorSaveData>(json)); return Task.FromResult(YamlSerialization.Deserialize<LevelGraphEditorSaveData?>(json));
} }
} }

View File

@ -14,20 +14,15 @@ public abstract class RoomInjectionProcessorTemplate<TConfig> : IRoomInjectionPr
{ {
public abstract string GetId(); public abstract string GetId();
public Task<bool> CanBePlaced(RandomNumberGenerator randomNumberGenerator, string? jsonConfigData) public Task<bool> CanBePlaced(RandomNumberGenerator randomNumberGenerator, string? yamlConfigData)
{ {
if (jsonConfigData == null) if (yamlConfigData == null)
{ {
return Task.FromResult(false); return Task.FromResult(false);
} }
var configData = JsonSerialization.Deserialize<TConfig>(jsonConfigData); var configData = YamlSerialization.Deserialize<TConfig>(yamlConfigData);
if (configData == null) return configData == null ? Task.FromResult(false) : OnCreateConfigData(randomNumberGenerator, configData);
{
return Task.FromResult(false);
}
return OnCreateConfigData(randomNumberGenerator, configData);
} }
/// <summary> /// <summary>

View File

@ -5,7 +5,7 @@ using ColdMint.scripts.character;
using ColdMint.scripts.damage; using ColdMint.scripts.damage;
using ColdMint.scripts.item; using ColdMint.scripts.item;
using ColdMint.scripts.item.weapon; using ColdMint.scripts.item.weapon;
using ColdMint.scripts.pickable;
using Godot; using Godot;
namespace ColdMint.scripts.projectile; namespace ColdMint.scripts.projectile;
@ -175,7 +175,7 @@ public partial class ProjectileTemplate : CharacterBody2D
characterTemplate.AddForce(force); characterTemplate.AddForce(force);
} }
} }
else if (target is WeaponTemplate weaponTemplate) else if (target is PickAbleTemplate pickAbleTemplate)
{ {
if (KnockbackForce != Vector2.Zero) if (KnockbackForce != Vector2.Zero)
{ {
@ -192,7 +192,7 @@ public partial class ProjectileTemplate : CharacterBody2D
force.X = forceX * Config.CellSize; force.X = forceX * Config.CellSize;
force.Y = KnockbackForce.Y * Config.CellSize; force.Y = KnockbackForce.Y * Config.CellSize;
weaponTemplate.ApplyImpulse(force); pickAbleTemplate.ApplyImpulse(force);
} }
} }
} }

View File

@ -1,4 +1,5 @@
using System.IO; using System;
using System.IO;
using System.Text.Encodings.Web; using System.Text.Encodings.Web;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -9,6 +10,12 @@ namespace ColdMint.scripts.serialization;
/// <para>JsonSerialization</para> /// <para>JsonSerialization</para>
/// <para>Json序列化工具</para> /// <para>Json序列化工具</para>
/// </summary> /// </summary>
/// <remarks>
///<para>This serializer is no longer recommended and Yaml is recommended instead of Json.</para>
///<para>此序列化器已不再推荐使用建议用Yaml代替Json。</para>
/// </remarks>
/// <seealso cref="YamlSerialization"/>
[Obsolete("The Json serializer is out of date, we recommend yaml serialization.\nJson序列化器已过时了我们推荐使用Yaml。", true)]
public static class JsonSerialization public static class JsonSerialization
{ {
private static readonly JsonSerializerOptions Options = new() private static readonly JsonSerializerOptions Options = new()
@ -47,7 +54,7 @@ public static class JsonSerialization
{ {
return JsonSerializer.Serialize(obj, Options); return JsonSerializer.Serialize(obj, Options);
} }
/// <summary> /// <summary>
/// <para>Deserialize Json to an object</para> /// <para>Deserialize Json to an object</para>
/// <para>将Json反序列化为对象</para> /// <para>将Json反序列化为对象</para>

View File

@ -0,0 +1,58 @@
using System.IO;
using System.Threading.Tasks;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
namespace ColdMint.scripts.serialization;
public static class YamlSerialization
{
/// <summary>
/// <para>YamlDeserializer</para>
/// <para>Yaml反序列化器</para>
/// </summary>
private static readonly IDeserializer YamlDeserializer = new DeserializerBuilder()
.WithNamingConvention(UnderscoredNamingConvention.Instance) // convent snake_case
.Build();
private static readonly ISerializer YamlSerializer = new SerializerBuilder()
.WithNamingConvention(UnderscoredNamingConvention.Instance) // convent snake_case
.Build();
/// <summary>
/// <para>Read a Json file to type T</para>
/// <para>读取一个Json文件到T类型</para>
/// </summary>
/// <param name="path"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static async Task<T?> ReadYamlFileToObj<T>(string path)
{
await using var openStream = File.OpenRead(path);
var yaml = await new StreamReader(openStream).ReadToEndAsync();
return YamlDeserializer.Deserialize<T>(yaml);
}
/// <summary>
/// <para>Serialize the object to Json</para>
/// <para>将对象序列化为Yaml</para>
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static string Serialize(object obj)
{
return YamlSerializer.Serialize(obj);
}
/// <summary>
/// <para>Deserialize Yaml to the object</para>
/// <para>反序列化Yaml到对象</para>
/// </summary>
/// <param name="yaml"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T Deserialize<T>(string yaml)
{
return YamlDeserializer.Deserialize<T>(yaml);
}
}

View File

@ -1,9 +1,7 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using ColdMint.scripts.debug; using ColdMint.scripts.debug;
using ColdMint.scripts.inventory;
using ColdMint.scripts.item; using ColdMint.scripts.item;
using ColdMint.scripts.item.weapon; using ColdMint.scripts.item.weapon;