2024-06-14 23:37:41 +00:00
|
|
|
using System;
|
|
|
|
using System.Collections;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
|
|
|
using BlueWater.Maps;
|
|
|
|
using BlueWater.Utility;
|
|
|
|
using UnityEngine;
|
|
|
|
using Random = UnityEngine.Random;
|
|
|
|
|
|
|
|
namespace BlueWater.Enemies.Bosses.SandMole.Skills
|
|
|
|
{
|
|
|
|
public class GateOfSpikes : BaseSkill
|
|
|
|
{
|
|
|
|
private GateOfSpikesData _gateOfSpikesData;
|
|
|
|
private SandMole _sandMole;
|
|
|
|
private AnimationController _animationController;
|
|
|
|
private Collider _userCollider;
|
|
|
|
private Collider _targetCollider;
|
|
|
|
private Transform _particleInstantiateLocation;
|
|
|
|
|
|
|
|
private List<Vector3> _spikes;
|
|
|
|
|
|
|
|
protected override void BasicSetting()
|
|
|
|
{
|
|
|
|
if (!_sandMole)
|
|
|
|
{
|
|
|
|
_sandMole = SkillUser.GetComponent<SandMole>();
|
|
|
|
_animationController = _sandMole.AnimationController;
|
|
|
|
_userCollider = _sandMole.CharacterCollider;
|
|
|
|
_targetCollider = _sandMole.Target;
|
|
|
|
_particleInstantiateLocation = MapManager.Instance.SandMoleMapController.ParticleInstantiateLocation;
|
|
|
|
}
|
|
|
|
_gateOfSpikesData = (GateOfSpikesData)SkillData;
|
|
|
|
_spikes = new List<Vector3>(_gateOfSpikesData.SpikeCount);
|
|
|
|
|
|
|
|
base.BasicSetting();
|
|
|
|
}
|
|
|
|
|
|
|
|
public override void ActivateSkill(params Action[] actions)
|
|
|
|
{
|
|
|
|
Utils.StartUniqueCoroutine(this, ref SkillCoroutineInstance, SkillCoroutine(actions));
|
|
|
|
}
|
|
|
|
|
|
|
|
private IEnumerator SkillCoroutine(params Action[] actions)
|
|
|
|
{
|
|
|
|
EnableSkill = false;
|
|
|
|
_sandMole.StopMove();
|
|
|
|
_animationController.SetAnimationParameter("skillIndex", (int)SandMoleSkill.GateOfSpikes);
|
|
|
|
|
|
|
|
var animationStarted = false;
|
|
|
|
yield return StartCoroutine(_animationController.WaitForAnimationToRun("GateOfSpikes",
|
|
|
|
success => animationStarted = success));
|
|
|
|
|
|
|
|
if (!animationStarted || !SkillUser || !_userCollider)
|
|
|
|
{
|
|
|
|
EndSkill(0, actions[0]);
|
|
|
|
yield break;
|
|
|
|
}
|
|
|
|
|
|
|
|
IsUsingSkill = true;
|
|
|
|
_animationController.ResetAnimationSpeed();
|
|
|
|
var startPosition = SkillUser.transform.position;
|
|
|
|
var targetCenterPosition = _targetCollider.transform.position;
|
|
|
|
startPosition.y = targetCenterPosition.y;
|
|
|
|
var targetVector = targetCenterPosition - startPosition;
|
|
|
|
var targetDirection = targetVector.normalized;
|
|
|
|
_sandMole.CurrentDirection = targetDirection;
|
|
|
|
var spikeSpawnPosition = _userCollider.bounds.center;
|
|
|
|
var validAttackPositions = new List<Vector3>();
|
|
|
|
|
|
|
|
while (validAttackPositions.Count < _gateOfSpikesData.SpikeCount)
|
|
|
|
{
|
|
|
|
var randomCircle = Random.insideUnitCircle * _gateOfSpikesData.Radius;
|
|
|
|
var randomPosition = targetCenterPosition + new Vector3(randomCircle.x, 0, randomCircle.y);
|
|
|
|
|
|
|
|
if (!IsPositionValid(randomPosition)) continue;
|
|
|
|
|
|
|
|
validAttackPositions.Add(randomPosition);
|
|
|
|
_spikes.Add(randomPosition);
|
|
|
|
var spike = Instantiate(_gateOfSpikesData.SpikePrefab, spikeSpawnPosition, Quaternion.identity,
|
|
|
|
_particleInstantiateLocation).GetComponent<GateOfSpike>();
|
|
|
|
spike.GetComponentInChildren<ProjectileController>().Initialize(_gateOfSpikesData.Damage, _gateOfSpikesData.TargetLayer);
|
|
|
|
spike.Initialize(randomPosition);
|
|
|
|
}
|
|
|
|
|
|
|
|
EndSkill(SkillData.Cooldown, actions[0]);
|
|
|
|
}
|
|
|
|
|
|
|
|
private bool IsPositionValid(Vector3 position)
|
|
|
|
{
|
2024-06-15 01:20:43 +00:00
|
|
|
var isGrounded = Physics.Raycast(position + Vector3.up, Vector3.down, 5f, _gateOfSpikesData.GroundLayer);
|
2024-06-14 23:37:41 +00:00
|
|
|
|
2024-06-15 01:20:43 +00:00
|
|
|
return isGrounded && _spikes.All(element => !(Vector3.Distance(position, element) < _gateOfSpikesData.MinDistanceBetweenAttacks));
|
2024-06-14 23:37:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void EndSkill(float cooldown, Action action)
|
|
|
|
{
|
|
|
|
Utils.EndUniqueCoroutine(this, ref SkillCoroutineInstance);
|
|
|
|
|
|
|
|
_animationController.SetAnimationParameter("skillIndex", (int)SandMoleSkill.None);
|
|
|
|
action?.Invoke();
|
|
|
|
|
|
|
|
Utils.StartUniqueCoroutine(this, ref CooldownCoroutineInstance,Utils.CoolDownCoroutine(cooldown, EndCooldown));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|