projectEli/Assets/NeoFPS/Core/Damage/DamageLayers.cs
2022-11-06 20:28:33 -05:00

280 lines
9.0 KiB
C#

using System;
using UnityEngine;
namespace NeoFPS
{
[Flags]
public enum DamageType : byte
{
None = 0,
Default = 1,
Fall = 2,
Explosion = 4,
Drowning = 8,
All = 255
}
[Flags]
public enum DamageTeamFilter : byte
{
None = 0, // 00000000
Team1 = 1, // 00000001
Team2 = 2, // 00000010
Team3 = 4, // 00000100
Team4 = 8, // 00001000
Team5 = 16, // 00010000
Team6 = 32, // 00100000
Team7 = 64, // 01000000
Team8 = 128, // 10000000
All = 255, // 11111111
}
public static class DamageTeamFilterMasks
{
public const byte NotTeam1 = 254; // 11111110
public const byte NotTeam2 = 253; // 11111101
public const byte NotTeam3 = 251; // 11111011
public const byte NotTeam4 = 247; // 11110111
public const byte NotTeam5 = 239; // 11101111
public const byte NotTeam6 = 223; // 11011111
public const byte NotTeam7 = 191; // 10111111
public const byte NotTeam8 = 127; // 01111111
}
[Serializable]
public struct DamageFilter
{
public static readonly DamageFilter AllDamageAllTeams = new DamageFilter (DamageType.All, DamageTeamFilter.All);
public static readonly DamageFilter DefaultAllTeams = new DamageFilter (DamageType.Default, DamageTeamFilter.All);
public static readonly DamageFilter AllTeam1 = new DamageFilter (DamageType.All, DamageTeamFilter.Team1);
public static readonly DamageFilter AllTeam2 = new DamageFilter (DamageType.All, DamageTeamFilter.Team2);
public static readonly DamageFilter AllTeam3 = new DamageFilter (DamageType.All, DamageTeamFilter.Team3);
public static readonly DamageFilter AllTeam4 = new DamageFilter (DamageType.All, DamageTeamFilter.Team4);
public static readonly DamageFilter AllTeam5 = new DamageFilter (DamageType.All, DamageTeamFilter.Team5);
public static readonly DamageFilter AllTeam6 = new DamageFilter (DamageType.All, DamageTeamFilter.Team6);
public static readonly DamageFilter AllTeam7 = new DamageFilter (DamageType.All, DamageTeamFilter.Team7);
public static readonly DamageFilter AllTeam8 = new DamageFilter (DamageType.All, DamageTeamFilter.Team8);
public static readonly DamageFilter AllNotTeam1 = new DamageFilter (DamageType.All, 254);
public static readonly DamageFilter AllNotTeam2 = new DamageFilter (DamageType.All, 253);
public static readonly DamageFilter AllNotTeam3 = new DamageFilter (DamageType.All, 251);
public static readonly DamageFilter AllNotTeam4 = new DamageFilter (DamageType.All, 247);
public static readonly DamageFilter AllNotTeam5 = new DamageFilter (DamageType.All, 239);
public static readonly DamageFilter AllNotTeam6 = new DamageFilter (DamageType.All, 223);
public static readonly DamageFilter AllNotTeam7 = new DamageFilter (DamageType.All, 191);
public static readonly DamageFilter AllNotTeam8 = new DamageFilter (DamageType.All, 127);
public static readonly DamageFilter DefaultTeam1 = new DamageFilter (DamageType.Default, DamageTeamFilter.Team1);
public static readonly DamageFilter DefaultTeam2 = new DamageFilter (DamageType.Default, DamageTeamFilter.Team2);
public static readonly DamageFilter DefaultTeam3 = new DamageFilter (DamageType.Default, DamageTeamFilter.Team3);
public static readonly DamageFilter DefaultTeam4 = new DamageFilter (DamageType.Default, DamageTeamFilter.Team4);
public static readonly DamageFilter DefaultTeam5 = new DamageFilter (DamageType.Default, DamageTeamFilter.Team5);
public static readonly DamageFilter DefaultTeam6 = new DamageFilter (DamageType.Default, DamageTeamFilter.Team6);
public static readonly DamageFilter DefaultTeam7 = new DamageFilter (DamageType.Default, DamageTeamFilter.Team7);
public static readonly DamageFilter DefaultTeam8 = new DamageFilter (DamageType.Default, DamageTeamFilter.Team8);
public static readonly DamageFilter DefaultNotTeam1 = new DamageFilter (DamageType.Default, 254);
public static readonly DamageFilter DefaultNotTeam2 = new DamageFilter (DamageType.Default, 253);
public static readonly DamageFilter DefaultNotTeam3 = new DamageFilter (DamageType.Default, 251);
public static readonly DamageFilter DefaultNotTeam4 = new DamageFilter (DamageType.Default, 239);
public static readonly DamageFilter DefaultNotTeam5 = new DamageFilter (DamageType.Default, 239);
public static readonly DamageFilter DefaultNotTeam6 = new DamageFilter (DamageType.Default, 223);
public static readonly DamageFilter DefaultNotTeam7 = new DamageFilter (DamageType.Default, 191);
public static readonly DamageFilter DefaultNotTeam8 = new DamageFilter (DamageType.Default, 127);
[SerializeField]
private ushort m_Value;
public ushort value
{
get { return m_Value; }
}
public DamageFilter (ushort v)
{
m_Value = v;
}
public DamageFilter (DamageType type, byte teamFilter)
{
m_Value = (ushort)((uint)type + ((uint)teamFilter << 8));
}
public DamageFilter (DamageType type, DamageTeamFilter teamFilter)
{
m_Value = (ushort)((uint)type + ((uint)teamFilter << 8));
}
// Checks
public static bool operator ==(DamageFilter x, DamageFilter y)
{
return (x.m_Value == y.m_Value);
}
public static bool operator !=(DamageFilter x, DamageFilter y)
{
return (x.m_Value != y.m_Value);
}
public override bool Equals (object obj)
{
if (obj is DamageFilter)
return m_Value == ((DamageFilter)obj).m_Value;
if (obj is ushort)
return m_Value == (ushort)obj;
return false;
}
public override int GetHashCode ()
{
return m_Value.GetHashCode ();
}
public bool CollidesWith (DamageFilter other, bool friendlyFire)
{
// Compare damage types
uint x = (uint)m_Value & 0xFF;
uint y = (uint)other.m_Value & 0xFF;
if ((x & y) == 0)
return false;
// Ignore team filters with friendly fire
if (friendlyFire)
return true;
// Compare team filters
x = (uint)m_Value & 0xFF00;
y = (uint)other.m_Value & 0xFF00;
return (x & y) != 0;
}
// Implicit conversions
public static implicit operator DamageFilter (ushort value)
{
return new DamageFilter (value);
}
public static implicit operator ushort (DamageFilter dam)
{
return dam.value;
}
// Getters
public DamageTeamFilter GetTeamFilter ()
{
uint teamFilter = (uint)m_Value & 0xFF00;
return (DamageTeamFilter)(teamFilter >> 8);
}
public DamageType GetDamageType ()
{
uint damageType = (uint)m_Value & 0x00FF;
return (DamageType)damageType;
}
public bool IsDamageType (DamageType dt)
{
uint damageType = (uint)m_Value & 0x00FF;
return damageType == (uint)dt;
}
public bool HasDamageType (DamageType dt)
{
uint damageType = (uint)m_Value & 0x00FF;
return (damageType & (uint)dt) != 0;
}
public bool IsTeam(DamageTeamFilter team)
{
uint damageType = ((uint)m_Value & 0xFF00) >> 8;
return damageType == (uint)team;
}
public bool HasTeam(DamageTeamFilter team)
{
uint damageType = ((uint)m_Value & 0xFF00) >> 8;
return (damageType & (uint)team) != 0;
}
// Modifiers
public void SetDamageType (DamageType type)
{
uint teamFilter = (uint)m_Value & 0xFF00;
m_Value = (ushort)((uint)type + teamFilter);
}
public void SetTeamFilter (DamageTeamFilter teamFilter)
{
uint damageType = (uint)m_Value & 0xFF;
m_Value = (ushort)(damageType + ((uint)teamFilter << 8));
}
public void AddTeam (byte team)
{
if (team > 8)
{
Debug.LogError ("DamageFilter cannot use a team value greater than 8");
return;
}
if (team == 0)
{
Debug.LogError ("Attempting to add team 0 (must be 1-8)");
return;
}
uint teamFilter = 1U << (7 + team);
m_Value = (ushort)(m_Value | teamFilter);
}
public void RemoveTeam (byte team)
{
if (team > 8)
{
Debug.LogError ("DamageFilter cannot use a team value greater than 8");
return;
}
if (team == 0)
{
Debug.LogError ("Attempting to remove team 0 (must be 1-8)");
return;
}
uint teamFilter = ~(1U << (7 + team));
m_Value = (ushort)(m_Value & teamFilter);
}
public static DamageFilter FromTypeAndTeam (DamageType type, byte team)
{
if (team > 8)
{
Debug.LogError ("DamageFilter cannot use a team value greater than 8");
return new DamageFilter (type, DamageTeamFilter.None);
}
if (team == 0)
return new DamageFilter (type, DamageTeamFilter.All);
ushort result = (ushort)((uint)type + (1U << (7 + team)));
return new DamageFilter (result);
}
public static DamageFilter FromTypeAndExcludedTeam (DamageType type, byte team)
{
if (team > 8)
{
Debug.LogError ("DamageFilter cannot use a team value greater than 8");
return new DamageFilter (type, DamageTeamFilter.All);
}
if (team == 0)
return new DamageFilter (type, DamageTeamFilter.All);
uint result = (uint)type | 0x00FF;
result |= ~(1U << (7 + team));
return new DamageFilter ((ushort)result);
}
}
}