You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1334 lines
38 KiB

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<Vector3, Vector3, VectorOptions>[] 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;
// 아군 스킬인지.
private bool _bFriendlySkill;
protected bool bFriendlySkill
{
get => _bFriendlySkill;
set
{
if(_bFriendlySkill != value)
{
_bFriendlySkill = value;
TargetTags = Bitset32.GetMask(bFriendlySkill ? EntityTag.Enemy : EntityTag.Player);
}
}
}
public Bitset32.Mask TargetTags { get; private set; }
protected IBattleEntity caster;
protected Transform casterTransform => caster != null ? (caster as Entity).transform : null;
protected UnityEngine.Vector2 casterPos => caster != null ? (caster as Entity).transform.position : UnityEngine.Vector2.zero;
// 타겟.
protected IBattleEntity target;
protected Transform targetTransform => target != null ? (target as Entity).transform : null;
protected UnityEngine.Vector2 targetPos => target != null ? (target as Entity).transform.position : UnityEngine.Vector2.zero;
protected float sqrtDistToTarget => target != null ? ((UnityEngine.Vector2)transform.position - targetPos).sqrMagnitude : 9999f;
// 여러명 타겟
protected List<IBattleEntity> targets;
// 추적 타겟.
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
#region Init
// 초기화.
public void Init(BattleMgr mgr)
{
battleMgr = mgr;
skAnims = transform.GetComponentsInChildren<SkeletonAnimation>(true);
asEffects = transform.GetComponentsInChildren<AudioSource>(true);
ptcEffects = transform.GetComponentsInChildren<ParticleSystem>(true);
twcShots = new TweenerCore<Vector3, Vector3, VectorOptions>[trfShots.Length];
targets = new List<IBattleEntity>();
_bFriendlySkill = true;
TargetTags = Bitset32.GetMask(EntityTag.Enemy);
}
// 사거리 가져오기.
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
protected void LateUpdate()
{
if (bTrace && trfTrace != null)
transform.position = trfTrace.position;
}
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;
}
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();
}
target = null;
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.Instance.EfcOn)
{
asEffects[index].Play();
}
}
// 사운드 랜덤 재생.
public void PlaySoundRandom(int istartindex)
{
if (SoundMgr.Instance.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, ShakeStrength, iVibrato, useFrom);
}
}
// 직선으로 발사 메서드를 사용하기 전에, SetDistance를 가장 먼저 시퀀스에 포함시켜 날려보낼 거리를 할당필요
// 직선으로 발사
public void ShotToFront(float ftime)
{
if (target != null || twcShots.Length < 1)
return;
Vector3 v3endpos = targetPos;
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 endpos;
trfShots[0].position = trfShotStart.position;
if (useFrom == 0)
{
if (TargetFinder.TryFindNearest(casterPos, TargetTags, out var target))
endpos = (target as Entity).transform.position;
else
endpos = Vector3.zero;
}
else
{
endpos = battleMgr.GetPlayer().transform.position;
}
float dist = Vector3.Distance(trfShotStart.position, endpos);
trfShots[0].rotation = Quaternion.identity;
trfShots[0].DOJump(endpos, dist * 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;
v3endpos = trfShots[i].position + Random.insideUnitSphere * Random.Range(8, 15);
trfShots[i].rotation = Quaternion.identity;
trfShots[i].DOJump(v3endpos, 4f, 1, ftime);
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;
if (TargetFinder.TryFindNearest(casterPos, TargetTags, out var target))
SavePos[0] = (target as Entity).transform.position;
else
SavePos[0] = Vector3.zero;
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);
twcShots[icol] = trfShots[icol].DOMove(v3endpos, fTime).SetEase(Ease.Linear).SetAutoKill(true);
}
public void CrossScreenToTarget(int icol)
{
if (target != null || twcShots.Length < 1)
return;
StartCoroutine(CrossScreenToTargetDelay(icol, fDelayTime));
}
// 단일 타겟에게 발사.
public void ShotToTarget(float ftime)
{
if (twcShots.Length < 1) return;
if (TargetFinder.TryFindNearest(casterPos, TargetTags, out target))
{
trfShots[0].position = trfShotStart.position;
trfShots[0].gameObject.SetActive(true);
twcShots[0] = trfShots[0].DOMove(targetPos, ftime).SetEase(Ease.OutQuint).SetAutoKill(true);
}
}
// 복수 타겟에게 발사.
public void ShotToTargets(float ftime)
{
targets = TargetFinder.GetNears(casterPos, TargetTags, twcShots.Length);
for (int i = 0; i < targets.Count; i++)
{
var target = targets[i] as Entity;
if (target is null)
{
trfShots[i].gameObject.SetActive(false);
continue;
}
trfShots[i].position = trfShotStart.position;
trfShots[i].gameObject.SetActive(true);
twcShots[i] = trfShots[i].DOMove(target.transform.position, ftime).SetEase(Ease.Linear).SetAutoKill(true);
}
}
// 단일 타겟에게 발사 후 이어서 발사 및 데미지.
HashSet<IBattleEntity> trainShotExceptSet = new();
public void ShotToTargetTrain(float ftime)
{
if (target is null || twcShots.Length < 1) return;
trainShotExceptSet.Clear();
iShot++;
trfShotStart.position = casterPos;
trainShotExceptSet.Add(target);
trfShots[0].position = trfShotStart.position;
trfShots[0].gameObject.SetActive(true);
twcShots[0] = trfShots[0].DOMove(targetPos, ftime).SetEase(Ease.Linear).SetAutoKill(false).OnComplete(ShotTrainDamage);
}
// 현재 타겟에게 데미지 후 다른 타겟에게 이어서 발사.
protected void ShotTrainDamage()
{
SendDamageSingle();
iShot++;
// 최대 횟수면 중지.
if (iShot > iMaxShot)
{
twcShots[0].Kill(false);
return;
}
// 다른 타겟 없으면 중지.
if (!TargetFinder.TryFindNearest(trfShots[0].position, TargetTags, out var newTarget, trainShotExceptSet))
{
twcShots[0].Kill(false);
StopSkill();
return;
}
target = newTarget;
trainShotExceptSet.Add(newTarget);
float distance = UnityEngine.Vector2.SqrMagnitude(targetPos - (UnityEngine.Vector2)trfShots[0].position);
if (distance > 12 * 12)
{
twcShots[0].Kill(false);
StopSkill();
return;
}
// 위치 변경 후 다시 재생.
twcShots[0].ChangeValues(trfShots[0].position, targetPos);
twcShots[0].Restart();
}
// 콜라이더 하나만 사용할 때 사용가능 콜라이더 범위안에 적에게 발사
private void ShotToBounds()
{
if (!TargetFinder.TryFindNearest(casterPos, colliders[0].bounds, TargetTags, out target))
{
skAnims[0].timeScale = 1.0f;
if (skAnims[0].AnimationName != "idle")
SetAnimation("idle");
return;
}
if (transform.position.x > targetPos.x)
transform.localScale = Global.V3_1XRev;
else
transform.localScale = Global.V3_1;
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(IBattleEntity battleEntity)
{
var creature = battleEntity as CreatureBase;
if (creature != null)
{
switch (debuff)
{
case eSkillDebuff.Stun: creature.SetStun(fDebuffTime); break;
case eSkillDebuff.DecMove: creature.SetDecMove(fDebuffTime, (float)BigInteger.Divide(biDebuffValue, dConst.RateMaxBi)); break;
case eSkillDebuff.Push: creature.PushFrame((float)BigInteger.Divide(biDebuffValue, dConst.RateMaxBi)); break;
case eSkillDebuff.DamageSec: creature.SetDamageSec(fDebuffTime, biDebuffValue, fCrtDam, iCrtRate, idNumber); break;
}
}
battleEntity.GetDamage(biDmg, fCrtDam, iCrtRate, idNumber);
}
// 전체 데미지.
public void SendDamageAll()
{
battleMgr.LoopAllBattleEntities((battleEntity) =>
{
if((battleEntity as Entity).HasTagsAny(TargetTags))
{
SendDamage(battleEntity);
}
return true;
});
}
// 단일 데미지.
public void SendDamageSingle()
{
SendDamage(target);
if (bFriendlySkill)
IVCameraController.SShakeCamera(0.1f, ShakeStrength, iVibrato);
}
public void SendDamageMultiful()
{
for(int i = 0; i < targets.Count; i++)
{
SendDamage(targets[i]);
}
targets.Clear();
}
// 범위 데미지.
public void SendDamageBounds(int boundindex)
{
if (boundindex >= colliders.Length) return;
var bound = colliders[boundindex].bounds;
battleMgr.LoopAllBattleEntities((battleEntity) =>
{
Entity entity = battleEntity as Entity;
if (entity.HasTagsAny(TargetTags) && bound.Contains(entity.transform.position))
{
SendDamage(battleEntity);
}
return true;
});
if (bFriendlySkill)
IVCameraController.SShakeCamera(0.1f, ShakeStrength, iVibrato);
}
public void SendDamageBoundsDt(int boundindex)
{
if (boundindex >= colliders.Length) return;
var bound = colliders[boundindex].bounds;
battleMgr.LoopAllBattleEntities((battleEntity) =>
{
Entity entity = battleEntity as Entity;
if (entity.HasTagsAny(TargetTags) && bound.Contains(entity.transform.position))
{
float sqrDist = (entity.transform.position - bound.center).sqrMagnitude;
if (sqrDist <= fDistance * fDistance)
SendDamage(battleEntity);
}
return true;
});
if (bFriendlySkill)
IVCameraController.SShakeCamera(0.1f, ShakeStrength, iVibrato);
}
// 하나의 콜라이더만 사용할 때 사용 (몬스터를 관통하는 투사체류)
public void CorSendDamageBoundsContinue(float ftime)
{
StartCoroutine(SendDamageBoundsContinue(ftime));
}
private IEnumerator SendDamageBoundsContinue(float duration)
{
float tick = 0f;
while(duration > tick)
{
SendDamageBounds(0);
yield return YieldInstructionCache.WaitForSeconds(0.2f);
}
}
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.Stun: // 기절
DebuffStunSingle();
break;
case eSkillDebuff.DecMove: // 둔화
DebuffDecMovSingle();
break;
case eSkillDebuff.Push: // 넉백
DebuffPushSingle();
break;
case eSkillDebuff.DamageSec:// 출혈
DebuffDamageSecSingle();
break;
}
}
public void DebuffBounds(eSkillDebuff eDebuff, int boundsIndex)
{
switch (eDebuff)
{
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;
}
}
public void DebuffAll(eSkillDebuff eDebuff)
{
switch (eDebuff)
{
case eSkillDebuff.Stun: DebuffStunAll(); break; // 기절
case eSkillDebuff.DecMove: DebuffDecMovAll(); break; // 둔화
case eSkillDebuff.Push: DebuffPushAll(); break; // 넉백
case eSkillDebuff.DamageSec: DebuffDamageSecAll(); 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(target, 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(target, 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(target, 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(target, 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(target, 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, IBattleEntity caster, IBattleEntity target, bool bright)
{
this.caster = caster;
this.target = target;
switch (skillType)
{
// 시전자 위치에서 일정 범위에 데미지.
case eSkillType.RangeValueAtUse:
StartSkillRange(bfriendskill, casterPos, fcrtdam, icrtrate, biDmg, bright);
break;
// 타겟 위치에서 일정 범위에 데미지.
case eSkillType.RangeValueAtTarget:
StartSkillRange(bfriendskill, targetPos, fcrtdam, icrtrate, biDmg, bright);
break;
// 시전자를 따라다니며 일정 범위에 데미지.
case eSkillType.RangeValueTraceUse:
StartSkillRangeTrace(bfriendskill, casterTransform, fcrtdam, icrtrate, biDmg, bright);
break;
// 타겟을 따라다니며 일정 범위에 데미지.
case eSkillType.RangeValueTraceTarget:
StartSkillRangeTrace(bfriendskill, targetTransform, fcrtdam, icrtrate, biDmg, bright);
break;
// 시전자 위치에서 타겟에 데미지.
case eSkillType.OneValueAtUse:
StartSkillTarget(bfriendskill, casterPos, fcrtdam, icrtrate, biDmg, bright, target);
break;
// 타겟 위치에서 타겟에 데미지.
case eSkillType.OneValueAtTarget:
StartSkillTarget(bfriendskill, targetPos, fcrtdam, icrtrate, biDmg, bright, target);
break;
// 시전자를 따라다니며 타겟에 데미지.
case eSkillType.OneValueTraceUse:
StartSkillTargetTrace(bfriendskill, casterTransform, fcrtdam, icrtrate, biDmg, bright, target);
break;
// 타겟을 따라다니며 타겟에 데미지.
case eSkillType.OneValueTraceTarget:
StartSkillTargetTrace(bfriendskill, targetTransform, fcrtdam, icrtrate, biDmg, bright, target);
break;
}
}
// 타겟 데미지.
protected void StartSkillTarget(bool bfriendskill, Vector3 v3pos, float fcrtdam, int icrtrate, BigInteger bidmg, bool bright, IBattleEntity target)
{
if (IsPlaying) return;
bFriendlySkill = bfriendskill;
fCrtDam = fcrtdam;
iCrtRate = icrtrate;
biDmg = bidmg;
this.target = target;
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, IBattleEntity target)
{
if (IsPlaying) return;
trfTrace = trftrace;
bFriendlySkill = bfriendskill;
fCrtDam = fcrtdam;
iCrtRate = icrtrate;
biDmg = bidmg;
this.target = target;
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
}