Browse Source

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
tags/v2.0.0
NorbiPeti 2 years ago
parent
commit
5bfd0b7f10
8 changed files with 163 additions and 566 deletions
  1. +0
    -132
      TechbloxModdingAPI/FlyCam.cs
  2. +0
    -1
      TechbloxModdingAPI/Main.cs
  3. +51
    -0
      TechbloxModdingAPI/Player.FlyCamSettings.cs
  4. +85
    -98
      TechbloxModdingAPI/Player.cs
  5. +0
    -39
      TechbloxModdingAPI/Players/FlyCamEngine.cs
  6. +2
    -1
      TechbloxModdingAPI/Players/PlayerBuildingMode.cs
  7. +24
    -295
      TechbloxModdingAPI/Players/PlayerEngine.cs
  8. +1
    -0
      TechbloxModdingAPI/TechbloxModdingAPI.csproj

+ 0
- 132
TechbloxModdingAPI/FlyCam.cs View File

@@ -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);
}
}
}

+ 0
- 1
TechbloxModdingAPI/Main.cs View File

@@ -71,7 +71,6 @@ namespace TechbloxModdingAPI
Input.FakeInput.Init();
// init object-oriented classes
Player.Init();
FlyCam.Init();
Block.Init();
BlockGroup.Init();
Wire.Init();


+ 51
- 0
TechbloxModdingAPI/Player.FlyCamSettings.cs View 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;
}
}
}

+ 85
- 98
TechbloxModdingAPI/Player.cs View File

@@ -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,50 +129,33 @@ 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>
/// The player's current rotation.
/// </summary>
/// <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>
/// The player's current velocity.
/// </summary>
/// <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>
/// The player's current angular velocity.
@@ -174,36 +163,18 @@ 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;
private float _ping = -1f;

/// <summary>
/// The player's latest network ping time.
@@ -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;
}
@@ -227,14 +198,15 @@ namespace TechbloxModdingAPI
/// </summary>
/// <value>The initial health.</value>
public float InitialHealth
{
get => playerEngine.GetInitialHealth(Id);
{
get
{
var opt = playerEngine.GetCharacterStruct<CharacterHealthEntityStruct>(Id);
return opt ? opt.Get().initialHealth : -1f;
}

set
{
playerEngine.SetInitialHealth(Id, value);
}
}
set => playerEngine.GetCharacterStruct<CharacterHealthEntityStruct>(Id).Get().initialHealth = value;
}

/// <summary>
/// The player's current health in Simulation (aka Time Running) mode.
@@ -242,12 +214,13 @@ namespace TechbloxModdingAPI
/// <value>The current health.</value>
public float CurrentHealth
{
get => playerEngine.GetCurrentHealth(Id);
get
{
var opt = playerEngine.GetCharacterStruct<CharacterHealthEntityStruct>(Id);
return opt ? opt.Get().currentHealth : -1f;
}

set
{
playerEngine.DamagePlayer(Id, CurrentHealth - value);
}
set => playerEngine.GetCharacterStruct<CharacterHealthEntityStruct>(Id).Get().currentHealth = value;
}

/// <summary>
@@ -255,14 +228,20 @@ namespace TechbloxModdingAPI
/// </summary>
/// <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);
}
}
set
{
ref var healthStruct = ref playerEngine.GetCharacterStruct<CharacterHealthEntityStruct>(Id).Get();
healthStruct.canTakeDamage = value;
healthStruct.canTakeDamageStat = value;
}
}

/// <summary>
/// The player's lives when initially entering Simulation (aka Time Running) mode.
@@ -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);
get
{
var opt = playerEngine.GetCharacterStruct<CharacterLivesEntityComponent>(Id);
return opt ? opt.Get().currentLives : uint.MaxValue;
}

set => playerEngine.SetCurrentLives(Id, value);
set => playerEngine.GetCharacterStruct<CharacterLivesEntityComponent>(Id).Get().currentLives = value;
}

/// <summary>
/*/// <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;


+ 0
- 39
TechbloxModdingAPI/Players/FlyCamEngine.cs View File

@@ -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;
}
}
}

+ 2
- 1
TechbloxModdingAPI/Players/PlayerBuildingMode.cs View File

@@ -5,6 +5,7 @@
BlockMode,
ColourMode,
ConfigMode,
BlueprintMode
BlueprintMode,
MaterialMode
}
}

+ 24
- 295
TechbloxModdingAPI/Players/PlayerEngine.cs View File

@@ -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));
var characterGroups = CharacterExclusiveGroups.AllCharacters;
for (int i = 0; i < characterGroups.count; i++)
{
EGID egid = new EGID(playerId, characterGroups[i]);
var opt = entitiesDB.QueryEntityOptional<T>(egid);
if (opt.Exists)
return opt;
}

return new OptionalRef<T>();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref T GetCharacterStruct<T>(uint playerId, out bool exists) where T : unmanaged, IEntityComponent
public OptionalRef<T> GetPlayerStruct<T>(uint playerId, PlayerType type) 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);
}
}

exists = false;
T[] arr = new T[1];
return ref arr[0]; //Return default value
var playerGroup = type == PlayerType.Local ? PlayersExclusiveGroups.LocalPlayers : PlayersExclusiveGroups.RemotePlayers;
EGID egid = new EGID(playerId, playerGroup);
return entitiesDB.QueryEntityOptional<T>(egid);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool GetPlayerStruct<T>(uint playerId, out T s) where T : unmanaged, IEntityComponent
public OptionalRef<T> GetCameraStruct<T>(uint playerId) 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;
}
}
s = default;
return false;
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)


+ 1
- 0
TechbloxModdingAPI/TechbloxModdingAPI.csproj View File

@@ -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…
Cancel
Save