ThrowBall/Assets/Plugins/RayFire/Scripts/Classes/Rigid/RFDamage.cs

214 lines
7.2 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
namespace RayFire
{
[Serializable]
public class RFDamage
{
[FormerlySerializedAs ("enable")] public bool en;
[FormerlySerializedAs ("maxDamage")] public float max;
[FormerlySerializedAs ("currentDamage")] public float cur;
[FormerlySerializedAs ("collect")] public bool col;
[FormerlySerializedAs ("multiplier")] public float mlt;
[FormerlySerializedAs ("toShards")] public bool shr;
/// /////////////////////////////////////////////////////////
/// Constructor
/// /////////////////////////////////////////////////////////
// Constructor
public RFDamage()
{
InitValues();
}
// Reset
public void InitValues()
{
en = false;
max = 100f;
cur = 0f;
col = false;
mlt = 1f;
shr = false;
}
// Reset
public void LocalReset()
{
cur = 0f;
}
// Pool Reset
public void GlobalReset()
{
InitValues();
}
// Copy from
public void CopyFrom(RFDamage source)
{
en = source.en;
max = source.max;
col = source.col;
mlt = source.mlt;
shr = source.shr;
LocalReset();
}
/// /////////////////////////////////////////////////////////
/// Methods
/// /////////////////////////////////////////////////////////
// Apply damage
public static bool ApplyDamage (RayfireRigid scr, float value, Vector3 point, float radius, Collider collider)
{
// Initialize if not
if (scr.initialized == false)
{
scr.Initialize();
// Set birth time before actual time to avoid BirthTime limitations check.
scr.limitations.birthTime -= (scr.limitations.time + 1f);
}
// Already demolished or should be
if (scr.limitations.demolished == true || scr.limitations.demolitionShould == true)
return false;
// Apply damage and get demolition state
bool demolitionState = ApplyTo (scr, value, point, radius, collider);
// Check for activation
if (scr.activation.dmg > 0 && scr.damage.cur > scr.activation.dmg)
scr.Activate();
// TODO demolish first to activate only demolished fragments AND activate if object can't be demolished
// Set demolition info
if (demolitionState == true)
{
// Demolition available check
if (scr.DemolitionState() == false)
return false;
// Set damage position
scr.limitations.contactVector3 = point;
scr.clsDemol.damageRadius = radius;
// Set small radius for cluster demolition by gun with 0 radius. IMPORTANT
if (radius == 0)
scr.clsDemol.damageRadius = 0.05f;
// Demolish object
scr.limitations.demolitionShould = true;
// Demolish
scr.DemolishForced();
// Mesh Was demolished
if (scr.limitations.demolished == true)
return true;
// Cluster was
if (scr.IsCluster == true)
if (scr.HasFragments == true)
return true;
}
return false;
}
// Add damage
public static bool ApplyTo(RayfireRigid scr, float value, Vector3 point, float radius = 0f, Collider collider = null)
{
// Apply damage to connected cluster per shard level
if (scr.objTp == ObjectType.ConnectedCluster && scr.damage.shr == true)
return ApplyToShard (scr, value, point, radius, collider);
// Apply to rigid itself
return ApplyToRigid (scr, value);
}
/// /////////////////////////////////////////////////////////
/// To rigid
/// /////////////////////////////////////////////////////////
// Add damage to Rigid
public static bool ApplyToRigid(RayfireRigid scr, float damageValue)
{
// Add damage
scr.damage.cur += damageValue;
// Check
if (scr.damage.en == true && scr.damage.cur >= scr.damage.max)
return true;
return false;
}
/// /////////////////////////////////////////////////////////
/// To shards
/// /////////////////////////////////////////////////////////
// Add damage to shard
public static bool ApplyToShard (RayfireRigid scr, float value, Vector3 point, float radius, Collider collider)
{
// Add damage by collider
if (collider != null)
return ApplyToShard (scr, value, collider);
// Add damage by radius
if (radius > 0)
return ApplyToShards (scr, value, point, radius);
return false;
}
// Add damage to shard by collider
public static bool ApplyToShard(RayfireRigid scr, float value, Collider collider)
{
for (int i = 0; i < scr.clsDemol.cluster.shards.Count; i++)
if (scr.clsDemol.cluster.shards[i].col == collider)
{
// Apply damage to shard
scr.clsDemol.cluster.shards[i].dm += value;
// Flag damaged shard
if (scr.clsDemol.cluster.shards[i].dm > scr.damage.max)
return true;
// Skip checking whole list
break;
}
return false;
}
// Add damage to shards in radius
public static bool ApplyToShards(RayfireRigid scr, float value, Vector3 point, float radius)
{
// TODO use mask
// bool maxReached = false;
// int mask = scr.gameObject.layer;
Collider[] colliders = Physics.OverlapSphere (point, radius);
HashSet<Collider> collidersHash = new HashSet<Collider>(colliders);
// Apply damage to shard
for (int i = 0; i < scr.clsDemol.cluster.shards.Count; i++)
if (collidersHash.Contains (scr.clsDemol.cluster.shards[i].col) == true)
scr.clsDemol.cluster.shards[i].dm += value;
// Flag damaged shard
for (int i = 0; i < scr.clsDemol.cluster.shards.Count; i++)
if (scr.clsDemol.cluster.shards[i].dm > scr.damage.max)
return true;
return false;
}
}
}