using System; using Unity.Mathematics; using RobocraftX.Common; using GamecraftModdingAPI.Players; namespace GamecraftModdingAPI { /// /// An in-game player character. Any Leo you see is a player. /// public class Player { // static functionality private static PlayerEngine playerEngine = new PlayerEngine(); /// /// Checks if the specified player exists. /// /// Whether the player exists. /// Player type. public static bool Exists(PlayerType player) { switch (player) { case PlayerType.Remote: return playerEngine.GetRemotePlayer() != uint.MaxValue; case PlayerType.Local: return playerEngine.GetLocalPlayer() != uint.MaxValue; } return false; } /// /// Checks if the specified player exists. /// /// Whether the player exists. /// The player's unique identifier. public static bool Exists(uint player) { return playerEngine.ExistsById(player); } /// /// Initializes a new instance of the class. /// /// The player's unique identifier. public Player(uint id) { this.Id = id; if (!Exists(id)) { throw new PlayerNotFoundException($"No player with id {id} exists"); } this.Type = playerEngine.GetLocalPlayer() == id ? PlayerType.Local : PlayerType.Remote; } /// /// Initializes a new instance of the class. /// /// The player type. Chooses the first available player matching the criteria. public Player(PlayerType player) { uint localId = playerEngine.GetLocalPlayer(); switch (player) { case PlayerType.Local: this.Id = playerEngine.GetLocalPlayer(); break; case PlayerType.Remote: this.Id = playerEngine.GetRemotePlayer(); break; } if (this.Id == uint.MaxValue) { throw new PlayerNotFoundException($"No player of {player} type exists"); } this.Type = player; } // object fields & properties /// /// The player's type. /// The player type is always relative to the current client, not the game host. /// /// The enumerated player type. public PlayerType Type { get; } /// /// The player's unique identifier. /// /// The identifier. public uint Id { get; private set; } /// /// The player's current position. /// /// The position. public float3 Position { get { return playerEngine.GetLocation(Id); } set { playerEngine.SetLocation(Id, value, false); } } /// /// The player's current rotation. /// /// The rotation. public quaternion Rotation { get { return playerEngine.GetRotation(Id); } set { playerEngine.SetRotation(Id, value); } } /// /// The player's current velocity. /// /// The velocity. public float3 Velocity { get { return playerEngine.GetLinearVelocity(Id); } set { playerEngine.SetLinearVelocity(Id, value); } } /// /// The player's current angular velocity. /// /// The angular velocity. public float3 AngularVelocity { get { return playerEngine.GetAngularVelocity(Id); } set { playerEngine.SetAngularVelocity(Id, value); } } /// /// The player's mass. /// /// The mass. public float Mass { get { return 1f / playerEngine.GetMass(Id).InverseMass; } // FIXME: Setting mass doesn't do anything /*set { playerEngine.SetInverseMass(Id, 1f / value); }*/ } private float _ping = -1f; /// /// The player's latest network ping time. /// /// The ping (s). public float Ping { get { float? temp = playerEngine.GetLastPingTime(Id, Type); if (temp.HasValue) { _ping = temp.Value; } return _ping; } } // object methods /// /// Teleport the player to the specified coordinates. /// /// The x coordinate. /// The y coordinate. /// The z coordinate. /// If set to true teleport relative to the player's current position. /// If set to true exit any seat the player is in. public void Teleport(float x, float y, float z, bool relative = true, bool exitSeat = true) { float3 location = new float3(x, y, z); if (relative) { location += playerEngine.GetLocation(Id); } playerEngine.SetLocation(Id, location, exitSeat: exitSeat); } /// /// Returns the block the player is currently looking at. /// /// The maximum distance from the player (default is the player's building reach) /// The block or null if not found public Block GetBlockLookedAt(float maxDistance = -1f) { var egid = playerEngine.GetThingLookedAt(Id, maxDistance); return egid.HasValue && egid.Value.groupID == CommonExclusiveGroups.OWNED_BLOCKS_GROUP ? new Block(egid.Value) : null; } /// /// Returns the rigid body the player is currently looking at during simulation. /// /// The maximum distance from the player (default is the player's building reach) /// The block or null if not found public SimBody GetSimBodyLookedAt(float maxDistance = -1f) { var egid = playerEngine.GetThingLookedAt(Id, maxDistance); return egid.HasValue && egid.Value.groupID == CommonExclusiveGroups.SIMULATION_BODIES_GROUP ? new SimBody(egid.Value) : null; } // internal methods public static void Init() { Utility.GameEngineManager.AddGameEngine(playerEngine); } } }