2362 lines
98 KiB
C#
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);
|
|
}
|
|
} |