Project_WL/Assets/Script/Character/Projectile/ProjectileBase.cs

388 lines
16 KiB
C#
Raw Normal View History

2024-12-15 01:39:39 +00:00
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<Actor> 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);
2024-12-15 01:39:39 +00:00
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<double> act_returnDmg;
protected Action<Actor> 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 = m_ProjectTileData.IsSkill() ? Get_SkillDamage() : m_ProjectTileData.shooter.Get_DamageInfo(m_ProjectTileData);
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 (!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;
2024-12-15 01:39:39 +00:00
case eProjectileStartPos.Custom: transform.position = _data.v3_StartPos; break;
}
if (!DSUtil.CheckNull(_data.target))
{
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);
}
2024-12-15 01:39:39 +00:00
/// <summary>
/// 쿨타임을 감소시킨다. f_ExtraValue1 값을 사용한다.
/// </summary>
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));
}
/// <summary>
/// active 스킬 실행 여부
/// </summary>
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;
}
2024-12-17 01:48:30 +00:00
protected DamageInfo Get_DamageInfo(bool extradmg = false, bool calcri = true)
{
m_DamageInfo.bExtraDmg = extradmg;
if (calcri) m_DamageInfo.Cal_Cri(m_ProjectTileData.shooter.m_AttackType, m_ProjectTileData.shooter.Get_StatInfo());
return m_DamageInfo;
}
2024-12-15 01:39:39 +00:00
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<Actor> Get_Enemies()
{ return ActorInfo.Ins.Get_EnemyActors(m_ProjectTileData.shooter.IsEnemy(), transform.position); }
protected List<Actor> Get_Enemies(Transform tf, float dist)
{ return ActorInfo.Ins.Get_EnemyActors(m_ProjectTileData.shooter.IsEnemy(), tf.position, dist); }
protected void Show_HitEffect(bool effectbyHit, Actor target)
{
2024-12-15 22:56:30 +00:00
if (!DSUtil.CheckNull(m_ProjectTileData) && !string.IsNullOrEmpty(str_HitEffect))
InGameInfo.Ins.Show_Effect(str_HitEffect, Get_HitEffectPos(effectbyHit, target));
2024-12-15 01:39:39 +00:00
}
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);
}
/// <summary>
/// 포물선 움직임
/// </summary>
/// <param name="journeyTime">시작위치에서 종료위치까지 도달하는 시간, 값이 높을수록 느리게 간다.</param>
/// <param name="reduceHeight">Center값을 줄이기, 해당 값이 높을수록 포물선의 높이는 낮아진다.</param>
/// <returns></returns>
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<Actor>();
if (m_ProjectTileData.shooter.IsEnemy() != hitter.IsEnemy())
{
2024-12-17 01:48:30 +00:00
hitter.Get_Damage(Get_DamageInfo());
2024-12-15 01:39:39 +00:00
m_ProjectTileData.Action_OnHit?.Invoke(hitter);
Show_HitEffect(true, hitter);
2024-12-16 04:00:50 +00:00
if (Off_byHit) Off(false);
2024-12-15 01:39:39 +00:00
return true;
}
break;
}
return false;
}
public void Set_Checkers()
{
var chekers = GetComponentsInChildren<ProjectileHitChecker>(true);
for (int i = 0; i < chekers.Length; i++)
chekers[i].Set(this);
}
public void Set_CheckersSize(float addsize)
{
var chekers = GetComponentsInChildren<ProjectileHitChecker>(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
}