Integrate FlyCam class into Player
Using QueryEntityOptional directly with the player properties Character structs are camera structs in build mode The FlyCam rotation is not updated in build mode, only the camera is
This commit is contained in:
parent
220eb02a19
commit
5bfd0b7f10
8 changed files with 163 additions and 566 deletions
|
@ -1,132 +0,0 @@
|
|||
using RobocraftX.Physics;
|
||||
using Svelto.ECS;
|
||||
using Svelto.ECS.EntityStructs;
|
||||
using Techblox.FlyCam;
|
||||
using TechbloxModdingAPI.Blocks;
|
||||
using TechbloxModdingAPI.Players;
|
||||
using TechbloxModdingAPI.Utility;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TechbloxModdingAPI
|
||||
{
|
||||
public class FlyCam : EcsObjectBase
|
||||
{
|
||||
private static FlyCamEngine Engine = new FlyCamEngine();
|
||||
|
||||
public override EGID Id { get; }
|
||||
|
||||
public FlyCam(uint id) => Id = new EGID(id, Techblox.FlyCam.FlyCam.Group);
|
||||
|
||||
/// <summary>
|
||||
/// The local player's camera.
|
||||
/// </summary>
|
||||
public static FlyCam LocalCamera => new FlyCam(Player.LocalPlayer.Id);
|
||||
|
||||
/// <summary>
|
||||
/// The current position of the camera.
|
||||
/// </summary>
|
||||
public float3 Position
|
||||
{
|
||||
get => Engine.GetComponent<PositionEntityStruct>(this).position;
|
||||
set
|
||||
{
|
||||
Engine.GetComponent<PositionEntityStruct>(this).position = value;
|
||||
Engine.GetComponent<RigidBodyEntityStruct>(this).position = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The current rotation of the camera.
|
||||
/// </summary>
|
||||
public float3 Rotation
|
||||
{
|
||||
get => ((Quaternion) Engine.GetComponent<RotationEntityStruct>(this).rotation).eulerAngles;
|
||||
set
|
||||
{
|
||||
Engine.GetComponent<RotationEntityStruct>(this).rotation = Quaternion.Euler(value);
|
||||
Engine.GetComponent<RigidBodyEntityStruct>(this).rotation = Quaternion.Euler(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The current direction the camera is moving.
|
||||
/// </summary>
|
||||
public float3 MovementDirection
|
||||
{
|
||||
get => Engine.GetComponent<FlyCamMovementComponent>(this).movementDirection;
|
||||
set => Engine.GetComponent<FlyCamMovementComponent>(this).movementDirection = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the camera (player) is sprinting.
|
||||
/// </summary>
|
||||
public bool Sprinting
|
||||
{
|
||||
get => Engine.GetComponent<FlyCamMovementComponent>(this).sprinting;
|
||||
set => Engine.GetComponent<FlyCamMovementComponent>(this).sprinting = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The speed setting of the camera.
|
||||
/// </summary>
|
||||
public float Speed
|
||||
{
|
||||
get => Engine.GetComponent<FlyCamMovementSettingsComponent>(this).speed;
|
||||
set => Engine.GetComponent<FlyCamMovementSettingsComponent>(this).speed = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The multiplier setting to use when sprinting.
|
||||
/// </summary>
|
||||
public float SpeedSprintMultiplier
|
||||
{
|
||||
get => Engine.GetComponent<FlyCamMovementSettingsComponent>(this).speedSprintMultiplier;
|
||||
set => Engine.GetComponent<FlyCamMovementSettingsComponent>(this).speedSprintMultiplier = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The acceleration setting of the camera.
|
||||
/// </summary>
|
||||
public float Acceleration
|
||||
{
|
||||
get => Engine.GetComponent<FlyCamMovementSettingsComponent>(this).acceleration;
|
||||
set => Engine.GetComponent<FlyCamMovementSettingsComponent>(this).acceleration = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The current velocity of the camera.
|
||||
/// </summary>
|
||||
public float3 Velocity
|
||||
{
|
||||
get => Engine.GetComponent<RigidBodyEntityStruct>(this).velocity;
|
||||
set => Engine.GetComponent<RigidBodyEntityStruct>(this).velocity = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The current angular velocity of the camera.
|
||||
/// </summary>
|
||||
public float3 AngularVelocity
|
||||
{
|
||||
get => Engine.GetComponent<RigidBodyEntityStruct>(this).angularVelocity;
|
||||
set => Engine.GetComponent<RigidBodyEntityStruct>(this).angularVelocity = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The player's selected block ID in their hand.
|
||||
/// </summary>
|
||||
/// <value>The selected block.</value>
|
||||
public BlockIDs SelectedBlock => (BlockIDs)Engine.GetSelectedBlock(this);
|
||||
|
||||
/// <summary>
|
||||
/// The player's selected block color in their hand.
|
||||
/// </summary>
|
||||
/// <value>The selected block's color.</value>
|
||||
public BlockColor SelectedColor => new BlockColor(Engine.GetSelectedColor(this));
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
GameEngineManager.AddGameEngine(Engine);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -71,7 +71,6 @@ namespace TechbloxModdingAPI
|
|||
Input.FakeInput.Init();
|
||||
// init object-oriented classes
|
||||
Player.Init();
|
||||
FlyCam.Init();
|
||||
Block.Init();
|
||||
BlockGroup.Init();
|
||||
Wire.Init();
|
||||
|
|
51
TechbloxModdingAPI/Player.FlyCamSettings.cs
Normal file
51
TechbloxModdingAPI/Player.FlyCamSettings.cs
Normal file
|
@ -0,0 +1,51 @@
|
|||
using RobocraftX.Physics;
|
||||
using Svelto.ECS;
|
||||
using Svelto.ECS.EntityStructs;
|
||||
using Techblox.FlyCam;
|
||||
using TechbloxModdingAPI.Blocks;
|
||||
using TechbloxModdingAPI.Players;
|
||||
using TechbloxModdingAPI.Utility;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TechbloxModdingAPI
|
||||
{
|
||||
public partial class Player
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the camera (player) is sprinting.
|
||||
/// </summary>
|
||||
public bool Sprinting
|
||||
{
|
||||
get => playerEngine.GetCharacterStruct<FlyCamMovementComponent>(Id).Get().sprinting;
|
||||
set => playerEngine.GetCharacterStruct<FlyCamMovementComponent>(Id).Get().sprinting = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The speed setting of the camera.
|
||||
/// </summary>
|
||||
public float Speed
|
||||
{
|
||||
get => playerEngine.GetCharacterStruct<FlyCamMovementSettingsComponent>(Id).Get().speed;
|
||||
set => playerEngine.GetCharacterStruct<FlyCamMovementSettingsComponent>(Id).Get().speed = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The multiplier setting to use when sprinting.
|
||||
/// </summary>
|
||||
public float SpeedSprintMultiplier
|
||||
{
|
||||
get => playerEngine.GetCharacterStruct<FlyCamMovementSettingsComponent>(Id).Get().speedSprintMultiplier;
|
||||
set => playerEngine.GetCharacterStruct<FlyCamMovementSettingsComponent>(Id).Get().speedSprintMultiplier = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The acceleration setting of the camera.
|
||||
/// </summary>
|
||||
public float Acceleration
|
||||
{
|
||||
get => playerEngine.GetCharacterStruct<FlyCamMovementSettingsComponent>(Id).Get().acceleration;
|
||||
set => playerEngine.GetCharacterStruct<FlyCamMovementSettingsComponent>(Id).Get().acceleration = value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +1,23 @@
|
|||
using System;
|
||||
using RobocraftX.Character;
|
||||
using Unity.Mathematics;
|
||||
using RobocraftX.Common;
|
||||
using RobocraftX.Common.Players;
|
||||
using RobocraftX.Physics;
|
||||
using Svelto.ECS;
|
||||
using Techblox.Camera;
|
||||
using Techblox.FlyCam;
|
||||
using TechbloxModdingAPI.Blocks;
|
||||
using TechbloxModdingAPI.Players;
|
||||
using TechbloxModdingAPI.Utility;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TechbloxModdingAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// An in-game player character. Any Leo you see is a player.
|
||||
/// </summary>
|
||||
public class Player : IEquatable<Player>, IEquatable<EGID>
|
||||
public partial class Player : IEquatable<Player>, IEquatable<EGID>
|
||||
{
|
||||
// static functionality
|
||||
private static PlayerEngine playerEngine = new PlayerEngine();
|
||||
|
@ -123,15 +129,8 @@ namespace TechbloxModdingAPI
|
|||
/// <value>The position.</value>
|
||||
public float3 Position
|
||||
{
|
||||
get
|
||||
{
|
||||
return playerEngine.GetLocation(Id);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
playerEngine.SetLocation(Id, value, false);
|
||||
}
|
||||
get => playerEngine.GetCharacterStruct<RigidBodyEntityStruct>(Id).Get().position;
|
||||
set => playerEngine.SetLocation(Id, value, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -140,15 +139,12 @@ namespace TechbloxModdingAPI
|
|||
/// <value>The rotation.</value>
|
||||
public float3 Rotation
|
||||
{
|
||||
get
|
||||
{
|
||||
return playerEngine.GetRotation(Id);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
playerEngine.SetRotation(Id, value);
|
||||
}
|
||||
get => ((Quaternion) (GameState.IsBuildMode()
|
||||
? playerEngine.GetCameraStruct<CharacterCameraEntityStruct>(Id).Get().rotation
|
||||
: playerEngine.GetCharacterStruct<RigidBodyEntityStruct>(Id).Get().rotation)).eulerAngles;
|
||||
set => _ = GameState.IsBuildMode()
|
||||
? playerEngine.GetCameraStruct<CharacterCameraEntityStruct>(Id).Get().rotation = quaternion.Euler(value)
|
||||
: playerEngine.GetCharacterStruct<RigidBodyEntityStruct>(Id).Get().rotation = quaternion.Euler(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -157,15 +153,8 @@ namespace TechbloxModdingAPI
|
|||
/// <value>The velocity.</value>
|
||||
public float3 Velocity
|
||||
{
|
||||
get
|
||||
{
|
||||
return playerEngine.GetLinearVelocity(Id);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
playerEngine.SetLinearVelocity(Id, value);
|
||||
}
|
||||
get => playerEngine.GetCharacterStruct<RigidBodyEntityStruct>(Id).Get().velocity;
|
||||
set => playerEngine.GetCharacterStruct<RigidBodyEntityStruct>(Id).Get().velocity = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -174,34 +163,16 @@ namespace TechbloxModdingAPI
|
|||
/// <value>The angular velocity.</value>
|
||||
public float3 AngularVelocity
|
||||
{
|
||||
get
|
||||
{
|
||||
return playerEngine.GetAngularVelocity(Id);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
playerEngine.SetAngularVelocity(Id, value);
|
||||
}
|
||||
get => playerEngine.GetCharacterStruct<RigidBodyEntityStruct>(Id).Get().angularVelocity;
|
||||
set => playerEngine.GetCharacterStruct<RigidBodyEntityStruct>(Id).Get().angularVelocity = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The player's mass.
|
||||
/// </summary>
|
||||
/// <value>The mass.</value>
|
||||
public float Mass
|
||||
{
|
||||
get
|
||||
{
|
||||
return 1f / playerEngine.GetMass(Id).InverseMass;
|
||||
}
|
||||
|
||||
// FIXME: Setting mass doesn't do anything
|
||||
/*set
|
||||
{
|
||||
playerEngine.SetInverseMass(Id, 1f / value);
|
||||
}*/
|
||||
}
|
||||
public float Mass =>
|
||||
1f / playerEngine.GetCharacterStruct<RigidBodyEntityStruct>(Id).Get().physicsMass.InverseMass;
|
||||
|
||||
private float _ping = -1f;
|
||||
|
||||
|
@ -213,10 +184,10 @@ namespace TechbloxModdingAPI
|
|||
{
|
||||
get
|
||||
{
|
||||
float? temp = playerEngine.GetLastPingTime(Id, Type);
|
||||
if (temp.HasValue)
|
||||
var opt = playerEngine.GetPlayerStruct<PlayerNetworkStatsEntityStruct>(Id, Type);
|
||||
if (opt)
|
||||
{
|
||||
_ping = temp.Value;
|
||||
_ping = opt.Get().lastPingTimeSinceLevelLoad ?? _ping;
|
||||
}
|
||||
return _ping;
|
||||
}
|
||||
|
@ -228,12 +199,13 @@ namespace TechbloxModdingAPI
|
|||
/// <value>The initial health.</value>
|
||||
public float InitialHealth
|
||||
{
|
||||
get => playerEngine.GetInitialHealth(Id);
|
||||
|
||||
set
|
||||
get
|
||||
{
|
||||
playerEngine.SetInitialHealth(Id, value);
|
||||
var opt = playerEngine.GetCharacterStruct<CharacterHealthEntityStruct>(Id);
|
||||
return opt ? opt.Get().initialHealth : -1f;
|
||||
}
|
||||
|
||||
set => playerEngine.GetCharacterStruct<CharacterHealthEntityStruct>(Id).Get().initialHealth = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -242,12 +214,13 @@ namespace TechbloxModdingAPI
|
|||
/// <value>The current health.</value>
|
||||
public float CurrentHealth
|
||||
{
|
||||
get => playerEngine.GetCurrentHealth(Id);
|
||||
|
||||
set
|
||||
get
|
||||
{
|
||||
playerEngine.DamagePlayer(Id, CurrentHealth - value);
|
||||
var opt = playerEngine.GetCharacterStruct<CharacterHealthEntityStruct>(Id);
|
||||
return opt ? opt.Get().currentHealth : -1f;
|
||||
}
|
||||
|
||||
set => playerEngine.GetCharacterStruct<CharacterHealthEntityStruct>(Id).Get().currentHealth = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -256,11 +229,17 @@ namespace TechbloxModdingAPI
|
|||
/// <value><c>true</c> if damageable; otherwise, <c>false</c>.</value>
|
||||
public bool Damageable
|
||||
{
|
||||
get => playerEngine.GetDamageable(Id);
|
||||
get
|
||||
{
|
||||
var opt = playerEngine.GetCharacterStruct<CharacterHealthEntityStruct>(Id);
|
||||
return opt.Get().canTakeDamageStat;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
playerEngine.SetDamageable(Id, value);
|
||||
ref var healthStruct = ref playerEngine.GetCharacterStruct<CharacterHealthEntityStruct>(Id).Get();
|
||||
healthStruct.canTakeDamage = value;
|
||||
healthStruct.canTakeDamageStat = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -270,9 +249,13 @@ namespace TechbloxModdingAPI
|
|||
/// <value>The initial lives.</value>
|
||||
public uint InitialLives
|
||||
{
|
||||
get => playerEngine.GetInitialLives(Id);
|
||||
get
|
||||
{
|
||||
var opt = playerEngine.GetCharacterStruct<CharacterLivesEntityComponent>(Id);
|
||||
return opt ? opt.Get().initialLives : uint.MaxValue;
|
||||
}
|
||||
|
||||
set => playerEngine.SetInitialLives(Id, value);
|
||||
set => playerEngine.GetCharacterStruct<CharacterLivesEntityComponent>(Id).Get().initialLives = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -281,19 +264,23 @@ namespace TechbloxModdingAPI
|
|||
/// <value>The current lives.</value>
|
||||
public uint CurrentLives
|
||||
{
|
||||
get => playerEngine.GetCurrentLives(Id);
|
||||
|
||||
set => playerEngine.SetCurrentLives(Id, value);
|
||||
get
|
||||
{
|
||||
var opt = playerEngine.GetCharacterStruct<CharacterLivesEntityComponent>(Id);
|
||||
return opt ? opt.Get().currentLives : uint.MaxValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
set => playerEngine.GetCharacterStruct<CharacterLivesEntityComponent>(Id).Get().currentLives = value;
|
||||
}
|
||||
|
||||
/*/// <summary>
|
||||
/// Whether the Game Over screen is displayed for the player.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if game over; otherwise, <c>false</c>.</value>
|
||||
public bool GameOver
|
||||
{
|
||||
get => playerEngine.GetGameOverScreen(Id);
|
||||
}
|
||||
}*/
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player is dead.
|
||||
|
@ -313,7 +300,8 @@ namespace TechbloxModdingAPI
|
|||
{
|
||||
get
|
||||
{
|
||||
return BuildCamera.SelectedBlock;
|
||||
var optstruct = playerEngine.GetCharacterStruct<EquippedPartStruct>(Id);
|
||||
return optstruct ? (BlockIDs) optstruct.Get().SelectedDBPartID : BlockIDs.Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -325,7 +313,8 @@ namespace TechbloxModdingAPI
|
|||
{
|
||||
get
|
||||
{
|
||||
return BuildCamera.SelectedColor;
|
||||
var optstruct = playerEngine.GetCharacterStruct<EquippedColourStruct>(Id);
|
||||
return optstruct ? new BlockColor(optstruct.Get().indexInPalette) : BlockColors.Default;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,7 +326,8 @@ namespace TechbloxModdingAPI
|
|||
{
|
||||
get
|
||||
{
|
||||
return new BlockColor(playerEngine.GetSelectedColor(Id));
|
||||
var optstruct = playerEngine.GetCharacterStruct<EquippedColourStruct>(Id);
|
||||
return optstruct ? new BlockColor(optstruct.Get().indexInPalette) : BlockColors.Default;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -346,9 +336,11 @@ namespace TechbloxModdingAPI
|
|||
/// </summary>
|
||||
public Blueprint SelectedBlueprint
|
||||
{
|
||||
get => playerEngine.GetPlayerStruct(Id, out LocalBlueprintInputStruct lbis)
|
||||
? new Blueprint(lbis.selectedBlueprintId)
|
||||
: null;
|
||||
get
|
||||
{
|
||||
var lbiso = playerEngine.GetPlayerStruct<LocalBlueprintInputStruct>(Id, Type);
|
||||
return lbiso ? new Blueprint(lbiso.Get().selectedBlueprintId) : null;
|
||||
}
|
||||
set => BlockGroup._engine.SelectBlueprint(value?.Id ?? uint.MaxValue);
|
||||
}
|
||||
|
||||
|
@ -356,7 +348,7 @@ namespace TechbloxModdingAPI
|
|||
/// The player's mode in time stopped mode, determining what they place.
|
||||
/// </summary>
|
||||
public PlayerBuildingMode BuildingMode => (PlayerBuildingMode) playerEngine
|
||||
.GetCharacterStruct<PlayerInputTimeStoppedContextStruct>(Id, out _).timeStoppedContext;
|
||||
.GetCharacterStruct<PlayerInputTimeStoppedContextStruct>(Id).Get().timeStoppedContext;
|
||||
|
||||
// object methods
|
||||
|
||||
|
@ -373,7 +365,7 @@ namespace TechbloxModdingAPI
|
|||
float3 location = new float3(x, y, z);
|
||||
if (relative)
|
||||
{
|
||||
location += playerEngine.GetLocation(Id);
|
||||
location += Position;
|
||||
}
|
||||
playerEngine.SetLocation(Id, location, exitSeat: exitSeat);
|
||||
}
|
||||
|
@ -395,7 +387,7 @@ namespace TechbloxModdingAPI
|
|||
/// Returns the rigid body the player is currently looking at during simulation.
|
||||
/// </summary>
|
||||
/// <param name="maxDistance">The maximum distance from the player (default is the player's building reach)</param>
|
||||
/// <returns>The block or null if not found</returns>
|
||||
/// <returns>The body or null if not found</returns>
|
||||
public SimBody GetSimBodyLookedAt(float maxDistance = -1f)
|
||||
{
|
||||
var egid = playerEngine.GetThingLookedAt(Id, maxDistance);
|
||||
|
@ -413,11 +405,6 @@ namespace TechbloxModdingAPI
|
|||
return playerEngine.GetSelectedBlocks(Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The camera of this player used when building.
|
||||
/// </summary>
|
||||
public FlyCam BuildCamera => new FlyCam(Id);
|
||||
|
||||
public bool Equals(Player other)
|
||||
{
|
||||
if (ReferenceEquals(null, other)) return false;
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
using Svelto.ECS;
|
||||
using Techblox.FlyCam;
|
||||
using TechbloxModdingAPI.Engines;
|
||||
using TechbloxModdingAPI.Utility;
|
||||
|
||||
namespace TechbloxModdingAPI.Players
|
||||
{
|
||||
public class FlyCamEngine : IApiEngine
|
||||
{
|
||||
public void Ready()
|
||||
{
|
||||
}
|
||||
|
||||
public EntitiesDB entitiesDB { get; set; }
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name => "TechbloxModdingAPIFlyCamEngine";
|
||||
public bool isRemovable => false;
|
||||
|
||||
public ref T GetComponent<T>(FlyCam cam) where T : unmanaged, IEntityComponent
|
||||
{
|
||||
return ref entitiesDB.QueryEntityOrDefault<T>(cam);
|
||||
}
|
||||
|
||||
public ushort GetSelectedBlock(FlyCam cam)
|
||||
{
|
||||
var oc = entitiesDB.QueryEntityOptional<EquippedPartStruct>(cam);
|
||||
return oc ? (ushort) oc.Get().SelectedDBPartID : ushort.MaxValue;
|
||||
}
|
||||
|
||||
public byte GetSelectedColor(FlyCam cam)
|
||||
{
|
||||
var oc = entitiesDB.QueryEntityOptional<EquippedColourStruct>(cam);
|
||||
return oc ? oc.Get().indexInPalette : (byte) 255;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
BlockMode,
|
||||
ColourMode,
|
||||
ConfigMode,
|
||||
BlueprintMode
|
||||
BlueprintMode,
|
||||
MaterialMode
|
||||
}
|
||||
}
|
|
@ -21,6 +21,7 @@ using HarmonyLib;
|
|||
using RobocraftX.Common;
|
||||
using Svelto.ECS.DataStructures;
|
||||
using TechbloxModdingAPI.Engines;
|
||||
using TechbloxModdingAPI.Utility;
|
||||
|
||||
namespace TechbloxModdingAPI.Players
|
||||
{
|
||||
|
@ -98,17 +99,6 @@ namespace TechbloxModdingAPI.Players
|
|||
|| entitiesDB.Exists<PlayerIDStruct>(playerId, PlayersExclusiveGroups.RemotePlayers);
|
||||
}
|
||||
|
||||
public float3 GetLocation(uint playerId)
|
||||
{
|
||||
if (entitiesDB == null) return float3.zero;
|
||||
ref var rbes = ref GetCharacterStruct<RigidBodyEntityStruct>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
return rbes.position;
|
||||
}
|
||||
return float3.zero;
|
||||
}
|
||||
|
||||
public bool SetLocation(uint playerId, float3 location, bool exitSeat = true)
|
||||
{
|
||||
if (entitiesDB == null) return false;
|
||||
|
@ -131,233 +121,6 @@ namespace TechbloxModdingAPI.Players
|
|||
return false;
|
||||
}
|
||||
|
||||
public float3 GetRotation(uint playerId)
|
||||
{
|
||||
if (entitiesDB == null) return float3.zero;
|
||||
ref var rbes = ref GetCharacterStruct<RigidBodyEntityStruct>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
return ((Quaternion) rbes.rotation).eulerAngles;
|
||||
}
|
||||
return default(float3);
|
||||
}
|
||||
|
||||
public bool SetRotation(uint playerId, float3 value)
|
||||
{
|
||||
if (entitiesDB == null) return false;
|
||||
ref var rbes = ref GetCharacterStruct<RigidBodyEntityStruct>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
Quaternion q = rbes.rotation;
|
||||
q.eulerAngles = value;
|
||||
rbes.rotation = q;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public float3 GetLinearVelocity(uint playerId)
|
||||
{
|
||||
if (entitiesDB == null) return float3.zero;
|
||||
ref var rbes = ref GetCharacterStruct<RigidBodyEntityStruct>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
return rbes.velocity;
|
||||
}
|
||||
return float3.zero;
|
||||
}
|
||||
|
||||
public bool SetLinearVelocity(uint playerId, float3 value)
|
||||
{
|
||||
if (entitiesDB == null) return false;
|
||||
ref var rbes = ref GetCharacterStruct<RigidBodyEntityStruct>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
rbes.velocity = value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public float3 GetAngularVelocity(uint playerId)
|
||||
{
|
||||
if (entitiesDB == null) return float3.zero;
|
||||
ref var rbes = ref GetCharacterStruct<RigidBodyEntityStruct>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
return rbes.angularVelocity;
|
||||
}
|
||||
return float3.zero;
|
||||
}
|
||||
|
||||
public bool SetAngularVelocity(uint playerId, float3 value)
|
||||
{
|
||||
if (entitiesDB == null) return false;
|
||||
ref var rbes = ref GetCharacterStruct<RigidBodyEntityStruct>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
rbes.angularVelocity = value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public PhysicsMass GetMass(uint playerId)
|
||||
{
|
||||
if (entitiesDB == null) return default(PhysicsMass);
|
||||
ref var rbes = ref GetCharacterStruct<RigidBodyEntityStruct>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
return rbes.physicsMass;
|
||||
}
|
||||
return default(PhysicsMass);
|
||||
}
|
||||
|
||||
public bool SetInverseMass(uint playerId, float inverseMass)
|
||||
{
|
||||
if (entitiesDB == null) return false;
|
||||
ref var rbes = ref GetCharacterStruct<RigidBodyEntityStruct>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
rbes.physicsMass.InverseInertia = inverseMass;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public float? GetLastPingTime(uint playerId, PlayerType type)
|
||||
{
|
||||
if (entitiesDB == null) return null;
|
||||
EGID egid = new EGID(playerId, PlayerGroupFromEnum(type));
|
||||
if (entitiesDB.Exists<PlayerNetworkStatsEntityStruct>(egid))
|
||||
{
|
||||
//return entitiesDB.QueryEntity<PlayerNetworkStatsEntityStruct>(egid).lastPingTimeSinceLevelLoad; - TODO
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public float GetInitialHealth(uint playerId)
|
||||
{
|
||||
if (entitiesDB == null) return 0;
|
||||
ref var c = ref GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
return c.initialHealth;
|
||||
}
|
||||
return -1f;
|
||||
}
|
||||
|
||||
public bool SetInitialHealth(uint playerId, float val)
|
||||
{
|
||||
if (entitiesDB == null) return false;
|
||||
ref var c = ref GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
c.initialHealth = val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public float GetCurrentHealth(uint playerId)
|
||||
{
|
||||
if (entitiesDB == null) return 0;
|
||||
ref var c = ref GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
return c.currentHealth;
|
||||
}
|
||||
return -1f;
|
||||
}
|
||||
|
||||
public bool SetCurrentHealth(uint playerId, float val)
|
||||
{
|
||||
if (entitiesDB == null) return false;
|
||||
ref var c = ref GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
c.currentHealth = val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool DamagePlayer(uint playerId, float amount)
|
||||
{
|
||||
if (entitiesDB == null) return false;
|
||||
return SetCurrentHealth(playerId, GetCurrentHealth(playerId) - amount);
|
||||
}
|
||||
|
||||
public bool GetDamageable(uint playerId)
|
||||
{
|
||||
if (entitiesDB == null) return false;
|
||||
ref var c = ref GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
return c.canTakeDamageStat;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool SetDamageable(uint playerId, bool val)
|
||||
{
|
||||
if (entitiesDB == null) return false;
|
||||
ref var ches = ref GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
ches.canTakeDamage = val;
|
||||
ches.canTakeDamage = val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public uint GetInitialLives(uint playerId)
|
||||
{
|
||||
if (entitiesDB == null) return 0;
|
||||
ref var c = ref GetCharacterStruct<CharacterLivesEntityComponent>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
return c.initialLives;
|
||||
}
|
||||
return uint.MaxValue;
|
||||
}
|
||||
|
||||
public bool SetInitialLives(uint playerId, uint val)
|
||||
{
|
||||
if (entitiesDB == null) return false;
|
||||
ref var c = ref GetCharacterStruct<CharacterLivesEntityComponent>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
c.initialLives = val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public uint GetCurrentLives(uint playerId)
|
||||
{
|
||||
if (entitiesDB == null) return 0;
|
||||
ref var c = ref GetCharacterStruct<CharacterLivesEntityComponent>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
return c.currentLives;
|
||||
}
|
||||
return uint.MaxValue;
|
||||
}
|
||||
|
||||
public bool SetCurrentLives(uint playerId, uint val)
|
||||
{
|
||||
if (entitiesDB == null) return false;
|
||||
ref var c = ref GetCharacterStruct<CharacterLivesEntityComponent>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
c.currentLives = val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool GetGameOverScreen(uint playerId)
|
||||
{
|
||||
if (entitiesDB == null) return false;
|
||||
|
@ -372,78 +135,44 @@ namespace TechbloxModdingAPI.Players
|
|||
return entitiesDB.Exists<RigidBodyEntityStruct>(playerId, CharacterExclusiveGroups.DeadCharacters);
|
||||
}
|
||||
|
||||
public int GetSelectedBlock(uint playerId)
|
||||
{
|
||||
if (entitiesDB == null) return 0;
|
||||
ref var c = ref GetCharacterStruct<EquippedPartStruct>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
return c.SelectedDBPartID;
|
||||
}
|
||||
return ushort.MaxValue;
|
||||
}
|
||||
|
||||
public byte GetSelectedColor(uint playerId)
|
||||
{
|
||||
if (entitiesDB == null) return 0;
|
||||
ref var c = ref GetCharacterStruct<EquippedColourStruct>(playerId, out bool exists);
|
||||
if (exists)
|
||||
{
|
||||
return c.indexInPalette;
|
||||
}
|
||||
return 255;
|
||||
}
|
||||
|
||||
// reusable methods
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private ExclusiveGroup PlayerGroupFromEnum(PlayerType type)
|
||||
public OptionalRef<T> GetCharacterStruct<T>(uint playerId) where T : unmanaged, IEntityComponent
|
||||
{
|
||||
return type == PlayerType.Local ? PlayersExclusiveGroups.LocalPlayers : PlayersExclusiveGroups.RemotePlayers;
|
||||
}
|
||||
if (GameState.IsBuildMode())
|
||||
return entitiesDB.QueryEntityOptional<T>(new EGID(playerId, Techblox.FlyCam.FlyCam.Group));
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ref T GetCharacterStruct<T>(uint playerId, out bool exists) where T : unmanaged, IEntityComponent
|
||||
{
|
||||
var characterGroups = CharacterExclusiveGroups.AllCharacters;
|
||||
for (int i = 0; i < characterGroups.count; i++)
|
||||
{
|
||||
EGID egid = new EGID(playerId, characterGroups[i]);
|
||||
if (entitiesDB.Exists<T>(egid))
|
||||
{
|
||||
exists = true;
|
||||
return ref entitiesDB.QueryEntity<T>(egid);
|
||||
}
|
||||
var opt = entitiesDB.QueryEntityOptional<T>(egid);
|
||||
if (opt.Exists)
|
||||
return opt;
|
||||
}
|
||||
|
||||
exists = false;
|
||||
T[] arr = new T[1];
|
||||
return ref arr[0]; //Return default value
|
||||
return new OptionalRef<T>();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool GetPlayerStruct<T>(uint playerId, out T s) where T : unmanaged, IEntityComponent
|
||||
public OptionalRef<T> GetPlayerStruct<T>(uint playerId, PlayerType type) where T : unmanaged, IEntityComponent
|
||||
{
|
||||
var playerGroups = PlayersExclusiveGroups.AllPlayers;
|
||||
for (int i = 0; i < playerGroups.count; i++)
|
||||
{
|
||||
EGID egid = new EGID(playerId, playerGroups[i]);
|
||||
if (entitiesDB.Exists<T>(egid))
|
||||
{
|
||||
s = entitiesDB.QueryEntity<T>(egid);
|
||||
return true;
|
||||
var playerGroup = type == PlayerType.Local ? PlayersExclusiveGroups.LocalPlayers : PlayersExclusiveGroups.RemotePlayers;
|
||||
EGID egid = new EGID(playerId, playerGroup);
|
||||
return entitiesDB.QueryEntityOptional<T>(egid);
|
||||
}
|
||||
}
|
||||
s = default;
|
||||
return false;
|
||||
|
||||
public OptionalRef<T> GetCameraStruct<T>(uint playerId) where T : unmanaged, IEntityComponent
|
||||
{
|
||||
return entitiesDB.QueryEntityOptional<T>(new EGID(playerId, CameraExclusiveGroups.CameraGroup));
|
||||
}
|
||||
|
||||
public EGID GetThingLookedAt(uint playerId, float maxDistance = -1f)
|
||||
{
|
||||
if (!entitiesDB.TryQueryMappedEntities<CharacterCameraRayCastEntityStruct>(
|
||||
CameraExclusiveGroups.CameraGroup, out var mapper))
|
||||
return EGID.Empty;
|
||||
mapper.TryGetEntity(playerId, out CharacterCameraRayCastEntityStruct rayCast);
|
||||
var opt = GetCameraStruct<CharacterCameraRayCastEntityStruct>(playerId);
|
||||
if (!opt) return EGID.Empty;
|
||||
CharacterCameraRayCastEntityStruct rayCast = opt;
|
||||
float distance = maxDistance < 0
|
||||
? GhostBlockUtils.GetBuildInteractionDistance(entitiesDB, rayCast,
|
||||
GhostBlockUtils.GhostCastMethod.GhostCastProportionalToBlockSize)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
<PackageProjectUrl>https://git.exmods.org/modtainers/GamecraftModdingAPI</PackageProjectUrl>
|
||||
<NeutralLanguage>en-CA</NeutralLanguage>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>8</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
</PropertyGroup>
|
||||
|
|
Loading…
Reference in a new issue