108 lines
4.0 KiB
C#

using System.Collections.Generic;
namespace ET.Server
{
[FriendOf(typeof(Hero))]
public static class HeroService
{
private const int HeroLevelCap = 60;
private const int HeroSkillCap = 10;
public static Hero SummonHero(Player player, int configId)
{
HeroComponent heroComp = player.GetComponent<HeroComponent>() ?? player.AddComponent<HeroComponent>();
Hero hero = heroComp.AddHero(configId);
player.SetDirty();
LogExtensions.Audit("Hero", "SummonHero", $"{{\"playerId\":{player.Id},\"heroId\":{hero.Id},\"configId\":{configId}}}");
return hero;
}
public static bool TryAddExp(Player player, Hero hero, int itemId, int itemCount, out string reason)
{
reason = string.Empty;
BagComponent bag = player.GetComponent<BagComponent>() ?? player.AddComponent<BagComponent>();
var costs = new List<CostEntry> { new() { ItemId = itemId, Count = itemCount } };
if (!bag.RemoveItems(costs))
{
reason = "item_not_enough";
return false;
}
int beforeLevel = hero.Level;
hero.Exp += itemCount * 100;
while (hero.Exp >= hero.Level * 100 && hero.Level < HeroLevelCap)
{
hero.Exp -= hero.Level * 100;
hero.Level += 1;
}
LogExtensions.Audit("Hero", "HeroAddExp", $"{{\"playerId\":{player.Id},\"heroId\":{hero.Id},\"itemId\":{itemId},\"count\":{itemCount},\"beforeLevel\":{beforeLevel},\"afterLevel\":{hero.Level}}}");
TryAuditFirstMaxLevel(player, hero, beforeLevel);
player.SetDirty();
return true;
}
public static bool TrySkillUp(Player player, Hero hero, int skillIndex, int costItemId, int costCount, out string reason)
{
reason = string.Empty;
if (skillIndex < 0 || skillIndex >= hero.Skills.Count)
{
reason = "invalid_index";
return false;
}
if (hero.Skills[skillIndex] >= HeroSkillCap)
{
reason = "skill_max";
return false;
}
BagComponent bag = player.GetComponent<BagComponent>() ?? player.AddComponent<BagComponent>();
var costs = new List<CostEntry> { new() { ItemId = costItemId, Count = costCount } };
if (!bag.RemoveItems(costs))
{
reason = "item_not_enough";
return false;
}
int beforeLevel = hero.Skills[skillIndex];
hero.Skills[skillIndex] += 1;
LogExtensions.Audit("Hero", "HeroSkillUp", $"{{\"playerId\":{player.Id},\"heroId\":{hero.Id},\"skillIndex\":{skillIndex},\"before\":{beforeLevel},\"after\":{hero.Skills[skillIndex]}}}");
TryAuditFirstMaxSkill(player, hero);
player.SetDirty();
return true;
}
private static void TryAuditFirstMaxLevel(Player player, Hero hero, int beforeLevel)
{
if (hero.MaxLevelAudited || beforeLevel >= HeroLevelCap || hero.Level < HeroLevelCap)
{
return;
}
hero.MaxLevelAudited = true;
LogExtensions.Audit("Hero", "HeroFirstMaxLevel", $"{{\"playerId\":{player.Id},\"heroId\":{hero.Id},\"level\":{hero.Level}}}");
}
private static void TryAuditFirstMaxSkill(Player player, Hero hero)
{
if (hero.MaxSkillAudited)
{
return;
}
int skillCount = hero.Skills.Count > 4 ? 4 : hero.Skills.Count;
for (int i = 0; i < skillCount; ++i)
{
if (hero.Skills[i] < HeroSkillCap)
{
return;
}
}
hero.MaxSkillAudited = true;
LogExtensions.Audit("Hero", "HeroFirstFullSkill", $"{{\"playerId\":{player.Id},\"heroId\":{hero.Id}}}");
}
}
}