Implement Equals for the OOPs & fix Player properties

Fixed setting player properties
Changed player rotation to float3
Added constructor for BlockColor with an index param
Improved Player.Exists() ~~hopefully~~
This commit is contained in:
Norbi Peti 2020-06-05 00:20:35 +02:00
parent cd78fd6718
commit cae626197f
5 changed files with 178 additions and 67 deletions

View file

@ -19,7 +19,7 @@ namespace GamecraftModdingAPI
/// A single (perhaps scaled) block. Properties may return default values if the block is removed and then setting them is ignored.
/// For specific block type operations, use the specialised block classes in the GamecraftModdingAPI.Blocks namespace.
/// </summary>
public class Block
public class Block : IEquatable<Block>, IEquatable<EGID>
{
protected static readonly PlacementEngine PlacementEngine = new PlacementEngine();
protected static readonly MovementEngine MovementEngine = new MovementEngine();
@ -139,7 +139,7 @@ namespace GamecraftModdingAPI
{
}
public EGID Id { get; protected set; }
public EGID Id { get; }
/// <summary>
/// The block's current position or zero if the block no longer exists.
@ -218,8 +218,7 @@ namespace GamecraftModdingAPI
{
byte index = BlockEngine.GetBlockInfo<ColourParameterEntityStruct>(Id, out var exists).indexInPalette;
if (!exists) index = byte.MaxValue;
if (index == byte.MaxValue) return new BlockColor { Color = BlockColors.Default };
return new BlockColor { Color = (BlockColors)(index % 10), Darkness = (byte)(index / 10) };
return new BlockColor(index);
}
set
{
@ -292,6 +291,31 @@ namespace GamecraftModdingAPI
return $"{nameof(Id)}: {Id}, {nameof(Position)}: {Position}, {nameof(Type)}: {Type}, {nameof(Color)}: {Color}, {nameof(Exists)}: {Exists}";
}
public bool Equals(Block other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Id.Equals(other.Id);
}
public bool Equals(EGID other)
{
return Id.Equals(other);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((Block) obj);
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
public static void Init()
{
GameEngineManager.AddGameEngine(PlacementEngine);

View file

@ -5,6 +5,26 @@
public BlockColors Color;
public byte Darkness;
public BlockColor(byte index)
{
if (index == byte.MaxValue)
{
Color = BlockColors.Default;
Darkness = 0;
}
else
{
Color = (BlockColors) (index % 10);
Darkness = (byte) (index / 10);
}
}
public BlockColor(BlockColors color, byte darkness)
{
Color = color;
Darkness = darkness;
}
public override string ToString()
{
return $"{nameof(Color)}: {Color}, {nameof(Darkness)}: {Darkness}";

View file

@ -2,6 +2,8 @@
using Unity.Mathematics;
using RobocraftX.Common;
using RobocraftX.Common.Players;
using Svelto.ECS;
using GamecraftModdingAPI.Players;
using GamecraftModdingAPI.Blocks;
@ -11,7 +13,7 @@ namespace GamecraftModdingAPI
/// <summary>
/// An in-game player character. Any Leo you see is a player.
/// </summary>
public class Player
public class Player : IEquatable<Player>, IEquatable<EGID>
{
// static functionality
private static PlayerEngine playerEngine = new PlayerEngine();
@ -63,7 +65,6 @@ namespace GamecraftModdingAPI
/// <param name="player">The player type. Chooses the first available player matching the criteria.</param>
public Player(PlayerType player)
{
uint localId = playerEngine.GetLocalPlayer();
switch (player)
{
case PlayerType.Local:
@ -93,7 +94,7 @@ namespace GamecraftModdingAPI
/// The player's unique identifier.
/// </summary>
/// <value>The identifier.</value>
public uint Id { get; private set; }
public uint Id { get; }
/// <summary>
/// The player's current position.
@ -116,7 +117,7 @@ namespace GamecraftModdingAPI
/// The player's current rotation.
/// </summary>
/// <value>The rotation.</value>
public quaternion Rotation
public float3 Rotation
{
get
{
@ -299,11 +300,11 @@ namespace GamecraftModdingAPI
/// The player's selected block color in their hand.
/// </summary>
/// <value>The selected block's color.</value>
public BlockColors SelectedColor
public BlockColor SelectedColor
{
get
{
return (BlockColors)playerEngine.GetSelectedColor(Id);
return new BlockColor(playerEngine.GetSelectedColor(Id));
}
}
@ -311,11 +312,11 @@ namespace GamecraftModdingAPI
/// The player's selected block colour in their hand.
/// </summary>
/// <value>The selected block's colour.</value>
public BlockColors SelectedColour
public BlockColor SelectedColour
{
get
{
return (BlockColors)playerEngine.GetSelectedColor(Id);
return new BlockColor(playerEngine.GetSelectedColor(Id));
}
}
@ -365,6 +366,33 @@ namespace GamecraftModdingAPI
: null;
}
public bool Equals(Player other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Id == other.Id;
}
public bool Equals(EGID other)
{
return Id == other.entityID && other.groupID == (Type == PlayerType.Local
? PlayersExclusiveGroups.LocalPlayers
: PlayersExclusiveGroups.RemotePlayers);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((Player) obj);
}
public override int GetHashCode()
{
return (int) Id;
}
// internal methods
public static void Init()

View file

@ -14,6 +14,7 @@ using Gamecraft.CharacterVulnerability.Entities;
using Svelto.ECS;
using Unity.Mathematics;
using Unity.Physics;
using UnityEngine;
using GamecraftModdingAPI.Engines;
@ -65,28 +66,14 @@ namespace GamecraftModdingAPI.Players
public bool ExistsById(uint playerId)
{
PlayerIDStruct[] players = entitiesDB.QueryEntities<PlayerIDStruct>(PlayersExclusiveGroups.LocalPlayers).ToFastAccess(out uint count);
for (int i = 0; i < count; i++)
{
if (players[i].ID.entityID == playerId)
{
return true;
}
}
players = entitiesDB.QueryEntities<PlayerIDStruct>(PlayersExclusiveGroups.RemotePlayers).ToFastAccess(out count);
for (int i = 0; i < count; i++)
{
if (players[i].ID.entityID == playerId)
{
return true;
}
}
return false;
return entitiesDB.Exists<PlayerIDStruct>(playerId, PlayersExclusiveGroups.LocalPlayers)
|| entitiesDB.Exists<PlayerIDStruct>(playerId, PlayersExclusiveGroups.RemotePlayers);
}
public float3 GetLocation(uint playerId)
{
if (GetCharacterStruct<RigidBodyEntityStruct>(playerId, out RigidBodyEntityStruct rbes))
ref var rbes = ref GetCharacterStruct<RigidBodyEntityStruct>(playerId, out bool exists);
if (exists)
{
return rbes.position;
}
@ -114,20 +101,24 @@ namespace GamecraftModdingAPI.Players
return false;
}
public quaternion GetRotation(uint playerId)
public float3 GetRotation(uint playerId)
{
if (GetCharacterStruct<RigidBodyEntityStruct>(playerId, out RigidBodyEntityStruct rbes))
ref var rbes = ref GetCharacterStruct<RigidBodyEntityStruct>(playerId, out bool exists);
if (exists)
{
return rbes.rotation;
return ((Quaternion) rbes.rotation).eulerAngles;
}
return quaternion.identity;
return default;
}
public bool SetRotation(uint playerId, quaternion value)
public bool SetRotation(uint playerId, float3 value)
{
if (GetCharacterStruct<RigidBodyEntityStruct>(playerId, out RigidBodyEntityStruct rbes))
ref var rbes = ref GetCharacterStruct<RigidBodyEntityStruct>(playerId, out bool exists);
if (exists)
{
rbes.rotation = value;
Quaternion q = rbes.rotation;
q.eulerAngles = value;
rbes.rotation = q;
return true;
}
return false;
@ -135,7 +126,8 @@ namespace GamecraftModdingAPI.Players
public float3 GetLinearVelocity(uint playerId)
{
if (GetCharacterStruct<RigidBodyEntityStruct>(playerId, out RigidBodyEntityStruct rbes))
ref var rbes = ref GetCharacterStruct<RigidBodyEntityStruct>(playerId, out bool exists);
if (exists)
{
return rbes.velocity;
}
@ -144,7 +136,8 @@ namespace GamecraftModdingAPI.Players
public bool SetLinearVelocity(uint playerId, float3 value)
{
if (GetCharacterStruct<RigidBodyEntityStruct>(playerId, out RigidBodyEntityStruct rbes))
ref var rbes = ref GetCharacterStruct<RigidBodyEntityStruct>(playerId, out bool exists);
if (exists)
{
rbes.velocity = value;
return true;
@ -154,7 +147,8 @@ namespace GamecraftModdingAPI.Players
public float3 GetAngularVelocity(uint playerId)
{
if (GetCharacterStruct<RigidBodyEntityStruct>(playerId, out RigidBodyEntityStruct rbes))
ref var rbes = ref GetCharacterStruct<RigidBodyEntityStruct>(playerId, out bool exists);
if (exists)
{
return rbes.angularVelocity;
}
@ -163,7 +157,8 @@ namespace GamecraftModdingAPI.Players
public bool SetAngularVelocity(uint playerId, float3 value)
{
if (GetCharacterStruct<RigidBodyEntityStruct>(playerId, out RigidBodyEntityStruct rbes))
ref var rbes = ref GetCharacterStruct<RigidBodyEntityStruct>(playerId, out bool exists);
if (exists)
{
rbes.angularVelocity = value;
return true;
@ -173,7 +168,8 @@ namespace GamecraftModdingAPI.Players
public PhysicsMass GetMass(uint playerId)
{
if (GetCharacterStruct<RigidBodyEntityStruct>(playerId, out RigidBodyEntityStruct rbes))
ref var rbes = ref GetCharacterStruct<RigidBodyEntityStruct>(playerId, out bool exists);
if (exists)
{
return rbes.physicsMass;
}
@ -182,7 +178,8 @@ namespace GamecraftModdingAPI.Players
public bool SetInverseMass(uint playerId, float inverseMass)
{
if (GetCharacterStruct<RigidBodyEntityStruct>(playerId, out RigidBodyEntityStruct rbes))
ref var rbes = ref GetCharacterStruct<RigidBodyEntityStruct>(playerId, out bool exists);
if (exists)
{
rbes.physicsMass.InverseInertia = inverseMass;
return true;
@ -202,7 +199,8 @@ namespace GamecraftModdingAPI.Players
public float GetInitialHealth(uint playerId)
{
if (GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out CharacterHealthEntityStruct c))
ref var c = ref GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out bool exists);
if (exists)
{
return c.initialHealth;
}
@ -211,7 +209,8 @@ namespace GamecraftModdingAPI.Players
public bool SetInitialHealth(uint playerId, float val)
{
if (GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out CharacterHealthEntityStruct c))
ref var c = ref GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out bool exists);
if (exists)
{
c.initialHealth = val;
return true;
@ -221,7 +220,8 @@ namespace GamecraftModdingAPI.Players
public float GetCurrentHealth(uint playerId)
{
if (GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out CharacterHealthEntityStruct c))
ref var c = ref GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out bool exists);
if (exists)
{
return c.currentHealth;
}
@ -230,7 +230,8 @@ namespace GamecraftModdingAPI.Players
public bool SetCurrentHealth(uint playerId, float val)
{
if (GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out CharacterHealthEntityStruct c))
ref var c = ref GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out bool exists);
if (exists)
{
c.currentHealth = val;
return true;
@ -252,7 +253,8 @@ namespace GamecraftModdingAPI.Players
public bool GetDamageable(uint playerId)
{
if (GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out CharacterHealthEntityStruct c))
ref var c = ref GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out bool exists);
if (exists)
{
return c.canTakeDamageStat;
}
@ -261,7 +263,8 @@ namespace GamecraftModdingAPI.Players
public bool SetDamageable(uint playerId, bool val)
{
if (GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out CharacterHealthEntityStruct ches))
ref var ches = ref GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out bool exists);
if (exists)
{
ches.canTakeDamage = val;
ches.canTakeDamage = val;
@ -272,7 +275,8 @@ namespace GamecraftModdingAPI.Players
public uint GetInitialLives(uint playerId)
{
if (GetCharacterStruct<CharacterLivesEntityComponent>(playerId, out CharacterLivesEntityComponent c))
ref var c = ref GetCharacterStruct<CharacterLivesEntityComponent>(playerId, out bool exists);
if (exists)
{
return c.initialLives;
}
@ -281,7 +285,8 @@ namespace GamecraftModdingAPI.Players
public bool SetInitialLives(uint playerId, uint val)
{
if (GetCharacterStruct<CharacterLivesEntityComponent>(playerId, out CharacterLivesEntityComponent c))
ref var c = ref GetCharacterStruct<CharacterLivesEntityComponent>(playerId, out bool exists);
if (exists)
{
c.initialLives = val;
return true;
@ -291,7 +296,8 @@ namespace GamecraftModdingAPI.Players
public uint GetCurrentLives(uint playerId)
{
if (GetCharacterStruct<CharacterLivesEntityComponent>(playerId, out CharacterLivesEntityComponent c))
ref var c = ref GetCharacterStruct<CharacterLivesEntityComponent>(playerId, out bool exists);
if (exists)
{
return c.currentLives;
}
@ -300,7 +306,8 @@ namespace GamecraftModdingAPI.Players
public bool SetCurrentLives(uint playerId, uint val)
{
if (GetCharacterStruct<CharacterLivesEntityComponent>(playerId, out CharacterLivesEntityComponent c))
ref var c = ref GetCharacterStruct<CharacterLivesEntityComponent>(playerId, out bool exists);
if (exists)
{
c.currentLives = val;
return true;
@ -310,7 +317,8 @@ namespace GamecraftModdingAPI.Players
public bool GetGameOverScreen(uint playerId)
{
if (GetCharacterStruct<CharacterLivesEntityComponent>(playerId, out CharacterLivesEntityComponent c))
ref var c = ref GetCharacterStruct<CharacterLivesEntityComponent>(playerId, out bool exists);
if (exists)
{
return c.gameOverScreen;
}
@ -324,7 +332,8 @@ namespace GamecraftModdingAPI.Players
public int GetSelectedBlock(uint playerId)
{
if (GetCharacterStruct<EquippedPartStruct>(playerId, out EquippedPartStruct c))
ref var c = ref GetCharacterStruct<EquippedPartStruct>(playerId, out bool exists);
if (exists)
{
return c.SelectedDBPartID;
}
@ -333,7 +342,8 @@ namespace GamecraftModdingAPI.Players
public byte GetSelectedColor(uint playerId)
{
if (GetCharacterStruct<EquippedColourStruct>(playerId, out EquippedColourStruct c))
ref var c = ref GetCharacterStruct<EquippedColourStruct>(playerId, out bool exists);
if (exists)
{
return c.indexInPalette;
}
@ -349,7 +359,7 @@ namespace GamecraftModdingAPI.Players
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool GetCharacterStruct<T>(uint playerId, out T s) where T : unmanaged, IEntityComponent
public ref T GetCharacterStruct<T>(uint playerId, out bool exists) where T : unmanaged, IEntityComponent
{
ExclusiveGroup[] characterGroups = CharacterExclusiveGroups.AllCharacters;
for (int i = 0; i < characterGroups.Length; i++)
@ -357,12 +367,14 @@ namespace GamecraftModdingAPI.Players
EGID egid = new EGID(playerId, characterGroups[i]);
if (entitiesDB.Exists<T>(egid))
{
s = entitiesDB.QueryEntity<T>(egid);
return true;
exists = true;
return ref entitiesDB.QueryEntity<T>(egid);
}
}
s = default;
return false;
exists = false;
T[] arr = new T[1];
return ref arr[0]; //Return default value
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]

View file

@ -1,15 +1,17 @@
using RobocraftX.Common;
using RobocraftX.Physics;
using System;
using Svelto.ECS;
using Unity.Mathematics;
using UnityEngine;
using RobocraftX.Common;
using RobocraftX.Physics;
namespace GamecraftModdingAPI
{
/// <summary>
/// A rigid body (like a cluster of connected blocks) during simulation.
/// </summary>
public class SimBody
public class SimBody : IEquatable<SimBody>, IEquatable<EGID>
{
public EGID Id { get; }
@ -91,6 +93,31 @@ namespace GamecraftModdingAPI
return $"{nameof(Id)}: {Id}, {nameof(Position)}: {Position}, {nameof(Mass)}: {Mass}, {nameof(Static)}: {Static}";
}
public bool Equals(SimBody other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Id.Equals(other.Id);
}
public bool Equals(EGID other)
{
return Id.Equals(other);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((SimBody) obj);
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
/// <summary>
/// Returns the object identified by the given ID (A-Z).
/// This has the same result as calling ObjectIdentifier.GetByID(id) and then GetRigidBody() with the duplicates filtered out.