using CodeStage.AntiCheat.ObscuredTypes; using System; using System.Collections.Generic; using UnityEngine; using Random = UnityEngine.Random; public class ObjectPool where T : new() { private Stack pool = new Stack(); public T Get() { return pool.Count > 0 ? pool.Pop() : new T(); } public void Release(T obj) { pool.Push(obj); } } [Serializable] public class TableDataBase { public virtual string Get_Name() { return "no name"; } public virtual string Get_Desc() { return "no desc"; } public virtual string Get_ImagePath(eActorStatus actorStatus = eActorStatus.Idle) { return ""; } public virtual float Get_Value(int lv, float balance, float defaultval, float perlv, bool abandon = false) { if (lv <= 0) return 0f; float val; if (Mathf.Approximately(0f, balance)) val = lv * perlv; else val = Mathf.Pow(lv * perlv, balance * Mathf.Sqrt(lv)); val *= 0.0001f; val += defaultval; if (abandon) val = Mathf.Floor(val); // 소수점 이하 모두 버림 return val; } } public class ActorTableDataBase : TableDataBase { public eRole m_Role; ObscuredInt _id; public int n_ID { get { return _id; } set { _id = value; _id.RandomizeCryptoKey(); } } ObscuredFloat _AttackCoolTime; public float f_AttackCoolTime { get { return _AttackCoolTime; } set { _AttackCoolTime = value; _AttackCoolTime.RandomizeCryptoKey(); } } ObscuredInt _atkMin; public int n_AttackMin { get { return _atkMin; } set { _atkMin = value; _atkMin.RandomizeCryptoKey(); } } ObscuredInt _atkMax; public int n_AttackMax { get { return _atkMax; } set { _atkMax = value; _atkMax.RandomizeCryptoKey(); } } ObscuredFloat _cri; public float f_Cri { get { return _cri; } set { _cri = value; _cri.RandomizeCryptoKey(); } } ObscuredFloat _criDmg; public float f_CriDmg { get { return _criDmg; } set { _criDmg = value; _criDmg.RandomizeCryptoKey(); } } ObscuredInt _hp; public int n_HP { get { return _hp; } set { _hp = value; _hp.RandomizeCryptoKey(); } } ObscuredInt _shield; public int n_Shield { get { return _shield; } set { _shield = value; _shield.RandomizeCryptoKey(); } } ObscuredFloat _Avoid_Meele; public float n_Avoid_Meele { get { return _Avoid_Meele; } set { _Avoid_Meele = value; _Avoid_Meele.RandomizeCryptoKey(); } } ObscuredFloat _Avoid_Range; public float n_Avoid_Range { get { return _Avoid_Range; } set { _Avoid_Range = value; _Avoid_Range.RandomizeCryptoKey(); } } ObscuredInt _Specificity1; public int n_Specificity1 { get { return _Specificity1; } set { _Specificity1 = value; _Specificity1.RandomizeCryptoKey(); } } ObscuredInt _Specificity2; public int n_Specificity2 { get { return _Specificity2; } set { _Specificity2 = value; _Specificity2.RandomizeCryptoKey(); } } ObscuredInt _Specificity3; public int n_Specificity3 { get { return _Specificity3; } set { _Specificity3 = value; _Specificity3.RandomizeCryptoKey(); } } ObscuredInt _Specificity4; public int n_Specificity4 { get { return _Specificity4; } set { _Specificity4 = value; _Specificity4.RandomizeCryptoKey(); } } public int n_Name; public string s_Projectile, s_Image; public virtual eAttackType Get_AttackType() { return eAttackType.Max; } public override string Get_Name() { return table_localtext.Ins.Get_Text(n_Name); } public virtual bool IsBoss() { return false; } } public class StatTableDataBase : TableDataBase { public eStat Stat; public ObscuredDouble BaseValue, ValuePerLv; public ObscuredInt MaxLv, CostBase, CostIncrease; public string Icon; public double Get_Cost(int lv) { return CostBase + CostIncrease * lv; } } public class CardSkillData { public CardListTableData m_Data; Actor m_Actor; ObscuredBool _StartBattle; public bool StartBattle { get { return _StartBattle; } set { _StartBattle = value; _StartBattle.RandomizeCryptoKey(); } } ObscuredInt _UseCount; public int UseCount { get { return _UseCount; } set { _UseCount = value; _UseCount.RandomizeCryptoKey(); } } ObscuredInt _UseCount_Acc; public int UseCount_Acc { get { return _UseCount_Acc; } set { _UseCount_Acc = value; _UseCount_Acc.RandomizeCryptoKey(); } } public float m_LifeTime = 0f; public List list_identity = new List(); public void Add(Actor actor, CardListTableData data) { m_Actor = actor; m_Data = data; StartBattle = false; UseCount_Acc = UseCount = 0; m_LifeTime = 0f; switch (data.e_CardType) { case eCardType.G1_AddPotion: InGameInfo.Ins.Add_Potion(m_Data.Get_IntValue2(), m_Data.Get_IntValue1()); break; case eCardType.G1_MagicMissile: m_LifeTime = m_Data.Get_FloatValue3(); break; case eCardType.G3_HealHalfHPAndRefillPotions: actor.Heal(eHealType.Normal, m_Data.Get_FloatValue2()); actor.Refill_AllPotions(); InGameInfo.Ins.Set_Texts(); break; // 버프 case eCardType.G1_AddMaxAttack: actor.Set_Buff(true, eStat.Attack_Max, m_Data.Get_IntValue1()); break; case eCardType.G1_AddMinAttack: actor.Set_Buff(true, eStat.Attack_Min, m_Data.Get_IntValue1()); break; case eCardType.G1_AddHitRate: actor.Set_Buff(true, eStat.HitRate, m_Data.Get_IntValue1()); break; case eCardType.G1_AddCriDmg: actor.Set_Buff(true, eStat.CriDmg, m_Data.Get_FloatValue2()); break; case eCardType.G1_DodgeNextNAttacks: actor.Set_Buff(true, eStat.AvoidAll_Count, m_Data.Get_IntValue1()); break; case eCardType.G2_ReduceMeeleEnemyDamage: actor.Set_Buff(true, eStat.ReduceMeeleDmg, m_Data.Get_IntValue1()); break; case eCardType.G2_ReduceRangeEnemyDamage: actor.Set_Buff(true, eStat.ReduceRangeDmg, m_Data.Get_IntValue1()); break; case eCardType.G2_IncreaseDamageToBacklineEnemies: actor.Set_Buff(true, eStat.AddDmgMul_MiddleLine, m_Data.Get_FloatValue2()); break; case eCardType.G3_IncreaseAttackSpeed: { var cooltime = actor.Get_ActorStatInfo().Get_Stat(eStat.AttackCoolTime); // 기본 공속 cooltime -= cooltime * m_Data.Get_FloatValue2(); actor.Get_ActorStatInfo().Set_Stat(eStat.AttackCoolTime, cooltime); } break; case eCardType.G3_IncreaseMeleeDodge: { var avoid = actor.Get_ActorStatInfo().Get_Stat(eStat.Avoid_Melee); // 기본 회피(근) avoid += avoid * m_Data.Get_FloatValue2(); actor.Get_ActorStatInfo().Set_Stat(eStat.Avoid_Melee, avoid); } break; case eCardType.G4_MaxAttackIncreasesByShield: actor.OnEvent_MyShield_Hit(); break; case eCardType.G4_MaxAttackUpAndHealOnKill: actor.Set_Buff(true, eStat.Attack_Max, m_Data.Get_IntValue1()); break; // 디퍼프 case eCardType.G3_DodgeFirstRangedAttack: InGameInfo.Ins.OnEvent_MakeMob(); break; // 즉시 지급 case eCardType.G3_GetInstantGold: InGameInfo.Ins.Add_Goods(MyValue.ItemID_Gold, Random.Range(m_Data.Get_IntValue1(), (int)m_Data.Get_FloatValue2())); break; } } public void Add_UseCountACC(int valueindex, Action act, int initvalue = 0) { ++UseCount_Acc; var compare = valueindex == 1 ? m_Data.Get_IntValue1() : valueindex == 2 ? m_Data.Get_IntValue2() : m_Data.Get_IntValue3(); if (UseCount_Acc >= compare) { UseCount_Acc = initvalue; act?.Invoke(); } } public void Init_IngameDatas() { StartBattle = true; } public void Init_EveryMeetMonster() { UseCount = 0; list_identity.Clear(); } public void Update() { if (m_LifeTime > 0f) { m_LifeTime -= Time.deltaTime; if (m_LifeTime <= 0f) { m_LifeTime = m_Data.Get_FloatValue3(); if (m_Data.e_CardType == eCardType.G1_MagicMissile) { ++UseCount; m_Actor.Shoot_AddProjectiles(this); } } } } } public class ProjectileData { public string s_Projectile; public eRole m_Role; public eAttackType e_AttackType; public eCardType e_CardType; public Actor Hitter, Target; public ActorStatInfo m_HitterStat; public float m_Speed; public bool isCri; public void Set(string _Projectile, eRole _Role, eAttackType _AttackType, Actor hitter, ActorStatInfo _Stat, eCardType cardtype = eCardType.Max) { s_Projectile = _Projectile; m_Role = _Role; e_AttackType = _AttackType; Hitter = hitter; m_HitterStat = _Stat; e_CardType = cardtype; } public void Set(Actor target, float speed) { Target = target; m_Speed = speed; } public void Copy(ProjectileData pd) { pd.s_Projectile = s_Projectile; pd.m_Role = m_Role; pd.Hitter = Hitter; pd.Target = Target; pd.m_Speed = m_Speed; pd.m_HitterStat = m_HitterStat; pd.e_AttackType = e_AttackType; } } public partial class StatusEffectData { float LifeTime, DotTime, RepeatEffectDelayTime; bool bDot; double curValue; StatusOptionSetActorData m_Data; StatusConditionsListTableData m_sclData; Actor m_Target; EffectBase m_eff, m_eff_repeat; public void Set(StatusOptionSetActorData data, Actor target = null) { bActiveSkill = bDot = false; m_Data = data; m_sclData = m_Data.m_sclData; m_Target = target; if (m_Target == null) m_Target = m_Data.m_TData.Get_Target(data.m_Actor, m_Target, data.m_Actor.Get_Data().m_Role); var sosdata = m_Data.m_TData; switch (sosdata.e_ActiveConditions) { // 시간으로 제어하지 않는 조건들 case eActiveConditions.Appear: LifeTime = 0f; break; case eActiveConditions.MaxHp_Up: case eActiveConditions.MaxHp_Down: case eActiveConditions.MaxHpRate: case eActiveConditions.MaxShield_Up: case eActiveConditions.MaxShield_Down: case eActiveConditions.MaxShield_Rate: LifeTime = 0f; m_Target.Set_ActiveConditionData(m_Data.m_TData.e_ActiveConditions, this); break; default: { bDot = sosdata.b_DotDmg; var time = sosdata.Get_StatValue1(); var v = sosdata.Get_StatValue2(); if (LifeTime > 0) { if (v > curValue) { if (LifeTime < time) LifeTime = time; curValue = v; Set_BufforDebuff(v); } else if (Mathf.Approximately((float)curValue, (float)v)) { if (LifeTime < time) LifeTime = time; } } else { curValue = v; LifeTime = time; DotTime = 0f; Set_BufforDebuff(v); } } break; } switch (sosdata.e_StatusConditionsType) { case eStatusConditionsType.Invincibility_Count: m_Target.Set_StatusEffectData(sosdata.e_StatusConditionsType, this); break; } Set_Common(); } public void Set_byCard(eStatusConditionsType scType, float time, Actor target) { m_sclData = table_StatusConditionsList.Ins.Get_Data_orNull(scType); if (m_sclData == null) return; m_Target = target; if (LifeTime < time) LifeTime = time; Set_Common(); } void Set_Common() { if (!bDot) { if (!string.IsNullOrEmpty(m_sclData.s_SkillEffect) && !m_sclData.s_SkillEffect.Equals("None")) { if (m_eff == null || LifeTime <= 0f) m_eff = EffectMgr.Ins.Get_EffectBase(m_sclData.s_SkillEffect); if (m_eff) m_eff.Set(m_sclData.s_SkillEffect, m_sclData.e_EffectPivot, m_Target, m_Target.Get_World_Position(m_sclData.e_EffectPivot), LifeTime); } } if (!string.IsNullOrEmpty(m_sclData.s_RepeatEffect) && !m_sclData.s_RepeatEffect.Equals("None")) RepeatEffectDelayTime = Mathf.Max(Time.deltaTime, m_sclData.f_RepeatEffectStartDelay); } void Set_BufforDebuff(double v) { if (m_Target == null) { Set_Off(); return; } switch (m_Data.m_TData.e_BuffType) { case eBuffType.Buff: m_Target.Set_Buff(m_Data.m_TData.e_Stat1, v); break; case eBuffType.Debuff: m_Target.Set_DeBuff(m_Data.m_TData.e_Stat1, Math.Abs(v)); break; } if (m_Target.IsDead()) Set_Off(); } void Set_BufforDebuff(bool off = false) { var sosdata = m_Data.m_TData; switch (sosdata.e_BuffType) { case eBuffType.Buff: m_Target.Set_Buff(m_Data.m_TData.e_Stat1, off ? 0 : sosdata.Get_StatValue1()); m_Target.Set_Buff(m_Data.m_TData.e_Stat2, off ? 0 : sosdata.Get_StatValue2()); break; case eBuffType.Debuff: m_Target.Set_DeBuff(m_Data.m_TData.e_Stat1, off ? 0 : sosdata.Get_StatValue1()); m_Target.Set_DeBuff(m_Data.m_TData.e_Stat2, off ? 0 : sosdata.Get_StatValue2()); break; } } public void Counting(int arg1, int arg2) { var sosdata = m_Data.m_TData; switch (sosdata.e_StatusConditionsType) { case eStatusConditionsType.Invincibility_Count: if (arg1 <= 0) Set_Off(); break; } switch (sosdata.e_ActiveConditions) { case eActiveConditions.MaxHp_Up: if (arg1 >= sosdata.Get_Rate_orValue()) { if (!m_eff.gameObject.activeInHierarchy) m_eff.gameObject.SetActive(true); Set_BufforDebuff(); } else { m_eff.Off(); Set_BufforDebuff(true); } break; case eActiveConditions.MaxHp_Down: if (arg1 <= m_Data.m_TData.Get_Rate_orValue()) { if (!m_eff.gameObject.activeInHierarchy) m_eff.gameObject.SetActive(true); Set_BufforDebuff(); } else { m_eff.Off(); Set_BufforDebuff(true); } break; case eActiveConditions.MaxHpRate: if ((arg1 / (float)arg2) <= m_Data.m_TData.Get_Rate_orValue()) { if (sosdata.e_StatusConditionsType == eStatusConditionsType.Destruct) { if (m_Target.Get_SelfDestructData().m_Status == eSelfDestructStatus.None) { m_Target.Set_SelfDestruct(m_Data); m_Target.Get_SelfDestructData().eff_SelfDestruct = m_eff; m_eff.gameObject.SetActive(false); } } else { if (!m_eff.gameObject.activeInHierarchy) m_eff.gameObject.SetActive(true); Set_BufforDebuff(); } } else { m_eff.Off(); Set_BufforDebuff(true); } break; case eActiveConditions.MaxShield_Up: break; case eActiveConditions.MaxShield_Down: break; case eActiveConditions.MaxShield_Rate: break; } } public void Off() { if (m_Data != null) { var sosdata = m_Data.m_TData; switch (sosdata.e_ActiveConditions) { // 시간으로 제어하지 않는 조건들 case eActiveConditions.Appear: case eActiveConditions.MaxHp_Up: case eActiveConditions.MaxHp_Down: case eActiveConditions.MaxHpRate: case eActiveConditions.MaxShield_Up: case eActiveConditions.MaxShield_Down: case eActiveConditions.MaxShield_Rate: break; default: Set_BufforDebuff(0); break; } } Set_Off(); } void Set_Off() { LifeTime = 0f; bDot = false; m_eff?.Off(); m_eff_repeat?.Off(); } public void Update() { Update_ActiveSkill(); if (RepeatEffectDelayTime > 0f) { RepeatEffectDelayTime -= Time.deltaTime; if (RepeatEffectDelayTime <= 0f) { m_eff_repeat = EffectMgr.Ins.Show_FollowEffect(m_sclData.s_RepeatEffect, m_sclData.e_EffectPivot, m_Target, m_Target.Get_World_Position(m_sclData.e_EffectPivot), Mathf.Max(Time.deltaTime, LifeTime - m_sclData.f_RepeatEffectStartDelay)); } } if (bDot) { DotTime -= Time.deltaTime; if (DotTime <= 0f) { DotTime = 1f; m_Target.Get_Dmg((int)curValue); EffectMgr.Ins.Show_Effect(m_sclData.s_SkillEffect, m_Target.Get_World_Position(m_sclData.e_EffectPivot), 1f); } } if (LifeTime > 0f) { LifeTime -= Time.deltaTime; if (LifeTime < 0f) { Off(); } } } public bool IsActive() { return LifeTime > 0f; } public StatusOptionSetActorData Get_Data() { return m_Data; } } public partial class StatusEffectData { bool bActiveSkill; float ActiveSkillRunTime; public void Set_ActiveSkill(StatusOptionSetActorData data) { bActiveSkill = true; m_Data = data; m_sclData = m_Data.m_sclData; m_Target = m_Data.m_Actor; Set_Common(); ActiveSkillRunTime = m_Data.m_TData.Get_Rate_orValue(); } public void Update_ActiveSkill() { if (bActiveSkill) { if (ActiveSkillRunTime > 0f) { ActiveSkillRunTime -= Time.deltaTime; if (ActiveSkillRunTime <= 0f) { ActiveSkillRunTime = m_Data.m_TData.Get_Rate_orValue(); var actor = m_Data.m_Actor; var targets = m_Data.m_TData.Get_Targets(actor, actor.Get_Target(), actor.Get_Data().m_Role); switch (m_Data.m_TData.e_StatusConditionsType) { case eStatusConditionsType.Heal_Hp_Add: targets.ForEach(f => f.Heal(eHealType.Normal, (int)m_Data.m_TData.Get_StatValue1())); break; } } } } } } public enum eSelfDestructStatus { None, Check_Rate /* 자폭 확률 켜짐 */, Soon /* 곧 자폭함 */ } public class SelfDestructData { public eSelfDestructStatus m_Status; public EffectBase eff_SelfDestruct; public Coroutine co_SelfDestruct; public StatusOptionSetActorData m_Data; public void Set_Status(eSelfDestructStatus status) { m_Status = status; } public void Set(StatusOptionSetActorData data) { m_Data = data; } public void Stop(Actor actor) { if (co_SelfDestruct != null) { actor.StopCoroutine(co_SelfDestruct); co_SelfDestruct = null; eff_SelfDestruct.Off(); } } } public class SetEquipmentData { public ObscuredInt m_MainValue, m_SetGroupID; public Dictionary dic_Stat = new Dictionary(); public List list_SkillId = new List(); public void Add(EquipmentSetOptionTableData data, int set) { if (data == null) return; dic_Stat.Clear(); list_SkillId.Clear(); m_SetGroupID = data.n_SetId; m_SetGroupID.RandomizeCryptoKey(); if (set >= data.n_SetCondition1) { Add_Stat(data.e_SetStat1, data.f_SetStatValue1); if (data.n_Set1CardSkill > 0) list_SkillId.Add(data.n_Set1CardSkill); } if (set >= data.n_SetCondition2) { Add_Stat(data.e_SetStat2, data.f_SetStatValue2); if (data.n_Set2CardSkill > 0) list_SkillId.Add(data.n_Set2CardSkill); } if (set >= data.n_SetCondition3) { Add_Stat(data.e_SetStat3, data.f_SetStatValue3); if (data.n_Set3CardSkill > 0) list_SkillId.Add(data.n_Set3CardSkill); } if (set >= 6) m_MainValue = data.n_IncreaseMainStatSet6_Mul; else if (set >= 5) m_MainValue = data.n_IncreaseMainStatSet5_Mul; else if (set >= 4) m_MainValue = data.n_IncreaseMainStatSet4_Mul; else if (set >= 3) m_MainValue = data.n_IncreaseMainStatSet3_Mul; else if (set >= 2) m_MainValue = data.n_IncreaseMainStatSet2_Mul; else m_MainValue = 0; m_MainValue.RandomizeCryptoKey(); } void Add_Stat(eStat stat, float value) { if (stat >= eStat.Max) return; if (!dic_Stat.ContainsKey(stat)) dic_Stat.Add(stat, 0f); dic_Stat[stat] += value; dic_Stat[stat].RandomizeCryptoKey(); } } public class ItemSimpleData { ObscuredInt _itemid; ObscuredDouble _amount; public int itemid { get { return _itemid; } set { _itemid = value; _itemid.RandomizeCryptoKey(); } } public double amount { get { return _amount; } set { _amount = value; _amount.RandomizeCryptoKey(); } } }