using DG.Tweening; using DG.Tweening.Core; using DG.Tweening.Plugins.Options; using IVDataFormat; using Spine.Unity; using System.Collections; using System.Collections.Generic; using System.Numerics; using UnityEngine; using UnityEngine.Events; using Quaternion = UnityEngine.Quaternion; using Random = UnityEngine.Random; using Vector3 = UnityEngine.Vector3; public class IVSkill : MonoBehaviour { [System.Serializable] public struct stSkillSequence { public float time; public UnityEvent method; } #region Skill Settings [SerializeField] // 스킬 종류. protected eSkillType skillType; [SerializeField, Space(10)] // 상태이상. protected eSkillDebuff debuff; [SerializeField, Space(10)] // 타겟/캐릭터 따라다님. protected bool bTrace = false; [SerializeField] // 적 끌어당김. protected bool bPull = false; [SerializeField] // 사거리. protected int iRange = 1000000; [SerializeField] // 총 연출 시간. protected float fPlayTime = 1f; [SerializeField] protected float ShakeStrength = 0f; [SerializeField] protected int iVibrato = 10; [SerializeField] protected int useFrom; // 발사체 시작 위치. [SerializeField, Space(10)] protected Transform trfShotStart; // 발사체. [SerializeField, Space(10)] protected Transform[] trfShots; protected TweenerCore[] twcShots; [SerializeField, Space(10)] protected SpriteRenderer[] sprShotItems; // 스킬 범위. [SerializeField, Space(10)] protected Collider[] colliders; // 최대 타격 횟수. 발사체 1개를 연속 발사하는 경우에만 사용. [SerializeField] protected int iMaxShot; protected int iShot; [SerializeField, Space(10)] protected IVBullet[] bullets; [SerializeField] protected IVSummon summon; // 스킬 연출 및 기능. [SerializeField, Space(10)] protected stSkillSequence[] skillSequences; protected SkeletonAnimation[] skAnims; protected ParticleSystem[] ptcEffects; protected AudioSource[] asEffects; #endregion Skill Settings public int idNumber = -1; #region Variables protected BattleMgr battleMgr; protected Transform trfObject; // 재생중. Coroutine playSkillCoroutine; protected bool IsPlaying => playSkillCoroutine != null; // 아군 스킬인지. protected bool bFriendlySkill = true; // 타겟. protected int iTarget = -1; // 여러명 타겟 protected List iTargets; // 추적 타겟. protected Transform trfTrace = null; // 크리티컬 배율. protected float fCrtDam = 0f; // 크리티컬 확률. protected int iCrtRate = 0; // 데미지1. protected BigInteger biDmg = 0; // 값. protected float fRate = 0f; // 소환물 공격간격 protected float fSummonInterval = 0.3f; // 상태이상 수치, 시간. protected BigInteger biDebuffValue; protected float fDebuffTime; protected bool bfront; // 같은 대상인지 구분 protected int iDamCnt = 0; // 직선으로 날려보낼 거리 protected float fDistance; // 날라가는 시간, 딜레이 시간 protected float fTime, fDelayTime; protected float fx = 0, fy = 0; protected int iSplit; private Vector3[] SavePos = new Vector3[13]; #endregion Variables protected void LateUpdate() { if (bTrace && trfTrace != null) transform.position = trfTrace.position; } #region Init // 초기화. public void Init(BattleMgr mgr) { battleMgr = mgr; skAnims = transform.GetComponentsInChildren(true); asEffects = transform.GetComponentsInChildren(true); ptcEffects = transform.GetComponentsInChildren(true); twcShots = new TweenerCore[trfShots.Length]; iTargets = new List(); } // 사거리 가져오기. public int GetRange() { return iRange / dConst.RangeDivide; } #endregion Init #region SetOption // 상태이상. public void SetDebuff(BigInteger bivalue, float ftime) { biDebuffValue = bivalue; fDebuffTime = ftime; } public void MoveToShotPos(int ishotNum) { if (transform.Find("trfObject") != null) trfObject = transform.Find("trfObject"); trfObject.position = trfShots[ishotNum].position; } public void SetTransform() { for (int i = 0; i < trfShots.Length; i++) { trfShots[i].position = trfShotStart.position + Vector3.up * 4f; trfShots[i].gameObject.SetActive(true); } } public void SetSplit(int isplit) { iSplit = isplit; } public void SetDistance(float fdt) { fDistance = fdt; } public void SetBulletTime(float ftime) { fTime = ftime; } public void SetDelayTime(float ftime) { fDelayTime = ftime; } public void SetX(float x) { fx = x; } public void SetY(float y) { fy = y; } public void setDistanceRandom() { fDistance = Random.Range(5, 12); } public void setFront() { bfront = battleMgr.GetIsFront(bFriendlySkill); ChangeFront(bfront); } public void setSummonAttackInterval(float finterval) { fSummonInterval = finterval; } public void StartFade(int inum) { if(useFrom == 0) { if (inum > 0) battleMgr.SkillFade(true); else battleMgr.SkillFade(false); } } #endregion #region Base Method private void ChangeFront(bool bFrontRight) { if (bFrontRight) { transform.localScale = Global.V3_1; } else { transform.localScale = Global.V3_1XRev; } } protected IEnumerator PlaySkill() { float elapsed = 0f; int currentSequenceIndex = 0; float offset = 0f; while(elapsed < fPlayTime) { if(currentSequenceIndex < skillSequences.Length) { var sequence = skillSequences[currentSequenceIndex]; if (offset + sequence.time <= elapsed) { sequence.method?.Invoke(); offset += sequence.time; ++currentSequenceIndex; } } elapsed += Time.deltaTime; yield return null; } iTarget = -1; playSkillCoroutine = null; gameObject.SetActive(false); } public void StopSkill() { if (!IsPlaying) return; StopCoroutine(playSkillCoroutine); for (int i = 0; i < skAnims.Length; ++i) { skAnims[i].enabled = false; } for (int i = 0; i < trfShots.Length; ++i) { if (twcShots[i] != null && twcShots[i].IsPlaying()) twcShots[i].Pause(); trfShots[i].gameObject?.SetActive(false); } for (int i = 0; i < ptcEffects.Length; ++i) { ptcEffects[i]?.Stop(); } for (int i = 0; i < asEffects.Length; ++i) { asEffects[i]?.Stop(); } iTarget = -1; playSkillCoroutine = null; gameObject.SetActive(false); } #endregion Base Method #region Control Method // 애니메이션 재생. public void PlayAnimation(int index) { if (index < 0 || index >= skAnims.Length) return; skAnims[index].enabled = true; skAnims[index].AnimationState.SetAnimation(0, "animation", false); } public void SetAnimation(string name) { if(skAnims[0] != null) { skAnims[0].enabled = true; if(name == "idle") skAnims[0].AnimationState.SetAnimation(0, "idle", true); else if (name == "move") skAnims[0].AnimationState.SetAnimation(0, "move", true); else skAnims[0].AnimationState.SetAnimation(0, name, false); } } // 사운드 재생. public void PlaySound(int index) { if (index < 0 || index >= asEffects.Length) return; if (SoundMgr.EfcOn) { asEffects[index].Play(); } } // 사운드 랜덤 재생. public void PlaySoundRandom(int istartindex) { if (SoundMgr.EfcOn) { int index = Random.Range(istartindex, asEffects.Length); asEffects[index].Play(); } } // 카메라 흔들기. public void ShakeCamera1(float fstrength) { IVCameraController.SShakeCamera(0.1f, fstrength); } // 카메라 흔들기. public void ShakeCamera3(float fstrength) { IVCameraController.SShakeCamera(0.3f, fstrength); } // 카메라 흔들기. public void ShakeCamera5(float fstrength) { IVCameraController.SShakeCamera(0.5f, fstrength); } // 카메라 흔들기. public void ShakeCamera10(float fstrength) { IVCameraController.SShakeCamera(1f, fstrength); } #endregion Control Method #region Shot Method public void SetBullet() { for (int i = 0; i < bullets.Length; ++i) { bullets[i].SetStatus(battleMgr, biDmg, fCrtDam, iCrtRate, idNumber, iDamCnt, ShakeStrength, iVibrato, useFrom); } } // 직선으로 발사 메서드를 사용하기 전에, SetDistance를 가장 먼저 시퀀스에 포함시켜 날려보낼 거리를 할당필요 // 직선으로 발사 public void ShotToFront(float ftime) { if (iTarget < 0 || twcShots.Length < 1) return; Vector3 v3endpos = battleMgr.GetTargetPos(bFriendlySkill, iTarget); Vector3 v3driection = (v3endpos - trfShotStart.position).normalized; v3endpos = trfShotStart.position + v3driection * fDistance; trfShots[0].position = trfShotStart.position; trfShots[0].right = v3driection; trfShots[0].gameObject.SetActive(true); twcShots[0] = trfShots[0].DOMove(v3endpos, ftime).SetEase(Ease.Linear).SetAutoKill(true); } private IEnumerator ShotToAngle(float ftime) { float sum = 0f; float addAngle = 360f / trfShots.Length; Vector3 direction; Vector3 dir = Vector3.left; for (int i = 0; i < trfShots.Length; i++) { trfShots[i].position = trfShotStart.position; trfShots[i].gameObject.SetActive(true); direction = Quaternion.Euler(0, 0, sum) * dir; twcShots[i] = trfShots[i].DOMove(trfShotStart.position + direction * fDistance, ftime).SetEase(Ease.Linear).SetAutoKill(true); trfShots[i].rotation = Quaternion.Euler(0, 0, sum); yield return YieldInstructionCache.WaitForSeconds(0.02f); sum += -addAngle; } } public void ShotToAngleDelay(float ftime) { for(int i = 0; i < trfShots.Length; i++) { trfShots[i].gameObject.SetActive(false); } StartCoroutine(ShotToAngle(ftime)); } public void ThrowToTarget(float ftime) { Vector3 v3endpos; trfShots[0].position = trfShotStart.position; if (useFrom == 0) v3endpos = battleMgr.GetTargetPos(true, battleMgr.GetTargetIndex(true)); else v3endpos = battleMgr.GetPlayer().transform.position; float fdt = Vector3.Distance(trfShotStart.position, battleMgr.GetTargetPos(true, battleMgr.GetTargetIndex(true))); trfShots[0].rotation = Quaternion.identity; trfShots[0].DOJump(v3endpos, fdt*0.3f , 1,ftime).SetEase(Ease.OutCubic); // ftime trfShots[0].DORotate(new Vector3(0, 0, Random.Range(120, 360)), 1f); } public void ThrowToFront(float ftime) { trfShots[0].position = trfShotStart.position; Vector3 v3endpos; if (battleMgr.GetIsFront(bFriendlySkill)) v3endpos = trfShotStart.position + (Vector3.right * fDistance); else v3endpos = trfShotStart.position + (Vector3.left * fDistance); trfShots[0].DOJump(v3endpos, 4f, 1, ftime); } public void ThrowToRandom(float ftime) { StartCoroutine(ThrowToRandomDelay(ftime)); } public IEnumerator ThrowToRandomDelay(float ftime) { for (int i = 0; i < trfShots.Length; i++) { trfShots[i].position = trfShotStart.position; Vector3 v3endpos; //Quaternion v3endrot; v3endpos = trfShots[i].position + Random.insideUnitSphere * Random.Range(8, 15); trfShots[i].rotation = Quaternion.identity; //v3endrot = Quaternion.Euler()); trfShots[i].DOJump(v3endpos, 4f, 1, ftime);//.SetEase(Ease.InQuad); trfShots[i].DORotate(new Vector3(0, 0, Random.Range(120, 360)), 1f); yield return YieldInstructionCache.WaitForSeconds(0.1f); } } public void ThrowToRandomChain(float ftime) { for(int i = 1; i < sprShotItems.Length; i++) { sprShotItems[i].enabled = false; } trfShots[0].position = trfShotStart.position; SavePos[0] = battleMgr.GetTargetPos(true,battleMgr.GetTargetIndex(true)); trfShots[0].rotation = Quaternion.identity; trfShots[0].DOJump(SavePos[0], 2f, 1, 0.5f); // ftime trfShots[0].DORotate(new Vector3(0, 0, Random.Range(120, 360)), 1f); StartCoroutine(ThrowToRandomChainRepeat(1, ftime)); } public IEnumerator ThrowToRandomChainRepeat(int icnt, float ftime) { yield return new WaitForSeconds(0.5f); ftime *= 0.5f; int saveCnt = 0; int splitNum = 2; int throwCnt = iSplit; for (int i = icnt; i < trfShots.Length; i++) { sprShotItems[i].enabled = true; trfShots[i].position = SavePos[(i-1)/ iSplit]; SavePos[i] = trfShots[i].position + Random.insideUnitSphere * Random.Range((12 / splitNum) + 2, (14 / splitNum) + 2); trfShots[i].rotation = Quaternion.identity; trfShots[i].DOMove(SavePos[i],ftime); trfShots[i].DORotate(new Vector3(0, 0, Random.Range(120, 360)), 1f); saveCnt++; if (i >= throwCnt) { yield return new WaitForSeconds(ftime); for(int j = 0; j < throwCnt; j++) { sprShotItems[j].enabled = false; } throwCnt = iSplit + throwCnt* iSplit; //ftime *= 0.5f; splitNum++; } } } // 좌우 직선으로 발사 (대각선 x) public void ShotToFrontHorizon(float ftime) { Vector3 v3endpos; if (battleMgr.GetIsFront(bFriendlySkill)) v3endpos = trfShotStart.position + (Vector3.right * fDistance); else v3endpos = trfShotStart.position + (Vector3.left * fDistance); trfShots[0].position = trfShotStart.position; trfShots[0].gameObject.SetActive(true); twcShots[0] = trfShots[0].DOMove(v3endpos, ftime).SetEase(Ease.Linear).SetAutoKill(true); } // 발사 메서드를 사용하기 전에, SetDistance를 가장 먼저 시퀀스에 포함시켜 날려보낼 거리를 할당필요 // 화면을 가로지르는 투사체 발사 private IEnumerator CrossScreenToTargetDelay(int icol, float fdelay) { Vector3 v3startpos, v3endpos, v3targetpos; v3targetpos = trfShotStart.position + new Vector3(fx, fy, 0); if (bfront) { v3startpos = v3targetpos + Vector3.left * fDistance; v3endpos = v3targetpos + Vector3.right * fDistance; } else { v3startpos = v3targetpos + Vector3.right * fDistance; v3endpos = v3targetpos + Vector3.left * fDistance; } trfShots[icol].position = v3startpos; trfShots[icol].gameObject.SetActive(true); yield return new WaitForSeconds(fdelay); //skAnims[0].transform.position = new Vector3(skAnims[0].transform.position.x, trfShots[0].position.y, skAnims[0].transform.position.z); twcShots[icol] = trfShots[icol].DOMove(v3endpos, fTime).SetEase(Ease.Linear).SetAutoKill(true); } public void CrossScreenToTarget(int icol) { if (iTarget < 0 || twcShots.Length < 1) return; StartCoroutine(CrossScreenToTargetDelay(icol, fDelayTime)); } // 단일 타겟에게 발사. public void ShotToTarget(float ftime) { iTarget = battleMgr.GetTargetIndexExcept(bFriendlySkill, iTarget); if (iTarget < 0 || twcShots.Length < 1) return; Vector3 v3endpos = battleMgr.GetTargetPos(bFriendlySkill, iTarget); trfShots[0].position = trfShotStart.position; trfShots[0].gameObject.SetActive(true); twcShots[0] = trfShots[0].DOMove(v3endpos, ftime).SetEase(Ease.OutQuint).SetAutoKill(true); } // 복수 타겟에게 발사. public void ShotToTargets(float ftime) { int[] itargets; Vector3[] v3endposes; iTarget = battleMgr.GetTargetIndexExcept(bFriendlySkill, iTarget); // 아군이 사용한 스킬. if (bFriendlySkill) { itargets = battleMgr.GetEnemyIndexes(twcShots.Length, iTarget); v3endposes = battleMgr.GetEnemyPoses(itargets); } // 적이 사용한 스킬. else { itargets = battleMgr.GetFriendlyIndexes(twcShots.Length, iTarget); v3endposes = battleMgr.GetFriendlyPoses(); } for (int i = 0; i < itargets.Length; i++) { if (itargets[i] < 0) { trfShots[0].gameObject.SetActive(false); continue; } iTargets.Add(itargets[i]); trfShots[i].position = trfShotStart.position; trfShots[i].gameObject.SetActive(true); twcShots[i] = trfShots[i].DOMove(v3endposes[i], ftime).SetEase(Ease.Linear).SetAutoKill(true); } } // 단일 타겟에게 발사 후 이어서 발사 및 데미지. public void ShotToTargetTrain(float ftime) { if (iTarget < 0 || twcShots.Length < 1) return; iShot++; trfShotStart.position = battleMgr.GetPlayer().transform.position; Vector3 v3endpos = battleMgr.GetTargetPos(bFriendlySkill, iTarget); trfShots[0].position = trfShotStart.position; trfShots[0].gameObject.SetActive(true); twcShots[0] = trfShots[0].DOMove(v3endpos, ftime).SetEase(Ease.Linear).SetAutoKill(false).OnComplete(ShotTrainDamage); } // 현재 타겟에게 데미지 후 다른 타겟에게 이어서 발사. protected void ShotTrainDamage() { SendDamageSingle(); iShot++; // 최대 횟수면 중지. if (iShot > iMaxShot) { twcShots[0].Kill(false); return; } // 다른 타겟 없으면 중지. iTarget = battleMgr.GetTargetIndexExceptObj(trfShots[0].position, bFriendlySkill, iTarget); float distance = BattleMgr.SCalcDistance(trfShots[0].position, battleMgr.GetTargetPos(true, iTarget)); if (iTarget < 0 || distance > 12) { twcShots[0].Kill(false); StopSkill(); return; } // 위치 변경 후 다시 재생. Vector3 v3endpos = battleMgr.GetTargetPos(bFriendlySkill, iTarget); twcShots[0].ChangeValues(trfShots[0].position, v3endpos); twcShots[0].Restart(); } // 콜라이더 하나만 사용할 때 사용가능 콜라이더 범위안에 적에게 발사 private void ShotToBounds() { iTarget = battleMgr.GetTargetPosInBounds(bFriendlySkill, colliders[0].bounds); if (transform.position.x > battleMgr.GetTargetPos(true,iTarget).x) transform.localScale = Global.V3_1XRev; else transform.localScale = Global.V3_1; if (battleMgr.GetTarget(true, iTarget) == null || battleMgr.GetTarget(true, iTarget).GetDie()) return; if (iTarget < 0) { skAnims[0].timeScale = 1.0f; if (skAnims[0].AnimationName != "idle") { SetAnimation("idle"); return; } } skAnims[0].timeScale = 3.0f; SetAnimation("attack"); SendDamageSingle(); } public IEnumerator ShotToBoundsContinue(float ftime) { int icount = 0; float itick = 0f; while(icount < 100 && itick < ftime) { ShotToBounds(); icount++; yield return new WaitForSeconds(0.2f); itick += 0.2f; if (itick >= ftime || icount >= 100) StopCoroutine(nameof(ShotToBoundsContinue)); } } public void corShotToBoundsContinue(float ftime) { StartCoroutine(ShotToBoundsContinue(ftime)); } #endregion Shot Method #region Damage Method public void SetSummon() { summon.SetStatus(biDmg, fCrtDam,iCrtRate, fPlayTime - 2f, battleMgr.GetPlayer().transform.position, idNumber, fSummonInterval); } public void SendDamage(CreatureBase target) { if (!target.IsBattleAvail()) return; switch (debuff) { case eSkillDebuff.Stun: // 기절 target.SetStun(fDebuffTime); break; case eSkillDebuff.DecMove: // 둔화 target.SetDecMove(fDebuffTime, (float)BigInteger.Divide(biDebuffValue, dConst.RateMaxBi)); break; case eSkillDebuff.Push: // 넉백 target.PushFrame((float)BigInteger.Divide(biDebuffValue, dConst.RateMaxBi)); break; case eSkillDebuff.DamageSec:// 출혈 target.SetDamageSec(fDebuffTime, biDebuffValue, fCrtDam, iCrtRate, idNumber); break; } target.GetDamage(biDmg, fCrtDam, iCrtRate); } // 전체 데미지. public void SendDamageAll() { DebuffAll(debuff); // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.DamageToEnemyAll(biDmg, fCrtDam, iCrtRate); } // 적이 사용한 스킬. else { battleMgr.DamageToFriendly(biDmg, fCrtDam, iCrtRate); } } // 단일 데미지. public void SendDamageSingle() { DebuffSingle(debuff); // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.DamageToEnemy(iTarget, biDmg, fCrtDam, iCrtRate, shake : ShakeStrength, ivibrato : iVibrato, idnum: idNumber); } // 적이 사용한 스킬. else { battleMgr.DamageToFriendly(biDmg, fCrtDam, iCrtRate); } } public void SendDamageMultiful() { for(int i = 0; i < iTargets.Count; i++) { DebuffSingle(debuff); // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.DamageToEnemy(iTargets[i], biDmg, fCrtDam, iCrtRate, idnum: idNumber); } // 적이 사용한 스킬. else { battleMgr.DamageToFriendly(biDmg, fCrtDam, iCrtRate); } } iTargets.Clear(); } // 범위 데미지. public void SendDamageBounds(int boundindex) { if (boundindex >= colliders.Length) return; DebuffBounds(debuff, boundindex); // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.DamageToEnemy(colliders[boundindex].bounds, biDmg, fCrtDam, iCrtRate, idNumber, shake : ShakeStrength, ivibrato : iVibrato); } // 적이 사용한 스킬. else { battleMgr.DamageToFriendly(colliders[boundindex].bounds, biDmg, fCrtDam, iCrtRate); } } public void SendDamageBoundsDt(int boundindex) { if (boundindex >= colliders.Length) return; DebuffBounds(debuff, boundindex); // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.DamageToEnemyDt(colliders[boundindex].bounds, biDmg, fCrtDam, iCrtRate, idNumber, shake: ShakeStrength, ivibrato: iVibrato, fdistance : fDistance); } // 적이 사용한 스킬. else { battleMgr.DamageToFreiendlyDt(colliders[boundindex].bounds, biDmg, fCrtDam, iCrtRate, fdistance: fDistance); } } // 하나의 콜라이더만 사용할 때 사용 (몬스터를 관통하는 투사체류) public void CorSendDamageBoundsContinue(float ftime) { StartCoroutine(SendDamageBoundsContinue(ftime)); } private IEnumerator SendDamageBoundsContinue(float ftime) { float itick = 0f; while(ftime > itick) { DebuffBounds(debuff, 0); // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.DamageToEnemy(colliders[0].bounds, biDmg, fCrtDam, iCrtRate, idNumber, shake : ShakeStrength, ivibrato: iVibrato); } // 적이 사용한 스킬. else { battleMgr.DamageToFriendly(colliders[0].bounds, biDmg, fCrtDam, iCrtRate); } yield return YieldInstructionCache.WaitForSeconds(0.2f); } } // 하나의 콜라이더만 사용할 때 사용(몬스터를 관통하는 투사체류) public void corSendDamageBoundsContinueNOL(float ftime) { StartCoroutine(SendDamageBoundsContinueNOL(ftime)); } private IEnumerator SendDamageBoundsContinueNOL(float ftime) { float itick = 0f; while (ftime > itick) { DebuffBounds(debuff, 0); // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.DamageToEnemy(colliders[0].bounds, biDmg, fCrtDam, iCrtRate, idNumber, iDamCnt, shake : ShakeStrength, ivibrato: iVibrato); } // 적이 사용한 스킬. else { battleMgr.DamageToFriendly(colliders[0].bounds, biDmg, fCrtDam, iCrtRate, iDamCnt); } yield return YieldInstructionCache.WaitForSeconds(0.1f); } } public void SendDamageBoundsNonOverLapping(int boundindex) { if (boundindex >= colliders.Length) return; DebuffBounds(debuff, 0); // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.DamageToEnemy(colliders[boundindex].bounds, biDmg, fCrtDam, iCrtRate, iDamCnt, idNumber, shake : ShakeStrength, ivibrato: iVibrato); } // 적이 사용한 스킬. else { battleMgr.DamageToFriendly(colliders[boundindex].bounds, biDmg, fCrtDam, iCrtRate, iDamCnt); } } // 위의 메서드 SendDamageBoundsNonOverLapping를 쓰기 전에 최초로 한번은 사용 public void AddDamCnt() { iDamCnt++; } #endregion Damage Method #region Move Method public void RushToEnemy(float fdt) { if(useFrom == 0) battleMgr.RushToEnemy(fdt); else battleMgr.RushToEnemy(fdt, useFrom); } // 사용전 setDistance 설정 필요 public void RushToDir(int dir) { battleMgr.RushToDir(dir, fDistance, bfront); } #endregion #region Debuff Method public void DebuffSingle(eSkillDebuff eDebuff) { switch (eDebuff) { case eSkillDebuff.None: // 없음 break; case eSkillDebuff.Stun: // 기절 DebuffStunSingle(); break; case eSkillDebuff.DecMove: // 둔화 DebuffDecMovSingle(); break; case eSkillDebuff.Push: // 넉백 DebuffPushSingle(); break; case eSkillDebuff.DamageSec:// 출혈 DebuffDamageSecSingle(); break; default: break; } } public void DebuffBounds(eSkillDebuff eDebuff, int boundsIndex) { switch (eDebuff) { case eSkillDebuff.None: // 없음 break; case eSkillDebuff.Stun: // 기절 DebuffStunBounds(boundsIndex); break; case eSkillDebuff.DecMove: // 둔화 DebuffDecMovBounds(boundsIndex); break; case eSkillDebuff.Push: // 넉백 DebuffPushBounds(boundsIndex); break; case eSkillDebuff.DamageSec:// 출혈 DebuffDamageSecBounds(boundsIndex); break; case eSkillDebuff.Pull: // 끌어당기기 DebuffPushPullBounds(boundsIndex); break; default: break; } } public void DebuffAll(eSkillDebuff eDebuff) { switch (eDebuff) { case eSkillDebuff.None: // 없음 break; case eSkillDebuff.Stun: // 기절 DebuffStunAll(); break; case eSkillDebuff.DecMove: // 둔화 DebuffDecMovAll(); break; case eSkillDebuff.Push: // 넉백 DebuffPushAll(); break; case eSkillDebuff.DamageSec:// 출혈 DebuffDamageSecAll(); break; default: break; } } // 전체 둔화. public void DebuffDecMovAll() { float fdebuffValue = (float)BigInteger.Divide(biDebuffValue, dConst.RateMaxBi); // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.DecMovToEnemyAll(fDebuffTime, fdebuffValue); } // 적이 사용한 스킬. else { battleMgr.DecMovToFriendlyAll(fDebuffTime, fdebuffValue); } } // 단일 둔화. public void DebuffDecMovSingle() { float fdebuffValue = (float)BigInteger.Divide(biDebuffValue, dConst.RateMaxBi); // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.DecMovToEnemy(iTarget, fDebuffTime, fdebuffValue); } // 적이 사용한 스킬. else { battleMgr.DecMovToFriendly(fDebuffTime, fdebuffValue); } } // 범위 둔화. public void DebuffDecMovBounds(int boundindex) { if (boundindex >= colliders.Length) return; float fdebuffValue = (float)BigInteger.Divide(biDebuffValue, dConst.RateMaxBi); // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.DecMovToEnemy(colliders[boundindex].bounds, fDebuffTime, fdebuffValue); } // 적이 사용한 스킬. else { battleMgr.DecMovToFriendly(colliders[boundindex].bounds, fDebuffTime, fdebuffValue); } } // 전체 출혈. public void DebuffDamageSecAll() { // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.DamageSecToEnemyAll(fDebuffTime, biDebuffValue, fCrtDam, iCrtRate, idNumber); } // 적이 사용한 스킬. else { battleMgr.DamageSecToFriendlyAll(fDebuffTime, biDebuffValue, fCrtDam, iCrtRate); } } // 단일 출혈. public void DebuffDamageSecSingle() { // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.DamageSecToEnemy(iTarget, fDebuffTime, biDebuffValue, fCrtDam, iCrtRate, idNumber); } // 적이 사용한 스킬. else { battleMgr.DamageSecToFriendly(fDebuffTime, biDebuffValue, fCrtDam, iCrtRate); } } // 범위 출혈. public void DebuffDamageSecBounds(int boundindex) { if (boundindex >= colliders.Length) return; // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.DamageSecToEnemy(colliders[boundindex].bounds, fDebuffTime, biDebuffValue, fCrtDam, iCrtRate, iDamCnt, idNumber); } // 적이 사용한 스킬. else { battleMgr.DamageSecToFriendly(colliders[boundindex].bounds, fDebuffTime, biDebuffValue, fCrtDam, iCrtRate, iDamCnt); } } // 전체 기절. public void DebuffStunAll() { // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.StunToEnemyAll(fDebuffTime); } // 적이 사용한 스킬. else { battleMgr.StunToFriendlyAll(fDebuffTime); } } // 단일 기절. public void DebuffStunSingle() { // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.StunToEnemy(iTarget, fDebuffTime); } // 적이 사용한 스킬. else { battleMgr.StunToFriendly(fDebuffTime); } } // 범위 기절. public void DebuffStunBounds(int boundindex) { if (boundindex >= colliders.Length) return; // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.StunToEnemy(colliders[boundindex].bounds, fDebuffTime); } // 적이 사용한 스킬. else { battleMgr.StunToFriendly(colliders[boundindex].bounds, fDebuffTime); } } // 전체 넉백. public void DebuffPushAll() { float fdebuffValue = (float)BigInteger.Divide(biDebuffValue, dConst.RateMaxBi); // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.PushToEnemyAll(fdebuffValue); } // 적이 사용한 스킬. else { battleMgr.PushToFriendlyAll(fdebuffValue); } } // 단일 넉백. public void DebuffPushSingle() { float fdebuffValue = (float)BigInteger.Divide(biDebuffValue, dConst.RateMaxBi); // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.PushToEnemy(iTarget, fdebuffValue, iDamCnt); } // 적이 사용한 스킬. else { battleMgr.PushToFriendly(fdebuffValue, iDamCnt); } } // 범위 넉백. public void DebuffPushBounds(int boundindex) { if (boundindex >= colliders.Length) return; float fdebuffValue = (float)BigInteger.Divide(biDebuffValue, dConst.RateMaxBi); // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.PushToEnemy(colliders[boundindex].bounds, fdebuffValue, iDamCnt); } // 적이 사용한 스킬. else { battleMgr.PushToFriendly(colliders[boundindex].bounds, fdebuffValue, iDamCnt); } } // 범위 끌어당기기 public void DebuffPushPullBounds(int boundindex) { if (boundindex >= colliders.Length) return; // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.PullToEnemy(colliders[boundindex].bounds, biDebuffValue, trfShots[boundindex]); } // 적이 사용한 스킬. else { battleMgr.PullToFriendly(colliders[boundindex].bounds, biDebuffValue, trfShots[boundindex]); } } #endregion Debuff Method #region Heal Method // 전체 힐. public void SendHealAll() { // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.HealToFriendly(fRate); } // 적이 사용한 스킬. else { battleMgr.HealToEnemyAll(fRate); } } // 단일 힐. public void SendHealSingle() { // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.HealToFriendly(fRate); } // 적이 사용한 스킬. else { battleMgr.HealToEnemy(iTarget, fRate); } } // 범위 힐. public void SendHealRange(int boundindex) { if (boundindex >= colliders.Length) return; // 아군이 사용한 스킬. if (bFriendlySkill) { battleMgr.HealToFriendly(colliders[boundindex].bounds, fRate); } // 적이 사용한 스킬. else { battleMgr.HealToEnemy(colliders[boundindex].bounds, fRate); } } #endregion Heal Method #region Start Skill public void StartSkill(bool bfriendskill, float fcrtdam, int icrtrate, BigInteger biDmg, Transform trfuse, Transform trftarget, int itarget, bool bright) { switch (skillType) { // 시전자 위치에서 일정 범위에 데미지. case eSkillType.RangeValueAtUse: StartSkillRange(bfriendskill, trfuse.position, fcrtdam, icrtrate, biDmg, bright); break; // 타겟 위치에서 일정 범위에 데미지. case eSkillType.RangeValueAtTarget: StartSkillRange(bfriendskill, trftarget.position, fcrtdam, icrtrate, biDmg, bright); break; // 시전자를 따라다니며 일정 범위에 데미지. case eSkillType.RangeValueTraceUse: StartSkillRangeTrace(bfriendskill, trfuse, fcrtdam, icrtrate, biDmg, bright); break; // 타겟을 따라다니며 일정 범위에 데미지. case eSkillType.RangeValueTraceTarget: StartSkillRangeTrace(bfriendskill, trftarget, fcrtdam, icrtrate, biDmg, bright); break; // 시전자 위치에서 타겟에 데미지. case eSkillType.OneValueAtUse: StartSkillTarget(bfriendskill, trfuse.position, fcrtdam, icrtrate, biDmg, bright, itarget); break; // 타겟 위치에서 타겟에 데미지. case eSkillType.OneValueAtTarget: StartSkillTarget(bfriendskill, trftarget.position, fcrtdam, icrtrate, biDmg, bright, itarget); break; // 시전자를 따라다니며 타겟에 데미지. case eSkillType.OneValueTraceUse: StartSkillTargetTrace(bfriendskill, trfuse, fcrtdam, icrtrate, biDmg, bright, itarget); break; // 타겟을 따라다니며 타겟에 데미지. case eSkillType.OneValueTraceTarget: StartSkillTargetTrace(bfriendskill, trftarget, fcrtdam, icrtrate, biDmg, bright, itarget); break; } } // 타겟 데미지. protected void StartSkillTarget(bool bfriendskill, Vector3 v3pos, float fcrtdam, int icrtrate, BigInteger bidmg, bool bright, int itarget) { if (IsPlaying) return; bFriendlySkill = bfriendskill; fCrtDam = fcrtdam; iCrtRate = icrtrate; biDmg = bidmg; iTarget = itarget; iShot = 0; transform.position = v3pos; if (ptcEffects.Length == 0) ChangeFront(bright); gameObject.SetActive(true); playSkillCoroutine = StartCoroutine(PlaySkill()); } // 타겟 데미지(타겟 트레이스). protected void StartSkillTargetTrace(bool bfriendskill, Transform trftrace, float fcrtdam, int icrtrate, BigInteger bidmg, bool bright, int itarget) { if (IsPlaying) return; trfTrace = trftrace; bFriendlySkill = bfriendskill; fCrtDam = fcrtdam; iCrtRate = icrtrate; biDmg = bidmg; iTarget = itarget; iShot = 0; transform.position = trftrace.position; if (ptcEffects.Length == 0) ChangeFront(bright); gameObject.SetActive(true); playSkillCoroutine = StartCoroutine(PlaySkill()); } // 범위 데미지. protected void StartSkillRange(bool bfriendskill, Vector3 v3pos, float fcrtdam, int icrtrate, BigInteger bidmg, bool bright) { if (IsPlaying) return; bFriendlySkill = bfriendskill; fCrtDam = fcrtdam; iCrtRate = icrtrate; biDmg = bidmg; transform.position = v3pos; if (ptcEffects.Length == 0) ChangeFront(bright); gameObject.SetActive(true); playSkillCoroutine = StartCoroutine(PlaySkill()); } // 범위 데미지(타겟 트레이스). protected void StartSkillRangeTrace(bool bfriendskill, Transform trftrace, float fcrtdam, int icrtrate, BigInteger bidmg, bool bright) { if (IsPlaying) return; trfTrace = trftrace; bFriendlySkill = bfriendskill; fCrtDam = fcrtdam; iCrtRate = icrtrate; biDmg = bidmg; transform.position = trftrace.position; if (ptcEffects.Length == 0) ChangeFront(bright); gameObject.SetActive(true); playSkillCoroutine = StartCoroutine(PlaySkill()); } #endregion Start Skill }