first commit
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
using OTGIntegrated.Combat;
|
||||
using OTGIntegrated.Stats;
|
||||
using UnityEngine;
|
||||
|
||||
namespace OTGIntegrated.Weapons
|
||||
{
|
||||
public sealed class WeaponController : MonoBehaviour
|
||||
{
|
||||
public Transform attackOrigin;
|
||||
public LayerMask hitMask = ~0;
|
||||
[SerializeField] private float meleeRadius = 0.7f;
|
||||
|
||||
private readonly Collider[] hits = new Collider[16];
|
||||
|
||||
public bool Attack(WeaponData weapon, PlayerStats stats)
|
||||
{
|
||||
if (weapon == null || stats == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Transform origin = attackOrigin != null ? attackOrigin : transform;
|
||||
Vector3 start = origin.position + Vector3.up * 0.8f;
|
||||
Vector3 forward = origin.forward;
|
||||
forward.y = 0f;
|
||||
forward = forward.sqrMagnitude > 0.001f ? forward.normalized : transform.forward;
|
||||
|
||||
float finalDamage = weapon.damage + stats.Damage;
|
||||
bool critical = Random.value < stats.CriticalChance;
|
||||
if (critical)
|
||||
{
|
||||
finalDamage *= 1.75f;
|
||||
}
|
||||
|
||||
if (weapon.isRanged)
|
||||
{
|
||||
if (Physics.Raycast(start, forward, out RaycastHit hit, weapon.range, hitMask, QueryTriggerInteraction.Ignore))
|
||||
{
|
||||
return ApplyDamage(hit.collider, finalDamage, critical);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector3 center = start + forward * Mathf.Max(0.6f, weapon.range * 0.55f);
|
||||
int count = Physics.OverlapSphereNonAlloc(center, meleeRadius + weapon.range * 0.12f, hits, hitMask, QueryTriggerInteraction.Ignore);
|
||||
bool damaged = false;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Collider hit = hits[i];
|
||||
if (hit == null || hit.transform == transform || hit.GetComponentInParent<PlayerStats>() != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ApplyDamage(hit, finalDamage, critical))
|
||||
{
|
||||
damaged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return damaged;
|
||||
}
|
||||
|
||||
private bool ApplyDamage(Collider collider, float amount, bool critical)
|
||||
{
|
||||
Damageable damageable = collider.GetComponentInParent<Damageable>();
|
||||
if (damageable == null || !damageable.IsAlive)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
damageable.TakeDamage(amount, gameObject);
|
||||
if (critical)
|
||||
{
|
||||
OTGIntegrated.Core.GameEvents.RaiseNotification("Критический удар");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
Gizmos.color = new Color(1f, 0.45f, 0.1f, 0.25f);
|
||||
Transform origin = attackOrigin != null ? attackOrigin : transform;
|
||||
Gizmos.DrawWireSphere(origin.position + origin.forward * 1.3f + Vector3.up * 0.8f, meleeRadius);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user