From cae626197f5f736311bc092cf642766a9cc90dbe Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Fri, 5 Jun 2020 00:20:35 +0200 Subject: [PATCH] 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~~ --- GamecraftModdingAPI/Block.cs | 32 +++++- GamecraftModdingAPI/Blocks/BlockColor.cs | 20 ++++ GamecraftModdingAPI/Player.cs | 44 ++++++-- GamecraftModdingAPI/Players/PlayerEngine.cs | 116 +++++++++++--------- GamecraftModdingAPI/SimBody.cs | 33 +++++- 5 files changed, 178 insertions(+), 67 deletions(-) diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index d7752c8..f97c57c 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -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. /// - public class Block + public class Block : IEquatable, IEquatable { 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; } /// /// The block's current position or zero if the block no longer exists. @@ -218,8 +218,7 @@ namespace GamecraftModdingAPI { byte index = BlockEngine.GetBlockInfo(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); diff --git a/GamecraftModdingAPI/Blocks/BlockColor.cs b/GamecraftModdingAPI/Blocks/BlockColor.cs index fc87eb7..d7ada0d 100644 --- a/GamecraftModdingAPI/Blocks/BlockColor.cs +++ b/GamecraftModdingAPI/Blocks/BlockColor.cs @@ -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}"; diff --git a/GamecraftModdingAPI/Player.cs b/GamecraftModdingAPI/Player.cs index af20e36..086c910 100644 --- a/GamecraftModdingAPI/Player.cs +++ b/GamecraftModdingAPI/Player.cs @@ -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 /// /// An in-game player character. Any Leo you see is a player. /// - public class Player + public class Player : IEquatable, IEquatable { // static functionality private static PlayerEngine playerEngine = new PlayerEngine(); @@ -63,7 +65,6 @@ namespace GamecraftModdingAPI /// The player type. Chooses the first available player matching the criteria. public Player(PlayerType player) { - uint localId = playerEngine.GetLocalPlayer(); switch (player) { case PlayerType.Local: @@ -93,7 +94,7 @@ namespace GamecraftModdingAPI /// The player's unique identifier. /// /// The identifier. - public uint Id { get; private set; } + public uint Id { get; } /// /// The player's current position. @@ -116,7 +117,7 @@ namespace GamecraftModdingAPI /// The player's current rotation. /// /// The rotation. - public quaternion Rotation + public float3 Rotation { get { @@ -299,11 +300,11 @@ namespace GamecraftModdingAPI /// The player's selected block color in their hand. /// /// The selected block's color. - 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. /// /// The selected block's colour. - 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() diff --git a/GamecraftModdingAPI/Players/PlayerEngine.cs b/GamecraftModdingAPI/Players/PlayerEngine.cs index c86a4ae..bcbfd11 100644 --- a/GamecraftModdingAPI/Players/PlayerEngine.cs +++ b/GamecraftModdingAPI/Players/PlayerEngine.cs @@ -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(PlayersExclusiveGroups.LocalPlayers).ToFastAccess(out uint count); - for (int i = 0; i < count; i++) - { - if (players[i].ID.entityID == playerId) - { - return true; - } - } - players = entitiesDB.QueryEntities(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(playerId, PlayersExclusiveGroups.LocalPlayers) + || entitiesDB.Exists(playerId, PlayersExclusiveGroups.RemotePlayers); } public float3 GetLocation(uint playerId) { - if (GetCharacterStruct(playerId, out RigidBodyEntityStruct rbes)) + ref var rbes = ref GetCharacterStruct(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(playerId, out RigidBodyEntityStruct rbes)) - { - return rbes.rotation; - } - return quaternion.identity; + ref var rbes = ref GetCharacterStruct(playerId, out bool exists); + if (exists) + { + return ((Quaternion) rbes.rotation).eulerAngles; + } + return default; } - public bool SetRotation(uint playerId, quaternion value) + public bool SetRotation(uint playerId, float3 value) { - if (GetCharacterStruct(playerId, out RigidBodyEntityStruct rbes)) + ref var rbes = ref GetCharacterStruct(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(playerId, out RigidBodyEntityStruct rbes)) + ref var rbes = ref GetCharacterStruct(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(playerId, out RigidBodyEntityStruct rbes)) + ref var rbes = ref GetCharacterStruct(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(playerId, out RigidBodyEntityStruct rbes)) + ref var rbes = ref GetCharacterStruct(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(playerId, out RigidBodyEntityStruct rbes)) + ref var rbes = ref GetCharacterStruct(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(playerId, out RigidBodyEntityStruct rbes)) + ref var rbes = ref GetCharacterStruct(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(playerId, out RigidBodyEntityStruct rbes)) + ref var rbes = ref GetCharacterStruct(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(playerId, out CharacterHealthEntityStruct c)) + ref var c = ref GetCharacterStruct(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(playerId, out CharacterHealthEntityStruct c)) + ref var c = ref GetCharacterStruct(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(playerId, out CharacterHealthEntityStruct c)) + ref var c = ref GetCharacterStruct(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(playerId, out CharacterHealthEntityStruct c)) + ref var c = ref GetCharacterStruct(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(playerId, out CharacterHealthEntityStruct c)) + ref var c = ref GetCharacterStruct(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(playerId, out CharacterHealthEntityStruct ches)) + ref var ches = ref GetCharacterStruct(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(playerId, out CharacterLivesEntityComponent c)) + ref var c = ref GetCharacterStruct(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(playerId, out CharacterLivesEntityComponent c)) + ref var c = ref GetCharacterStruct(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(playerId, out CharacterLivesEntityComponent c)) + ref var c = ref GetCharacterStruct(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(playerId, out CharacterLivesEntityComponent c)) + ref var c = ref GetCharacterStruct(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(playerId, out CharacterLivesEntityComponent c)) + ref var c = ref GetCharacterStruct(playerId, out bool exists); + if (exists) { return c.gameOverScreen; } @@ -323,8 +331,9 @@ namespace GamecraftModdingAPI.Players } public int GetSelectedBlock(uint playerId) - { - if (GetCharacterStruct(playerId, out EquippedPartStruct c)) + { + ref var c = ref GetCharacterStruct(playerId, out bool exists); + if (exists) { return c.SelectedDBPartID; } @@ -333,7 +342,8 @@ namespace GamecraftModdingAPI.Players public byte GetSelectedColor(uint playerId) { - if (GetCharacterStruct(playerId, out EquippedColourStruct c)) + ref var c = ref GetCharacterStruct(playerId, out bool exists); + if (exists) { return c.indexInPalette; } @@ -349,7 +359,7 @@ namespace GamecraftModdingAPI.Players } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool GetCharacterStruct(uint playerId, out T s) where T : unmanaged, IEntityComponent + public ref T GetCharacterStruct(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(egid)) { - s = entitiesDB.QueryEntity(egid); - return true; + exists = true; + return ref entitiesDB.QueryEntity(egid); } } - s = default; - return false; + + exists = false; + T[] arr = new T[1]; + return ref arr[0]; //Return default value } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/GamecraftModdingAPI/SimBody.cs b/GamecraftModdingAPI/SimBody.cs index d9ba0c2..420a655 100644 --- a/GamecraftModdingAPI/SimBody.cs +++ b/GamecraftModdingAPI/SimBody.cs @@ -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 { /// /// A rigid body (like a cluster of connected blocks) during simulation. /// - public class SimBody + public class SimBody : IEquatable, IEquatable { 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(); + } + /// /// 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.