添加 CharacterBuilder;为 Item 添加了 Guid;开工库存系统

This commit is contained in:
milimoe 2024-11-14 00:26:09 +08:00
parent b25698d91b
commit 184a5342b8
Signed by: milimoe
GPG Key ID: 05D280912DA6C69E
11 changed files with 234 additions and 48 deletions

View File

@ -131,7 +131,17 @@ namespace Milimoe.FunGame.Core.Api.Utility
TXTHelper.AppendErrorLog(e.GetErrorInfo());
}
}
return (T)(object)new OpenSkill(id, name, args);
Skill openSkill = new OpenSkill(id, name, args);
if (args.TryGetValue("values", out object? value) && value is Dictionary<string, object> dict)
{
foreach (string key in dict.Keys)
{
openSkill.Values[key] = dict[key];
}
}
return (T)(object)openSkill;
}
if (typeof(T) == typeof(Effect))
{
@ -167,7 +177,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
TXTHelper.AppendErrorLog(e.GetErrorInfo());
}
}
return (T)(object)GetItem();
return (T)(object)new OpenItem(id, name, args);
}
if (typeof(T) == typeof(Room))
{

View File

@ -15,17 +15,15 @@ namespace Milimoe.FunGame.Core.Api.Utility
public class JsonTool
{
/// <summary>
/// 序列化选项<para/>
/// 已经默认添加了下列转换器:<para/>
/// <see cref="DateTimeConverter"/>, <see cref="DataTableConverter"/>, <see cref="DataSetConverter"/>
/// 序列化选项
/// </summary>
public JsonSerializerOptions JsonSerializerOptions => options;
public static JsonSerializerOptions JsonSerializerOptions => JsonManager.GeneralOptions;
/// <summary>
/// 注册一个自定义转换器,支持 <see cref="BaseEntityConverter{T}"/>
/// </summary>
/// <param name="converter"></param>
public void AddConverter(JsonConverter converter)
public static void AddConverter(JsonConverter converter)
{
if (!JsonSerializerOptions.Converters.Contains(converter))
JsonSerializerOptions.Converters.Add(converter);
@ -49,7 +47,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public string GetString<T>(T obj) => JsonManager.GetString(obj, options);
public string GetString<T>(T obj) => JsonManager.GetString(obj, JsonSerializerOptions);
/// <summary>
/// 反序列化Json对象
@ -57,14 +55,14 @@ namespace Milimoe.FunGame.Core.Api.Utility
/// <typeparam name="T"></typeparam>
/// <param name="json"></param>
/// <returns></returns>
public T? GetObject<T>(string json) => JsonManager.GetObject<T>(json, options);
public T? GetObject<T>(string json) => JsonManager.GetObject<T>(json, JsonSerializerOptions);
/// <summary>
/// 反序列化Json对象此方法可能无法返回正确的类型请注意辨别
/// </summary>
/// <param name="json"></param>
/// <returns></returns>
public object? GetObject(string json) => JsonManager.GetObject(json, options);
public object? GetObject(string json) => JsonManager.GetObject(json, JsonSerializerOptions);
/// <summary>
/// 反序列化Hashtable中Key对应的Json对象
@ -73,7 +71,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
/// <param name="table"></param>
/// <param name="key"></param>
/// <returns></returns>
public T? GetObject<T>(Hashtable table, string key) => JsonManager.GetObject<T>(table, key, options);
public T? GetObject<T>(Hashtable table, string key) => JsonManager.GetObject<T>(table, key, JsonSerializerOptions);
/// <summary>
/// 反序列化Dictionary中Key对应的Json对象
@ -82,7 +80,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
/// <param name="dict"></param>
/// <param name="key"></param>
/// <returns></returns>
public T? GetObject<T>(Dictionary<string, object> dict, string key) => JsonManager.GetObject<T>(dict, key, options);
public T? GetObject<T>(Dictionary<string, object> dict, string key) => JsonManager.GetObject<T>(dict, key, JsonSerializerOptions);
/// <summary>
/// 反序列化IEnumerable中的Json对象 可指定反序列化选项
@ -91,7 +89,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
/// <param name="e"></param>
/// <param name="index"></param>
/// <returns></returns>
public T? JsonDeserializeFromIEnumerable<T>(IEnumerable<object> e, int index) => JsonManager.GetObject<T>(e, index, options);
public T? JsonDeserializeFromIEnumerable<T>(IEnumerable<object> e, int index) => JsonManager.GetObject<T>(e, index, JsonSerializerOptions);
/// <summary>
/// 反序列化多个Json对象
@ -100,18 +98,6 @@ namespace Milimoe.FunGame.Core.Api.Utility
/// <typeparam name="T"></typeparam>
/// <param name="json"></param>
/// <returns></returns>
public List<T> GetObjects<T>(string json) => JsonManager.GetObjects<T>(json, options);
/// <summary>
/// Private JsonSerializerOptions
/// </summary>
private readonly JsonSerializerOptions options = new()
{
WriteIndented = true,
PropertyNameCaseInsensitive = true,
ReferenceHandler = ReferenceHandler.IgnoreCycles,
Converters = { new DateTimeConverter(), new DataTableConverter(), new DataSetConverter(), new UserConverter(), new RoomConverter(),
new CharacterConverter(), new MagicResistanceConverter(), new EquipSlotConverter(), new SkillConverter(), new EffectConverter(), new ItemConverter() }
};
public List<T> GetObjects<T>(string json) => JsonManager.GetObjects<T>(json, JsonSerializerOptions);
}
}

View File

@ -1306,6 +1306,7 @@ namespace Milimoe.FunGame.Core.Entity
{
Id = Id,
Name = Name,
Guid = Guid,
FirstName = FirstName,
NickName = NickName,
Profile = Profile.Copy(),
@ -1394,7 +1395,7 @@ namespace Milimoe.FunGame.Core.Entity
Skills.Clear();
Items.Clear();
Id = c.Id;
Guid = original.Guid;
Guid = c.Guid;
Name = c.Name;
FirstName = c.FirstName;
NickName = c.NickName;

View File

@ -0,0 +1,82 @@
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Entity
{
public class CharacterBuilder(long id, string name, string firstName, string nickName, PrimaryAttribute primaryAttribute, double initialATK, double initialHP, double initialMP, double initialSTR, double strGrowth, double initialAGI, double agiGrowth, double initialINT, double intGrowth, double initialSPD, double initialHR, double initialMR)
{
public long Id { get; set; } = id;
public string Name { get; set; } = name;
public string FirstName { get; set; } = firstName;
public string NickName { get; set; } = nickName;
public PrimaryAttribute PrimaryAttribute { get; set; } = primaryAttribute;
public double InitialATK { get; set; } = initialATK;
public double InitialHP { get; set; } = initialHP;
public double InitialMP { get; set; } = initialMP;
public double InitialSTR { get; set; } = initialSTR;
public double STRGrowth { get; set; } = strGrowth;
public double InitialAGI { get; set; } = initialAGI;
public double AGIGrowth { get; set; } = agiGrowth;
public double InitialINT { get; set; } = initialINT;
public double INTGrowth { get; set; } = intGrowth;
public double InitialSPD { get; set; } = initialSPD;
public double InitialHR { get; set; } = initialHR;
public double InitialMR { get; set; } = initialMR;
public Character Build(int level, IEnumerable<Skill> skills, IEnumerable<Item> items, EquipSlot? equips = null)
{
Character character = Factory.GetCharacter();
character.Id = Id;
character.Name = Name;
character.FirstName = FirstName;
character.NickName = NickName;
character.PrimaryAttribute = PrimaryAttribute;
character.InitialATK = InitialATK;
character.InitialHP = InitialHP;
character.InitialMP = InitialMP;
character.InitialSTR = InitialSTR;
character.STRGrowth = STRGrowth;
character.InitialAGI = InitialAGI;
character.AGIGrowth = AGIGrowth;
character.InitialINT = InitialINT;
character.INTGrowth = INTGrowth;
character.InitialSPD = InitialSPD;
character.InitialHR = InitialHR;
character.InitialMR = InitialMR;
if (level > 1)
{
character.Level = level;
}
foreach (Skill skill in skills)
{
Skill newskill = skill.Copy();
newskill.Character = character;
newskill.Level = skill.Level;
newskill.CurrentCD = 0;
character.Skills.Add(newskill);
}
foreach (Item item in items)
{
Item newitem = item.Copy(true);
newitem.Character = character;
character.Items.Add(newitem);
}
if (equips != null)
{
Item? mcp = equips.MagicCardPack;
Item? w = equips.Weapon;
Item? a = equips.Armor;
Item? s = equips.Shoes;
Item? ac1 = equips.Accessory1;
Item? ac2 = equips.Accessory2;
if (mcp != null) character.Equip(mcp);
if (w != null) character.Equip(w);
if (a != null) character.Equip(a);
if (s != null) character.Equip(s);
if (ac1 != null) character.Equip(ac1);
if (ac2 != null) character.Equip(ac2);
}
return character;
}
}
}

View File

@ -11,6 +11,11 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary>
public class Item : BaseEntity, IItem
{
/// <summary>
/// 唯一标识符
/// </summary>
public override Guid Guid { get; set; } = Guid.NewGuid();
/// <summary>
/// 物品的描述
/// </summary>
@ -499,6 +504,7 @@ namespace Milimoe.FunGame.Core.Entity
SetPropertyToItemModuleNew(item);
item.Id = Id;
item.Name = Name;
item.Guid = Guid;
item.Description = Description;
item.GeneralDescription = GeneralDescription;
item.BackgroundStory = BackgroundStory;
@ -519,6 +525,8 @@ namespace Milimoe.FunGame.Core.Entity
item.IsTradable = IsTradable;
item.NextTradableTime = NextTradableTime;
item.RemainUseTimes = RemainUseTimes;
if (item is OpenItem)
{
item.Skills.Active = Skills.Active?.Copy();
if (item.Skills.Active != null)
{
@ -538,6 +546,7 @@ namespace Milimoe.FunGame.Core.Entity
newskill.Level = copyLevel ? skill.Level : 1;
item.Skills.Magics.Add(newskill);
}
}
return item;
}

21
Entity/Item/OpenItem.cs Normal file
View File

@ -0,0 +1,21 @@
namespace Milimoe.FunGame.Core.Entity
{
/// <summary>
/// 用于动态扩展物品
/// </summary>
public class OpenItem : Item
{
public override long Id { get; set; }
public override string Name { get; set; }
public OpenItem(long id, string name, Dictionary<string, object> args)
{
Id = id;
Name = name;
foreach (string key in args.Keys)
{
Others[key] = args[key];
}
}
}
}

View File

@ -5,12 +5,13 @@
public long Id => User.Id;
public string Name { get; set; } = "";
public User User { get; }
public Dictionary<string, Character> Characters { get; set; } = new();
public Dictionary<string, Item> Items { get; set; } = new();
public Dictionary<string, Character> Characters { get; } = [];
public Dictionary<string, Item> Items { get; } = [];
internal Inventory(User user)
{
User = user;
Name = user.Username + "的库存";
}
}
}

View File

@ -0,0 +1,52 @@
using System.Text.Json;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Common.Architecture;
namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
{
public class InventoryConverter : BaseEntityConverter<Inventory>
{
public override Inventory NewInstance()
{
return Factory.GetInventory();
}
public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Inventory result)
{
switch (propertyName)
{
case nameof(Inventory.Name):
result.Name = reader.GetString() ?? "";
break;
case nameof(Inventory.Characters):
Dictionary<string, Character> characters = NetworkUtility.JsonDeserialize<Dictionary<string, Character>>(ref reader, options) ?? [];
foreach (string key in characters.Keys)
{
result.Characters[key] = characters[key];
}
break;
case nameof(Inventory.Items):
Dictionary<string, Item> items = NetworkUtility.JsonDeserialize<Dictionary<string, Item>>(ref reader, options) ?? [];
foreach (string key in items.Keys)
{
result.Items[key] = items[key];
}
break;
}
}
public override void Write(Utf8JsonWriter writer, Inventory value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteString(nameof(Inventory.Name), value.Name);
writer.WritePropertyName(nameof(Inventory.Characters));
JsonSerializer.Serialize(writer, value.Characters, options);
writer.WritePropertyName(nameof(Inventory.Items));
JsonSerializer.Serialize(writer, value.Items, options);
writer.WriteEndObject();
}
}
}

View File

@ -23,6 +23,9 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
case nameof(Item.Name):
result.Name = reader.GetString() ?? "";
break;
case nameof(Item.Guid):
result.Guid = reader.GetGuid();
break;
case nameof(Item.Description):
result.Description = reader.GetString() ?? "";
break;
@ -112,6 +115,8 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
writer.WriteNumber(nameof(Item.Id), (int)value.Id);
writer.WriteString(nameof(Item.Name), value.Name);
writer.WritePropertyName(nameof(Item.Guid));
JsonSerializer.Serialize(writer, value.Guid, options);
writer.WriteString(nameof(Item.Description), value.Description);
writer.WriteString(nameof(Item.GeneralDescription), value.GeneralDescription);
writer.WriteString(nameof(Item.BackgroundStory), value.BackgroundStory);

View File

@ -1,6 +1,7 @@
using System.Text.Json;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Interface.Entity;
using Milimoe.FunGame.Core.Library.Common.Architecture;
using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Library.SQLScript.Entity;
@ -67,12 +68,25 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
case UserQuery.Column_AutoKey:
result.AutoKey = reader.GetString() ?? "";
break;
case nameof(Inventory):
Inventory inventory = NetworkUtility.JsonDeserialize<Inventory>(ref reader, options) ?? Factory.GetInventory();
result.Inventory.Name = inventory.Name;
foreach (string key in inventory.Characters.Keys)
{
result.Inventory.Characters[key] = inventory.Characters[key];
}
foreach (string key in inventory.Items.Keys)
{
result.Inventory.Items[key] = inventory.Items[key];
}
break;
}
}
public override void Write(Utf8JsonWriter writer, User value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteNumber(UserQuery.Column_UID, value.Id);
writer.WriteString(UserQuery.Column_Username, value.Username);
writer.WriteString(UserQuery.Column_RegTime, value.RegTime.ToString(General.GeneralDateTimeFormat));
@ -86,6 +100,9 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
writer.WriteNumber(UserQuery.Column_Materials, value.Materials);
writer.WriteNumber(UserQuery.Column_GameTime, value.GameTime);
writer.WriteString(UserQuery.Column_AutoKey, value.AutoKey);
writer.WritePropertyName(nameof(Inventory));
JsonSerializer.Serialize(writer, value.Inventory, options);
writer.WriteEndObject();
}
}

View File

@ -13,14 +13,16 @@ namespace Milimoe.FunGame.Core.Service
/// <summary>
/// 默认的序列化选项
/// </summary>
private readonly static JsonSerializerOptions GeneralOptions = new()
internal static JsonSerializerOptions GeneralOptions { get; } = new()
{
WriteIndented = true,
PropertyNameCaseInsensitive = true,
Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),
ReferenceHandler = ReferenceHandler.IgnoreCycles,
Converters = { new DateTimeConverter(), new DataTableConverter(), new DataSetConverter(), new UserConverter(), new RoomConverter(),
new CharacterConverter(), new MagicResistanceConverter(), new EquipSlotConverter(), new SkillConverter(), new EffectConverter(), new ItemConverter() }
new CharacterConverter(), new MagicResistanceConverter(), new EquipSlotConverter(), new SkillConverter(), new EffectConverter(), new ItemConverter(),
new InventoryConverter()
}
};
/// <summary>