诸多更新和问题修复 (#97)

* 添加 OpenFactory,可以动态扩展技能和物品

* 修改 Effect 的反序列化解析;增加对闪避/暴击判定的先前事件编程接口

* 补充魔法伤害的判定

* 装备系统优化;角色的复制问题修复

* 添加物品品质;更新装备饰品替换机制;添加第一滴血、团队模式

* 添加技能选取

* 添加团队死斗模式
This commit is contained in:
milimoe 2024-11-04 09:30:26 +08:00 committed by GitHub
parent 60ae91e488
commit 3db586cab2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
42 changed files with 1869 additions and 609 deletions

View File

@ -1,7 +1,7 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Interface.Base;
namespace Milimoe.FunGame.Core.Api.Factory
namespace Milimoe.FunGame.Core.Api.EntityFactory
{
internal class CharacterFactory : IFactory<Character>
{

View File

@ -1,7 +1,7 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Interface.Base;
namespace Milimoe.FunGame.Core.Api.Factory
namespace Milimoe.FunGame.Core.Api.EntityFactory
{
internal class EffectFactory : IFactory<Effect>
{

View File

@ -2,7 +2,7 @@
using Milimoe.FunGame.Core.Interface.Base;
using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Api.Factory
namespace Milimoe.FunGame.Core.Api.EntityFactory
{
internal class InventoryFactory : IFactory<Inventory>
{

View File

@ -1,7 +1,7 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Interface.Base;
namespace Milimoe.FunGame.Core.Api.Factory
namespace Milimoe.FunGame.Core.Api.EntityFactory
{
internal class ItemFactory : IFactory<Item>
{

View File

@ -2,7 +2,7 @@
using Milimoe.FunGame.Core.Interface.Base;
using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Api.Factory
namespace Milimoe.FunGame.Core.Api.EntityFactory
{
internal class RoomFactory : IFactory<Room>
{

View File

@ -1,7 +1,7 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Interface.Base;
namespace Milimoe.FunGame.Core.Api.Factory
namespace Milimoe.FunGame.Core.Api.EntityFactory
{
internal class SkillFactory : IFactory<Skill>
{

View File

@ -2,7 +2,7 @@ using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Interface.Base;
using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Api.Factory
namespace Milimoe.FunGame.Core.Api.EntityFactory
{
internal class UserFactory : IFactory<User>
{

View File

@ -0,0 +1,20 @@
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
namespace Milimoe.FunGame.Core.Api.OpenEntityAdapter
{
public class OpenItemAdapter
{
public static void Adaptation<T>(EntityModuleConfig<T> config) where T : BaseEntity
{
foreach (string key in config.Keys)
{
if (config[key] is Item prev)
{
Item next = prev.Copy();
if (next is T t) config[key] = t;
}
}
}
}
}

View File

@ -0,0 +1,20 @@
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
namespace Milimoe.FunGame.Core.Api.OpenEntityAdapter
{
public class OpenSkillAdapter
{
public static void Adaptation<T>(EntityModuleConfig<T> config) where T : BaseEntity
{
foreach (string key in config.Keys)
{
if (config[key] is Skill prev)
{
Skill next = prev.Copy();
if (next is T t) config[key] = t;
}
}
}
}
}

View File

@ -4,7 +4,7 @@ using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Api.Utility
{
/// <summary>
/// 简易的实体模组配置文件生成器<para/>
/// 简易的实体模组配置文件生成器,适用范围:动态扩展技能和物品、保存玩家的存档<para/>
/// 仅支持继承了 <see cref="BaseEntity"/> 的实体类型,每个 <see cref="EntityModuleConfig{T}"/> 仅保存一种实体类型的数据
/// <para/>文件会保存为:程序目录/configs/<see cref="ModuleName"/>/<see cref="FileName"/>.json
/// </summary>

View File

@ -1,5 +1,6 @@
using System.Data;
using Milimoe.FunGame.Core.Api.Factory;
using Milimoe.FunGame.Core.Api.EntityFactory;
using Milimoe.FunGame.Core.Api.OpenEntityAdapter;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Library.SQLScript.Entity;
@ -8,6 +9,194 @@ namespace Milimoe.FunGame.Core.Api.Utility
{
public class Factory
{
/// <summary>
/// 支持动态扩展的工厂实例
/// </summary>
public static Factory OpenFactory { get; } = new();
private Factory()
{
}
internal HashSet<EntityFactoryDelegate<Character>> CharacterFactories { get; } = [];
internal HashSet<EntityFactoryDelegate<Inventory>> InventoryFactories { get; } = [];
internal HashSet<EntityFactoryDelegate<Skill>> SkillFactories { get; } = [];
internal HashSet<EntityFactoryDelegate<Effect>> EffectFactories { get; } = [];
internal HashSet<EntityFactoryDelegate<Item>> ItemFactories { get; } = [];
internal HashSet<EntityFactoryDelegate<Room>> RoomFactories { get; } = [];
internal HashSet<EntityFactoryDelegate<User>> UserFactories { get; } = [];
public delegate T? EntityFactoryDelegate<T>(long id, string name, Dictionary<string, object> args);
/// <summary>
/// 注册工厂方法
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="d"></param>
public void RegisterFactory<T>(EntityFactoryDelegate<T> d)
{
if (typeof(T) == typeof(Character) && d is EntityFactoryDelegate<Character> character)
{
CharacterFactories.Add(character);
}
if (typeof(T) == typeof(Inventory) && d is EntityFactoryDelegate<Inventory> inventory)
{
InventoryFactories.Add(inventory);
}
if (typeof(T) == typeof(Skill) && d is EntityFactoryDelegate<Skill> skill)
{
SkillFactories.Add(skill);
}
if (typeof(T) == typeof(Effect) && d is EntityFactoryDelegate<Effect> effect)
{
EffectFactories.Add(effect);
}
if (typeof(T) == typeof(Item) && d is EntityFactoryDelegate<Item> item)
{
ItemFactories.Add(item);
}
if (typeof(T) == typeof(Room) && d is EntityFactoryDelegate<Room> room)
{
RoomFactories.Add(room);
}
if (typeof(T) == typeof(User) && d is EntityFactoryDelegate<User> user)
{
UserFactories.Add(user);
}
}
/// <summary>
/// 构造一个实体实例
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="id"></param>
/// <param name="name"></param>
/// <param name="args"></param>
/// <returns></returns>
/// <exception cref="NotSupportedInstanceClassException"></exception>
public T GetInstance<T>(long id, string name, Dictionary<string, object> args)
{
if (typeof(T) == typeof(Character))
{
foreach (EntityFactoryDelegate<Character> d in CharacterFactories)
{
if (d.Invoke(id, name, args) is T character)
{
return character;
}
}
return (T)(object)GetCharacter();
}
if (typeof(T) == typeof(Inventory))
{
foreach (EntityFactoryDelegate<Inventory> d in InventoryFactories)
{
if (d.Invoke(id, name, args) is T inventory)
{
return inventory;
}
}
return (T)(object)GetInventory();
}
if (typeof(T) == typeof(Skill))
{
foreach (EntityFactoryDelegate<Skill> d in SkillFactories)
{
if (d.Invoke(id, name, args) is T skill)
{
return skill;
}
}
return (T)(object)new OpenSkill(id, name, args);
}
if (typeof(T) == typeof(Effect))
{
foreach (EntityFactoryDelegate<Effect> d in EffectFactories)
{
if (d.Invoke(id, name, args) is T effect)
{
return effect;
}
}
return (T)(object)GetEffect();
}
if (typeof(T) == typeof(Item))
{
foreach (EntityFactoryDelegate<Item> d in ItemFactories)
{
if (d.Invoke(id, name, args) is T item)
{
return item;
}
}
return (T)(object)GetItem();
}
if (typeof(T) == typeof(Room))
{
foreach (EntityFactoryDelegate<Room> d in RoomFactories)
{
if (d.Invoke(id, name, args) is T room)
{
return room;
}
}
return (T)(object)GetRoom();
}
if (typeof(T) == typeof(User))
{
foreach (EntityFactoryDelegate<User> d in UserFactories)
{
if (d.Invoke(id, name, args) is T user)
{
return user;
}
}
return (T)(object)GetUser();
}
throw new NotSupportedInstanceClassException();
}
/// <summary>
/// 此方法使用 <see cref="EntityModuleConfig{T}"/> 取得一个实体字典
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="module_name"></param>
/// <param name="file_name"></param>
/// <returns></returns>
public static Dictionary<string, T> GetGameModuleInstances<T>(string module_name, string file_name) where T : BaseEntity
{
EntityModuleConfig<T> config = new(module_name, file_name);
config.LoadConfig();
if (typeof(T) == typeof(Skill))
{
OpenSkillAdapter.Adaptation(config);
}
if (typeof(T) == typeof(Item))
{
OpenItemAdapter.Adaptation(config);
}
return config;
}
/// <summary>
/// 使用 <see cref="EntityModuleConfig{T}"/> 构造一个实体字典并保存
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="module_name"></param>
/// <param name="file_name"></param>
/// <param name="dict"></param>
/// <returns></returns>
public static void CreateGameModuleEntityConfig<T>(string module_name, string file_name, Dictionary<string, T> dict) where T : BaseEntity
{
EntityModuleConfig<T> config = new(module_name, file_name);
foreach (string key in dict.Keys)
{
config[key] = dict[key];
}
config.SaveConfig();
}
private readonly static CharacterFactory CharacterFactory = new();
private readonly static InventoryFactory InventoryFactory = new();
private readonly static SkillFactory SkillFactory = new();
@ -152,7 +341,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
/// 获取大厅(-1号房
/// </summary>
/// <returns></returns>
internal static Room GetHall()
public static Room GetHall()
{
return RoomFactory.Create();
}

View File

@ -1,4 +1,3 @@
using System.Collections;
using Milimoe.FunGame.Core.Library.Common.Addon;
using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Service;

View File

@ -1,5 +1,4 @@
using System.Collections;
using Milimoe.FunGame.Core.Api.Transmittal;
using Milimoe.FunGame.Core.Api.Transmittal;
using Milimoe.FunGame.Core.Interface.Addons;
using Milimoe.FunGame.Core.Library.Constant;

View File

@ -809,7 +809,7 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary>
/// <param name="item"></param>
/// <param name="slot"></param>
public bool Equip(Item item, EquipItemToSlot slot)
public bool Equip(Item item, EquipSlotType slot)
{
bool result = false;
double pastHP = HP;
@ -818,57 +818,59 @@ namespace Milimoe.FunGame.Core.Entity
double pastMaxMP = MaxMP;
switch (slot)
{
case EquipItemToSlot.MagicCardPack:
case EquipSlotType.MagicCardPack:
if (item.ItemType == ItemType.MagicCardPack)
{
UnEquip(EquipItemToSlot.MagicCardPack);
UnEquip(EquipSlotType.MagicCardPack);
EquipSlot.MagicCardPack = item;
item.OnItemEquip(this, EquipItemToSlot.MagicCardPack);
item.OnItemEquip(this, EquipSlotType.MagicCardPack);
result = true;
}
break;
case EquipItemToSlot.Weapon:
case EquipSlotType.Weapon:
if (item.ItemType == ItemType.Weapon)
{
UnEquip(EquipItemToSlot.Weapon);
UnEquip(EquipSlotType.Weapon);
EquipSlot.Weapon = item;
item.OnItemEquip(this, EquipItemToSlot.Weapon);
item.OnItemEquip(this, EquipSlotType.Weapon);
result = true;
}
break;
case EquipItemToSlot.Armor:
case EquipSlotType.Armor:
if (item.ItemType == ItemType.Armor)
{
UnEquip(EquipItemToSlot.Armor);
UnEquip(EquipSlotType.Armor);
EquipSlot.Armor = item;
item.OnItemEquip(this, EquipItemToSlot.Armor);
item.OnItemEquip(this, EquipSlotType.Armor);
result = true;
}
break;
case EquipItemToSlot.Shoes:
case EquipSlotType.Shoes:
if (item.ItemType == ItemType.Shoes)
{
UnEquip(EquipItemToSlot.Shoes);
UnEquip(EquipSlotType.Shoes);
EquipSlot.Shoes = item;
item.OnItemEquip(this, EquipItemToSlot.Shoes);
item.OnItemEquip(this, EquipSlotType.Shoes);
result = true;
}
break;
case EquipItemToSlot.Accessory1:
case EquipSlotType.Accessory1:
if (item.ItemType == ItemType.Accessory)
{
UnEquip(EquipItemToSlot.Accessory1);
UnEquip(EquipSlotType.Accessory1);
EquipSlot.Accessory1 = item;
item.OnItemEquip(this, EquipItemToSlot.Accessory1);
EquipSlot.LastEquipSlotType = EquipSlotType.Accessory1;
item.OnItemEquip(this, EquipSlotType.Accessory1);
result = true;
}
break;
case EquipItemToSlot.Accessory2:
case EquipSlotType.Accessory2:
if (item.ItemType == ItemType.Accessory)
{
UnEquip(EquipItemToSlot.Accessory2);
UnEquip(EquipSlotType.Accessory2);
EquipSlot.Accessory2 = item;
item.OnItemEquip(this, EquipItemToSlot.Accessory2);
EquipSlot.LastEquipSlotType = EquipSlotType.Accessory2;
item.OnItemEquip(this, EquipSlotType.Accessory2);
result = true;
}
break;
@ -891,21 +893,29 @@ namespace Milimoe.FunGame.Core.Entity
switch (item.ItemType)
{
case ItemType.MagicCardPack:
return Equip(item, EquipItemToSlot.MagicCardPack);
return Equip(item, EquipSlotType.MagicCardPack);
case ItemType.Weapon:
return Equip(item, EquipItemToSlot.Weapon);
return Equip(item, EquipSlotType.Weapon);
case ItemType.Armor:
return Equip(item, EquipItemToSlot.Armor);
return Equip(item, EquipSlotType.Armor);
case ItemType.Shoes:
return Equip(item, EquipItemToSlot.Shoes);
return Equip(item, EquipSlotType.Shoes);
case ItemType.Accessory:
if (EquipSlot.Accessory1 != null && EquipSlot.Accessory2 is null)
if (EquipSlot.Accessory1 is null)
{
return Equip(item, EquipItemToSlot.Accessory2);
return Equip(item, EquipSlotType.Accessory1);
}
else if (EquipSlot.Accessory1 != null && EquipSlot.Accessory2 is null)
{
return Equip(item, EquipSlotType.Accessory2);
}
else if (EquipSlot.Accessory1 != null && EquipSlot.Accessory2 != null && EquipSlot.LastEquipSlotType == EquipSlotType.Accessory1)
{
return Equip(item, EquipSlotType.Accessory2);
}
else
{
return Equip(item, EquipItemToSlot.Accessory1);
return Equip(item, EquipSlotType.Accessory1);
}
}
return false;
@ -916,51 +926,51 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public Item? UnEquip(EquipItemToSlot type)
public Item? UnEquip(EquipSlotType type)
{
Item? result = null;
switch (type)
{
case EquipItemToSlot.MagicCardPack:
case EquipSlotType.MagicCardPack:
if (EquipSlot.MagicCardPack != null)
{
result = EquipSlot.MagicCardPack;
EquipSlot.MagicCardPack.OnItemUnEquip(EquipItemToSlot.MagicCardPack);
EquipSlot.MagicCardPack.OnItemUnEquip(EquipSlotType.MagicCardPack);
}
break;
case EquipItemToSlot.Weapon:
case EquipSlotType.Weapon:
if (EquipSlot.Weapon != null)
{
result = EquipSlot.Weapon;
EquipSlot.Weapon.OnItemUnEquip(EquipItemToSlot.Weapon);
EquipSlot.Weapon.OnItemUnEquip(EquipSlotType.Weapon);
}
break;
case EquipItemToSlot.Armor:
case EquipSlotType.Armor:
if (EquipSlot.Armor != null)
{
result = EquipSlot.Armor;
EquipSlot.Armor.OnItemUnEquip(EquipItemToSlot.Armor);
EquipSlot.Armor.OnItemUnEquip(EquipSlotType.Armor);
}
break;
case EquipItemToSlot.Shoes:
case EquipSlotType.Shoes:
if (EquipSlot.Shoes != null)
{
result = EquipSlot.Shoes;
EquipSlot.Shoes.OnItemUnEquip(EquipItemToSlot.Shoes);
EquipSlot.Shoes.OnItemUnEquip(EquipSlotType.Shoes);
}
break;
case EquipItemToSlot.Accessory1:
case EquipSlotType.Accessory1:
if (EquipSlot.Accessory1 != null)
{
result = EquipSlot.Accessory1;
EquipSlot.Accessory1.OnItemUnEquip(EquipItemToSlot.Accessory1);
EquipSlot.Accessory1.OnItemUnEquip(EquipSlotType.Accessory1);
}
break;
case EquipItemToSlot.Accessory2:
case EquipSlotType.Accessory2:
if (EquipSlot.Accessory2 != null)
{
result = EquipSlot.Accessory2;
EquipSlot.Accessory2.OnItemUnEquip(EquipItemToSlot.Accessory2);
EquipSlot.Accessory2.OnItemUnEquip(EquipSlotType.Accessory2);
}
break;
}
@ -1128,32 +1138,32 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine("== 装备栏 ==");
if (EquipSlot.MagicCardPack != null)
{
builder.AppendLine(ItemSet.GetEquipItemToSlotTypeName(EquipItemToSlot.MagicCardPack) + "" + EquipSlot.MagicCardPack.Name);
builder.AppendLine(ItemSet.GetEquipSlotTypeName(EquipSlotType.MagicCardPack) + "" + EquipSlot.MagicCardPack.Name);
builder.AppendLine(EquipSlot.MagicCardPack.Description);
}
if (EquipSlot.Weapon != null)
{
builder.AppendLine(ItemSet.GetEquipItemToSlotTypeName(EquipItemToSlot.Weapon) + "" + EquipSlot.Weapon.Name);
builder.AppendLine(ItemSet.GetEquipSlotTypeName(EquipSlotType.Weapon) + "" + EquipSlot.Weapon.Name);
builder.AppendLine(EquipSlot.Weapon.Description);
}
if (EquipSlot.Armor != null)
{
builder.AppendLine(ItemSet.GetEquipItemToSlotTypeName(EquipItemToSlot.Armor) + "" + EquipSlot.Armor.Name);
builder.AppendLine(ItemSet.GetEquipSlotTypeName(EquipSlotType.Armor) + "" + EquipSlot.Armor.Name);
builder.AppendLine(EquipSlot.Armor.Description);
}
if (EquipSlot.Shoes != null)
{
builder.AppendLine(ItemSet.GetEquipItemToSlotTypeName(EquipItemToSlot.Shoes) + "" + EquipSlot.Shoes.Name);
builder.AppendLine(ItemSet.GetEquipSlotTypeName(EquipSlotType.Shoes) + "" + EquipSlot.Shoes.Name);
builder.AppendLine(EquipSlot.Shoes.Description);
}
if (EquipSlot.Accessory1 != null)
{
builder.AppendLine(ItemSet.GetEquipItemToSlotTypeName(EquipItemToSlot.Accessory1) + "" + EquipSlot.Accessory1.Name);
builder.AppendLine(ItemSet.GetEquipSlotTypeName(EquipSlotType.Accessory1) + "" + EquipSlot.Accessory1.Name);
builder.AppendLine(EquipSlot.Accessory1.Description);
}
if (EquipSlot.Accessory2 != null)
{
builder.AppendLine(ItemSet.GetEquipItemToSlotTypeName(EquipItemToSlot.Accessory2) + "" + EquipSlot.Accessory2.Name);
builder.AppendLine(ItemSet.GetEquipSlotTypeName(EquipSlotType.Accessory2) + "" + EquipSlot.Accessory2.Name);
builder.AppendLine(EquipSlot.Accessory2.Description);
}
}
@ -1288,7 +1298,7 @@ namespace Milimoe.FunGame.Core.Entity
Name = Name,
FirstName = FirstName,
NickName = NickName,
Profile = Profile,
Profile = Profile.Copy(),
MagicType = MagicType,
FirstRoleType = FirstRoleType,
SecondRoleType = SecondRoleType,
@ -1307,7 +1317,7 @@ namespace Milimoe.FunGame.Core.Entity
ExATK2 = ExATK2,
InitialDEF = InitialDEF,
ExDEF2 = ExDEF2,
MDF = MDF,
MDF = MDF.Copy(),
PhysicalPenetration = PhysicalPenetration,
MagicalPenetration = MagicalPenetration,
InitialHR = InitialHR,
@ -1349,5 +1359,94 @@ namespace Milimoe.FunGame.Core.Entity
c.Recovery();
return c;
}
/// <summary>
/// 复活此角色,回复出厂状态
/// </summary>
/// <returns></returns>
public void Respawn()
{
Item? mcp = UnEquip(EquipSlotType.MagicCardPack);
Item? w = UnEquip(EquipSlotType.Weapon);
Item? a = UnEquip(EquipSlotType.Armor);
Item? s = UnEquip(EquipSlotType.Shoes);
Item? ac1 = UnEquip(EquipSlotType.Accessory1);
Item? ac2 = UnEquip(EquipSlotType.Accessory2);
List<Skill> skills = new(Skills);
List<Item> items = new(Items);
Character c = Copy();
Effects.Clear();
Skills.Clear();
Items.Clear();
Id = c.Id;
Name = c.Name;
FirstName = c.FirstName;
NickName = c.NickName;
Profile = c.Profile.Copy();
MagicType = c.MagicType;
FirstRoleType = c.FirstRoleType;
SecondRoleType = c.SecondRoleType;
ThirdRoleType = c.ThirdRoleType;
Promotion = c.Promotion;
PrimaryAttribute = c.PrimaryAttribute;
Level = c.Level;
EXP = c.EXP;
CharacterState = c.CharacterState;
InitialHP = c.InitialHP;
ExHP2 = c.ExHP2;
InitialMP = c.InitialMP;
ExMP2 = c.ExMP2;
EP = c.EP;
InitialATK = c.InitialATK;
ExATK2 = c.ExATK2;
InitialDEF = c.InitialDEF;
ExDEF2 = c.ExDEF2;
MDF = c.MDF.Copy();
PhysicalPenetration = c.PhysicalPenetration;
MagicalPenetration = c.MagicalPenetration;
InitialHR = c.InitialHR;
ExHR = c.ExHR;
InitialMR = c.InitialMR;
ExMR = c.ExMR;
ER = c.ER;
InitialSTR = c.InitialSTR;
InitialAGI = c.InitialAGI;
InitialINT = c.InitialINT;
ExSTR = c.ExSTR;
ExAGI = c.ExAGI;
ExINT = c.ExINT;
STRGrowth = c.STRGrowth;
AGIGrowth = c.AGIGrowth;
INTGrowth = c.INTGrowth;
InitialSPD = c.InitialSPD;
ExSPD = c.ExSPD;
ExActionCoefficient = c.ExActionCoefficient;
AccelerationCoefficient = c.AccelerationCoefficient;
ExCDR = c.ExCDR;
ATR = c.ATR;
ExCritRate = c.ExCritRate;
ExCritDMG = c.ExCritDMG;
ExEvadeRate = c.ExEvadeRate;
foreach (Skill skill in skills)
{
Skill newskill = skill.Copy();
newskill.Character = this;
newskill.Level = skill.Level;
Skills.Add(newskill);
}
foreach (Item item in items)
{
Item newitem = item.Copy(true);
newitem.Character = this;
Items.Add(newitem);
}
if (mcp != null) Equip(mcp);
if (w != null) Equip(w);
if (a != null) Equip(a);
if (s != null) Equip(s);
if (ac1 != null) Equip(ac1);
if (ac2 != null) Equip(ac2);
Recovery(0D);
}
}
}

View File

@ -64,5 +64,24 @@ namespace Milimoe.FunGame.Core.Entity
/// 角色的故事
/// </summary>
public Dictionary<string, string> Stories { get; set; } = [];
/// <summary>
/// 复制一个角色资料
/// </summary>
/// <returns></returns>
public CharacterProfile Copy()
{
return new(Name, FirstName, NickName)
{
Birthplace = Birthplace,
Birthday = Birthday,
Status = Status,
Affiliation = Affiliation,
Sex = Sex,
Height = Height,
Weight = Weight,
Stories = new(Stories)
};
}
}
}

View File

@ -32,6 +32,11 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary>
public Item? Accessory2 { get; internal set; } = null;
/// <summary>
/// 上一次装备的饰品槽
/// </summary>
public EquipSlotType LastEquipSlotType { get; internal set; } = EquipSlotType.Accessory1;
/// <summary>
/// 是否有任意装备
/// </summary>
@ -40,38 +45,5 @@ namespace Milimoe.FunGame.Core.Entity
{
return MagicCardPack != null || Weapon != null || Armor != null || Shoes != null || Accessory1 != null || Accessory2 != null;
}
/// <summary>
/// 获取物品所装备的栏位
/// </summary>
/// <returns></returns>
public EquipItemToSlot GetEquipItemToSlot(Item item)
{
if (MagicCardPack == item)
{
return EquipItemToSlot.MagicCardPack;
}
else if (Weapon == item)
{
return EquipItemToSlot.Weapon;
}
else if (Armor == item)
{
return EquipItemToSlot.Armor;
}
else if (Shoes == item)
{
return EquipItemToSlot.Shoes;
}
else if (Accessory1 == item)
{
return EquipItemToSlot.Accessory1;
}
else if (Accessory2 == item)
{
return EquipItemToSlot.Accessory2;
}
return EquipItemToSlot.None;
}
}
}

View File

@ -14,5 +14,58 @@
public double Element { get; set; } = 0;
public double Fleabane { get; set; } = 0;
public double Particle { get; set; } = 0;
/// <summary>
/// 对所有抗性赋值
/// </summary>
/// <param name="value"></param>
/// <param name="assignment"></param>
public void SetAllValue(double value, bool assignment = true)
{
if (assignment)
{
None = value;
Particle = value;
Fleabane = value;
Element = value;
Shadow = value;
Bright = value;
PurityContemporary = value;
PurityNatural = value;
Starmark = value;
}
else
{
None += value;
Particle += value;
Fleabane += value;
Element += value;
Shadow += value;
Bright += value;
PurityContemporary += value;
PurityNatural += value;
Starmark += value;
}
}
/// <summary>
/// 复制一个魔法抗性对象
/// </summary>
/// <returns></returns>
public MagicResistance Copy()
{
return new()
{
None = None,
Starmark = Starmark,
PurityNatural = PurityNatural,
PurityContemporary = PurityContemporary,
Bright = Bright,
Shadow = Shadow,
Element = Element,
Fleabane = Fleabane,
Particle = Particle
};
}
}
}

View File

@ -1,7 +1,8 @@
using System.Text;
using System.Net.NetworkInformation;
using System.Text;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Interface.Base;
using Milimoe.FunGame.Core.Interface.Entity;
using Milimoe.FunGame.Core.Library.Common.Addon;
using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Entity
@ -42,7 +43,7 @@ namespace Milimoe.FunGame.Core.Entity
public bool Unequipable { get; set; } = true;
/// <summary>
/// 装备槽位
/// 当前装备槽位
/// </summary>
public virtual EquipSlotType EquipSlotType { get; set; } = EquipSlotType.None;
@ -51,6 +52,21 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary>
public virtual WeaponType WeaponType { get; set; } = WeaponType.None;
/// <summary>
/// 品质类型
/// </summary>
public virtual QualityType QualityType { get; set; } = QualityType.White;
/// <summary>
/// 稀有度类型
/// </summary>
public virtual RarityType RarityType { get; set; } = RarityType.OneStar;
/// <summary>
/// 物品评级
/// </summary>
public virtual ItemRankType RankType { get; set; } = ItemRankType.D;
/// <summary>
/// 快捷键
/// </summary>
@ -140,9 +156,10 @@ namespace Milimoe.FunGame.Core.Entity
/// <summary>
/// 当装备物品时
/// </summary>
public void OnItemEquip(Character character, EquipItemToSlot type)
public void OnItemEquip(Character character, EquipSlotType type)
{
Character = character;
EquipSlotType = type;
foreach (Skill skill in Skills.Passives)
{
if (!skill.IsActive && skill.Level > 0)
@ -164,13 +181,14 @@ namespace Milimoe.FunGame.Core.Entity
/// <summary>
/// 当取消装备物品时
/// </summary>
public void OnItemUnEquip(EquipItemToSlot type)
public void OnItemUnEquip(EquipSlotType type)
{
if (Character != null)
{
if (Skills.Active != null)
{
foreach (Effect e in Character.Effects.Where(e => e.Skill == Skills.Active && e.Level > 0).ToList())
List<Effect> effects = Character.Effects.Where(e => e.Skill == Skills.Active && e.Level > 0).ToList();
foreach (Effect e in effects)
{
Character.Effects.Remove(e);
e.OnEffectLost(Character);
@ -178,7 +196,8 @@ namespace Milimoe.FunGame.Core.Entity
}
foreach (Skill skill in Skills.Passives)
{
foreach (Effect e in Character.Effects.Where(e => e.Skill == skill && e.Level > 0).ToList())
List<Effect> effects = Character.Effects.Where(e => e.Skill == skill && e.Level > 0).ToList();
foreach (Effect e in effects)
{
Character.Effects.Remove(e);
e.OnEffectLost(Character);
@ -186,28 +205,42 @@ namespace Milimoe.FunGame.Core.Entity
}
switch (type)
{
case EquipItemToSlot.MagicCardPack:
case EquipSlotType.MagicCardPack:
Character.EquipSlot.MagicCardPack = null;
break;
case EquipItemToSlot.Weapon:
case EquipSlotType.Weapon:
Character.EquipSlot.Weapon = null;
break;
case EquipItemToSlot.Armor:
case EquipSlotType.Armor:
Character.EquipSlot.Armor = null;
break;
case EquipItemToSlot.Shoes:
case EquipSlotType.Shoes:
Character.EquipSlot.Shoes = null;
break;
case EquipItemToSlot.Accessory1:
case EquipSlotType.Accessory1:
Character.EquipSlot.Accessory1 = null;
break;
case EquipItemToSlot.Accessory2:
case EquipSlotType.Accessory2:
Character.EquipSlot.Accessory2 = null;
break;
}
OnItemUnEquipped(Character, this, type);
}
Character = null;
EquipSlotType = EquipSlotType.None;
}
/// <summary>
/// 设置游戏内的行动顺序表实例
/// </summary>
/// <param name="queue"></param>
public void SetGamingQueue(IGamingQueue queue)
{
if (Skills.Active != null) Skills.Active.GamingQueue = queue;
foreach (Skill skill in Skills.Passives)
{
skill.GamingQueue = queue;
}
}
/// <summary>
@ -215,8 +248,19 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary>
public void UseItem(IGamingQueue queue, Character character, List<Character> enemys, List<Character> teammates)
{
OnItemUsed(character, this);
Skills.Active?.OnSkillCasted(queue, character, enemys, teammates);
bool cancel = false;
bool used = false;
if (Skills.Active != null)
{
Skill skill = Skills.Active;
List<Character> targets = queue.SelectTargets(character, skill, enemys, teammates, out cancel);
if (!cancel)
{
skill.OnSkillCasted(queue, character, targets);
used = true;
}
}
OnItemUsed(character, this, cancel, used);
}
/// <summary>
@ -232,7 +276,9 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary>
/// <param name="character"></param>
/// <param name="item"></param>
public virtual void OnItemUsed(Character character, Item item)
/// <param name="cancel"></param>
/// <param name="used"></param>
public virtual void OnItemUsed(Character character, Item item, bool cancel, bool used)
{
}
@ -253,7 +299,7 @@ namespace Milimoe.FunGame.Core.Entity
/// <param name="character"></param>
/// <param name="item"></param>
/// <param name="type"></param>
public virtual void OnItemEquipped(Character character, Item item, EquipItemToSlot type)
public virtual void OnItemEquipped(Character character, Item item, EquipSlotType type)
{
}
@ -264,17 +310,16 @@ namespace Milimoe.FunGame.Core.Entity
/// <param name="character"></param>
/// <param name="item"></param>
/// <param name="type"></param>
public virtual void OnItemUnEquipped(Character character, Item item, EquipItemToSlot type)
public virtual void OnItemUnEquipped(Character character, Item item, EquipSlotType type)
{
}
protected Item(ItemType type, bool isInGame = true, EquipSlotType slot = EquipSlotType.None)
protected Item(ItemType type, bool isInGame = true)
{
ItemType = type;
IsInGameItem = isInGame;
EquipSlotType = slot;
}
internal Item() { }
@ -307,7 +352,7 @@ namespace Milimoe.FunGame.Core.Entity
StringBuilder builder = new();
builder.AppendLine($"【{Name}】");
builder.AppendLine($"{ItemSet.GetItemTypeName(ItemType)}" + (IsPurchasable && Price > 0 ? $" 售价:{Price}" : ""));
builder.AppendLine($"{ItemSet.GetItemTypeName(ItemType) + (ItemType == ItemType.Weapon && WeaponType != WeaponType.None ? "-" + ItemSet.GetWeaponTypeName(WeaponType) : "")}" + (IsPurchasable && Price > 0 ? $" 售价:{Price}" : ""));
if (RemainUseTimes > 0)
{
@ -369,61 +414,83 @@ namespace Milimoe.FunGame.Core.Entity
}
/// <summary>
/// 设置一些属性给从 <see cref="ItemModule"/> 新建来的 <paramref name="newbyItemModule"/><para/>
/// 对于还原存档而言,在使用 JSON 反序列化 Item且从 <see cref="ItemModule.GetItem"/> 中获取了实例后,需要使用此方法复制给新实例
/// 设置一些属性给从工厂构造出来的 <paramref name="newbyFactory"/> 对象
/// </summary>
/// <param name="newbyItemModule"></param>
public void SetPropertyToItemModuleNew(Item newbyItemModule)
/// <param name="newbyFactory"></param>
public void SetPropertyToItemModuleNew(Item newbyFactory)
{
newbyItemModule.WeaponType = WeaponType;
newbyItemModule.EquipSlotType = EquipSlotType;
newbyItemModule.Equipable = Equipable;
newbyItemModule.IsPurchasable = IsPurchasable;
newbyItemModule.Price = Price;
newbyItemModule.IsSellable = IsSellable;
newbyItemModule.NextSellableTime = NextSellableTime;
newbyItemModule.IsTradable = IsTradable;
newbyItemModule.NextTradableTime = NextTradableTime;
newbyFactory.WeaponType = WeaponType;
newbyFactory.EquipSlotType = EquipSlotType;
newbyFactory.Equipable = Equipable;
newbyFactory.IsPurchasable = IsPurchasable;
newbyFactory.Price = Price;
newbyFactory.IsSellable = IsSellable;
newbyFactory.NextSellableTime = NextSellableTime;
newbyFactory.IsTradable = IsTradable;
newbyFactory.NextTradableTime = NextTradableTime;
}
/// <summary>
/// 复制一个物品
/// </summary>
/// <returns></returns>
public Item Copy()
public Item Copy(bool copyLevel = false)
{
Item item = new()
{
Id = Id,
Name = Name,
Description = Description,
GeneralDescription = GeneralDescription,
ItemType = ItemType,
Equipable = Equipable,
Unequipable = Unequipable,
EquipSlotType = EquipSlotType,
WeaponType = WeaponType,
Key = Key,
Enable = Enable,
IsInGameItem = IsInGameItem,
IsPurchasable = IsPurchasable,
Price = Price,
IsSellable = IsSellable,
NextSellableTime = NextSellableTime,
IsTradable = IsTradable,
NextTradableTime = NextTradableTime,
RemainUseTimes = RemainUseTimes,
};
Item item = Factory.OpenFactory.GetInstance<Item>(Id, Name, []);
SetPropertyToItemModuleNew(item);
item.Id = Id;
item.Name = Name;
item.Description = Description;
item.GeneralDescription = GeneralDescription;
item.BackgroundStory = BackgroundStory;
item.ItemType = ItemType;
item.Equipable = Equipable;
item.Unequipable = Unequipable;
item.WeaponType = WeaponType;
item.QualityType = QualityType;
item.RarityType = RarityType;
item.RankType = RankType;
item.Key = Key;
item.Enable = Enable;
item.IsInGameItem = IsInGameItem;
item.IsPurchasable = IsPurchasable;
item.Price = Price;
item.IsSellable = IsSellable;
item.NextSellableTime = NextSellableTime;
item.IsTradable = IsTradable;
item.NextTradableTime = NextTradableTime;
item.RemainUseTimes = RemainUseTimes;
item.Skills.Active = Skills.Active?.Copy();
if (item.Skills.Active != null && copyLevel)
{
item.Skills.Active.Level = Skills.Active?.Level ?? 0;
}
foreach (Skill skill in Skills.Passives)
{
Skill newskill = skill.Copy();
newskill.Item = item;
newskill.Level = copyLevel ? skill.Level : 0;
item.Skills.Passives.Add(newskill);
}
return item;
}
/// <summary>
/// 设置所有技能的等级
/// </summary>
/// <param name="level"></param>
public void SetLevel(int level)
{
if (Skills.Active != null)
{
Skills.Active.Level = level;
}
foreach (Skill skill in Skills.Passives)
{
skill.Level = level;
}
}
/// <summary>
/// 所属的角色
/// </summary>

View File

@ -90,6 +90,11 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary>
public IGamingQueue? GamingQueue { get; set; } = null;
/// <summary>
/// 用于动态扩展特效的参数
/// </summary>
public Dictionary<string, object> Values { get; } = [];
/// <summary>
/// 输出文本或日志
/// </summary>
@ -102,9 +107,16 @@ namespace Milimoe.FunGame.Core.Entity
}
}
protected Effect(Skill skill)
protected Effect(Skill skill, Dictionary<string, object>? args = null)
{
Skill = skill;
if (args != null)
{
foreach (string key in args.Keys)
{
Values[key] = args[key];
}
}
}
internal Effect()
@ -240,10 +252,9 @@ namespace Milimoe.FunGame.Core.Entity
/// 吟唱结束后释放技能(魔法)/ 直接释放技能(战技/爆发技)
/// </summary>
/// <param name="caster"></param>
/// <param name="enemys"></param>
/// <param name="teammates"></param>
/// <param name="targets"></param>
/// <param name="others"></param>
public virtual void OnSkillCasted(Character caster, List<Character> enemys, List<Character> teammates, Dictionary<string, object> others)
public virtual void OnSkillCasted(Character caster, List<Character> targets, Dictionary<string, object> others)
{
}
@ -323,6 +334,17 @@ namespace Milimoe.FunGame.Core.Entity
}
/// <summary>
/// 闪避检定前触发
/// </summary>
/// <param name="character"></param>
/// <param name="throwingBonus"></param>
/// <returns>返回 false 表示不进行闪避检定</returns>
public virtual bool BeforeEvadeCheck(Character character, ref double throwingBonus)
{
return true;
}
/// <summary>
/// 在触发闪避时
/// </summary>
@ -335,6 +357,17 @@ namespace Milimoe.FunGame.Core.Entity
return false;
}
/// <summary>
/// 暴击检定前触发
/// </summary>
/// <param name="character"></param>
/// <param name="throwingBonus"></param>
/// <returns>返回 false 表示不进行暴击检定</returns>
public virtual bool BeforeCriticalCheck(Character character, ref double throwingBonus)
{
return true;
}
/// <summary>
/// 在触发暴击时
/// </summary>
@ -441,20 +474,24 @@ namespace Milimoe.FunGame.Core.Entity
/// <returns></returns>
public Effect Copy(Skill skill)
{
Effect copy = new(skill)
Dictionary<string, object> args = new()
{
EffectType = EffectType,
TargetSelf = TargetSelf,
TargetCount = TargetCount,
TargetRange = TargetRange,
Durative = Durative,
Duration = Duration,
DurationTurn = DurationTurn,
MagicType = MagicType,
Description = Description,
GamingQueue = GamingQueue
{ "skill", skill },
{ "values", Values }
};
Effect copy = Factory.OpenFactory.GetInstance<Effect>(Id, Name, args);
copy.Id = Id;
copy.Name = Name;
copy.Description = Description;
copy.EffectType = EffectType;
copy.TargetSelf = TargetSelf;
copy.TargetCount = TargetCount;
copy.TargetRange = TargetRange;
copy.Durative = Durative;
copy.Duration = Duration;
copy.DurationTurn = DurationTurn;
copy.MagicType = MagicType;
copy.GamingQueue = GamingQueue;
return copy;
}

34
Entity/Skill/OpenSkill.cs Normal file
View File

@ -0,0 +1,34 @@
using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Entity
{
/// <summary>
/// 用于动态扩展技能,<see cref="Description"/> 返回所有特效的描述
/// </summary>
public class OpenSkill : Skill
{
public override long Id { get; set; }
public override string Name { get; set; }
public override string Description => string.Join("\r\n", Effects);
public OpenSkill(long id, string name, Dictionary<string, object> args, Character? character = null) : base(SkillType.Passive, character)
{
Id = id;
Name = name;
foreach (string str in args.Keys)
{
Values[str] = args[str];
switch (str)
{
default:
break;
}
}
}
public override IEnumerable<Effect> AddInactiveEffectToCharacter()
{
return Effects;
}
}
}

View File

@ -2,7 +2,6 @@
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Interface.Base;
using Milimoe.FunGame.Core.Interface.Entity;
using Milimoe.FunGame.Core.Library.Common.Addon;
using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Entity
@ -27,6 +26,11 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary>
public virtual string GeneralDescription { get; set; } = "";
/// <summary>
/// 释放技能时的口号
/// </summary>
public virtual string Slogan { get; set; } = "";
/// <summary>
/// 技能等级,等于 0 时可以称之为尚未学习
/// </summary>
@ -78,6 +82,21 @@ namespace Milimoe.FunGame.Core.Entity
[InitRequired]
public bool IsMagic => SkillType == SkillType.Magic;
/// <summary>
/// 可选取自身
/// </summary>
public virtual bool CanSelectSelf { get; set; } = false;
/// <summary>
/// 可选取的作用目标数量
/// </summary>
public virtual int CanSelectTargetCount { get; set; } = 1;
/// <summary>
/// 可选取的作用范围
/// </summary>
public virtual double CanSelectTargetRange { get; set; } = 0;
/// <summary>
/// 实际魔法消耗 [ 魔法 ]
/// </summary>
@ -103,7 +122,7 @@ namespace Milimoe.FunGame.Core.Entity
/// <summary>
/// 实际能量消耗 [ 战技 ]
/// </summary>
public double RealEPCost => IsSuperSkill ? EPCost : Math.Max(0, EPCost * (1 - Calculation.PercentageCheck((Character?.INT ?? 0) * 0.00075)));
public double RealEPCost => CostAllEP ? Math.Max(MinCostEP, Character?.EP ?? MinCostEP) : (IsSuperSkill ? EPCost : Math.Max(0, EPCost * (1 - Calculation.PercentageCheck((Character?.INT ?? 0) * 0.00075))));
/// <summary>
/// 能量消耗 [ 战技 ]
@ -111,6 +130,16 @@ namespace Milimoe.FunGame.Core.Entity
[InitOptional]
public virtual double EPCost { get; set; } = 0;
/// <summary>
/// 消耗所有能量 [ 战技 ]
/// </summary>
public virtual bool CostAllEP { get; set; } = false;
/// <summary>
/// 消耗所有能量的最小能量限制 [ 战技 ] 默认值100
/// </summary>
public virtual double MinCostEP { get; set; } = 100;
/// <summary>
/// 实际冷却时间
/// </summary>
@ -139,9 +168,9 @@ namespace Milimoe.FunGame.Core.Entity
public HashSet<Effect> Effects { get; } = [];
/// <summary>
/// 其他参数
/// 用于动态扩展技能的参数
/// </summary>
public Dictionary<string, object> OtherArgs { get; } = [];
public Dictionary<string, object> Values { get; } = [];
/// <summary>
/// 游戏中的行动顺序表实例,在技能效果被触发时,此实例会获得赋值,使用时需要判断其是否存在
@ -170,15 +199,14 @@ namespace Milimoe.FunGame.Core.Entity
internal Skill() { }
/// <summary>
/// 设置一些属性给从 <see cref="SkillModule"/> 新建来的 <paramref name="newbySkillModule"/><para/>
/// 对于还原存档而言,在使用 JSON 反序列化 Skill且从 <see cref="SkillModule.GetSkill"/> 中获取了实例后,需要使用此方法复制给新实例
/// 设置一些属性给从工厂构造出来的 <paramref name="newbyFactory"/> 对象
/// </summary>
/// <param name="newbySkillModule"></param>
public void SetPropertyToItemModuleNew(Skill newbySkillModule)
/// <param name="newbyFactory"></param>
public void SetPropertyToItemModuleNew(Skill newbyFactory)
{
newbySkillModule.Enable = Enable;
newbySkillModule.IsInEffect = IsInEffect;
newbySkillModule.CurrentCD = CurrentCD;
newbyFactory.Enable = Enable;
newbyFactory.IsInEffect = IsInEffect;
newbyFactory.CurrentCD = CurrentCD;
}
/// <summary>
@ -210,9 +238,37 @@ namespace Milimoe.FunGame.Core.Entity
OnLevelUp();
}
/// <summary>
/// 选取技能目标
/// </summary>
/// <param name="caster"></param>
/// <param name="enemys"></param>
/// <param name="teammates"></param>
/// <returns></returns>
public virtual List<Character> SelectTargets(Character caster, List<Character> enemys, List<Character> teammates)
{
if (CanSelectSelf)
{
return [caster];
}
else
{
List<Character> targets = [];
if (enemys.Count <= CanSelectTargetCount)
{
return [.. enemys];
}
return enemys.OrderBy(x => Random.Shared.Next()).Take(CanSelectTargetCount).ToList();
}
}
/// <summary>
/// 技能开始吟唱时 [ 吟唱魔法、释放战技和爆发技、预释放爆发技均可触发 ]
/// </summary>
/// <param name="queue"></param>
/// <param name="caster"></param>
public void OnSkillCasting(IGamingQueue queue, Character caster)
{
GamingQueue = queue;
@ -226,13 +282,16 @@ namespace Milimoe.FunGame.Core.Entity
/// <summary>
/// 触发技能效果
/// </summary>
public void OnSkillCasted(IGamingQueue queue, Character caster, List<Character> enemys, List<Character> teammates)
/// <param name="queue"></param>
/// <param name="caster"></param>
/// <param name="targets"></param>
public void OnSkillCasted(IGamingQueue queue, Character caster, List<Character> targets)
{
GamingQueue = queue;
foreach (Effect e in Effects)
{
e.GamingQueue = GamingQueue;
e.OnSkillCasted(caster, enemys, teammates, OtherArgs);
e.OnSkillCasted(caster, targets, Values);
}
}
@ -333,27 +392,33 @@ namespace Milimoe.FunGame.Core.Entity
/// <returns></returns>
public Skill Copy()
{
Skill s = new()
Dictionary<string, object> args = new()
{
Id = Id,
Name = Name,
Description = Description,
GeneralDescription = GeneralDescription,
SkillType = SkillType,
MPCost = MPCost,
CastTime = CastTime,
EPCost = EPCost,
CD = CD,
CurrentCD = CurrentCD,
HardnessTime = HardnessTime,
GamingQueue = GamingQueue
{ "values", Values }
};
Skill skill = Factory.OpenFactory.GetInstance<Skill>(Id, Name, args);
SetPropertyToItemModuleNew(skill);
skill.Id = Id;
skill.Name = Name;
skill.Description = Description;
skill.GeneralDescription = GeneralDescription;
skill.SkillType = SkillType;
skill.MPCost = MPCost;
skill.CastTime = CastTime;
skill.EPCost = EPCost;
skill.CD = CD;
skill.CurrentCD = CurrentCD;
skill.HardnessTime = HardnessTime;
skill.GamingQueue = GamingQueue;
if (skill is OpenSkill)
{
foreach (Effect e in Effects)
{
Effect neweffect = e.Copy(s);
s.Effects.Add(neweffect);
Effect neweffect = e.Copy(skill);
skill.Effects.Add(neweffect);
}
return s;
}
return skill;
}
/// <summary>

View File

@ -0,0 +1,8 @@
namespace Milimoe.FunGame.Core.Entity
{
public struct SkillTarget(Skill skill, List<Character> targets)
{
public Skill Skill { get; set; } = skill;
public List<Character> Targets { get; set; } = targets;
}
}

View File

@ -32,6 +32,8 @@
public int Kills { get; set; } = 0;
public int Deaths { get; set; } = 0;
public int Assists { get; set; } = 0;
public int FirstKills { get; set; } = 0;
public int FirstDeaths { get; set; } = 0;
public int Plays { get; set; } = 0;
public int Wins { get; set; } = 0;
public int Top3s { get; set; } = 0;
@ -40,5 +42,6 @@
public double Top3rates { get; set; } = 0;
public int LastRank { get; set; } = 0;
public double AvgRank { get; set; } = 0;
public double Rating { get; set; } = 0;
}
}

View File

@ -0,0 +1,14 @@
using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Entity.System
{
public class RoundRecord(int round, Character actor)
{
public int Round { get; set; } = round;
public Character Actor { get; set; } = actor;
public CharacterActionType ActionType { get; set; } = CharacterActionType.None;
public List<Character> Targets { get; set; } = [];
public Skill? Skill { get; set; } = null;
public Item? Item { get; set; } = null;
}
}

39
Entity/System/Team.cs Normal file
View File

@ -0,0 +1,39 @@
using Milimoe.FunGame.Core.Interface.Base;
namespace Milimoe.FunGame.Core.Entity
{
public class Team(string name, IEnumerable<Character> charaters)
{
public Guid Id { get; set; } = Guid.Empty;
public string Name { get; set; } = name;
public List<Character> Members { get; } = new(charaters);
public int Score { get; set; } = 0;
public bool IsWinner { get; set; } = false;
public int Count => Members.Count;
public List<Character> GetActiveCharacters(IGamingQueue queue)
{
return [.. Members.Where(queue.Queue.Contains)];
}
public List<Character> GetTeammates(Character character)
{
return [.. Members.Where(c => c != character)];
}
public List<Character> GetActiveTeammates(IGamingQueue queue, Character character)
{
return [.. Members.Where(c => queue.Queue.Contains(c) && c != character)];
}
public bool IsOnThisTeam(Character character)
{
return Members.Contains(character);
}
public override string ToString()
{
return Name;
}
}
}

View File

@ -99,5 +99,27 @@ namespace Milimoe.FunGame.Core.Interface.Base
/// <param name="caster"></param>
/// <param name="interrupter"></param>
public void InterruptCasting(Character caster, Character interrupter);
/// <summary>
/// 选取技能目标
/// </summary>
/// <param name="caster"></param>
/// <param name="skill"></param>
/// <param name="enemys"></param>
/// <param name="teammates"></param>
/// <param name="cancel"></param>
/// <returns></returns>
public List<Character> SelectTargets(Character caster, Skill skill, List<Character> enemys, List<Character> teammates, out bool cancel);
/// <summary>
/// 选取普通攻击目标
/// </summary>
/// <param name="character"></param>
/// <param name="attack"></param>
/// <param name="enemys"></param>
/// <param name="teammates"></param>
/// <param name="cancel"></param>
/// <returns></returns>
public List<Character> SelectTargets(Character character, NormalAttack attack, List<Character> enemys, List<Character> teammates, out bool cancel);
}
}

View File

@ -1,4 +1,5 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Interface.Addons;
namespace Milimoe.FunGame.Core.Library.Common.Addon
@ -28,7 +29,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
/// <summary>
/// 此模组中包含的角色
/// </summary>
public abstract List<Character> Characters { get; }
public abstract Dictionary<string, Character> Characters { get; }
/// <summary>
/// 加载标记
@ -49,12 +50,28 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
{
// 模组加载后,不允许再次加载此模组
IsLoaded = true;
// 注册工厂
Factory.OpenFactory.RegisterFactory(EntityFactory());
// 如果加载后需要执行代码请重写AfterLoad方法
AfterLoad();
}
return IsLoaded;
}
/// <summary>
/// 注册工厂
/// </summary>
protected virtual Factory.EntityFactoryDelegate<Character> EntityFactory()
{
return (id, name, args) =>
{
Character c = Factory.GetCharacter();
c.Id = id;
c.Name = name;
return c;
};
}
/// <summary>
/// 模组加载后需要做的事
/// </summary>

View File

@ -251,11 +251,11 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
public override string Author => "FunGamer";
public override List<Character> Characters
public override Dictionary<string, Character> Characters
{
get
{
List<Character> list = [];
Dictionary<string, Character> dict = [];
// 构建一个你想要的角色
Character c = Factory.GetCharacter();
c.Name = "Oshima";
@ -268,8 +268,8 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
c.InitialINT = 5;
c.InitialATK = 100;
c.InitialDEF = 10;
list.Add(c);
return list;
dict.Add(c.Name, c);
return dict;
}
}
}
@ -287,20 +287,31 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
public override string Author => "FunGamer";
public override List<Skill> Skills
public override Dictionary<string, Skill> Skills
{
get
{
List<Skill> list = [];
Dictionary<string, Skill> dict = [];
// 技能应该在GameModule中新建类继承Skill实现再自行构造。
return list;
return dict;
}
}
public override Skill? GetSkill(long id, string name, SkillType type)
protected override Factory.EntityFactoryDelegate<Skill> SkillFactory()
{
// 此方法将根据id和name返回一个你继承实现了的类对象。
return Factory.GetSkill();
// 注册一个工厂根据id和name返回一个你继承实现了的类对象。
return (id, name, args) =>
{
return null;
};
}
protected override Factory.EntityFactoryDelegate<Effect> EffectFactory()
{
return (id, name, args) =>
{
return null;
};
}
}
@ -317,20 +328,23 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
public override string Author => "FunGamer";
public override List<Item> Items
public override Dictionary<string, Item> Items
{
get
{
List<Item> list = [];
Dictionary<string, Item> dict = [];
// 物品应该在GameModule中新建类继承Item实现再自行构造。
return list;
return dict;
}
}
public override Item? GetItem(long id, string name, ItemType type)
protected override Factory.EntityFactoryDelegate<Item> ItemFactory()
{
// 此方法将根据id和name返回一个你继承实现了的类对象。
return Factory.GetItem();
// 注册一个工厂根据id和name返回一个你继承实现了的类对象。
return (id, name, args) =>
{
return null;
};
}
}
}

View File

@ -42,19 +42,19 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
/// 实际使用的角色组对象<para/>
/// 请使用 <see cref="GetDependencies"/> 自动填充,不要自己添加
/// </summary>
public List<Character> Characters { get; } = [];
public Dictionary<string, Character> Characters { get; } = [];
/// <summary>
/// 实际使用的技能组对象<para/>
/// 请使用 <see cref="GetDependencies"/> 自动填充,不要自己添加
/// </summary>
public List<Skill> Skills { get; } = [];
public Dictionary<string, Skill> Skills { get; } = [];
/// <summary>
/// 实际使用的物品组对象<para/>
/// 请使用 <see cref="GetDependencies"/> 自动填充,不要自己添加
/// </summary>
public List<Item> Items { get; } = [];
public Dictionary<string, Item> Items { get; } = [];
/// <summary>
/// 获得所有的依赖项<para/>
@ -69,15 +69,24 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
Maps.AddRange(loader.Maps.Keys.Where(MapsDepend.Contains).Select(str => loader.Maps[str]));
foreach (CharacterModule modules in loader.Characters.Keys.Where(CharactersDepend.Contains).Select(str => loader.Characters[str]))
{
Characters.AddRange(modules.Characters);
foreach (string key in modules.Characters.Keys)
{
Characters[key] = modules.Characters[key];
}
}
foreach (SkillModule modules in loader.Skills.Keys.Where(SkillsDepend.Contains).Select(str => loader.Skills[str]))
{
Skills.AddRange(modules.Skills);
foreach (string key in modules.Skills.Keys)
{
Skills[key] = modules.Skills[key];
}
}
foreach (ItemModule modules in loader.Items.Keys.Where(ItemsDepend.Contains).Select(str => loader.Items[str]))
{
Items.AddRange(modules.Items);
foreach (string key in modules.Items.Keys)
{
Items[key] = modules.Items[key];
}
}
}
}

View File

@ -1,7 +1,6 @@
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Interface.Addons;
using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Library.Common.Addon
{
@ -30,25 +29,13 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
/// <summary>
/// 此模组中包含的物品
/// </summary>
public abstract List<Item> Items { get; }
public abstract Dictionary<string, Item> Items { get; }
/// <summary>
/// 加载标记
/// </summary>
private bool IsLoaded = false;
/// <summary>
/// [可选实现] 在使用 <see cref="EntityModuleConfig{Item}"/> 后,可以按 id + name + type 来匹配已编码的物品
/// </summary>
/// <param name="id"></param>
/// <param name="name"></param>
/// <param name="type"></param>
/// <returns></returns>
public virtual Item? GetItem(long id, string name, ItemType type)
{
return null;
}
/// <summary>
/// 加载模组
/// </summary>
@ -63,12 +50,19 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
{
// 模组加载后,不允许再次加载此模组
IsLoaded = true;
// 注册工厂
Factory.OpenFactory.RegisterFactory(ItemFactory());
// 如果加载后需要执行代码请重写AfterLoad方法
AfterLoad();
}
return IsLoaded;
}
/// <summary>
/// 注册工厂
/// </summary>
protected abstract Factory.EntityFactoryDelegate<Item> ItemFactory();
/// <summary>
/// 模组加载后需要做的事
/// </summary>

View File

@ -1,7 +1,6 @@
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Interface.Addons;
using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Library.Common.Addon
{
@ -30,25 +29,13 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
/// <summary>
/// 此模组中包含的技能
/// </summary>
public abstract List<Skill> Skills { get; }
public abstract Dictionary<string, Skill> Skills { get; }
/// <summary>
/// 加载标记
/// </summary>
private bool IsLoaded = false;
/// <summary>
/// [可选实现] 在使用 <see cref="EntityModuleConfig{Skill}"/> 后,可以按 id + name + type 来匹配已编码的技能
/// </summary>
/// <param name="id"></param>
/// <param name="name"></param>
/// <param name="type"></param>
/// <returns></returns>
public virtual Skill? GetSkill(long id, string name, SkillType type)
{
return null;
}
/// <summary>
/// 加载模组
/// </summary>
@ -63,12 +50,25 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
{
// 模组加载后,不允许再次加载此模组
IsLoaded = true;
// 注册工厂
Factory.OpenFactory.RegisterFactory(SkillFactory());
Factory.OpenFactory.RegisterFactory(EffectFactory());
// 如果加载后需要执行代码请重写AfterLoad方法
AfterLoad();
}
return IsLoaded;
}
/// <summary>
/// 注册工厂
/// </summary>
protected abstract Factory.EntityFactoryDelegate<Skill> SkillFactory();
/// <summary>
/// 注册工厂(特效类)
/// </summary>
protected abstract Factory.EntityFactoryDelegate<Effect> EffectFactory();
/// <summary>
/// 模组加载后需要做的事
/// </summary>

View File

@ -21,6 +21,20 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
case nameof(Effect.Name):
result.Name = reader.GetString() ?? "";
break;
default:
if (reader.TokenType == JsonTokenType.Number)
{
result.Values[propertyName] = reader.GetDouble();
}
else if (reader.TokenType == JsonTokenType.String)
{
result.Values[propertyName] = reader.GetString() ?? "";
}
else if (reader.TokenType == JsonTokenType.True || reader.TokenType == JsonTokenType.False)
{
result.Values[propertyName] = reader.GetBoolean();
}
break;
}
}
@ -31,6 +45,28 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
writer.WriteNumber(nameof(Effect.Id), (int)value.Id);
writer.WriteString(nameof(Effect.Name), value.Name);
foreach (var kvp in value.Values)
{
switch (kvp.Value)
{
case int intValue:
writer.WriteNumber(kvp.Key, intValue);
break;
case double doubleValue:
writer.WriteNumber(kvp.Key, doubleValue);
break;
case bool boolValue:
writer.WriteBoolean(kvp.Key, boolValue);
break;
case string strValue:
writer.WriteString(kvp.Key, strValue);
break;
default:
JsonSerializer.Serialize(writer, kvp.Value, options);
break;
}
}
writer.WriteEndObject();
}
}

View File

@ -48,14 +48,14 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
break;
case nameof(EquipSlot.Accessory1):
temp = NetworkUtility.JsonDeserialize<Item>(ref reader, options) ?? new();
if (temp.EquipSlotType == EquipSlotType.Accessory)
if (temp.EquipSlotType == EquipSlotType.Accessory1)
{
result.Accessory1 = temp;
}
break;
case nameof(EquipSlot.Accessory2):
temp = NetworkUtility.JsonDeserialize<Item>(ref reader, options) ?? new();
if (temp.EquipSlotType == EquipSlotType.Accessory)
if (temp.EquipSlotType == EquipSlotType.Accessory2)
{
result.Accessory2 = temp;
}

View File

@ -41,6 +41,15 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
case nameof(Item.EquipSlotType):
result.EquipSlotType = (EquipSlotType)reader.GetInt32();
break;
case nameof(Item.QualityType):
result.QualityType = (QualityType)reader.GetInt32();
break;
case nameof(Item.RarityType):
result.RarityType = (RarityType)reader.GetInt32();
break;
case nameof(Item.RankType):
result.RankType = (ItemRankType)reader.GetInt32();
break;
case nameof(Item.IsInGameItem):
result.IsInGameItem = reader.GetBoolean();
break;
@ -101,6 +110,9 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
writer.WriteNumber(nameof(Item.ItemType), (int)value.ItemType);
writer.WriteNumber(nameof(Item.WeaponType), (int)value.WeaponType);
writer.WriteNumber(nameof(Item.EquipSlotType), (int)value.EquipSlotType);
writer.WriteNumber(nameof(Item.QualityType), (int)value.QualityType);
writer.WriteNumber(nameof(Item.RarityType), (int)value.RarityType);
writer.WriteNumber(nameof(Item.RankType), (int)value.RankType);
writer.WriteBoolean(nameof(Item.IsInGameItem), value.IsInGameItem);
writer.WriteBoolean(nameof(Item.Equipable), value.Equipable);
writer.WriteBoolean(nameof(Item.IsPurchasable), value.IsPurchasable);

View File

@ -10,7 +10,7 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
{
public override Skill NewInstance()
{
return new();
return new OpenSkill(0, "", []);
}
public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Skill result)
@ -29,12 +29,24 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
case nameof(Skill.GeneralDescription):
result.GeneralDescription = reader.GetString() ?? "";
break;
case nameof(Skill.Slogan):
result.Slogan = reader.GetString() ?? "";
break;
case nameof(Skill.Level):
result.Level = reader.GetInt32();
break;
case nameof(Skill.SkillType):
result.SkillType = (SkillType)reader.GetInt32();
break;
case nameof(Skill.CanSelectSelf):
result.CanSelectSelf = reader.GetBoolean();
break;
case nameof(Skill.CanSelectTargetCount):
result.CanSelectTargetCount = reader.GetInt32();
break;
case nameof(Skill.CanSelectTargetRange):
result.CanSelectTargetRange = reader.GetInt32();
break;
case nameof(Skill.Enable):
result.Enable = reader.GetBoolean();
break;
@ -66,11 +78,11 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
result.Effects.Add(effect);
}
break;
case nameof(Skill.OtherArgs):
Dictionary<string, object> others = NetworkUtility.JsonDeserialize<Dictionary<string, object>>(ref reader, options) ?? [];
foreach (string key in others.Keys)
case nameof(Skill.Values):
Dictionary<string, object> values = NetworkUtility.JsonDeserialize<Dictionary<string, object>>(ref reader, options) ?? [];
foreach (string key in values.Keys)
{
result.OtherArgs.Add(key, others[key]);
result.Values.Add(key, values[key]);
}
break;
}
@ -84,8 +96,12 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
writer.WriteString(nameof(Skill.Name), value.Name);
writer.WriteString(nameof(Skill.Description), value.Description);
if (value.GeneralDescription.Length > 0) writer.WriteString(nameof(Skill.GeneralDescription), value.GeneralDescription);
if (value.Slogan.Length > 0) writer.WriteString(nameof(Skill.Slogan), value.Slogan);
if (value.Level > 0) writer.WriteNumber(nameof(Skill.Level), value.Level);
writer.WriteNumber(nameof(Skill.SkillType), (int)value.SkillType);
if (value.CanSelectSelf) writer.WriteBoolean(nameof(Skill.CanSelectSelf), value.CanSelectSelf);
if (value.CanSelectTargetCount != 0) writer.WriteNumber(nameof(Skill.CanSelectTargetCount), value.CanSelectTargetCount);
if (value.CanSelectTargetRange != 0) writer.WriteNumber(nameof(Skill.CanSelectTargetRange), value.CanSelectTargetRange);
if (!value.Enable) writer.WriteBoolean(nameof(Skill.Enable), value.Enable);
if (value.IsInEffect) writer.WriteBoolean(nameof(Skill.IsInEffect), value.IsInEffect);
if (value.MPCost > 0) writer.WriteNumber(nameof(Skill.MPCost), value.MPCost);
@ -96,8 +112,8 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
if (value.HardnessTime > 0) writer.WriteNumber(nameof(Skill.HardnessTime), value.HardnessTime);
writer.WritePropertyName(nameof(Skill.Effects));
JsonSerializer.Serialize(writer, value.Effects, options);
writer.WritePropertyName(nameof(Skill.OtherArgs));
JsonSerializer.Serialize(writer, value.OtherArgs, options);
writer.WritePropertyName(nameof(Skill.Values));
JsonSerializer.Serialize(writer, value.Values, options);
writer.WriteEndObject();
}

View File

@ -325,6 +325,22 @@ namespace Milimoe.FunGame.Core.Library.Constant
};
}
public static string GetMagicResistanceName(MagicType type)
{
return type switch
{
MagicType.Starmark => "星痕抗性",
MagicType.PurityNatural => "现代结晶抗性",
MagicType.PurityContemporary => "纯粹结晶抗性",
MagicType.Bright => "光抗性",
MagicType.Shadow => "影抗性",
MagicType.Element => "元素抗性",
MagicType.Fleabane => "紫宛抗性",
MagicType.Particle => "时空抗性",
_ => "魔法抗性",
};
}
public static string GetContinuousKilling(int kills)
{
if (kills > 10) return "超越神的杀戮";
@ -447,7 +463,8 @@ namespace Milimoe.FunGame.Core.Library.Constant
EquipSlotType.Weapon => "武器",
EquipSlotType.Armor => "防具",
EquipSlotType.Shoes => "鞋子",
EquipSlotType.Accessory => "饰品",
EquipSlotType.Accessory1 => "饰品1",
EquipSlotType.Accessory2 => "饰品2",
_ => ""
};
}
@ -460,38 +477,11 @@ namespace Milimoe.FunGame.Core.Library.Constant
"武器" => EquipSlotType.Weapon,
"防具" => EquipSlotType.Armor,
"鞋子" => EquipSlotType.Shoes,
"饰品" => EquipSlotType.Accessory,
"饰品1" => EquipSlotType.Accessory1,
"饰品2" => EquipSlotType.Accessory2,
_ => EquipSlotType.None
};
}
public static string GetEquipItemToSlotTypeName(EquipItemToSlot type)
{
return type switch
{
EquipItemToSlot.MagicCardPack => "魔法卡包",
EquipItemToSlot.Weapon => "武器",
EquipItemToSlot.Armor => "防具",
EquipItemToSlot.Shoes => "鞋子",
EquipItemToSlot.Accessory1 => "饰品1",
EquipItemToSlot.Accessory2 => "饰品2",
_ => ""
};
}
public static EquipItemToSlot GetEquipItemToSlotTypeFromName(string name)
{
return name switch
{
"魔法卡包" => EquipItemToSlot.MagicCardPack,
"武器" => EquipItemToSlot.Weapon,
"防具" => EquipItemToSlot.Armor,
"鞋子" => EquipItemToSlot.Shoes,
"饰品1" => EquipItemToSlot.Accessory1,
"饰品2" => EquipItemToSlot.Accessory2,
_ => EquipItemToSlot.None
};
}
}
public class SkillSet

View File

@ -1,4 +1,5 @@
using System.Text;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Model;
@ -11,6 +12,11 @@ namespace Milimoe.FunGame.Core.Library.Constant
{
#region Static Variable
/// <summary>
/// 支持动态扩展的工厂实例
/// </summary>
public static Factory OpenFactory { get; } = Factory.OpenFactory;
/// <summary>
/// 空的实体类 用于object返回
/// </summary>

View File

@ -479,22 +479,9 @@ namespace Milimoe.FunGame.Core.Library.Constant
}
/// <summary>
/// 区别于 <see cref="EquipItemToSlot"/>,这个是定义物品所属的栏位
/// 指示物品在哪个栏位上
/// </summary>
public enum EquipSlotType
{
None,
MagicCardPack,
Weapon,
Armor,
Shoes,
Accessory
}
/// <summary>
/// 区别于 <see cref="EquipSlotType"/>,这个是指示物品具体在哪个栏位上
/// </summary>
public enum EquipItemToSlot
{
None,
MagicCardPack,
@ -759,7 +746,7 @@ namespace Milimoe.FunGame.Core.Library.Constant
D
}
public enum ItemQualityType
public enum QualityType
{
White,
Green,
@ -769,7 +756,7 @@ namespace Milimoe.FunGame.Core.Library.Constant
Red
}
public enum ItemRarityType
public enum RarityType
{
OneStar,
TwoStar,

View File

@ -179,4 +179,9 @@
{
public override string Message => "必须以异步方式读取数据 (#10036)";
}
public class NotSupportedInstanceClassException : Exception
{
public override string Message => "试图构造一个不支持的类的实例 (#10037)";
}
}

File diff suppressed because it is too large Load Diff

View File

@ -168,7 +168,7 @@
/// <summary>
/// 魔法值增长因子
/// </summary>
public double MPGrowthFactor { get; set; } = 1.5;
public double MPGrowthFactor { get; set; } = 0.14;
/// <summary>
/// 每级增加基础攻击力

View File

@ -1,4 +1,3 @@
using System;
using System.Reflection;
using Milimoe.FunGame.Core.Interface.Addons;
using Milimoe.FunGame.Core.Library.Common.Addon;