OneShotOneKill/Assets/Script/InGame/Actor/Actor.cs

2362 lines
98 KiB
C#

using CodeStage.AntiCheat.ObscuredTypes;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Random = UnityEngine.Random;
public class Actor : AddrHandleBase
{
[SerializeField] protected Animation m_anim;
protected int m_Identity; // 0 pc, 1~9 mob
protected bool isInit, isSetImage;
protected Actor _Target;
protected Actor m_Target { get { return _Target; } set { _Target = value; } }
protected ObscuredBool CantSetTarget;
protected ActorTableDataBase m_TableData;
protected Dictionary<eCardType, CardSkillData> dic_Card = new Dictionary<eCardType, CardSkillData>();
protected ObscuredBool bStartBattle, bResurrectioning;
protected HUD_HPShield m_HUD_HPShield;
protected SelfDestructData m_SelfDestructData = new SelfDestructData();
protected eActorStatus ActorStatus;
protected StatusConditionsListTableData m_AttackData;
ObscuredDouble m_AttackCoolTime;
protected List<StatusOptionSetTableData> list_Specificity = new List<StatusOptionSetTableData>();
Dictionary<eActiveConditions, List<StatusOptionSetActorData>> dic_activeCondition = new Dictionary<eActiveConditions, List<StatusOptionSetActorData>>();
protected ServerData m_ServerData;
protected ActorStatInfo m_StatInfo;
protected ProjectileData m_BaseAttackPD = new ProjectileData(); // 기본 공격
protected ActorStatInfo m_PDHPDmgStatInfo;
protected ProjectileData m_PDHPDmg = new ProjectileData(); // 체력 비례 데미지
protected Dictionary<eCardType, ProjectileData> dic_cardProjectile = new Dictionary<eCardType, ProjectileData>();
protected Dictionary<eCardType, List<ActorStatInfo>> dic_CardStatInfo = new Dictionary<eCardType, List<ActorStatInfo>>();
protected ObscuredInt m_AttackCount /* 공격 횟수 */, m_AttackSuccessCount /* 공격 성공 횟수 */, m_AvoidCount /* 회피 횟수 */;
protected ObscuredInt m_HitCount /* 맞은 횟수 */;
protected ObscuredInt m_TotalAttackCount, m_TotalAttackSuccessCount, m_TotalAvoidCount;
protected Dictionary<eAttackType, ObscuredInt> dic_HitType = new Dictionary<eAttackType, ObscuredInt>
{ { eAttackType.Melee, 0 }, { eAttackType.Range, 0 } };
protected Dictionary<eStatusConditionsType, StatusEffectData> dic_StatusEffect = new Dictionary<eStatusConditionsType, StatusEffectData>();
static List<eStatusConditionsType> list_NoUpdateCC = new List<eStatusConditionsType> // 업데이트 할 수 없는 CC기
{ eStatusConditionsType.Stun, eStatusConditionsType.Freezing };
Dictionary<eStatusConditionsType, StatusEffectData> dic_StatusEffectData = new Dictionary<eStatusConditionsType, StatusEffectData>();
Dictionary<eActiveConditions, List<StatusEffectData>> dic_ActiveConditionData = new Dictionary<eActiveConditions, List<StatusEffectData>>();
#if UNITY_EDITOR
private void Reset()
{
m_anim = GetComponent<Animation>();
}
#endif
protected virtual void Awake() { }
protected virtual void Update()
{
if (!bStartBattle || IsDead() || bResurrectioning || m_SelfDestructData.m_Status == eSelfDestructStatus.Soon) return;
foreach (var item in dic_StatusEffect) item.Value.Update();
if (IsCC()) return;
if (Get_AttackType() == eAttackType.Range && dic_StatusEffect[eStatusConditionsType.Blind].IsActive()) return;
if (m_AttackCoolTime > 0)
{
m_AttackCoolTime -= Time.deltaTime;
if (m_AttackCoolTime <= 0f)
{
m_AttackCoolTime = m_StatInfo.Get_TotalStat(eStat.AttackCoolTime);
m_AttackCoolTime.RandomizeCryptoKey();
if (m_Target && !m_Target.IsDead())
Play_Attack();
else
Find_Target();
}
}
foreach (var item in dic_Card) item.Value.Update();
}
void Init()
{
for (eCardType i = 0; i < eCardType.Max; i++)
{
dic_CardStatInfo.Add(i, new List<ActorStatInfo>());
for (int j = 0; j < table_cardlist.Ins.Get_Data(i).n_ProjectileCount; j++)
dic_CardStatInfo[i].Add(new ActorStatInfo(this, false));
}
for (eStatusConditionsType i = 0; i < eStatusConditionsType.Max; i++)
dic_StatusEffect.Add(i, new StatusEffectData());
}
public virtual void Set(int identity, ActorTableDataBase actordata, HUD_HPShield hUD_HPShield, ServerData sdata = null)
{
if (!isInit)
{
isInit = true;
Init();
}
gameObject.SetActive(true);
m_Identity = identity;
isSetImage = false;
ActorStatus = eActorStatus.Idle;
m_ServerData = sdata;
m_TableData = actordata;
m_HUD_HPShield = hUD_HPShield;
m_StatInfo = MyValue.Get_ActorStatInfo(this, m_TableData);
m_HUD_HPShield.Set(m_StatInfo);
Set_Battle(false);
bResurrectioning = false; bResurrectioning.RandomizeCryptoKey();
m_SelfDestructData.Set_Status(eSelfDestructStatus.None);
dic_Card.Clear();
m_StatInfo.Clear_BuffDebuff();
Set_Equipment();
Set_Specificity();
m_AttackCoolTime = m_StatInfo.Get_TotalStat(eStat.AttackCoolTime);
}
public ServerData Get_ServerData() { return m_ServerData; }
public virtual void Set(int index) { }
public virtual void ActorSet(ActorSettingData setdata)
{
if (gameObject.activeSelf) StartCoroutine(Co_ActorSet(setdata));
}
IEnumerator Co_ActorSet(ActorSettingData setdata)
{
if (setdata != null)
{
while (!bStartBattle) yield return null;
if (setdata.PreemptiveStrike) Set_Battle_PreemptiveStrike();
if (setdata.StunTime > 0f) Set_StatusEffect(eStatusConditionsType.Stun, setdata.StunTime);
}
}
public virtual void Set_TargetObj(bool active) { }
public void Init_IngameDatas()
{ // 탐험 입장 시 최초 한 번 실행
foreach (var item in dic_Card) item.Value.Init_IngameDatas();
m_TotalAttackCount = 0; m_TotalAttackCount.RandomizeCryptoKey();
m_TotalAvoidCount = 0; m_TotalAvoidCount.RandomizeCryptoKey();
m_TotalAttackSuccessCount = 0; m_TotalAttackSuccessCount.RandomizeCryptoKey();
dic_HitType[eAttackType.Melee] = 0; dic_HitType[eAttackType.Melee].RandomizeCryptoKey();
dic_HitType[eAttackType.Range] = 0; dic_HitType[eAttackType.Range].RandomizeCryptoKey();
}
public void Init_EveryMeetMonster()
{
foreach (var item in dic_Card) item.Value.Init_EveryMeetMonster();
m_AttackCount = 0; m_AttackCount.RandomizeCryptoKey();
m_AttackSuccessCount = 0; m_AttackSuccessCount.RandomizeCryptoKey();
m_HitCount = 0; m_HitCount.RandomizeCryptoKey();
m_AvoidCount = 0; m_AvoidCount.RandomizeCryptoKey();
}
public void Set_Trasform(Vector3 pos, float scale)
{
m_TableData = null;
transform.position = pos;
transform.localScale = Vector3.one * scale;
}
public void Set_Battle(bool battle)
{
if (m_StatInfo == null || m_TableData == null) return;
if (battle && SelectCardUI.Ins.IsActive()) return;
bStartBattle = battle; bStartBattle.RandomizeCryptoKey();
if (bStartBattle) Find_Target();
}
public virtual void Del_Target()
{
if (m_Target != null)
{
}
m_Target = null;
}
public virtual void Set_Target(Actor target)
{
if (isCantSetTarget()) return;
m_Target = target;
MonsterNodeControler.Ins.Set_TargetUI(m_Target);
}
public virtual bool isCantSetTarget() { return CantSetTarget; }
public Actor Get_Target() { return m_Target; }
public void Find_Target()
{
m_Target = InGameInfo.Ins.Get_Enemy_orNull(m_TableData.m_Role, isCantSetTarget());
if (IsRole(eRole.PC)) MonsterNodeControler.Ins.Set_TargetUI(m_Target);
}
public virtual Vector3 Get_World_Position(eEffectPivot pivot = eEffectPivot.Center) { return transform.position; }
public ActorStatInfo Get_ActorStatInfo() { return m_StatInfo; }
public bool IsRole(eRole role) { return m_TableData.m_Role == role; }
public ActorTableDataBase Get_Data() { return m_TableData; }
public virtual eAttackType Get_AttackType() { return m_TableData.Get_AttackType(); }
public void Set_HUD(bool active)
{
if (m_HUD_HPShield != null)
{
if (active)
m_HUD_HPShield.Set_Init(this);
else
m_HUD_HPShield.gameObject.SetActive(active);
}
}
public void Set_HUD() { if (m_HUD_HPShield && m_StatInfo != null) m_HUD_HPShield.Set(m_StatInfo); }
public bool IsBoss() { return m_TableData.IsBoss(); }
public virtual int Get_Identity() { return m_Identity; }
public virtual int Get_MobIndex() { return 0; }
public virtual void Set_MobIndex_byLineChange() { }
public SelfDestructData Get_SelfDestructData() { return m_SelfDestructData; }
protected virtual float Get_ProjectileSpeed() { return 0f; }
public CardSkillData Get_CardSkillData_orNull(eCardType cardType) { return dic_Card.ContainsKey(cardType) ? dic_Card[cardType] : null; }
#region
public virtual void Set_Line(eMobBattlePos eline) { }
public virtual eMobBattlePos Get_Line() { return eMobBattlePos.Backline; }
public virtual bool IsFrontLine() { return false; }
public virtual bool IsMiddleLine() { return false; }
public virtual bool IsBackLine() { return false; }
public virtual bool IsMobLine(eMobBattlePos eline) { return false; }
public bool IsDead() { return IsInvalid() || m_StatInfo == null || m_StatInfo.Get_TotalStat(eStat.HP) <= 0; }
public bool IsInvalid() { return m_TableData == null; }
public bool IsSet() { return isSetImage; }
public virtual bool IsShield() { return false; }
public int Get_TotalAttackCount() { return m_TotalAttackCount; }
public int Get_AttackCount() { return m_AttackCount; }
public void Add_CardSkill(CardListTableData data)
{
var skilldata = new CardSkillData();
dic_Card.Add(data.e_CardType, skilldata);
skilldata.Add(this, data);
var cardtype = eCardType.G1_MaxShieldUpOnSkillGain;
if (dic_Card.ContainsKey(cardtype))
if (data.e_CardGrade == eGrade.Common || data.e_CardGrade == eGrade.UnCommon)
{
m_StatInfo.Set_Stat(true, eStat.MaxShield, dic_Card[cardtype].m_Data.Get_IntValue1());
Refresh_PCUI();
}
OnEvent_RunSkillCard(data.e_CardType);
}
bool Can_RunCard(eCardType cardtype, eCardType addcard) { return dic_Card.ContainsKey(cardtype) && (addcard == eCardType.Max || cardtype == addcard); }
void Counting_onActiveCondition(eActiveConditions condition, int arg1, int arg2)
{
if (dic_ActiveConditionData.ContainsKey(condition))
{
for (int i = 0; i < dic_ActiveConditionData[condition].Count; i++)
dic_ActiveConditionData[condition][i].Counting(arg1, arg2);
}
}
public void Get_Dmg(int dmg, ProjectileData pdData = null)
{
int hitter_dmg = dmg;
var huddmg = IngameUIManager.Ins.Get_HUD_Dmg();
var isCri = pdData != null ? pdData.isCri : false;
bool ischeat_mujuck = false;
var my_shield = (int)m_StatInfo.Get_TotalStat(eStat.Shield);
if (my_shield > 0)
{ // 쉴드 우선 계산
if (my_shield >= hitter_dmg)
{
my_shield -= hitter_dmg;
hitter_dmg = 0;
}
else
{
hitter_dmg -= my_shield;
my_shield = 0;
var cardtype = eCardType.G1_HealHpOnShieldBreak;
if (dic_Card.ContainsKey(cardtype))
{
Heal(eHealType.Normal, dic_Card[cardtype].m_Data.Get_FloatValue1());
Set_StatusEffect(eStatusConditionsType.Heal_Hp_Add, 1f);
}
}
m_HUD_HPShield.Hit_Shield();
if (!ischeat_mujuck) m_StatInfo.Set_Stat(eStat.Shield, my_shield);
OnEvent_MyShield_Hit(pdData);
if (dic_Card.ContainsKey(eCardType.G1_NoSimultaneousHpShieldLoss))
hitter_dmg = 0;
}
if (hitter_dmg > 0)
{ // 쉴드를 깍고도 남은 경우
if (!ischeat_mujuck) m_StatInfo.Set_Stat(false, eStat.HP, hitter_dmg);
huddmg.Set(isCri, false, hitter_dmg, Get_World_Position());
if (IsDead())
{
var cardtype = eCardType.G5_ReviveOnDeath;
if (dic_Card.ContainsKey(cardtype))
{
if (DSUtil.RandomTrue(dic_Card[cardtype].m_Data.Get_FloatValue1()))
{
Set_Buff(true, eStat.Resurrection, 1);
Set_Buff(eStat.Resurrection_Shield, 1);
Set_Buff(eStat.Resurrection_Heal, 1);
}
}
cardtype = eCardType.G1_AutoUsePotionOnDeath;
if (dic_Card.ContainsKey(cardtype) && m_StatInfo.Get_TotalStat(eStat.Potion) > 0)
{
Use_Potion(true, 10); // 테스트 : 물약 회복량
return;
}
if (dic_activeCondition.ContainsKey(eActiveConditions.Die_Self))
{
for (int i = 0; i < dic_activeCondition[eActiveConditions.Die_Self].Count; i++)
{
var temp = dic_activeCondition[eActiveConditions.Die_Self][i];
if (temp.m_TData.e_StatusConditionsType == eStatusConditionsType.Resurrection)
{
// 부활 데이터 저장
Set_Buff(true, eStat.Resurrection, temp.m_TData.Get_Rate_orValue());
Set_Buff(temp.m_TData.e_Stat1, temp.m_TData.Get_StatValue1());
Set_Buff(temp.m_TData.e_Stat2, temp.m_TData.Get_StatValue2());
// 부활은 더이상 못하게 삭제
dic_activeCondition[eActiveConditions.Die_Self].RemoveAt(i);
break;
}
}
}
if (m_StatInfo.Get_BuffStat(eStat.Resurrection) > 0)
{
Set_Buff(false, eStat.Resurrection, 1);
Set_Buff(eStat.Resurrection_Shield, 1);
Set_Buff(eStat.Resurrection_Heal, 1);
StartCoroutine(Co_Resurrection());
}
else
{
Set_Die(pdData);
MonsterNodeControler.Ins.Check_LineAllDead();
if (IsRole(eRole.Mob)) { Set_HUD(false); }
else if (IsRole(eRole.PC)) DefeatUI.Ins.Set();
pdData?.Hitter.OnEvent_Kill(this);
pdData?.Hitter.Find_Target();
}
m_SelfDestructData.Stop(this);
}
else
{
if (m_SelfDestructData.m_Status == eSelfDestructStatus.Check_Rate)
{ // 자폭 가능 시, 얻어맞으면 value 확률로 자폭하기
if (DSUtil.RandomTrue(m_SelfDestructData.m_Data.m_TData.Get_StatValue1()))
m_SelfDestructData.co_SelfDestruct = StartCoroutine(Co_Selfdestruct());
}
if (dic_Card.ContainsKey(eCardType.G1_MaxDodgeWhenHpBelow))
{
var card = dic_Card[eCardType.G1_MaxDodgeWhenHpBelow];
if (m_StatInfo.Get_BuffStat(eStat.Avoid_G1_MaxDodgeWhenHpBelow) <= 0 &&
m_StatInfo.Get_TotalStat(eStat.HP) <= card.m_Data.Get_IntValue1())
{
Set_Buff(eStat.Avoid_G1_MaxDodgeWhenHpBelow, 0.9);
Refresh_PCUI();
}
}
}
}
else
huddmg.Set(isCri, true, dmg, Get_World_Position());
m_HUD_HPShield.Set(m_StatInfo);
Play_Hit();
OnEvent_ActiveConditions();
OnEvent_GetDmg(pdData);
}
public void Get_Dmg(ProjectileData pdData)
{
if (IsDead()) return;
switch (pdData.e_CardType)
{
case eCardType.G1_CastReaperOnLevelUp:
case eCardType.G1_CastReaperOnNthCrit:
Get_Dmg(9999, pdData);
return;
}
Check_Specificity(eActiveConditions.Hit_PreemptiveStrike, pdData);
if (pdData.e_AttackType == eAttackType.Range && dic_Card.ContainsKey(eCardType.G5_RangedDamageRandomReflect))
Reflect_Projectile(eCardType.G5_RangedDamageRandomReflect, pdData);
var huddmg = IngameUIManager.Ins.Get_HUD_Dmg();
if (dic_StatusEffect[eStatusConditionsType.Invincibility_Time].IsActive())
{
huddmg.Set(false, true, -5, Get_World_Position());
return;
}
var dmgimmune = (int)m_StatInfo.Get_TotalStat(eStat.Dmg_Immune);
if (dmgimmune > 0)
{
--dmgimmune;
m_StatInfo.Set_Buff(eStat.Dmg_Immune, dmgimmune);
huddmg.Set(false, true, -5, Get_World_Position());
if (dic_StatusEffectData.ContainsKey(eStatusConditionsType.Invincibility_Count))
dic_StatusEffectData[eStatusConditionsType.Invincibility_Count].Counting(dmgimmune, 0);
return;
}
var hitterstat = pdData.m_HitterStat;
if (IsShield())
{
huddmg.Set(false, true, -5, Get_World_Position());
return;
}
if (pdData.Hitter.Get_TotalAttackCount() == 1 && hitterstat.Get_BuffStat(eStat.MyRangeAttackAvoid) > 0)
{
hitterstat.Set_Buff(eStat.MyRangeAttackAvoid, 0);
Run_AvoidStatus(pdData, huddmg);
return;
}
var adddmg_1time = (int)hitterstat.Get_BuffStat(eStat.AddDmg_1Time);
hitterstat.Set_Buff(eStat.AddDmg_1Time, 0);
var adddmgmul_1time = hitterstat.Get_BuffStat(eStat.AddDmgMul_1Time);
hitterstat.Set_Buff(eStat.AddDmgMul_1Time, 0);
var hitterAttacktype = pdData.e_AttackType;
bool HitterisMob = pdData.Hitter.IsRole(eRole.Mob);
var isHit = HitterisMob || hitterAttacktype == eAttackType.Skill;
if (!isHit)
{ // 빗나감 체크는 PC만
var avoid = m_StatInfo.Get_TotalStat(hitterAttacktype == eAttackType.Melee ? eStat.Avoid_Melee : eStat.Avoid_Range);
isHit = DSUtil.RandomTrue(hitterstat.Get_TotalStat(eStat.HitRate) / (avoid * 3.69));
}
if (!isHit)
{ // 빗나감
pdData.Hitter.OnEvent_NoMiss_Hitter(pdData, false);
huddmg.Set(false, true, -1, Get_World_Position());
return;
}
if (HitterisMob && IsRole(eRole.PC))
{ // PC 회피율 적용
var avoid = m_StatInfo.Get_TotalStat(hitterAttacktype == eAttackType.Melee ? eStat.Avoid_Melee : eStat.Avoid_Range);
if (DSUtil.RandomTrue(avoid))
{ // 회피
Run_AvoidStatus(pdData, huddmg);
return;
}
}
if (hitterAttacktype == eAttackType.Melee && m_StatInfo.Get_TotalStat(eStat.Shield) > 0 &&
dic_Card.ContainsKey(eCardType.G2_NegateMeleeDamageWithShield) &&
DSUtil.RandomTrue(dic_Card[eCardType.G2_NegateMeleeDamageWithShield].m_Data.Get_FloatValue2()))
{ // 근접 무효화 체크
huddmg.Set(false, true, -3, Get_World_Position());
return;
}
if (hitterAttacktype == eAttackType.Range && m_StatInfo.Get_TotalStat(eStat.Shield) > 0 &&
dic_Card.ContainsKey(eCardType.G2_NegateRangedAttackWithShield) &&
DSUtil.RandomTrue(dic_Card[eCardType.G2_NegateRangedAttackWithShield].m_Data.Get_FloatValue2()))
{ // 원거리 무효화 체크
huddmg.Set(false, true, -4, Get_World_Position());
return;
}
var adddmg_mul = 1f;
var FirstAttackTripleDamage = pdData.Hitter.Get_CardSkillData_orNull(eCardType.G5_FirstAttackTripleDamage);
if (FirstAttackTripleDamage != null && m_HitCount == 0 && m_AvoidCount == 0)
adddmg_mul = FirstAttackTripleDamage.m_Data.Get_FloatValue1();
if (m_StatInfo.Get_BuffStat(eStat.AvoidAll_Count) > 0)
{
m_StatInfo.Set_Buff(eStat.AvoidAll_Count, m_StatInfo.Get_BuffStat(eStat.AvoidAll_Count) - 1);
Run_AvoidStatus(pdData, huddmg);
return;
}
var hitter_dmg = (int)(hitterstat.Get_Damage() * adddmg_mul);
hitter_dmg += adddmg_1time;
if (adddmgmul_1time > 0f) hitter_dmg = (int)(hitter_dmg * adddmgmul_1time);
if (IsMiddleLine() && hitterstat.Get_BuffStat(eStat.AddDmgMul_MiddleLine) > 0)
hitter_dmg = (int)(hitter_dmg * hitterstat.Get_BuffStat(eStat.AddDmgMul_MiddleLine));
if (pdData.isCri)
{
var hittercard = pdData.Hitter.Get_CardSkillData_orNull(eCardType.G1_ThirdCritDamage);
if (hittercard != null)
hittercard.Add_UseCountACC(1,
() => { hitterstat.Set_Buff(eStat.AddCriDmg_1Time, hittercard.m_Data.Get_FloatValue2()); });
hitter_dmg = (int)(hitter_dmg * hitterstat.Get_TotalStat(eStat.CriDmg));
Refresh_PCUI();
}
#region ()
var reducedmg = 0;
if (hitterAttacktype == eAttackType.Melee)
reducedmg = (int)m_StatInfo.Get_TotalStat(eStat.ReduceMeeleDmg);
else if (hitterAttacktype == eAttackType.Range)
{
reducedmg = (int)m_StatInfo.Get_TotalStat(eStat.ReduceRangeDmg);
if (dic_Card.ContainsKey(eCardType.G3_RangedHitNextAttackDamageUp))
m_StatInfo.Set_Buff(true, eStat.AddDmgMul_1Time, dic_Card[eCardType.G3_RangedHitNextAttackDamageUp].m_Data.Get_FloatValue2());
}
reducedmg += (int)m_StatInfo.Get_TotalStat(eStat.ReduceDmg);
hitter_dmg -= reducedmg;
#endregion
#region (%)
var reducedmg_rate = m_StatInfo.Get_TotalStat(hitterAttacktype == eAttackType.Melee ? eStat.ReduceMeeleDmg_Mul
: eStat.ReduceRangeDmg_Mul);
if (hitterAttacktype == eAttackType.Range && m_StatInfo.Get_TotalStat(eStat.Shield) > 0 &&
dic_Card.ContainsKey(eCardType.G2_ReduceRangedDamageWithShield))
reducedmg_rate += dic_Card[eCardType.G2_ReduceRangedDamageWithShield].m_Data.Get_FloatValue2();
hitter_dmg -= (int)(hitter_dmg * reducedmg_rate);
#endregion
if (hitter_dmg < 0) hitter_dmg = 1;
var dmg = hitter_dmg;
if (m_StatInfo.Get_TotalStat(eStat.Shield) > 0 && dic_Card.ContainsKey(eCardType.G4_ShieldedDamageReduction))
dmg -= (int)(dmg * dic_Card[eCardType.G4_ShieldedDamageReduction].m_Data.Get_FloatValue2());
if (hitterstat.Get_Stat(eStat.FixedDmg) > 0)
dmg = hitter_dmg = (int)hitterstat.Get_Stat(eStat.FixedDmg);
else if (pdData.isCri)
pdData.Hitter.OnEvent_Cri(pdData, dmg);
Get_Dmg(dmg, pdData);
++m_HitCount; m_HitCount.RandomizeCryptoKey();
pdData.Hitter.OnEvent_NoMiss_Hitter(pdData, true);
OnEvent_Hit(pdData, this, dmg);
}
void Reflect_Projectile(eCardType cardType, ProjectileData pdData, bool randomTarget = true, bool usecardprojectile = false)
{
var pd = Get_CardProjectileData(cardType);
pdData.Copy(pd);
pd.e_CardType = cardType;
if (usecardprojectile)
{
pd.s_Projectile = dic_Card[cardType].m_Data.s_Projectile;
pd.e_AttackType = dic_Card[cardType].m_Data.e_ProjectileAttackType;
}
pd.m_Role = m_TableData.m_Role;
if (randomTarget) pd.Target = InGameInfo.Ins.Get_RandomEnemy_orNull(pd.m_Role);
else pd.Target = pd.Hitter;
pd.Hitter = this;
if (pd.Target != null)
ProjectileMgr.Ins.Shoot_Projectile(pd, Get_World_Position(), pd.Target.Get_World_Position(), pd.Target, actor =>
{
actor.Get_Dmg(pd);
});
}
void Reflect_Projectile(ProjectileData pdData, int fixeddmg)
{
var pd = new ProjectileData();
pdData.Copy(pd);
pd.m_Role = m_TableData.m_Role;
pd.Target = pd.Hitter;
pd.Hitter = this;
pd.m_HitterStat.Set_Stat(eStat.FixedDmg, fixeddmg);
if (pd.Target != null)
ProjectileMgr.Ins.Shoot_Projectile(pd, Get_World_Position(), pd.Target.Get_World_Position(), pd.Target, actor =>
{
actor.Get_Dmg(pd);
});
}
protected virtual void Set_Die(ProjectileData pdData)
{
var isCurse = IsCurse();
foreach (var item in dic_StatusEffect)
item.Value.Off();
if (isCurse)
{
Set_StatusEffect(eStatusConditionsType.Curse_Explosion, 3f, true);
if (m_PDHPDmgStatInfo == null)
m_PDHPDmgStatInfo = new ActorStatInfo(this, false);
m_PDHPDmgStatInfo.Set_Stat(eStat.Attack_Min, m_StatInfo.Get_TotalStat(eStat.MaxHP) * 0.5);
m_PDHPDmgStatInfo.Set_Stat(eStat.Attack_Max, m_StatInfo.Get_TotalStat(eStat.MaxHP) * 0.5);
m_PDHPDmgStatInfo.Set_Stat(eStat.HitRate, m_StatInfo.Get_TotalStat(eStat.HitRate));
m_PDHPDmg.Set("", Get_Data().m_Role, eAttackType.Melee, this, m_PDHPDmgStatInfo);
var mobs = InGameInfo.Ins.Get_Mobs_4Nearby(Get_MobIndex());
for (int i = 0; i < mobs.Length; i++)
mobs[i].Get_Dmg(m_PDHPDmg);
}
}
IEnumerator Co_Selfdestruct()
{
var data = m_SelfDestructData.m_Data;
m_SelfDestructData.Set_Status(eSelfDestructStatus.Soon);
m_SelfDestructData.eff_SelfDestruct.Set(data.m_sclData.s_SkillEffect, Get_World_Position(), 3f);
yield return new WaitForSeconds(3f);
EffectMgr.Ins.Show_Effect($"{data.m_sclData.s_SkillEffect}_exp", Get_World_Position(), 1f);
Get_Dmg((int)m_StatInfo.Get_TotalStat(eStat.HP)); // 본인 자폭
// 정인호 : 자폭 데미지 주기 (플레이어 + 십자)
var dmg = (int)(m_StatInfo.Get_Damage() * data.m_TData.Get_StatValue2());
var pc = InGameInfo.Ins.Get_Enemy_orNull(eRole.Mob);
pc.Get_Dmg(dmg);
EffectMgr.Ins.Show_Effect($"{data.m_sclData.s_SkillEffect}_exp", pc.Get_World_Position(), 1f);
var mobs = InGameInfo.Ins.Get_Mobs_4Nearby(Get_MobIndex());
for (int i = 0; i < mobs.Length; i++)
{
mobs[i].Get_Dmg(dmg);
EffectMgr.Ins.Show_Effect($"{data.m_sclData.s_SkillEffect}_exp", mobs[i].Get_World_Position(), 1f);
}
}
IEnumerator Co_Resurrection()
{
bResurrectioning = true; bResurrectioning.RandomizeCryptoKey();
EffectMgr.Ins.Show_Effect(table_StatusConditionsList.Ins.Get_Data_orNull(eStatusConditionsType.Resurrection).s_SkillEffect,
Get_World_Position(), 3f);
yield return new WaitForSeconds(3f);
bResurrectioning = false; bResurrectioning.RandomizeCryptoKey();
Heal_Shield((float)m_StatInfo.Get_BuffStat(eStat.Resurrection_Shield));
var rh = m_StatInfo.Get_BuffStat(eStat.Resurrection_Heal);
if (dic_Card.ContainsKey(eCardType.G1_AngelFeatherHeal))
rh += rh * dic_Card[eCardType.G1_AngelFeatherHeal].m_Data.Get_FloatValue2();
Heal(eHealType.Normal, (float)rh);
}
public virtual void Shoot_Projectile()
{
if (m_Target == null) return;
if (Get_AttackCount() == 1 && Get_AttackType() == eAttackType.Range)
{
var card = m_Target.Get_CardSkillData_orNull(eCardType.G1_RangedFirstAttackSelfDamage);
if (card != null)
{
Shoot_BaseProjectile(this);
return;
}
}
Shoot_Projectile(m_Target, m_BaseAttackPD, target =>
{
OnEvent_ShootProjectile(m_BaseAttackPD);
target.Get_Dmg(m_BaseAttackPD);
ActorStatus = eActorStatus.Idle;
});
}
public void Shoot_BaseProjectile(Actor target)
{
Shoot_Projectile(target, m_BaseAttackPD, targetactor =>
{
OnEvent_ShootProjectile(m_BaseAttackPD);
targetactor.Get_Dmg(m_BaseAttackPD);
ActorStatus = eActorStatus.Idle;
});
}
public void Shoot_AddProjectiles(eCardType cardtype, params Actor[] fixedTarget)
{
if (dic_Card.ContainsKey(cardtype)) Shoot_AddProjectiles(dic_Card[cardtype], fixedTarget);
}
public void Shoot_AddProjectiles(CardSkillData card, params Actor[] fixedTarget)
{
var loop = card.m_Data.n_ProjectileCount > fixedTarget.Length ? card.m_Data.n_ProjectileCount : fixedTarget.Length;
for (int i = 0; i < loop; i++)
{
var cardtype = card.m_Data.e_CardType;
var attacktype = card.m_Data.e_ProjectileAttackType;
var delaytime = card.m_Data.f_ProjectileDelayTime;
var pd = Get_CardProjectileData(i, card);
pd.Set(card.m_Data.s_Projectile, m_TableData.m_Role, attacktype, this, dic_CardStatInfo[cardtype][i], cardtype);
if (fixedTarget.Length == 0)
{
Shoot_Projectile_Delay(MonsterNodeControler.Ins.Get_RandomTarget(), pd,
target => { target.Get_Dmg(pd); }, delaytime * i);
}
else
{
var targetLocal = fixedTarget.Length > i ? fixedTarget[i] : fixedTarget[0]; // <-- 중요: 로컬로 복사
Shoot_Projectile_Delay(targetLocal, pd, target => { target.Get_Dmg(pd); }, delaytime * i);
}
}
}
void Shoot_Projectile(Actor target, ProjectileData pd, Action<Actor> act_end)
{
if (target == null) return;
pd.Set(target, Get_ProjectileSpeed());
var startpos = Get_World_Position();
if (IsRole(eRole.PC))
{
var mobindex = target.Get_MobIndex();
if (mobindex < 0) mobindex += 3; // 라인 교체로 내려갔을 수도 있으므로 기존 위치로 잡음
switch (mobindex)
{
case 0: case 3: case 6: startpos = InGameInfo.Ins.tfs_ProjectileStart[0].position; break;
case 1: case 4: case 7: startpos = InGameInfo.Ins.tfs_ProjectileStart[1].position; break;
case 2: case 5: case 8: startpos = InGameInfo.Ins.tfs_ProjectileStart[2].position; break;
}
}
ProjectileMgr.Ins.Shoot_Projectile(pd, startpos, target.Get_World_Position(), target, act_end);
}
void Shoot_Projectile_Delay(Actor target, ProjectileData pd, Action<Actor> act_end, float delay)
{
if (target == null || target.IsDead() || target.Get_MobIndex() < 0) return;
StartCoroutine(Co_ProjectileDelay(target, pd, act_end, delay));
}
IEnumerator Co_ProjectileDelay(Actor target, ProjectileData pd, Action<Actor> act_end, float delay)
{
yield return new WaitForSeconds(delay);
Shoot_Projectile(target, pd, act_end);
}
public ProjectileData Get_BaseProjectileData() { return m_BaseAttackPD; }
ProjectileData Get_CardProjectileData(eCardType cardtype)
{
if (!dic_cardProjectile.ContainsKey(cardtype))
dic_cardProjectile.Add(cardtype, new ProjectileData());
return dic_cardProjectile[cardtype];
}
ProjectileData Get_CardProjectileData(int asinfoindex, CardSkillData card)
{
var cardtype = card.m_Data.e_CardType;
if (dic_CardStatInfo[cardtype].Count <= asinfoindex)
dic_CardStatInfo[cardtype].Add(new ActorStatInfo(this, false));
var asinfo = dic_CardStatInfo[cardtype][asinfoindex];
asinfo.Clear_All();
asinfo.Set_Stat(eStat.Cri, m_StatInfo.Get_TotalStat(eStat.Cri));
asinfo.Set_Stat(eStat.CriDmg, m_StatInfo.Get_TotalStat(eStat.CriDmg));
asinfo.Set_Stat(eStat.HitRate, m_StatInfo.Get_TotalStat(eStat.HitRate));
if (card.m_Data.n_UseDmg == 1)
{
asinfo.Set_Stat(eStat.Attack_Min, m_StatInfo.Get_TotalStat(eStat.Attack_Min) * card.m_Data.Get_FloatValue2());
asinfo.Set_Stat(eStat.Attack_Max, m_StatInfo.Get_TotalStat(eStat.Attack_Max) * card.m_Data.Get_FloatValue2());
}
else
{
asinfo.Set_Stat(eStat.Attack_Min, card.m_Data.Get_IntValue1());
asinfo.Set_Stat(eStat.Attack_Max, card.m_Data.Get_IntValue1());
}
// PC 버프도 넘겨야 하나? 일단 안 넘김
//m_StatInfo.Set_BuffDebuff(asinfo);
// 장비 능력치 추가
asinfo.Set_Stat(true, eStat.Attack_Min, m_StatInfo.Get_TotalStat(eStat.SkillDamageIncrease));
asinfo.Set_Stat(true, eStat.Attack_Max, m_StatInfo.Get_TotalStat(eStat.SkillDamageIncrease));
var amin = (int)(asinfo.Get_TotalStat(eStat.Attack_Min) * m_StatInfo.Get_TotalStat(eStat.SkillDamageIncrease_Mul));
asinfo.Set_Stat(true, eStat.Attack_Min, amin);
var amax = (int)(asinfo.Get_TotalStat(eStat.Attack_Max) * m_StatInfo.Get_TotalStat(eStat.SkillDamageIncrease_Mul));
asinfo.Set_Stat(true, eStat.Attack_Max, amax);
////////////////////
return Get_CardProjectileData(cardtype);
}
public void Shoot_Projectile_FixedDmg(eCardType cardtype, int fixedDmg, params Actor[] targets)
{
if (dic_Card.ContainsKey(cardtype))
Shoot_Projectile_FixedDmg(cardtype, dic_Card[cardtype].m_Data.s_Projectile, fixedDmg, targets);
}
public void Shoot_Projectile_FixedDmg(eCardType cardtype, string projectile, int fixedDmg, params Actor[] targets)
{
for (int i = 0; i < targets.Length; i++)
{
if (dic_CardStatInfo[cardtype].Count <= i)
dic_CardStatInfo[cardtype].Add(new ActorStatInfo(this, false));
var asinfo = dic_CardStatInfo[cardtype][i];
asinfo.Clear_All();
asinfo.Set_Stat(eStat.FixedDmg, fixedDmg);
asinfo.Set_Stat(eStat.HitRate, m_StatInfo.Get_TotalStat(eStat.HitRate));
var pd = Get_CardProjectileData(cardtype);
pd.Set(projectile, m_TableData.m_Role, eAttackType.Melee, this, asinfo);
Shoot_Projectile(targets[i], pd, targetlast => { targetlast.Get_Dmg(pd); });
}
}
/// <summary>
/// 신비한 폭발 쏘기
/// </summary>
void Shoot_MysticExplosion(int asinfoindex, CardSkillData card)
{
var pd = Get_CardProjectileData(asinfoindex, card);
var cardtype = card.m_Data.e_CardType;
pd.Set(card.m_Data.s_Projectile, m_TableData.m_Role, card.m_Data.e_ProjectileAttackType, this,
dic_CardStatInfo[cardtype][asinfoindex], cardtype);
var pos = InGameInfo.Ins.tfs_ProjectileStart[3].position;
ProjectileMgr.Ins.Shoot_Projectile(pd, pos, pos, null, null);
var enemies = InGameInfo.Ins.Get_LineMobs(eMobBattlePos.Frontline, eMobBattlePos.Middleline);
for (int i = 0; i < enemies.Count; i++)
enemies[i].Get_Dmg(pd);
}
void Shoot_Curse_RandomTarget()
{
var target = InGameInfo.Ins.Get_RandomEnemy_orNull(Get_Data().m_Role);
if (target) target.Set_StatusEffect(eStatusConditionsType.Curse, 999999f);
}
#endregion
#region
void Run_AvoidStatus(ProjectileData pdData, HUD_Dmg huddmg)
{
Play_Evasion();
huddmg.Set(false, true, -2, Get_World_Position());
pdData.Hitter.OnEvent_NoMiss_Hitter(pdData, false);
OnEvent_Avoid(pdData);
}
#endregion
#region
public void OnEvent_AfterLineChange()
{ // 이벤트 실행 타이밍 : 라인 체인지 직후
if (m_StatInfo != null && m_StatInfo.Get_BuffStat(eStat.PreemptiveStrike) > 0)
m_AttackCoolTime = Time.deltaTime;
}
public void OnEvent_RunSkillCard(eCardType addcard = eCardType.Max)
{ // 이벤트 실행 타이밍 : 최초, 카드 추가시, 라인 체인지 직후
// Can_RunCard : 항싱 실행 여부 체크도 포함
// Can_RunCard 체크가 아닌 경우 : 카드 획득 시 실행 여부만 체크 (한 번만 실행)
var cardtype = eCardType.G5_AllRangedEnemiesBlindIfBackline;
if (Can_RunCard(cardtype, addcard))
{
var enemies = InGameInfo.Ins.Get_AllEnemies(Get_Data().m_Role);
for (int i = 0; i < enemies.Count; i++)
{
var data = enemies[i].Get_Data();
if (data != null && enemies[i].IsMiddleLine() && data.Get_AttackType() == eAttackType.Range &&
!enemies[i].IsCC(eStatusConditionsType.Blind))
enemies[i].Set_StatusEffect(eStatusConditionsType.Blind, dic_Card[cardtype].m_Data.Get_FloatValue3());
}
}
cardtype = eCardType.G1_MeleeEnemiesAttackSelfChance;
if (Can_RunCard(cardtype, addcard))
{
var card = dic_Card[cardtype];
var enemies = InGameInfo.Ins.Get_LineMobs(eMobBattlePos.Frontline);
for (int i = 0; i < enemies.Count; i++)
{
if (enemies[i].Get_AttackType() == eAttackType.Melee && DSUtil.RandomTrue(card.m_Data.Get_FloatValue2()))
enemies[i].Shoot_BaseProjectile(enemies[i]);
}
}
cardtype = eCardType.G1_InstantCastMysticExplosion;
if (dic_Card.ContainsKey(cardtype) && cardtype == addcard)
Shoot_MysticExplosion(1, dic_Card[cardtype]);
cardtype = eCardType.G1_HolyDamageOnMeleeFrontAppear;
if (Can_RunCard(cardtype, addcard))
{
var enemies = InGameInfo.Ins.Get_AllEnemies(Get_Data().m_Role);
for (int i = 0; i < enemies.Count; i++)
{
if (enemies[i].IsDead()) continue;
var data = enemies[i].Get_Data();
if (data != null && enemies[i].IsFrontLine() && data.Get_AttackType() == eAttackType.Melee)
Shoot_AddProjectiles(dic_Card[cardtype], enemies[i]);
}
}
cardtype = eCardType.G1_RangedSpawnMagicMissile;
if (Can_RunCard(cardtype, addcard))
{
var enemies = InGameInfo.Ins.Get_AllEnemies(Get_Data().m_Role);
for (int i = 0; i < enemies.Count; i++)
{
if (enemies[i].IsDead()) continue;
var data = enemies[i].Get_Data();
if (data != null && data.Get_AttackType() == eAttackType.Range &&
DSUtil.RandomTrue(dic_Card[cardtype].m_Data.Get_FloatValue2()))
Shoot_AddProjectiles(dic_Card[cardtype], enemies[i]);
}
}
cardtype = eCardType.G1_EnemySpawnHolyDamage;
if (Can_RunCard(cardtype, addcard))
{
var enemies = InGameInfo.Ins.Get_AllEnemies(Get_Data().m_Role);
for (int i = 0; i < enemies.Count; i++)
{
if (enemies[i].IsDead()) continue;
if (DSUtil.RandomTrue(dic_Card[cardtype].m_Data.Get_FloatValue2()))
Shoot_AddProjectiles(dic_Card[cardtype], enemies[i]);
}
}
cardtype = eCardType.G1_CurseExplosionOnKill;
if (dic_Card.ContainsKey(cardtype) && cardtype == addcard)
Shoot_Curse_RandomTarget();
cardtype = eCardType.G1_FireMagicMissiles;
if (dic_Card.ContainsKey(cardtype) && cardtype == addcard)
{
var card = dic_Card[cardtype];
var targets = new List<Actor>();
for (int i = 0; i < card.m_Data.n_ProjectileCount; i++)
targets.Add(InGameInfo.Ins.Get_RandomEnemy_orNull(Get_Data().m_Role));
Shoot_AddProjectiles(card, targets.ToArray());
}
cardtype = eCardType.G1_LifeStealToRandomAll;
if (dic_Card.ContainsKey(cardtype) && cardtype == addcard)
{
var card = dic_Card[cardtype];
var target = InGameInfo.Ins.Get_RandomEnemy_orNull(Get_Data().m_Role);
if (target)
{
target.Get_Dmg(card.m_Data.Get_IntValue1());
Heal(eHealType.LifeSteal, card.m_Data.Get_IntValue1());
Set_StatusEffect(eStatusConditionsType.Heal_Hp_Add, 1f);
}
}
cardtype = eCardType.G1_GetRandomRareOrEpicSkill;
if (dic_Card.ContainsKey(cardtype) && cardtype == addcard)
Add_Card_Random(eGrade.UnCommon, eGrade.Rare);
cardtype = eCardType.G1_InstantFullHeal;
if (dic_Card.ContainsKey(cardtype) && cardtype == addcard)
{
Heal(eHealType.Normal, 1f);
Set_StatusEffect(eStatusConditionsType.Heal_Hp_Mul, 1f);
}
cardtype = eCardType.G1_CurseEnemiesOnBattlefield;
if (dic_Card.ContainsKey(cardtype) && cardtype == addcard)
{
var enemies = InGameInfo.Ins.Get_AllEnemies(Get_Data().m_Role).FindAll(f => !f.IsDead() && !f.IsCurse());
var targetcount = dic_Card[cardtype].m_Data.Get_IntValue1();
var targets = enemies.OrderBy(_ => Guid.NewGuid()).Take(targetcount).ToList();
targets.ForEach(f => f.Set_StatusEffect(eStatusConditionsType.Curse, 99999f));
}
cardtype = eCardType.G1_EnemySpawnStunChance;
if (Can_RunCard(cardtype, addcard))
{
var enemies = InGameInfo.Ins.Get_AllEnemies(m_TableData.m_Role);
var carddata = dic_Card[cardtype].m_Data;
for (int i = 0; i < enemies.Count; i++)
{
if (DSUtil.RandomTrue(carddata.Get_FloatValue2()))
enemies[i].Set_StatusEffect(carddata.e_StatusConditionsType, carddata.Get_FloatValue3());
}
}
cardtype = eCardType.G1_FullShieldRecover;
if (dic_Card.ContainsKey(cardtype) && cardtype == addcard)
{
Heal_Shield(1f);
Set_StatusEffect(eStatusConditionsType.Heal_Shield_Mul, 1f);
}
cardtype = eCardType.G1_InstantSkillReroll;
if (dic_Card.ContainsKey(cardtype) && cardtype == addcard)
SelectCardUI.Ins.Set_Cards(true);
cardtype = eCardType.G1_StunAllMeleeEnemies;
if (dic_Card.ContainsKey(cardtype) && cardtype == addcard)
{
var carddata = dic_Card[cardtype].m_Data;
var enemies = InGameInfo.Ins.Get_Enemies_byAttackType(Get_Data().m_Role, eAttackType.Melee);
for (int i = 0; i < enemies.Count; i++)
enemies[i].Set_StatusEffect(carddata.e_StatusConditionsType, carddata.Get_FloatValue3());
}
cardtype = eCardType.G1_StunAllRangedEnemies;
if (dic_Card.ContainsKey(cardtype) && cardtype == addcard)
{
var carddata = dic_Card[cardtype].m_Data;
var enemies = InGameInfo.Ins.Get_Enemies_byAttackType(Get_Data().m_Role, eAttackType.Range);
for (int i = 0; i < enemies.Count; i++)
enemies[i].Set_StatusEffect(carddata.e_StatusConditionsType, carddata.Get_FloatValue3());
}
cardtype = eCardType.G1_DealHolyDamageToAll;
if (dic_Card.ContainsKey(cardtype) && cardtype == addcard)
Shoot_AddProjectiles(dic_Card[cardtype], InGameInfo.Ins.Get_AllEnemies(Get_Data().m_Role).ToArray());
cardtype = eCardType.G1_ShieldIncreaseAttackPower;
if (dic_Card.ContainsKey(cardtype) && cardtype == addcard)
{
if (m_StatInfo.Get_TotalStat(eStat.Shield) > 0)
{
var carddata = dic_Card[cardtype].m_Data;
m_StatInfo.Set_Stat(true, eStat.Attack_Min, carddata.Get_IntValue1());
m_StatInfo.Set_Stat(true, eStat.Attack_Max, carddata.Get_IntValue1());
Refresh_PCUI();
}
}
cardtype = eCardType.G1_AttackRandomEnemy;
CantSetTarget = dic_Card.ContainsKey(cardtype);
CantSetTarget.RandomizeCryptoKey();
if (isCantSetTarget()) Find_Target();
}
private void TryActivateCard_NoMiss(eCardType cardtype, Action<CardSkillData> onTrigger)
{
if (!dic_Card.ContainsKey(cardtype))
return;
var card = dic_Card[cardtype];
int n = card.m_Data.Get_IntValue1();
if (m_TotalAttackSuccessCount >= n && m_TotalAttackSuccessCount % n == 0)
onTrigger?.Invoke(card);
}
protected void OnEvent_PlayAttack()
{
++m_TotalAttackCount; m_TotalAttackCount.RandomizeCryptoKey();
++m_AttackCount; m_AttackCount.RandomizeCryptoKey();
m_BaseAttackPD.Set(m_Target, Get_ProjectileSpeed());
Check_Specificity(eActiveConditions.Attack_Normal, m_BaseAttackPD);
eCardType cardtype = eCardType.Max;
if (m_AttackCount == 1)
{ // 첫번째 공격
cardtype = eCardType.G1_FirstAttack;
if (dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
if (card.UseCount > 0) return;
++card.UseCount;
m_StatInfo.Set_Buff(true, eStat.AddDmgMul_1Time, dic_Card[cardtype].m_Data.Get_FloatValue2());
}
cardtype = eCardType.G1_FirstAttackHeals;
if (dic_Card.ContainsKey(cardtype))
{
Heal(eHealType.Normal, dic_Card[cardtype].m_Data.Get_IntValue1());
Set_StatusEffect(eStatusConditionsType.Heal_Hp_Add, 1f);
}
cardtype = eCardType.G1_FirstAttackShieldPercent;
if (dic_Card.ContainsKey(cardtype))
{
Heal_Shield(dic_Card[cardtype].m_Data.Get_FloatValue2());
Set_StatusEffect(eStatusConditionsType.Heal_Shield_Mul, 1f);
}
cardtype = eCardType.G1_FirstAttackLightningStorm;
if (dic_Card.ContainsKey(cardtype))
{
var enemies = InGameInfo.Ins.Get_RandomAliveEnemies(Get_Data().m_Role,
dic_Card[cardtype].m_Data.Get_IntValue1()).ToArray();
Shoot_AddProjectiles(dic_Card[cardtype], enemies);
}
var G1_FirstAttackLightning = m_Target.Get_CardSkillData_orNull(eCardType.G1_FirstAttackLightning);
if (G1_FirstAttackLightning != null && DSUtil.RandomTrue(G1_FirstAttackLightning.m_Data.Get_FloatValue1()))
Shoot_AddProjectiles(G1_FirstAttackLightning, this);
cardtype = eCardType.G3_FirstAttackCritChanceUp;
if (dic_Card.ContainsKey(cardtype))
m_StatInfo.Set_Buff(true, eStat.AddCri_1Time, dic_Card[cardtype].m_Data.Get_FloatValue2());
}
cardtype = eCardType.G1_LowHPEnemyLightning;
if (dic_Card.ContainsKey(cardtype))
{
var data = dic_Card[cardtype].m_Data;
var target_hp = m_Target.Get_ActorStatInfo().Get_TotalStat(eStat.HP);
var target_maxhp = m_Target.Get_ActorStatInfo().Get_TotalStat(eStat.MaxHP);
if (target_hp < target_maxhp * data.Get_FloatValue1() && DSUtil.RandomTrue(data.Get_FloatValue3()))
Shoot_AddProjectiles(cardtype, m_Target);
}
}
public void OnEvent_ShootProjectile(ProjectileData pdData)
{
if (!pdData.m_HitterStat.IsMainAttack) return;
var cardtype = eCardType.G1_IllusionSpear;
if (dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
if (card.UseCount <= 0)
{
++card.UseCount;
Shoot_AddProjectiles(card, InGameInfo.Ins.Get_Enemy_orNull(m_TableData.m_Role, pdData.Target.Get_MobIndex() + 3));
}
}
}
public virtual void OnEvent_Kill(Actor deadactor)
{
var cardtype = eCardType.G1_FullHealAfterKillsOnce;
if (dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
card.Add_UseCountACC(1, () =>
{
AllHeal(eHealType.Normal);
Set_StatusEffect(eStatusConditionsType.Heal_Hp_Mul, 1f);
}, int.MinValue);
}
cardtype = eCardType.G1_KillCountRecoverFullShield;
if (dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
card.Add_UseCountACC(1, () =>
{
Heal_Shield(1f);
Set_StatusEffect(eStatusConditionsType.Heal_Shield_Add, 1f);
}, int.MinValue);
}
cardtype = eCardType.G1_DamageOnKill;
if (dic_Card.ContainsKey(cardtype))
Shoot_Projectile_FixedDmg(cardtype, dic_Card[cardtype].m_Data.Get_IntValue1(), InGameInfo.Ins.Get_RandomEnemy_orNull(Get_Data().m_Role));
cardtype = eCardType.G4_MaxAttackUpAndHealOnKill;
if (dic_Card.ContainsKey(cardtype))
{
var heal = (int)dic_Card[cardtype].m_Data.Get_FloatValue2();
Heal(eHealType.Normal, heal);
}
cardtype = eCardType.G5_ArcaneExplosionOnKill;
if (dic_Card.ContainsKey(cardtype))
Shoot_MysticExplosion(0, dic_Card[cardtype]);
cardtype = eCardType.G5_StunBacklineOnKill;
if (dic_Card.ContainsKey(cardtype))
{
var enemies = InGameInfo.Ins.Get_LineMobs(eMobBattlePos.Middleline);
for (int i = 0; i < enemies.Count; i++)
enemies[i].Set_StatusEffect(eStatusConditionsType.Stun, dic_Card[cardtype].m_Data.Get_FloatValue3());
}
if (deadactor.IsMiddleLine())
{
cardtype = eCardType.G1_HealOnBackKill;
if (dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
Heal(eHealType.Normal, card.m_Data.Get_IntValue1());
Set_StatusEffect(eStatusConditionsType.Heal_Hp_Add, 1f);
}
cardtype = eCardType.G1_CastMagicMissilesOnBackKill;
if (dic_Card.ContainsKey(cardtype))
Shoot_AddProjectiles(cardtype, InGameInfo.Ins.Get_RandomEnemy_orNull(Get_Data().m_Role));
cardtype = eCardType.G1_KillBacklineDealHolyDamage;
if (dic_Card.ContainsKey(cardtype))
Shoot_AddProjectiles(cardtype, InGameInfo.Ins.Get_RandomAliveEnemies(Get_Data().m_Role,
dic_Card[cardtype].m_Data.Get_IntValue2()).ToArray());
}
}
public void OnEvent_NoMiss_Hitter(ProjectileData pdData, bool nomiss)
{
if (!pdData.m_HitterStat.IsMainAttack) return;
var cardtype = eCardType.Max;
if (nomiss)
{
++m_TotalAttackSuccessCount; m_TotalAttackSuccessCount.RandomizeCryptoKey();
++m_AttackSuccessCount; m_AttackSuccessCount.RandomizeCryptoKey();
Check_Specificity(eActiveConditions.Attack_Hit, pdData);
TryActivateCard_NoMiss(eCardType.G4_NHitFiresDarkMissiles, card => Shoot_AddProjectiles(card, pdData.Target));
TryActivateCard_NoMiss(eCardType.G4_NHitCastsLightning, card =>
{
pdData.Target = InGameInfo.Ins.Get_RandomEnemy_orNull(Get_Data().m_Role);
Shoot_AddProjectiles(card, pdData.Target);
});
TryActivateCard_NoMiss(eCardType.G4_NHitHealsByMaxHPPercent, card => Heal(eHealType.Normal, card.m_Data.Get_FloatValue2()));
TryActivateCard_NoMiss(eCardType.G4_NHitCastsFireballAOE, card =>
{
var rndEnemy = InGameInfo.Ins.Get_RandomEnemy_orNull(Get_Data().m_Role);
if (rndEnemy)
{
pdData.Target = rndEnemy;
var rndindex = rndEnemy.Get_MobIndex();
Shoot_AddProjectiles(card, InGameInfo.Ins.Get_Mobs_4Nearby(rndindex));
}
});
cardtype = eCardType.G1_FifthAttackBack;
if (dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
card.Add_UseCountACC(1, () =>
{
var middletarget = InGameInfo.Ins.Get_Enemy_orNull(Get_Data().m_Role, pdData.Target.Get_MobIndex() + 3);
if (middletarget) Shoot_AddProjectiles(card, middletarget);
});
}
cardtype = eCardType.G1_ThunderOnFifthHit;
if (dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
card.Add_UseCountACC(1, () => { Shoot_AddProjectiles(card, pdData.Target); });
}
}
else
{
cardtype = eCardType.G1_DamageUpAfterMiss;
if (dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
Set_Buff(true, eStat.AddDmgMul_1Time, card.m_Data.Get_FloatValue2());
}
cardtype = eCardType.G1_MissRestoreShield;
if (dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
Heal_Shield(card.m_Data.Get_IntValue1());
Set_StatusEffect(eStatusConditionsType.Heal_Shield_Add, 1f);
}
cardtype = eCardType.G1_MissCastLightningRandomBackRow;
if (dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
var targets = InGameInfo.Ins.Get_LineMobs(eMobBattlePos.Middleline);
if (targets.Count > 0)
{
var target = targets[Random.Range(0, targets.Count)];
Shoot_AddProjectiles(card, target);
}
}
cardtype = eCardType.G1_MissCriticalDamageBackRow;
if (dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
var targets = InGameInfo.Ins.Get_LineMobs(eMobBattlePos.Middleline);
var count = card.m_Data.Get_IntValue1();
if (targets.Count > 0)
{
var selectedTargets = targets.OrderBy(x => Guid.NewGuid()).Take(count).ToList();
for (int i = 0; i < selectedTargets.Count; i++)
{
var pd = Get_CardProjectileData(i, card);
pd.Set(card.m_Data.s_Projectile, m_TableData.m_Role, card.m_Data.e_ProjectileAttackType, this, dic_CardStatInfo[cardtype][i], cardtype);
pd.isCri = true;
Shoot_Projectile(selectedTargets[i], pd, target => target.Get_Dmg(pd));
}
}
}
cardtype = eCardType.G1_MissCastLightningAdditionalAttack;
if (dic_Card.ContainsKey(cardtype))
Shoot_AddProjectiles(dic_Card[cardtype], pdData.Target);
cardtype = eCardType.G1_MissHolyDamage;
if (dic_Card.ContainsKey(cardtype))
Shoot_AddProjectiles(dic_Card[cardtype], pdData.Target);
}
cardtype = eCardType.G1_ElectricShockOnConsecutiveHits;
if (dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
if (nomiss)
card.Add_UseCountACC(1, () => { Shoot_AddProjectiles(card, pdData.Target); });
else
card.UseCount_Acc = 0;
}
}
public void OnEvent_Cri(ProjectileData pdData, int fixeddmg)
{
if (!pdData.m_HitterStat.IsMainAttack) return;
Check_Specificity(eActiveConditions.Attack_Critical, pdData);
var cardtype = eCardType.G2_CriUpAfterCri;
if (dic_Card.ContainsKey(cardtype))
{
Set_Buff(true, eStat.AddCri_1Time, dic_Card[cardtype].m_Data.Get_FloatValue2());
Refresh_PCUI();
}
cardtype = eCardType.G3_CritHitChainsToRandomEnemy;
if (dic_Card.ContainsKey(cardtype))
if (DSUtil.RandomTrue(dic_Card[cardtype].m_Data.Get_FloatValue2()))
Shoot_Projectile_FixedDmg(cardtype, fixeddmg, MonsterNodeControler.Ins.Get_RandomTarget());
cardtype = eCardType.G4_CritStunsAllEnemies;
if (dic_Card.ContainsKey(cardtype))
{
var enemies = InGameInfo.Ins.Get_AllEnemies(m_TableData.m_Role);
var carddata = dic_Card[cardtype].m_Data;
for (int i = 0; i < enemies.Count; i++)
enemies[i].Set_StatusEffect(carddata.e_StatusConditionsType, carddata.Get_FloatValue3());
}
cardtype = eCardType.G5_CastFireballOnCrit;
if (dic_Card.ContainsKey(cardtype))
{
var targets = InGameInfo.Ins.Get_Mobs_4Nearby(pdData.Target.Get_MobIndex());
Shoot_AddProjectiles(dic_Card[cardtype], targets);
}
cardtype = eCardType.G1_CastReaperOnNthCrit;
if (dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
card.Add_UseCountACC(1, () => { Shoot_AddProjectiles(card, pdData.Target); });
}
}
public void OnEvent_MeetNode(eStageNodeType nodeType)
{
var cardtype = eCardType.Max;
var data = MyValue.m_MyStageData.Get_CurNodeData();
switch (nodeType)
{
case eStageNodeType.Mob:
break;
case eStageNodeType.Treasure:
break;
case eStageNodeType.Merchant:
break;
case eStageNodeType.NPC:
break;
case eStageNodeType.Sanctuary:
cardtype = eCardType.G1_GainGoldOnSanctuaryFind;
if (dic_Card.ContainsKey(cardtype))
{
var gold = dic_Card[cardtype].m_Data.Get_IntValue1();
InGameInfo.Ins.Add_Goods(MyValue.ItemID_Gold, gold);
GetItemUI.Ins.Set(new ItemSimpleData { itemid = MyValue.ItemID_Gold, amount = gold });
}
cardtype = eCardType.G1_MaxHpPlusOnFountain;
if (dic_Card.ContainsKey(cardtype))
{
var sanctuarydata = data.Get_Data<StageNodeData_Mine>();
var sanctype = table_SanctuaryConfig.Ins.Get_Data(sanctuarydata.SanctuaryID).e_SanctuaryType;
if (sanctype != eSanctuaryType.Sanctuary)
{
Set_Buff(true, eStat.MaxHP, dic_Card[cardtype].m_Data.Get_IntValue1());
Refresh_PCUI();
}
}
cardtype = eCardType.G1_FullRecoverAtFountain;
if (dic_Card.ContainsKey(cardtype) && m_StatInfo.Get_TotalStat(eStat.Shield) > 0)
{
Heal(eHealType.Sactuary, 1f);
Set_StatusEffect(eStatusConditionsType.Heal_Hp_Mul, 1f);
}
cardtype = eCardType.G1_TwiceShrineFullRecover;
if (dic_Card.ContainsKey(cardtype))
{
dic_Card[cardtype].Add_UseCountACC(1, () =>
{
AllHeal(eHealType.Normal);
Set_StatusEffect(eStatusConditionsType.Heal_Hp_Mul, 1f);
});
}
break;
case eStageNodeType.BuffDebuff:
break;
case eStageNodeType.TwoWay:
break;
case eStageNodeType.Campfire:
cardtype = eCardType.G1_CampHealShield;
if (dic_Card.ContainsKey(cardtype))
{
Heal_Shield(dic_Card[cardtype].m_Data.Get_IntValue1());
Set_StatusEffect(eStatusConditionsType.Heal_Shield_Add, 1f);
}
cardtype = eCardType.G1_LevelUpOnCampFind;
if (dic_Card.ContainsKey(cardtype))
InGameInfo.Ins.PCLvUp_Imm();
cardtype = eCardType.G1_CampShieldHighIncreaseMaxAttack;
if (dic_Card.ContainsKey(cardtype))
{
if (m_StatInfo.Get_TotalStat(eStat.Shield) >=
m_StatInfo.Get_TotalStat(eStat.MaxShield) * dic_Card[cardtype].m_Data.Get_FloatValue2())
{
m_StatInfo.Set_Stat(true, eStat.Attack_Max, dic_Card[cardtype].m_Data.Get_IntValue1());
Refresh_PCUI();
}
}
cardtype = eCardType.G1_CampFillEmptyPotion;
if (dic_Card.ContainsKey(cardtype))
{
m_StatInfo.Set_Stat(true, eStat.Potion, dic_Card[cardtype].m_Data.Get_IntValue1());
InGameInfo.Ins.Set_Texts();
}
cardtype = eCardType.G1_CampRechargePotion;
if (dic_Card.ContainsKey(cardtype))
{
m_StatInfo.Set_Stat(true, eStat.Potion, dic_Card[cardtype].m_Data.Get_IntValue1());
InGameInfo.Ins.Set_Texts();
}
cardtype = eCardType.G2_GetSkillOnCamp;
if (dic_Card.ContainsKey(cardtype))
Add_Card_Random(eGrade.Common);
break;
case eStageNodeType.Nothing:
{
int heal = 0, shield = 0;
cardtype = eCardType.G1_HealEverySecOutOfCombat;
if (dic_Card.ContainsKey(cardtype))
heal += dic_Card[cardtype].m_Data.Get_IntValue1();
heal += (int)m_StatInfo.Get_TotalStat(eStat.ExplorationHpRecovery);
shield += (int)m_StatInfo.Get_TotalStat(eStat.ExplorationShieldRecovery);
if (heal > 0) { Heal(eHealType.Normal, heal); Set_StatusEffect(eStatusConditionsType.Heal_Hp_Add, 1f); }
if (shield > 0) { Heal_Shield(shield); Set_StatusEffect(eStatusConditionsType.Heal_Shield_Add, 1f); }
}
cardtype = eCardType.G1_ExploreRecoverShieldOverTime;
if (dic_Card.ContainsKey(cardtype))
{
Heal_Shield(dic_Card[cardtype].m_Data.Get_IntValue1());
Set_StatusEffect(eStatusConditionsType.Heal_Shield_Add, 1f);
}
break;
case eStageNodeType.Boss:
break;
case eStageNodeType.Random:
break;
}
if (nodeType != eStageNodeType.Nothing)
{
cardtype = eCardType.G1_StopExploreHealHP;
if (dic_Card.ContainsKey(cardtype))
{
Heal(eHealType.Normal, dic_Card[cardtype].m_Data.Get_IntValue1());
Set_StatusEffect(eStatusConditionsType.Heal_Hp_Add, 1f);
}
cardtype = eCardType.G1_StopExploreHealShield;
if (dic_Card.ContainsKey(cardtype))
{
Heal_Shield(dic_Card[cardtype].m_Data.Get_IntValue1());
Set_StatusEffect(eStatusConditionsType.Heal_Shield_Add, 1f);
}
}
}
public void OnEvent_LvUp()
{
var cardtype = eCardType.G1_HealOnLevelUp;
if (dic_Card.ContainsKey(cardtype))
{
Heal(eHealType.Normal, dic_Card[cardtype].m_Data.Get_IntValue1());
Set_StatusEffect(eStatusConditionsType.Heal_Hp_Add, 1f);
}
cardtype = eCardType.G1_MaxHpUpOnLevelUp;
if (dic_Card.ContainsKey(cardtype))
{
m_StatInfo.Set_Stat(true, eStat.MaxHP, dic_Card[cardtype].m_Data.Get_IntValue1());
Refresh_PCUI();
}
cardtype = eCardType.G1_MaxShieldUpOnLevelUp;
if (dic_Card.ContainsKey(cardtype))
{
m_StatInfo.Set_Stat(true, eStat.MaxShield, dic_Card[cardtype].m_Data.Get_IntValue1());
Refresh_PCUI();
}
cardtype = eCardType.G1_StunAllEnemiesOnLevelUp;
if (dic_Card.ContainsKey(cardtype))
{
var enemies = InGameInfo.Ins.Get_AllEnemies(Get_Data().m_Role);
for (int i = 0; i < enemies.Count; i++)
enemies[i].Set_StatusEffect(eStatusConditionsType.Stun, dic_Card[cardtype].m_Data.Get_FloatValue3());
}
cardtype = eCardType.G1_CurseEnemiesOnLevelUp;
if (dic_Card.ContainsKey(cardtype))
Shoot_Curse_RandomTarget();
cardtype = eCardType.G1_LevelUpRecoverShield;
if (dic_Card.ContainsKey(cardtype))
{
Heal_Shield(dic_Card[cardtype].m_Data.Get_IntValue1());
Set_StatusEffect(eStatusConditionsType.Heal_Shield_Add, 1f);
}
cardtype = eCardType.G2_ShieldRecoverOnLevelUp;
if (dic_Card.ContainsKey(cardtype))
m_StatInfo.Set_Stat(true, eStat.Shield, dic_Card[cardtype].m_Data.Get_IntValue1());
}
public void OnEvent_Avoid(ProjectileData pdData)
{
var actorstat = pdData.Hitter.Get_ActorStatInfo();
if (!actorstat.IsMainAttack) return;
++m_TotalAvoidCount; m_TotalAvoidCount.RandomizeCryptoKey();
++m_AvoidCount; m_AvoidCount.RandomizeCryptoKey();
var cardtype = eCardType.G3_MaxAttackUpEveryNDodges;
if (m_TotalAvoidCount > 0 && dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
if (m_TotalAvoidCount % (int)card.m_Data.Get_FloatValue2() == 0)
{
m_StatInfo.Set_Stat(true, eStat.Attack_Max, card.m_Data.Get_IntValue1());
IngameUIManager.Ins.m_PCMainStatUI.Set(m_StatInfo);
}
}
cardtype = eCardType.G1_LifeStealOnDodge;
if (dic_Card.ContainsKey(cardtype))
{
var radnomtarget = InGameInfo.Ins.Get_RandomEnemy_orNull(Get_Data().m_Role);
if (radnomtarget != null)
{
var card = dic_Card[cardtype];
radnomtarget.Get_Dmg(card.m_Data.Get_IntValue1());
radnomtarget.Set_StatusEffect(eStatusConditionsType.VampirHeal_Add, 1f);
Heal(eHealType.LifeSteal, card.m_Data.Get_IntValue1());
Set_StatusEffect(eStatusConditionsType.Heal_Hp_Add, 1f);
}
}
cardtype = eCardType.G1_HolyDamageToBackEnemiesOnDodge;
if (dic_Card.ContainsKey(cardtype))
{
var enemies = InGameInfo.Ins.Get_LineMobs(eMobBattlePos.Middleline);
Shoot_Projectile_FixedDmg(cardtype, dic_Card[cardtype].m_Data.Get_IntValue1(), enemies.ToArray());
}
cardtype = eCardType.G1_HealOnDoubleDodge;
if (dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
card.Add_UseCountACC(1, () =>
{
Heal(eHealType.Normal, card.m_Data.Get_IntValue2());
Set_StatusEffect(eStatusConditionsType.Heal_Hp_Add, 1f);
});
}
if (pdData.e_AttackType == eAttackType.Melee)
{
cardtype = eCardType.G1_LightningToBackOnMeleeDodge;
if (dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
var target = InGameInfo.Ins.Get_Enemy_orNull(Get_Data().m_Role, pdData.Hitter.Get_MobIndex() + 3);
Shoot_AddProjectiles(card, target);
}
}
else
{
cardtype = eCardType.G1_ReflectOnRangedDodge;
if (dic_Card.ContainsKey(cardtype))
Reflect_Projectile(cardtype, pdData);
cardtype = eCardType.G1_ShieldOnRangedDodge;
if (dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
Heal_Shield(card.m_Data.Get_IntValue1());
Set_StatusEffect(eStatusConditionsType.Heal_Shield_Add, 1f);
}
}
}
public void OnEvent_MyShield_Hit(ProjectileData pdData = null)
{
var cardtype = eCardType.G4_MaxAttackIncreasesByShield;
if (dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
m_StatInfo.Set_Buff(eStat.MaxAttack_byShield, (int)(m_StatInfo.Get_TotalStat(eStat.Shield) * card.m_Data.Get_FloatValue2()));
Refresh_PCUI();
}
cardtype = eCardType.G5_ReflectAllDamageWhenShielded;
if (dic_Card.ContainsKey(cardtype))
Reflect_Projectile(cardtype, pdData, false);
}
protected virtual void OnEvent_GetDmg(ProjectileData pd)
{
var cardtype = eCardType.G1_FullShieldIfHpLowAndShieldZero;
if (dic_Card.ContainsKey(cardtype) && !IsDead())
{
if (m_StatInfo.Get_TotalStat(eStat.Shield) == 0)
{
var card = dic_Card[cardtype];
if (m_StatInfo.Get_TotalStat(eStat.HP) <= card.m_Data.Get_IntValue1())
{
Heal_Shield(1f);
Set_StatusEffect(eStatusConditionsType.Heal_Shield_Mul, 1f);
}
}
}
if (m_StatInfo.Get_TotalStat(eStat.Reflection) > 0)
Reflect_Projectile(pd, (int)m_StatInfo.Get_TotalStat(eStat.Reflection));
}
public void OnEvent_Hit(ProjectileData pdData, Actor target, int dmg)
{
ActorStatInfo actorstat = pdData.m_HitterStat;
eAttackType attackType = pdData.e_AttackType;
eCardType cardtype = eCardType.Max;
if (IsMiddleLine())
{
var hittercard = pdData.Hitter.Get_CardSkillData_orNull(eCardType.G1_LifeStealOnBackAttack);
if (hittercard != null)
{
var rndtarget = InGameInfo.Ins.Get_RandomEnemy_orNull(pdData.Hitter.Get_Data().m_Role);
if (rndtarget)
{
rndtarget.Get_Dmg(hittercard.m_Data.Get_IntValue1());
pdData.Hitter.Heal(eHealType.LifeSteal, hittercard.m_Data.Get_IntValue1());
pdData.Hitter.Set_StatusEffect(eStatusConditionsType.Heal_Hp_Add, 1f);
}
}
}
if (!actorstat.IsMainAttack) return;
++dic_HitType[attackType]; dic_HitType[attackType].RandomizeCryptoKey();
Check_Specificity(eActiveConditions.Hit_Count, pdData);
Check_Specificity(eActiveConditions.Hit_Noraml, pdData);
if (attackType == eAttackType.Melee)
{
cardtype = eCardType.G4_NhMeleeHitRestoresShield;
if (dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
if (dic_HitType[attackType] >= card.m_Data.Get_IntValue1() && dic_HitType[attackType] % card.m_Data.Get_IntValue1() == 0)
{
m_StatInfo.Set_Stat(true, eStat.Shield, (int)(m_StatInfo.Get_TotalStat(eStat.MaxShield) * card.m_Data.Get_FloatValue2()));
Set_HUD();
}
}
cardtype = eCardType.G1_HolyDamageOnMeleeHit;
if (dic_Card.ContainsKey(cardtype))
Shoot_AddProjectiles(dic_Card[cardtype], pdData.Hitter);
cardtype = eCardType.G1_ReflectFirstMeleeDamage;
if (dic_Card.ContainsKey(cardtype) && !dic_Card[cardtype].list_identity.Contains(pdData.Hitter.Get_Identity()))
{
dic_Card[cardtype].list_identity.Add(pdData.Hitter.Get_Identity());
Reflect_Projectile(cardtype, pdData, false);
}
cardtype = eCardType.G1_ReflectLowMeleeAsHoly;
if (dic_Card.ContainsKey(cardtype) && dic_Card[cardtype].m_Data.Get_IntValue1() >= dmg)
Reflect_Projectile(cardtype, pdData, false, true);
}
else if (attackType == eAttackType.Range)
{
cardtype = eCardType.G1_HealOnRangedHit;
if (dic_Card.ContainsKey(cardtype))
{
Heal(eHealType.Normal, dic_Card[cardtype].m_Data.Get_IntValue1());
Set_StatusEffect(eStatusConditionsType.Heal_Hp_Add, 1f);
}
cardtype = eCardType.G1_HealOnRangedHitChance;
if (dic_Card.ContainsKey(cardtype))
{
if (DSUtil.RandomTrue(dic_Card[cardtype].m_Data.Get_FloatValue2()))
{
Heal(eHealType.Normal, dic_Card[cardtype].m_Data.Get_IntValue1());
Set_StatusEffect(eStatusConditionsType.Heal_Hp_Add, 1f);
}
}
cardtype = eCardType.G1_RangedHitDealHolyDamage;
if (dic_Card.ContainsKey(cardtype))
Shoot_AddProjectiles(dic_Card[cardtype], pdData.Hitter);
}
cardtype = eCardType.G1_NullifyDamageEveryNHits;
if (dic_Card.ContainsKey(cardtype))
{
var card = dic_Card[cardtype];
++card.UseCount;
if (card.UseCount >= card.m_Data.Get_IntValue1())
{
card.UseCount = 0;
Set_Buff(true, eStat.Dmg_Immune, 1);
Set_StatusEffect(eStatusConditionsType.Invincibility_Count, 1f);
}
}
cardtype = eCardType.G1_HealOnDoubleDodge;
if (dic_Card.ContainsKey(cardtype))
dic_Card[cardtype].UseCount_Acc = 0;
}
void OnEvent_ActiveConditions()
{
var my_shield = (int)m_StatInfo.Get_TotalStat(eStat.Shield);
var maxshield = (int)m_StatInfo.Get_TotalStat(eStat.MaxShield);
Counting_onActiveCondition(eActiveConditions.MaxShield_Up, my_shield, maxshield);
Counting_onActiveCondition(eActiveConditions.MaxShield_Down, my_shield, maxshield);
Counting_onActiveCondition(eActiveConditions.MaxShield_Rate, my_shield, maxshield);
var hp = (int)m_StatInfo.Get_TotalStat(eStat.HP);
var maxhp = (int)m_StatInfo.Get_TotalStat(eStat.MaxHP);
Counting_onActiveCondition(eActiveConditions.MaxHp_Up, hp, maxhp);
Counting_onActiveCondition(eActiveConditions.MaxHp_Down, hp, maxhp);
Counting_onActiveCondition(eActiveConditions.MaxHpRate, hp, maxhp);
}
#endregion
#region
void Set_Specificity()
{ // 특성 4종 세팅
dic_StatusEffectData.Clear();
dic_ActiveConditionData.Clear();
list_Specificity.Clear();
if (m_TableData.n_Specificity1 > 0) list_Specificity.Add(table_StatusOptionSet.Ins.Get_Data(m_TableData.n_Specificity1));
if (m_TableData.n_Specificity2 > 0) list_Specificity.Add(table_StatusOptionSet.Ins.Get_Data(m_TableData.n_Specificity2));
if (m_TableData.n_Specificity3 > 0) list_Specificity.Add(table_StatusOptionSet.Ins.Get_Data(m_TableData.n_Specificity3));
if (m_TableData.n_Specificity4 > 0) list_Specificity.Add(table_StatusOptionSet.Ins.Get_Data(m_TableData.n_Specificity4));
if (IsRole(eRole.PC)) DeckUI.list_Specificity = list_Specificity;
dic_activeCondition.Clear();
for (int i = 0; i < list_Specificity.Count; i++)
{
var temp = list_Specificity[i];
RunStatusEffect_Instantly(temp, temp.Get_Target(this, m_Target, m_TableData.m_Role), null);
if (!dic_activeCondition.ContainsKey(temp.e_ActiveConditions))
dic_activeCondition.Add(temp.e_ActiveConditions, new List<StatusOptionSetActorData>());
var sosActordata = new StatusOptionSetActorData
{
m_Actor = this,
m_TData = temp,
m_sclData = table_StatusConditionsList.Ins.Get_Data_orNull(temp.e_StatusConditionsType),
IsSet = false
};
dic_activeCondition[temp.e_ActiveConditions].Add(sosActordata);
switch (temp.e_ActiveConditions)
{
case eActiveConditions.ActiveSkill:
dic_StatusEffect[temp.e_StatusConditionsType].Set_ActiveSkill(sosActordata);
break;
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:
dic_StatusEffect[temp.e_StatusConditionsType].Set(sosActordata);
break;
}
switch (temp.e_StatusConditionsType)
{
case eStatusConditionsType.Battle: // 선제공격
Set_Battle_PreemptiveStrike();
break;
}
}
Refresh_PCUI();
m_BaseAttackPD.Set(m_TableData.s_Projectile, m_TableData.m_Role, Get_AttackType(), this, m_StatInfo);
OnEvent_ActiveConditions();
}
void Check_Specificity(eActiveConditions activeConditions, ProjectileData pdData)
{
if (dic_activeCondition.ContainsKey(activeConditions))
{
var data = dic_activeCondition[activeConditions];
for (int i = 0; i < data.Count; i++)
{
var temp = data[i];
bool bSuccess = false;
var rateval = temp.m_TData.Get_Rate_orValue();
switch (activeConditions)
{
//case eActiveConditions.Attack_Normal:
//case eActiveConditions.Attack_Hit:
//case eActiveConditions.Attack_Critical:
//case eActiveConditions.Attack_Special:
//case eActiveConditions.Hit_Noraml:
//case eActiveConditions.Hit_PreemptiveStrike:
//case eActiveConditions.Evasion_Rate:
//case eActiveConditions.Miss_Rate:
//case eActiveConditions.Potion_Use:
default: bSuccess = DSUtil.RandomTrue(rateval); break;
case eActiveConditions.Hit_Count:
case eActiveConditions.Evasion_Count:
case eActiveConditions.Miss_Count:
case eActiveConditions.Potion_Count:
++temp.Value;
bSuccess = temp.Value >= rateval;
if (bSuccess) temp.Value = 0;
break;
case eActiveConditions.MaxHp_Up:
break;
case eActiveConditions.MaxHp_Down:
break;
case eActiveConditions.MaxHpRate:
break;
case eActiveConditions.MaxShield_Up:
break;
case eActiveConditions.MaxShield_Down:
break;
case eActiveConditions.MaxShield_Rate:
break;
//case eActiveConditions.ActiveSkill:
//case eActiveConditions.Appear:
// bSuccess = true;
// break;
case eActiveConditions.SurviveAlone:
break;
case eActiveConditions.Die_Self:
bSuccess = pdData.Hitter.IsDead();
break;
case eActiveConditions.Die_Front:
break;
case eActiveConditions.Die_Back:
break;
case eActiveConditions.Die_Ally:
break;
}
if (bSuccess) Run_Specificity(temp, pdData);
}
}
}
public void Run_Specificity(StatusOptionSetActorData temp, ProjectileData pdData)
{
var sclData = temp.m_sclData;
var tData = temp.m_TData;
var caster = pdData.Hitter; // 효과를 건 주체
var role = caster.m_TableData.m_Role;
var target = pdData.Target;
List<Actor> targets = tData.Get_Targets(caster, target, Get_Data().m_Role);
foreach (var t in targets)
{
//if (t == null || t.IsDead()) continue;
switch (tData.e_StatusConditionsType)
{
case eStatusConditionsType.PC_Evasion_Melee:
if (caster.Get_ActorStatInfo().Get_BuffStat(eStat.PreemptiveStrike) > 0)
{
caster.Get_ActorStatInfo().Set_Buff(eStat.PreemptiveStrike, 0);
Set_Buff(tData.e_Stat1, temp.m_TData.Get_StatValue1());
}
break;
case eStatusConditionsType.PC_CriticalRate_Add:
// Hit_Count 피격 횟수 해당 피격 {Value} 횟수 충족 시 발동
m_StatInfo.Set_Buff(true, temp.m_TData.e_Stat1, temp.m_TData.Get_StatValue1());
m_StatInfo.Set_Buff(true, temp.m_TData.e_Stat2, temp.m_TData.Get_StatValue2());
Refresh_PCUI();
break;
case eStatusConditionsType.VampirHeal_Add:
{
var dmg = (int)temp.m_TData.Get_StatValue1();
t.Get_Dmg(dmg);
Heal(eHealType.LifeSteal, dmg);
Set_StatusEffect(tData.e_StatusConditionsType, 1f);
}
break;
case eStatusConditionsType.VampirHeal_Mul:
{
var dmg = (int)(temp.m_TData.Get_StatValue1() * t.Get_ActorStatInfo().Get_TotalStat(eStat.HP));
t.Get_Dmg(dmg);
Heal(eHealType.LifeSteal, dmg);
Set_StatusEffect(tData.e_StatusConditionsType, 1f);
}
break;
case eStatusConditionsType.Resurrection:
case eStatusConditionsType.ATK_SPD_Add:
case eStatusConditionsType.ATK_DMG_Add:
case eStatusConditionsType.Poison:
case eStatusConditionsType.Burn:
case eStatusConditionsType.Stun:
case eStatusConditionsType.Freezing:
case eStatusConditionsType.Blind:
case eStatusConditionsType.Slow:
t.Set_StatusEffect(temp, t);
break;
default:
t.Run_StatusOptionSet(false, tData, t);
break;
}
}
}
#endregion
#region
protected virtual void Set_Equipment()
{
var sdata = Get_ServerData();
if (sdata != null)
{
var setItemData = sdata.Get_EquipSetItemData(m_TableData.n_ID);
for (int i = 0; i < setItemData.list_SkillId.Count; i++)
InGameInfo.Ins.Add_Card(table_cardlist.Ins.Get_Data(setItemData.list_SkillId[i]), false);
}
}
#endregion
#region
protected bool IsCC()
{
for (int i = 0; i < list_NoUpdateCC.Count; i++)
if (dic_StatusEffect[list_NoUpdateCC[i]].IsActive())
return true;
return false;
}
public bool IsCC(eStatusConditionsType type) { return dic_StatusEffect[type].IsActive(); }
public bool IsCurse() { return dic_StatusEffect[eStatusConditionsType.Curse].IsActive(); }
public void Set_Buff(eStat stat, double v) { m_StatInfo.Set_Buff(stat, v); }
public void Set_Buff(bool add, eStat stat, double v) { m_StatInfo.Set_Buff(add, stat, v); }
public void Set_DeBuff(bool add, eStat stat, double v) { m_StatInfo.Set_Debuff(add, stat, v); }
public void Set_DeBuff(eStat stat, double v) { m_StatInfo.Set_Debuff(stat, v); }
public void Set_StatusEffectData(eStatusConditionsType type, StatusEffectData sedata)
{
if (!dic_StatusEffectData.ContainsKey(type))
dic_StatusEffectData.Add(type, sedata);
else
dic_StatusEffectData[type] = sedata;
}
public void Set_ActiveConditionData(eActiveConditions activeCondition, StatusEffectData sedata)
{
if (!dic_ActiveConditionData.ContainsKey(activeCondition))
dic_ActiveConditionData.Add(activeCondition, new List<StatusEffectData>());
dic_ActiveConditionData[activeCondition].Add(sedata);
}
public void Set_StatusEffect(StatusOptionSetActorData data, Actor target)
{
if (!IsDead()) dic_StatusEffect[data.m_TData.e_StatusConditionsType].Set(data, target);
}
public void Set_StatusEffect(eStatusConditionsType scType, float time, bool ignoredead = false)
{
if (!IsDead() || ignoredead) dic_StatusEffect[scType].Set_byCard(scType, time, this);
}
public void RunStatusEffect_Instantly(StatusOptionSetTableData sosdata, Actor target, Action<double> act)
{
if (target == null || target.IsDead()) return;
//if (!IsRole(eRole.PC)) return;
switch (sosdata.e_ActiveConditions)
{
case eActiveConditions.None:
case eActiveConditions.Instantly:
case eActiveConditions.Sancturay:
Run_StatusOptionSet(true, sosdata, target, act);
break;
}
}
public void Run_StatusOptionSet(bool checkRate, StatusOptionSetTableData sosdata, Actor target, Action<double> act = null)
{
if (checkRate && !DSUtil.RandomTrue(sosdata.Get_Rate_orValue())) return;
if (sosdata.e_StatusConditionsType != eStatusConditionsType.Invincibility_Time)
dic_StatusEffect[sosdata.e_StatusConditionsType].Set_byCard(sosdata.e_StatusConditionsType, 3f, this);
var statinfo = target.Get_ActorStatInfo();
switch (sosdata.e_StatusConditionsType)
{
default: // 기본은 그냥 스탯 추가
if (sosdata.e_Stat1 < eStat.Max) statinfo.Set_Buff(true, sosdata.e_Stat1, sosdata.Get_StatValue1());
if (sosdata.e_Stat2 < eStat.Max) statinfo.Set_Buff(true, sosdata.e_Stat2, sosdata.Get_StatValue2());
target.Set_HUD();
if (target.IsRole(eRole.PC)) InGameInfo.Ins.Set_Texts();
break;
case eStatusConditionsType.Recovery_All:
target.AllHeal(eHealType.Normal);
Set_StatusEffect(eStatusConditionsType.Heal_Hp_Mul, 1f);
break;
case eStatusConditionsType.LvUp: if (target.IsRole(eRole.PC)) InGameInfo.Ins.PCLvUp_Imm(); break;
case eStatusConditionsType.AddResurrection: target.Set_Buff(true, eStat.Resurrection, sosdata.Get_StatValue1()); break;
case eStatusConditionsType.GetSkillCard_N: if (target.IsRole(eRole.PC)) InGameInfo.Ins.Add_Card_Random(eGrade.Common); break;
case eStatusConditionsType.GetSkillCard_R: if (target.IsRole(eRole.PC)) InGameInfo.Ins.Add_Card_Random(eGrade.UnCommon); break;
case eStatusConditionsType.GetSkillCard_SR: if (target.IsRole(eRole.PC)) InGameInfo.Ins.Add_Card_Random(eGrade.Rare); break;
case eStatusConditionsType.GetSkillCard_SSR: if (target.IsRole(eRole.PC)) InGameInfo.Ins.Add_Card_Random(eGrade.Hero); break;
case eStatusConditionsType.GetSkillCard_UR: if (target.IsRole(eRole.PC)) InGameInfo.Ins.Add_Card_Random(eGrade.Legend); break;
case eStatusConditionsType.GetSkillCard_Random: if (target.IsRole(eRole.PC)) InGameInfo.Ins.Add_Card_Random(eGrade.None); break;
case eStatusConditionsType.IncreaseEXP_Mul: if (target.IsRole(eRole.PC)) Set_Mul(eStat.EXP_Mul); break;
case eStatusConditionsType.IncreaseGold_Mul: if (target.IsRole(eRole.PC)) Set_Mul(eStat.GOLD_Mul); break;
case eStatusConditionsType.GetSoul_Add:
if (target.IsRole(eRole.PC))
{
var soul = Random.Range((int)sosdata.Get_StatValue1(), (int)sosdata.Get_StatValue2() + 1);
InGameInfo.Ins.Add_Goods(MyValue.ItemID_Soul, soul);
GetItemUI.Ins.Set(new ItemSimpleData { itemid = MyValue.ItemID_Soul, amount = soul });
act?.Invoke(soul);
return;
}
break;
case eStatusConditionsType.GetGold_Add:
if (target.IsRole(eRole.PC))
{
var gold = Random.Range((int)sosdata.Get_StatValue1(), (int)sosdata.Get_StatValue2() + 1);
InGameInfo.Ins.Add_Goods(MyValue.ItemID_Gold, gold);
GetItemUI.Ins.Set(new ItemSimpleData { itemid = MyValue.ItemID_Gold, amount = gold });
act?.Invoke(gold);
return;
}
break;
case eStatusConditionsType.Invincibility_Time:
target.Set_StatusEffect(eStatusConditionsType.Invincibility_Time, sosdata.Get_StatValue1());
act?.Invoke(sosdata.Get_StatValue1());
return;
case eStatusConditionsType.Heal_Hp_Add:
{
var heal = (int)sosdata.Get_StatValue1();
if (sosdata.e_ActiveConditions == eActiveConditions.Sancturay &&
dic_Card.ContainsKey(eCardType.G1_SanctuaryHeal))
heal = (int)(heal * dic_Card[eCardType.G1_SanctuaryHeal].m_Data.Get_FloatValue2());
target.Heal(sosdata.e_ActiveConditions == eActiveConditions.Sancturay ?
eHealType.Sactuary : eHealType.Normal, heal);
act?.Invoke(heal);
return;
}
case eStatusConditionsType.GetExp_Add:
if (target.IsRole(eRole.PC))
{
var exp = (int)sosdata.Get_StatValue1();
if (sosdata.e_ActiveConditions == eActiveConditions.Sancturay &&
dic_Card.ContainsKey(eCardType.G1_SanctuaryHeal))
exp = (int)(exp * dic_Card[eCardType.G1_SanctuaryHeal].m_Data.Get_FloatValue2());
InGameInfo.Ins.Add_Goods(MyValue.ItemID_Exp, exp);
act?.Invoke(exp);
return;
}
break;
case eStatusConditionsType.Heal_Shield_Add:
{
var shield = (int)sosdata.Get_StatValue1();
target.Heal_Shield(shield);
act?.Invoke(shield);
return;
}
case eStatusConditionsType.Berserker_ATK_DMG_Add:
break;
case eStatusConditionsType.Berserker_ATK_SPD_Add:
break;
case eStatusConditionsType.Berserker_ATK_DMG_Mul:
break;
case eStatusConditionsType.Berserker_ATK_SPD_Mul:
break;
case eStatusConditionsType.Heal_Hp_Mul:
break;
case eStatusConditionsType.Heal_Hp_Random:
{
var heal = Random.Range((int)sosdata.Get_StatValue1(), (int)sosdata.Get_StatValue2());
if (sosdata.e_ActiveConditions == eActiveConditions.Sancturay &&
dic_Card.ContainsKey(eCardType.G1_SanctuaryHeal))
heal = (int)(heal * dic_Card[eCardType.G1_SanctuaryHeal].m_Data.Get_FloatValue2());
target.Heal(sosdata.e_ActiveConditions == eActiveConditions.Sancturay ?
eHealType.Sactuary : eHealType.Normal, heal);
act?.Invoke(heal);
return;
}
case eStatusConditionsType.Heal_Shield_Mul:
{
float heal = sosdata.Get_StatValue1();
var cardtype = eCardType.G1_TripleShieldSpring;
if (dic_Card.ContainsKey(cardtype))
heal *= dic_Card[cardtype].m_Data.Get_IntValue1();
target.Heal_Shield(heal);
act?.Invoke(heal);
return;
}
case eStatusConditionsType.Heal_Shield_Random:
{
var heal = Random.Range((int)sosdata.Get_StatValue1(), (int)sosdata.Get_StatValue2());
var cardtype = eCardType.G1_TripleShieldSpring;
if (dic_Card.ContainsKey(cardtype))
heal *= dic_Card[cardtype].m_Data.Get_IntValue1();
target.Heal_Shield(heal);
act?.Invoke(heal);
return;
}
case eStatusConditionsType.Destruct:
break;
case eStatusConditionsType.ATK_DMG_Mul:
break;
case eStatusConditionsType.ATK_SPD_Mul:
break;
case eStatusConditionsType.Death_ATK_Add:
break;
case eStatusConditionsType.Death_ATK_Mul:
break;
case eStatusConditionsType.Death_Growup:
break;
case eStatusConditionsType.Death_Heal_Add:
break;
case eStatusConditionsType.Death_Heal_Mul:
break;
case eStatusConditionsType.HitDamage_Add:
break;
case eStatusConditionsType.HitDamage_Mul:
break;
case eStatusConditionsType.HitDamage_Random:
break;
case eStatusConditionsType.IncreaseSoul_Mul:
break;
case eStatusConditionsType.Invincibility_Count:
break;
case eStatusConditionsType.Battle:
break;
}
act?.Invoke(0);
void Set_Mul(eStat stat)
{
var mul = m_StatInfo.Get_BuffStat(stat);
if (mul < 1) Set_Buff(stat, 2);
else Set_Buff(stat, mul * 2);
}
}
public void Set_SelfDestruct(StatusOptionSetActorData data)
{
if (data.m_TData.e_StatusConditionsType == eStatusConditionsType.Destruct)
{
if (m_SelfDestructData.m_Status == eSelfDestructStatus.None)
{
m_SelfDestructData.Set(data);
m_SelfDestructData.Set_Status(eSelfDestructStatus.Check_Rate);
}
}
}
void Set_Battle_PreemptiveStrike()
{
m_AttackCoolTime = Time.deltaTime * 2f;
Set_Buff(eStat.PreemptiveStrike, 1);
}
#endregion
#region
void Refresh_PCUI()
{
if (IsRole(eRole.PC)) IngameUIManager.Ins.m_PCMainStatUI.Set(m_StatInfo);
m_HUD_HPShield.Set(m_StatInfo);
}
public void Revive_byDefeatUI()
{
StartCoroutine(Co_Revive());
}
IEnumerator Co_Revive()
{
var scType = eStatusConditionsType.Resurrection;
dic_StatusEffect[scType].Set_byCard(scType, 3f, this);
yield return new WaitForSeconds(table_GlobalValue.Ins.Get_Float("ReviveTime_byDefeatUI"));
AllHeal(eHealType.Normal);
Set_StatusEffect(eStatusConditionsType.Heal_Hp_Mul, 1f);
Set_Battle(true);
}
public void Use_Potion(bool ignoreDie, int heal)
{
var statinfo = m_StatInfo;
if ((ignoreDie || !IsDead()) && !statinfo.isFullHP() && statinfo.Get_TotalStat(eStat.Potion) > 0)
{
var potionheal = heal;
statinfo.Set_Stat(false, eStat.Potion, 1);
Heal(eHealType.Potion, potionheal);
InGameInfo.Ins.Set_Texts();
eCardType cardtype = eCardType.G1_DarkMissileFromPotion;
if (dic_Card.ContainsKey(cardtype))
{
var mobs = InGameInfo.Ins.Get_LineMobs(eMobBattlePos.Frontline);
if (mobs.Count > 0)
Shoot_AddProjectiles(cardtype, mobs[Random.Range(0, mobs.Count)]);
}
cardtype = eCardType.G1_PotionDealHolyDamageRandomEnemy;
if (dic_Card.ContainsKey(cardtype))
Shoot_AddProjectiles(cardtype, InGameInfo.Ins.Get_RandomEnemy_orNull(Get_Data().m_Role));
cardtype = eCardType.G3_PotionUseDealsHealAsDamage;
if (dic_Card.ContainsKey(cardtype))
Shoot_Projectile_FixedDmg(cardtype, potionheal, InGameInfo.Ins.Get_AllEnemies(eRole.PC).ToArray());
}
}
public void AllHeal(eHealType healType)
{
Heal_Shield(1f);
Heal(healType, 1f);
}
void Heal_Common(eHealType healType, int heal)
{
var add_mul = 0d;
if (healType == eHealType.Potion) add_mul += m_StatInfo.Get_TotalStat(eStat.PotionEfficiencyUp);
if (healType != eHealType.Potion) add_mul += m_StatInfo.Get_TotalStat(eStat.NonCombatRecoveryEfficiency);
if (healType == eHealType.LifeSteal) add_mul += m_StatInfo.Get_TotalStat(eStat.LifeStealEfficiency);
heal += (int)(heal * add_mul);
var huddmg = IngameUIManager.Ins.Get_HUD_Dmg();
huddmg.Set_Heal(heal, Get_World_Position());
//EffectMgr.Ins.Show_Effect("Regeneration_health", Get_World_Position());
var cardtype = eCardType.G1_HolyDamageOnHeal;
if (dic_Card.ContainsKey(cardtype))
Shoot_Projectile_FixedDmg(cardtype, dic_Card[cardtype].m_Data.Get_IntValue1(), InGameInfo.Ins.Get_RandomEnemy_orNull(Get_Data().m_Role));
cardtype = eCardType.G1_ShieldOnFullHeal;
if (dic_Card.ContainsKey(cardtype) && m_StatInfo.isFullHP())
{
Heal_Shield(dic_Card[cardtype].m_Data.Get_IntValue1());
Set_StatusEffect(eStatusConditionsType.Heal_Shield_Add, 1f);
}
cardtype = eCardType.G5_ShieldHealWhenHealed;
if (dic_Card.ContainsKey(cardtype))
{
Heal_Shield(heal);
Set_StatusEffect(eStatusConditionsType.Heal_Shield_Add, 1f);
}
cardtype = eCardType.G1_MaxDodgeWhenHpBelow;
if (dic_Card.ContainsKey(cardtype))
{
if (m_StatInfo.Get_TotalStat(eStat.HP) > dic_Card[cardtype].m_Data.Get_IntValue1() &&
m_StatInfo.Get_BuffStat(eStat.Avoid_G1_MaxDodgeWhenHpBelow) > 0)
{
Set_Buff(eStat.Avoid_G1_MaxDodgeWhenHpBelow, 0);
Refresh_PCUI();
}
}
}
public void Heal_Shield(int shield)
{
m_StatInfo.Set_Stat(true, eStat.Shield, shield);
m_HUD_HPShield.Set(m_StatInfo);
}
public void Heal_Shield(float ratio)
{
var curshield = m_StatInfo.Get_TotalStat(eStat.Shield);
m_StatInfo.Set_Stat(true, eStat.Shield, m_StatInfo.Get_TotalStat(eStat.MaxShield) * ratio);
m_HUD_HPShield.Set(m_StatInfo);
}
public virtual void Heal(eHealType healType, int heal)
{
m_StatInfo.Set_Stat(true, eStat.HP, heal);
m_HUD_HPShield.Set(m_StatInfo);
Heal_Common(healType, heal);
}
public virtual void Heal(eHealType healType, float ratio)
{
var curhp = m_StatInfo.Get_TotalStat(eStat.HP);
m_StatInfo.Set_Stat(true, eStat.HP, m_StatInfo.Get_TotalStat(eStat.MaxHP) * ratio);
m_HUD_HPShield.Set(m_StatInfo);
Heal_Common(healType, (int)(m_StatInfo.Get_TotalStat(eStat.HP) - curhp));
}
public void Refill_AllPotions()
{
m_StatInfo.Set_Stat(true, eStat.Potion, m_StatInfo.Get_TotalStat(eStat.MaxPotion));
}
public void Add_Card_Random(params eGrade[] grade)
{
var lst = table_cardlist.Ins.Get_DataList(grade);
// dic_Card에 없는 카드들만 필터링
var available = lst.FindAll(x => !dic_Card.ContainsKey(x.e_CardType));
if (available.Count > 0)
{
// 랜덤으로 하나 선택
var randCard = available[Random.Range(0, available.Count)];
InGameInfo.Ins.Add_Card(randCard, false);
}
}
#endregion
#region
protected virtual void Play_Attack()
{
ActorStatus = eActorStatus.Attack;
OnEvent_PlayAttack();
}
protected virtual void Play_Hit()
{
}
protected virtual void Play_Evasion()
{
}
#endregion
public void Off()
{
gameObject.SetActive(false);
}
}