Skip to content

Instantly share code, notes, and snippets.

@josinSbazin
Created March 17, 2018 19:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save josinSbazin/f79d5eec518cb28ca93efd2d92ccb3e1 to your computer and use it in GitHub Desktop.
Save josinSbazin/f79d5eec518cb28ca93efd2d92ccb3e1 to your computer and use it in GitHub Desktop.
Stats
using System;
using System.Collections.Generic;
using Develop.DevScripts.Game.Effects;
using Develop.DevScripts.Game.Effects.Components;
using Develop.DevScripts.Managers;
using LeopotamGroup.Collections;
using NUnit.Framework.Constraints;
using UnityEngine;
using Modificator = Develop.DevScripts.Game.Effects.Components.StatsEffectComponent.Modificator;
namespace Develop.DevScripts.Game.CharStats
{
/// <summary>
/// Класс статов персонажа
/// </summary>
[Serializable]
public class Stats
{
#region Constants
/// <summary>
/// Коэффициент от школы
/// </summary>
private const float SchoolBonus = 1.5f;
/// <summary>
/// Максимальная прочность щита todo
/// </summary>
public int MaxShieldCapacity = 100;
/// <summary>
/// Максимальная мощность покрова todo
/// </summary>
public int MaxCoverCapacity = 50;
/// <summary>
/// ID для соответствующих параметров
/// </summary>
[Serializable]
public enum StatType
{
Athleticism,
Dexterity,
Imagination,
Repartee,
MaxHp,
Initiative,
CritChance,
HitChance,
DodgeChance,
InsanityMaxStock,
InsanityRecoveryRate,
EuphoriaResist,
HysteriaResist,
DysphoriaResist,
AthleticismMulty,
DexterityMulty,
ImaginationMulty,
EuphoriaDamage,
HysteriaDamage,
DysphoriaDamage
}
public enum ParametersType
{
Damage,
DamageIgnoringCover,
Insanity,
Combo,
Shield,
Hp,
Cover
}
#endregion
#region Effects
/// <summary>
/// Словарь модификаторов
/// </summary>
private readonly Dictionary<StatType, FastList<Modificator>> _mods
= new Dictionary<StatType, FastList<Modificator>>();
#endregion
#region Статы (первичные характеристики)
[SerializeField] private float _baseAthleticism;
/// <summary>
/// Атлетичность
/// </summary>
[HideInInspector] public float Athleticism;
[SerializeField] private float _baseDexterity;
/// <summary>
/// Сноровка
/// </summary>
[HideInInspector] public float Dexterity;
[SerializeField] private float _baseImagination;
/// <summary>
/// Воображение
/// </summary>
[HideInInspector] public float Imagination;
[SerializeField] private float _baseRepartee;
/// <summary>
/// Находчивость
/// </summary>
[HideInInspector] public float Repartee;
#endregion
#region Вторичные характеристики
#region Вычисляемые
private float BaseMaxHp
{
get { return 500f - 400f / (0.03f * Athleticism + 1); }
}
/// <summary>
/// Здоровье (Зд - количество очков здоровья).
/// </summary>
internal int MaxHp;
private float BaseInitiative
{
get { return 350f / (120f - 70f / (0.03f * Repartee + 1f)); }
}
/// <summary>
/// Инициатива (И - время, за которое курсор проходит шкалу от начала до конца, с).
/// </summary>
internal float Initiative;
private float BaseCritChance
{
get { return 50f - 40f / (0.03f * Repartee + 1f); }
}
/// <summary>
/// Шанс крита (ШК - шанс нанесения критического урона, %).
/// </summary>
internal float CritChance;
private float BaseHitChance
{
get { return 100f; }
}
/// <summary>
/// Шанс попадания (ШП - шанс попадания, %)
/// </summary>
internal float HitChance;
private float BaseDodgeChance
{
get { return 50f - 40f / (0.03f * Dexterity + 1f); }
}
/// <summary>
/// Шанс уворота (ШУ - шанс уровота от скиллов, от АОЕ скиллов увернуться нельзя, %).
/// </summary>
internal float DodgeChance;
private float BaseInsanityMaxStock
{
get { return 55f - 50f / (0.03f * Imagination + 1f); }
}
/// <summary>
/// Запас "безумия" (ЗапБ - максимальное количество расходуемого ресурса "искры", ед.).
/// </summary>
internal float InsanityMaxStock;
private float BaseInsanityRecoveryRate
{
get { return 95f - 90f / (0.03f * Imagination + 1f); }
}
/// <summary>
/// Скорость восстановления "безумия" (СВ - количество "безумия", восстанавливаемых за 1 ход, ед.).
/// </summary>
internal float InsanityRecoveryRate;
#endregion
#region Резисты
// Резист (Рэ, Ри, Рд - величина, на которую уменьшается входящий урон
// от умений соответствующей ветви талантов).
private float BaseEuphoriaResist
{
get { return 0f; }
}
/// <summary>
/// Рэ - резист к умениям "Эйфория", (ед.);
/// </summary>
internal float EuphoriaResist;
private float BaseHysteriaResist
{
get { return 0f; }
}
/// <summary>
/// Ри - резист к умениям "Истерия", (ед.);
/// </summary>
internal float HysteriaResist;
private float BaseDysphoriaResist
{
get { return 0f; }
}
/// <summary>
/// Рд - резист к умениям "Дисфория", (ед.);
/// </summary>
internal float DysphoriaResist;
#endregion
#region Мултипликаторы урона
private float BaseAthleticismMulty
{
get { return (100f - 100f / (0.03f * Athleticism + 1f)) / 100; }
}
/// <summary>
/// Мультипликатор "Атлетичности":
/// </summary>
internal float AthleticismMulty;
private float BaseDexterityMulty
{
get { return (100f - 100f / (0.03f * Dexterity + 1f)) / 100f; }
}
/// <summary>
/// Мультипликатор "Сноровки":
/// </summary>
internal float DexterityMulty;
private float BaseImaginationMulty
{
get { return (100f - 100f / (0.03f * Imagination + 1f)) / 100f; }
}
/// <summary>
/// Мультпликатор "Воображения":
/// </summary>
internal float ImaginationMulty;
#endregion
#region Уроны от школ
/// <summary>
/// Базовый урон с учетом циклов
/// </summary>
private float _baseDamageWithCycles
{
get { return 1 + BattleManager.Instance.Sinusoid.CyclesMod; }
}
private float BaseEuphoriaDamage
{
get
{
return _baseDamageWithCycles * (1 + AthleticismMulty) * (1 + DexterityMulty) *
(1 + ImaginationMulty * SchoolBonus);
}
}
/// <summary>
/// Рэ - Урон школы "Эйфория", (ед.);
/// </summary>
internal float EuphoriaDamage;
private float BaseHysteriaDamage
{
get
{
return _baseDamageWithCycles * (1 + AthleticismMulty) * (1 + DexterityMulty * SchoolBonus) *
(1 + ImaginationMulty);
}
}
/// <summary>
/// Уи - Урон школы "Истерия", (ед.);
/// </summary>
internal float HysteriaDamage;
private float BaseDysphoriaDamage
{
get
{
return _baseDamageWithCycles * (1 + AthleticismMulty * SchoolBonus) * (1 + DexterityMulty) *
(1 + ImaginationMulty);
}
}
/// <summary>
/// Уд - Урон школы "Дисфория", (ед.);
/// </summary>
internal float DysphoriaDamage;
#endregion
#endregion
#region Private Methods
/// <summary>
/// Рассчет параметров с учетом эффекта
/// </summary>
/// <param name="statType"> Тип параметра </param>
/// <param name="baseParam"> Базовое значение параметра </param>
/// <returns></returns>
private float CalcParam(StatType statType, float baseParam)
{
float finalValue = baseParam;
float sumPercentAdd = 0f;
FastList<Modificator> modificators;
bool hasMods = _mods.TryGetValue(statType, out modificators);
if (hasMods && modificators != null && modificators.Count > 0)
{
for (int i = 0; i < modificators.Count; i++)
{
Modificator mod = modificators[i];
switch (mod.ModifieType)
{
case Modificator.ModType.Flat:
finalValue += mod.Value;
break;
case Modificator.ModType.PercentAdd:
sumPercentAdd += mod.Value / 100f;
if (i + 1 >= modificators.Count
|| modificators[i + 1].ModifieType != Modificator.ModType.PercentAdd)
{
finalValue *= 1 + sumPercentAdd;
sumPercentAdd = 0;
}
break;
case Modificator.ModType.PercentMult:
finalValue *= 1 + mod.Value / 100f;
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
return (float) Math.Round(finalValue, 4);
}
#endregion
#region Public Methods
public void AddModificator(Modificator modificator)
{
FastList<Modificator> modifictorsByType;
bool hasMod = _mods.TryGetValue(modificator.StatType, out modifictorsByType);
if (modifictorsByType == null)
{
modifictorsByType = new FastList<Modificator>();
if (!hasMod)
{
_mods.Add(modificator.StatType, modifictorsByType);
}
}
modifictorsByType.Add(modificator);
Recalculate();
}
public void RemoveModificator(Modificator modificator)
{
FastList<Modificator> modifictorsByType;
if (_mods.TryGetValue(modificator.StatType, out modifictorsByType) && modifictorsByType != null)
{
modifictorsByType.Remove(modificator);
}
Recalculate();
}
/// <summary>
/// Пересчитать значения статов с учетом наложенных эффектов
/// </summary>
public void Recalculate()
{
Athleticism = CalcParam(StatType.Athleticism, _baseAthleticism);
Dexterity = CalcParam(StatType.Dexterity, _baseDexterity);
Imagination = CalcParam(StatType.Imagination, _baseImagination);
Repartee = CalcParam(StatType.Repartee, _baseRepartee);
MaxHp = Mathf.RoundToInt(CalcParam(StatType.MaxHp, BaseMaxHp));
Initiative = CalcParam(StatType.Initiative, BaseInitiative);
CritChance = CalcParam(StatType.CritChance, BaseCritChance);
HitChance = CalcParam(StatType.HitChance, BaseHitChance);
DodgeChance = CalcParam(StatType.DodgeChance, BaseDodgeChance);
InsanityMaxStock = CalcParam(StatType.InsanityMaxStock, BaseInsanityMaxStock);
InsanityRecoveryRate = CalcParam(StatType.InsanityRecoveryRate, BaseInsanityRecoveryRate);
EuphoriaResist = CalcParam(StatType.EuphoriaResist, BaseEuphoriaResist);
HysteriaResist = CalcParam(StatType.HysteriaResist, BaseHysteriaResist);
DysphoriaResist = CalcParam(StatType.DysphoriaResist, BaseDysphoriaResist);
AthleticismMulty = CalcParam(StatType.AthleticismMulty, BaseAthleticismMulty);
DexterityMulty = CalcParam(StatType.DexterityMulty, BaseDexterityMulty);
ImaginationMulty = CalcParam(StatType.ImaginationMulty, BaseImaginationMulty);
EuphoriaDamage = CalcParam(StatType.EuphoriaDamage, BaseEuphoriaDamage);
HysteriaDamage = CalcParam(StatType.HysteriaDamage, BaseHysteriaDamage);
DysphoriaDamage = CalcParam(StatType.DysphoriaDamage, BaseDysphoriaDamage);
CalculateOptimizedParameters();
}
#endregion
#region Otimazed Feild Parameters
private void CalculateOptimizedParameters()
{
InsanityMaxStockInvert = 1 / InsanityMaxStock;
}
/// <summary>
/// Оптимизация. 1 / на InsanityMaxStock
/// </summary>
internal float InsanityMaxStockInvert;
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment