using CodeStage.AntiCheat.ObscuredTypes; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public enum eProjectileStartPos { None, Shooter, ShooterCenter, Target, TargetCenter, Custom } public enum eProjectileStrait { Forward, Down } public class ProjectileData { public ProjectileBase m_ProjectileBase; public Actor shooter, target; public SkillListTableData m_SkillListTableData; public OptionConfigTableData m_OptionConfigTableData; public SkillTypeConfigTableData m_skillTypeConfigTable; public eEffect m_Skill = eEffect.None; public eSkillExtraType e_SkillExtraType = eSkillExtraType.None; public float Speed = 5f, LifeTime = 4f, HitDamage, DamageArea; public eProjectileStartPos eStartPos = eProjectileStartPos.None; public Vector3 v3_StartPos; public bool SetSkillExtraType = true, IsRandomPos, LookTarget = true, CheckOptionWhenStart = true; public double Amount; public Action Action_OnHit; ObscuredDouble _BaseDmg; ObscuredFloat _AddDmgPercent, _CC_AddTime, _CC_AddDmg, _CC_AddVal1, _CC_AddVal2; public ObscuredDouble BaseDmg { get { return _BaseDmg; } set { _BaseDmg = value; _BaseDmg.RandomizeCryptoKey(); } } public ObscuredFloat AddDmgPercent { get { return _AddDmgPercent; } set { _AddDmgPercent = value; _AddDmgPercent.RandomizeCryptoKey(); } } public ObscuredFloat CC_AddTime { get { return _CC_AddTime; } set { _CC_AddTime = value; _CC_AddTime.RandomizeCryptoKey(); } } public ObscuredFloat CC_AddDmg { get { return _CC_AddDmg; } set { _CC_AddDmg = value; _CC_AddDmg.RandomizeCryptoKey(); } } public ObscuredFloat CC_AddVal1 { get { return _CC_AddVal1; } set { _CC_AddVal1 = value; _CC_AddVal1.RandomizeCryptoKey(); } } public ObscuredFloat CC_AddVal2 { get { return _CC_AddVal2; } set { _CC_AddVal2 = value; _CC_AddVal2.RandomizeCryptoKey(); } } public bool IsSkill() { return !DSUtil.CheckNull(m_SkillListTableData); } public bool IsSkill(eEffect skill) { return IsSkill() && m_SkillListTableData.e_Skill == skill; } public Vector3 Get_EffectPos(Actor target) { var stcData = m_skillTypeConfigTable; if (!DSUtil.CheckNull(stcData)) { Vector3 effectPos; switch (stcData.e_EffectLocation) { case eEffectLocation.Top: effectPos = target.Get_Top_postion(); break; default: effectPos = target.Get_Center_position(); break; case eEffectLocation.Bottom: effectPos = target.Get_position(); break; } return new Vector3(effectPos.x + stcData.n_EffectPosition_X, effectPos.y + stcData.n_EffectPosition_Y, effectPos.z); } return Vector3.right * 1000000f; } public float Get_SkillDamagePercent() { var lv = shooter.Get_ServerData().Get_SkillLv(shooter.m_Role, m_SkillListTableData.n_SkillID); var tabledmg = m_SkillListTableData.Get_SkillDamage(shooter.Get_StatInfo(), lv); return tabledmg + (float)shooter.Get_StatInfo().Get_Stat(eStat.SKILL_Multiplier) + AddDmgPercent; } public ProjectileData Copy() { ProjectileData pd = new ProjectileData(); Copy(pd); return pd; } public void Copy(ProjectileData pd) { pd.m_ProjectileBase = m_ProjectileBase; pd.shooter = shooter; pd.Action_OnHit = Action_OnHit; pd.target = target; pd.m_skillTypeConfigTable = m_skillTypeConfigTable; pd.IsRandomPos = IsRandomPos; pd.LifeTime = LifeTime; pd.m_SkillListTableData = m_SkillListTableData; pd.m_Skill = m_Skill; pd.Speed = Speed; pd.v3_StartPos = v3_StartPos; pd.eStartPos = eStartPos; pd.HitDamage = HitDamage; pd.BaseDmg = BaseDmg; pd.CC_AddTime = CC_AddTime; pd.CC_AddDmg = CC_AddDmg; pd.CC_AddVal1 = CC_AddVal1; pd.CC_AddVal2 = CC_AddVal2; pd.DamageArea = DamageArea; } } public class ProjectileBase : MonoBehaviour { public bool m_Pierce; public string str_HitEffect; protected bool bFirstLoad = true; protected ProjectileData m_ProjectTileData; protected float m_LifeTime; protected Vector3 v3_scale; protected Action act_returnDmg; protected Action act_afterFreezing; DamageInfo m_DamageInfo; private void Awake() { v3_scale = transform.localScale; } private void OnEnable() { if (bFirstLoad) { Off_FisrLoad(); transform.position = Vector3.one * 100000f; Off(true); } } public void Off_FisrLoad() { bFirstLoad = false; } public virtual void Set(ProjectileData _data) { _data.AddDmgPercent = _data.CC_AddTime = _data.CC_AddDmg = _data.CC_AddVal1 = _data.CC_AddVal2 = 0f; m_ProjectTileData = _data; m_ProjectTileData.m_ProjectileBase = this; m_DamageInfo = Get_NewDamageInfo(); var isNullTarget = DSUtil.CheckNull(m_ProjectTileData.target); if (m_ProjectTileData.IsSkill()) { var skillData = m_ProjectTileData.m_SkillListTableData; if (m_ProjectTileData.SetSkillExtraType) m_ProjectTileData.e_SkillExtraType = skillData.e_SkillExtraType; } else { transform.localScale = v3_scale; var statinfo = m_ProjectTileData.shooter.Get_StatInfo(); if (!DSUtil.CheckNull(statinfo)) { m_ProjectTileData.Speed += (float)statinfo.Get_Stat(eStat.ProjectileSpeed_Up); transform.localScale += v3_scale * (float)statinfo.Get_Stat(eStat.ProjectileSize_Up); } } m_ProjectTileData.m_skillTypeConfigTable = table_skilltypeconfig.Ins.Get_Data_orNull(m_ProjectTileData.e_SkillExtraType); if (!isNullTarget && !DSUtil.CheckNull(m_ProjectTileData.m_skillTypeConfigTable) && m_ProjectTileData.m_skillTypeConfigTable.e_SkillExtraTiming == eSkillExtraTiming.Start) m_ProjectTileData.target.Check_Extra(m_DamageInfo); if (m_ProjectTileData.CheckOptionWhenStart) { m_ProjectTileData.CheckOptionWhenStart = false; m_ProjectTileData.shooter.Check_EnchantOption(m_DamageInfo, false); } Set_Checkers(); m_LifeTime = _data.LifeTime; gameObject.SetActive(true); switch (_data.eStartPos) { case eProjectileStartPos.Shooter: transform.position = _data.shooter.Get_CenterPositionFoward(); break; case eProjectileStartPos.ShooterCenter: transform.position = _data.shooter.Get_CenterPositionFoward(); break; default: transform.position = _data.target.Get_CenterPositionFoward(); break; case eProjectileStartPos.TargetCenter: transform.position = _data.target.Get_CenterPositionFoward(); break; case eProjectileStartPos.Custom: transform.position = _data.v3_StartPos; break; } if (!isNullTarget) { if (_data.LookTarget) { switch (_data.eStartPos) { case eProjectileStartPos.Shooter: case eProjectileStartPos.Target: transform.LookAt(_data.target.Get_position()); break; default: Vector3 targetPosition = _data.target.Get_Center_position(); targetPosition.y = _data.shooter.Get_Center_position().y; transform.LookAt(targetPosition); break; } } } else if (_data.LookTarget) transform.eulerAngles = _data.shooter.transform.eulerAngles; } protected void LookAt_ShooterFoward() { transform.rotation = m_ProjectTileData.shooter.transform.rotation; transform.eulerAngles = new Vector3(0f, transform.eulerAngles.y); } /// /// 쿨타임을 감소시킨다. f_ExtraValue1 값을 사용한다. /// protected void Set_ReduceCoolTime_byStep(int step) { if (IsStep(step)) m_ProjectTileData.shooter.Set_SkillCoolTime(false, m_ProjectTileData.m_SkillListTableData.n_SkillID, Get_AwakenData(step, 1)); } /// /// active 스킬 실행 여부 /// public void Show_Effect(Actor target, float effectLifeTime = 5f, CCData ccdata = null) { InGameInfo.Ins.Show_SkillTypeEffect(m_ProjectTileData, target, effectLifeTime, ccdata); } public virtual void Set_Shooter(Actor _shoter) { if (m_ProjectTileData != null) m_ProjectTileData.shooter = _shoter; } protected void Check_TargetBoss() { if (m_ProjectTileData != null) { if (!m_ProjectTileData.target.IsRole(eRole.Boss) || m_ProjectTileData.target.transform.localScale.x <= 2f) { var enemies = Get_Enemies(transform, 8f); var boss = enemies.Find(f => f.IsRole(eRole.Boss) || f.transform.localScale.x > 2f); if (boss != null) m_ProjectTileData.target = boss; } } } public ProjectileData Get_ProjectTileData() { return m_ProjectTileData; } DamageInfo Get_SkillDamage() { var dinfo = m_ProjectTileData.shooter.Get_DamageInfo(m_ProjectTileData, m_ProjectTileData.Get_SkillDamagePercent(), m_ProjectTileData.CC_AddVal2 > 0 && m_ProjectTileData.m_SkillListTableData.e_Skill == eEffect.Skill_IceBolt && m_ProjectTileData.target.IsSkillExtraStatus(eSkillExtraType.Frost)); dinfo.act_returnLastDmg = act_returnDmg; dinfo.act_AfterFreezing = act_afterFreezing; return dinfo; } protected DamageInfo Get_NewDamageInfo() { return m_ProjectTileData.IsSkill() ? Get_SkillDamage() : m_ProjectTileData.shooter.Get_DamageInfo(m_ProjectTileData); } protected DamageInfo Get_DamageInfo(bool extradmg = false, bool calcri = true) { m_DamageInfo.Damage = m_DamageInfo.BaseDmg; m_DamageInfo.bExtraDmg = extradmg; if (calcri) m_DamageInfo.Cal_Cri(m_ProjectTileData.shooter.m_AttackType, m_ProjectTileData.shooter.Get_StatInfo()); return m_DamageInfo; } protected bool IsStep(int _step) { var sdata = m_ProjectTileData.shooter.Get_ServerData(); if (!DSUtil.CheckNull(sdata)) { if (m_ProjectTileData.shooter.IsRole(eRole.PC)) return sdata.Get_SkillAwakenLv(m_ProjectTileData.m_SkillListTableData.n_SkillID) >= _step; else return sdata.Get_PetSkillAwakenLv(m_ProjectTileData.shooter.Get_ID()) >= _step; } return false; } protected Actor Get_NearstEnemy(float dist = 20f) { return ActorInfo.Ins.Get_Nearest_EnemyActor_orNull(m_ProjectTileData.shooter.IsEnemy(), transform.position, dist); } protected List Get_Enemies() { return ActorInfo.Ins.Get_EnemyActors(m_ProjectTileData.shooter.IsEnemy(), transform.position); } protected List Get_Enemies(Transform tf, float dist) { #if UNITY_EDITOR if (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == "StatTest") return new List { MainToStatTest.Ins.actors[1] }; #endif return ActorInfo.Ins.Get_EnemyActors(m_ProjectTileData.shooter.IsEnemy(), tf.position, dist); } protected void Show_HitEffect(bool effectbyHit, Actor target) { if (!DSUtil.CheckNull(m_ProjectTileData) && !string.IsNullOrEmpty(str_HitEffect)) InGameInfo.Ins.Show_Effect(str_HitEffect, Get_HitEffectPos(effectbyHit, target)); } Vector3 Get_HitEffectPos(bool effectbyHit, Actor target) { if (DSUtil.CheckNull(target)) effectbyHit = false; return effectbyHit ? target.Get_Center_position() : transform.position; } protected virtual void Off(bool forceoff = false) { if (forceoff || !m_Pierce) gameObject.SetActive(false); if (!bFirstLoad) Show_HitEffect(false, null); } protected IEnumerator Co_Off(float delay) { yield return new WaitForSeconds(delay); Off(true); } /// /// 포물선 움직임 /// /// 시작위치에서 종료위치까지 도달하는 시간, 값이 높을수록 느리게 간다. /// Center값을 줄이기, 해당 값이 높을수록 포물선의 높이는 낮아진다. /// protected IEnumerator Co_Move_Split(Action _actreach, Vector3 startpos, Vector3 targetpos, float journeyTime = 1.0f, float reduceHeight = 0.25f) { float startTime = Time.time; while (true) { Vector3 center = (startpos + targetpos) * 0.5f; //Center 값만큼 위로 올라간다. center -= new Vector3(0, 1f * reduceHeight, 0); //y값을 높이면 높이가 낮아진다. Vector3 riseRelCenter = startpos - center; Vector3 setRelCenter = targetpos - center; float fracComplete = (Time.time - startTime) / journeyTime; transform.position = Vector3.Slerp(riseRelCenter, setRelCenter, fracComplete); transform.position += center; if (fracComplete >= 1f) { _actreach?.Invoke(); break; } yield return null; } } protected IEnumerator Co_Move_Strait(eProjectileStrait direction) { while (m_ProjectTileData.LifeTime > 0f) { if (DSUtil.CheckNull(m_ProjectTileData.shooter)) break; if (direction == eProjectileStrait.Forward) transform.Translate(m_ProjectTileData.Speed * Time.deltaTime * Vector3.forward); else transform.Translate(m_ProjectTileData.Speed * Time.deltaTime * Vector3.down); m_ProjectTileData.LifeTime -= Time.deltaTime; yield return null; } Off(true); } protected virtual void OnTriggerEnter(Collider other) { ProcessCollider(other); } protected virtual void OnCollisionEnter(Collision collision) { ProcessCollider(collision.collider); } public virtual bool ProcessCollider(Collider other, bool Off_byHit = true) { switch (other.tag) { case "Player": case "Pet": case "Mob": case "Summon": if (DSUtil.CheckNull(m_ProjectTileData)) break; var hitter = other.GetComponent(); if (m_ProjectTileData.shooter.IsEnemy() != hitter.IsEnemy()) { hitter.Get_Damage(Get_DamageInfo()); m_ProjectTileData.Action_OnHit?.Invoke(hitter); Show_HitEffect(true, hitter); if (Off_byHit) Off(false); return true; } break; } return false; } public void Set_Checkers() { var chekers = GetComponentsInChildren(true); for (int i = 0; i < chekers.Length; i++) chekers[i].Set(this); } public void Set_CheckersSize(float addsize) { var chekers = GetComponentsInChildren(true); for (int i = 0; i < chekers.Length; i++) chekers[i].Set_Size(addsize); } protected float Get_AwakenData(int step, int index) { var data = table_skillawakenconfig.Ins.Get_Data_orNull(m_ProjectTileData.m_SkillListTableData.n_SkillID, step); if (DSUtil.CheckNull(data)) return 0f; switch (index) { case 1: return data.f_ExtraValue1; case 2: return data.f_ExtraValue2; case 3: return data.f_ExtraValue3; default: return 0f; } } protected int Get_FairyCount(eEffect _effect) { return m_ProjectTileData.shooter.Get_SelectSkill(_effect) ? 4 : 1; } #if UNITY_EDITOR protected void Add_AwakendLv(int lv) { if (m_ProjectTileData.shooter.IsRole(eRole.PC)) for (int i = 0; i < lv; i++) m_ProjectTileData.shooter.Get_ServerData().Add_SkillAwakenLv(m_ProjectTileData.m_SkillListTableData.n_SkillID); else if (m_ProjectTileData.shooter.IsRole(eRole.Pet)) m_ProjectTileData.shooter.Get_ServerData().Add_PetLv(m_ProjectTileData.shooter.Get_ID(), lv * 15); } #endif }