using System;
using BumpCombat.Player;
using UnityEngine;
namespace BumpCombat.Combat
{
public readonly struct CombatHitResult
{
public CombatHitResult(
GameObject attacker,
GameObject target,
bool isDash,
HitSide side,
float damage,
Vector2 knockbackDirection,
float knockbackForce,
Vector2 hitPosition,
bool isOffsetHit = false,
bool isStrongDash = false,
DamageTag damageTag = DamageTag.Collision,
string sourceId = null,
bool usesPositionBonus = true,
bool showsHitFeedback = true,
bool launchSucceeded = false,
bool isArtifactHit = false,
ActiveArtifactEffect artifactEffect = ActiveArtifactEffect.Dash,
bool isChargedArtifact = false)
{
Attacker = attacker;
Target = target;
IsDash = isDash;
Side = side;
Damage = damage;
KnockbackDirection = knockbackDirection;
KnockbackForce = knockbackForce;
HitPosition = hitPosition;
IsOffsetHit = isOffsetHit;
IsStrongDash = isStrongDash;
DamageTag = damageTag;
SourceId = sourceId;
UsesPositionBonus = usesPositionBonus;
ShowsHitFeedback = showsHitFeedback;
LaunchSucceeded = launchSucceeded;
IsArtifactHit = isArtifactHit;
ArtifactEffect = artifactEffect;
IsChargedArtifact = isChargedArtifact;
}
public static CombatHitResult ForArtifactContact(
GameObject attacker,
GameObject target,
ActiveArtifactEffect artifactEffect,
bool isChargedArtifact,
HitSide side,
Vector2 knockbackDirection,
Vector2 hitPosition,
DamageTag damageTag,
string sourceId,
bool isOffsetHit = false)
{
bool isDash = artifactEffect == ActiveArtifactEffect.Dash;
return new CombatHitResult(
attacker,
target,
isDash,
side,
0f,
knockbackDirection,
0f,
hitPosition,
isOffsetHit: isOffsetHit,
isStrongDash: isDash && isChargedArtifact,
damageTag: damageTag,
sourceId: sourceId,
usesPositionBonus: false,
showsHitFeedback: false,
launchSucceeded: false,
isArtifactHit: true,
artifactEffect: artifactEffect,
isChargedArtifact: isChargedArtifact);
}
public GameObject Attacker { get; }
public GameObject Target { get; }
public bool IsDash { get; }
public bool IsStrongDash { get; }
public DamageTag DamageTag { get; }
public string SourceId { get; }
public bool UsesPositionBonus { get; }
public bool ShowsHitFeedback { get; }
/// True only when a strong dash actually created the launch state.
public bool LaunchSucceeded { get; }
public bool IsArtifactHit { get; }
public ActiveArtifactEffect ArtifactEffect { get; }
public bool IsChargedArtifact { get; }
public bool IsOrdinaryBump => !IsDash && string.IsNullOrEmpty(SourceId);
public HitSide Side { get; }
public float Damage { get; }
public bool HasBackBonus => UsesPositionBonus && Side == HitSide.Back;
public bool IsOffsetHit { get; }
public bool HasPositionBonus =>
UsesPositionBonus && (Side == HitSide.Side || IsOffsetHit);
public Vector2 KnockbackDirection { get; }
public float KnockbackForce { get; }
public Vector2 HitPosition { get; }
}
/// A confirmed artifact effect on one enemy during one activation.
public readonly struct ArtifactEffectiveHitResult
{
public ArtifactEffectiveHitResult(
GameObject target,
int castIdentity,
ActiveArtifactEffect artifactEffect,
bool isCharged,
bool matchedShieldRequirement)
{
Target = target;
CastIdentity = castIdentity;
ArtifactEffect = artifactEffect;
IsCharged = isCharged;
MatchedShieldRequirement = matchedShieldRequirement;
}
public GameObject Target { get; }
public int CastIdentity { get; }
public ActiveArtifactEffect ArtifactEffect { get; }
public bool IsCharged { get; }
public bool MatchedShieldRequirement { get; }
}
public static class CombatEvents
{
public static event Action OnValidHit;
public static event Action OnArtifactEffectiveHit;
public static event Action OnRearAttackCancelled;
public static event Action OnStunApplied;
public static event Action OnAttackCancelled;
public static event Action OnEnemyStagger;
public static event Action OnEnemyStaggerCleared;
public static event Action OnLaunchResisted;
public static event Action OnKnockbackCompleted;
public static event Action OnEnemyRetired;
public static event Action OnEnemyDied;
public static event Action OnThunderShield;
public static void RaiseValidHit(CombatHitResult result)
{
OnValidHit?.Invoke(result);
}
public static void RaiseArtifactEffectiveHit(
GameObject target,
int castIdentity,
ActiveArtifactEffect artifactEffect,
bool isCharged,
bool matchedShieldRequirement = false)
{
OnArtifactEffectiveHit?.Invoke(new ArtifactEffectiveHitResult(
target,
castIdentity,
artifactEffect,
isCharged,
matchedShieldRequirement));
}
public static void RaiseRearAttackCancelled(GameObject target)
{
OnRearAttackCancelled?.Invoke(target);
}
public static void RaiseStunApplied(GameObject target, float duration)
{
OnStunApplied?.Invoke(target, duration);
}
public static void RaiseAttackCancelled(GameObject target, bool fromStun)
{
OnAttackCancelled?.Invoke(target, fromStun);
}
public static void RaiseEnemyStagger(
GameObject target,
int current,
int maximum,
bool broke)
{
OnEnemyStagger?.Invoke(target, current, maximum, broke);
}
public static void RaiseEnemyStaggerCleared(GameObject target)
{
OnEnemyStaggerCleared?.Invoke(target);
}
public static void RaiseLaunchResisted(GameObject target)
{
OnLaunchResisted?.Invoke(target);
}
public static void RaiseKnockbackCompleted(
GameObject target,
Vector2 start,
Vector2 end)
{
OnKnockbackCompleted?.Invoke(target, start, end);
}
public static void RaiseEnemyRetired(GameObject target)
{
OnEnemyRetired?.Invoke(target);
}
public static void RaiseEnemyDied(GameObject target)
{
OnEnemyDied?.Invoke(target);
}
public static void RaiseThunderShield(Vector2 center, float duration)
{
OnThunderShield?.Invoke(center, duration);
}
}
}