115 lines
5.1 KiB
C#
115 lines
5.1 KiB
C#
using UnityEngine;
|
|
using Saltosion.OneWeapon.Enemies;
|
|
using Saltosion.OneWeapon.Effects;
|
|
using Saltosion.OneWeapon.Player;
|
|
|
|
namespace Saltosion.OneWeapon.AI.Behaviours {
|
|
[RequireComponent(typeof(Follow), typeof(Enemy), typeof(Explodable))]
|
|
public class ExplodeFollowed : AIBehaviour {
|
|
public float StartExplodingRadius;
|
|
public float ExplodeOnImpactRadius;
|
|
public float ExplosionRadius;
|
|
public float FuseDuration;
|
|
[Tooltip("The amount of damage when barely in the explosion radius")]
|
|
public float MinDamage;
|
|
[Tooltip("The amount of damage when in impact radius")]
|
|
public float MaxDamage;
|
|
[Header("Graphics")]
|
|
public SpriteRenderer SpriteRenderer;
|
|
public Transform ExplosionAnimationTransform;
|
|
public float ExplosionAnimationDuration;
|
|
public float BlinkingRate;
|
|
|
|
private Enemy Enemy;
|
|
private Follow Follow;
|
|
private Explodable Explodable;
|
|
private float OriginalFollowPositionUpdateFrequency;
|
|
|
|
private bool Exploding = false;
|
|
private float FuseStartTime;
|
|
|
|
private bool ExplosionStarted = false;
|
|
private float ExplosionProgress = 0.0f;
|
|
|
|
private void Start() {
|
|
Enemy = GetComponent<Enemy>();
|
|
Follow = GetComponent<Follow>();
|
|
Explodable = GetComponent<Explodable>();
|
|
OriginalFollowPositionUpdateFrequency = Follow.TargetPositionUpdateFrequency;
|
|
}
|
|
|
|
public override bool CanBehave() {
|
|
return true;
|
|
}
|
|
|
|
public override void Execute() {
|
|
float Distance = Follow.Target != null ? (Follow.Target.position - transform.position).magnitude : float.PositiveInfinity;
|
|
bool ImpactExplode = Distance <= ExplodeOnImpactRadius;
|
|
bool TimeExplode = Exploding && Time.time - FuseStartTime >= FuseDuration;
|
|
if (!ExplosionStarted && (ImpactExplode || TimeExplode)) {
|
|
ExplosionStarted = true;
|
|
CurrentStatus = "BOOM";
|
|
} else if (Distance <= StartExplodingRadius && !Exploding) {
|
|
Exploding = true;
|
|
FuseStartTime = Time.time;
|
|
Follow.SetUpdateFrequency(OriginalFollowPositionUpdateFrequency / 3f);
|
|
CurrentStatus = "CloseEnoughNow";
|
|
} else if (Exploding) {
|
|
CurrentStatus = "Exploding: " + (Time.time - FuseStartTime).ToString("0.0") + " > " + FuseDuration.ToString("0.0");
|
|
} else {
|
|
CurrentStatus = "NotCloseEnough";
|
|
}
|
|
|
|
// Animation
|
|
if (ExplosionStarted) {
|
|
if (ExplosionProgress >= 1.0f) {
|
|
Explode(Distance);
|
|
} else {
|
|
ExplosionProgress += Time.deltaTime / ExplosionAnimationDuration;
|
|
float AnimMidpoint = 0.5f;
|
|
if (ExplosionProgress < AnimMidpoint) {
|
|
float MinifyProgress = ExplosionProgress / AnimMidpoint;
|
|
ExplosionAnimationTransform.localScale = new Vector3(1, 1, 1) * (1.0f - MinifyProgress * 0.5f);
|
|
} else {
|
|
float ExpansionProgress = (ExplosionProgress - AnimMidpoint) / (1.0f - AnimMidpoint);
|
|
ExplosionAnimationTransform.localScale = new Vector3(1, 1, 1) * (0.5f + ExpansionProgress);
|
|
}
|
|
}
|
|
}
|
|
if (Exploding) {
|
|
float Intensity = Mathf.Sin(Time.time * Mathf.PI * 2.0f * BlinkingRate) * 0.5f + 0.5f;
|
|
SpriteRenderer.material.SetFloat("_Intensity", Intensity);
|
|
} else {
|
|
SpriteRenderer.material.SetFloat("_Intensity", 0.0f);
|
|
}
|
|
}
|
|
|
|
private void OnDrawGizmosSelected() {
|
|
Gizmos.color = new Color(1.0f, 0.2f, 0.2f, 0.8f);
|
|
Gizmos.DrawWireSphere(transform.position, ExplodeOnImpactRadius);
|
|
Gizmos.color = new Color(1.0f, 0.0f, 0.0f, 1.0f);
|
|
Gizmos.DrawWireSphere(transform.position, ExplosionRadius);
|
|
Gizmos.color = new Color(1.0f, 0.5f, 0.5f, 0.5f);
|
|
Gizmos.DrawWireSphere(transform.position, StartExplodingRadius);
|
|
}
|
|
|
|
private void Explode(float distance) {
|
|
Collider2D[] NearbyColliders = Physics2D.OverlapCircleAll(transform.position, ExplosionRadius);
|
|
foreach (Collider2D Collider in NearbyColliders) {
|
|
PlayerFun PlayerFun = Collider.GetComponent<PlayerFun>();
|
|
Health Health = Collider.GetComponent<Health>();
|
|
if (PlayerFun != null) {
|
|
PlayerFun.TakeExplosionDamage();
|
|
}
|
|
if (Health != null) {
|
|
float ScaledDistance = Mathf.Clamp((distance - ExplodeOnImpactRadius) / (ExplosionRadius - ExplodeOnImpactRadius), 0, 1);
|
|
float Damage = MinDamage + (MaxDamage - MinDamage) * (1.0f - ScaledDistance);
|
|
Vector2 Direction = (Collider.transform.position - transform.position).normalized;
|
|
Health.Damage(Damage, Direction, false);
|
|
}
|
|
}
|
|
Explodable.Explode(true, false);
|
|
}
|
|
}
|
|
}
|