Add player health and block-in-hand
This commit is contained in:
parent
0b8491cecf
commit
2d89b82759
4 changed files with 272 additions and 8 deletions
|
@ -3,7 +3,7 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net472</TargetFramework>
|
<TargetFramework>net472</TargetFramework>
|
||||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
<Version>1.1.0</Version>
|
<Version>1.2.0</Version>
|
||||||
<Authors>Exmods</Authors>
|
<Authors>Exmods</Authors>
|
||||||
<PackageLicenseExpression>GNU General Public Licence 3+</PackageLicenseExpression>
|
<PackageLicenseExpression>GNU General Public Licence 3+</PackageLicenseExpression>
|
||||||
<PackageProjectUrl>https://git.exmods.org/modtainers/GamecraftModdingAPI</PackageProjectUrl>
|
<PackageProjectUrl>https://git.exmods.org/modtainers/GamecraftModdingAPI</PackageProjectUrl>
|
||||||
|
|
|
@ -4,6 +4,7 @@ using Unity.Mathematics;
|
||||||
using RobocraftX.Common;
|
using RobocraftX.Common;
|
||||||
|
|
||||||
using GamecraftModdingAPI.Players;
|
using GamecraftModdingAPI.Players;
|
||||||
|
using GamecraftModdingAPI.Blocks;
|
||||||
|
|
||||||
namespace GamecraftModdingAPI
|
namespace GamecraftModdingAPI
|
||||||
{
|
{
|
||||||
|
@ -199,6 +200,125 @@ namespace GamecraftModdingAPI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The player's initial health when entering Simulation (aka Time Running) mode.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The initial health.</value>
|
||||||
|
public float InitialHealth
|
||||||
|
{
|
||||||
|
get => playerEngine.GetInitialHealth(Id);
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
playerEngine.SetInitialHealth(Id, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The player's current health in Simulation (aka Time Running) mode.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The current health.</value>
|
||||||
|
public float CurrentHealth
|
||||||
|
{
|
||||||
|
get => playerEngine.GetCurrentHealth(Id);
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
playerEngine.DamagePlayer(Id, CurrentHealth - value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether this <see cref="T:GamecraftModdingAPI.Player"/> is damageable.
|
||||||
|
/// </summary>
|
||||||
|
/// <value><c>true</c> if damageable; otherwise, <c>false</c>.</value>
|
||||||
|
public bool Damageable
|
||||||
|
{
|
||||||
|
get => playerEngine.GetDamageable(Id);
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
playerEngine.SetDamageable(Id, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The player's lives when initially entering Simulation (aka Time Running) mode.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The initial lives.</value>
|
||||||
|
public uint InitialLives
|
||||||
|
{
|
||||||
|
get => playerEngine.GetInitialLives(Id);
|
||||||
|
|
||||||
|
set => playerEngine.SetInitialLives(Id, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The player's current lives in Simulation (aka Time Running) mode.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The current lives.</value>
|
||||||
|
public uint CurrentLives
|
||||||
|
{
|
||||||
|
get => playerEngine.GetCurrentLives(Id);
|
||||||
|
|
||||||
|
set => playerEngine.SetCurrentLives(Id, 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.
|
||||||
|
/// If <c>true</c>, hopefully it was quick.
|
||||||
|
/// </summary>
|
||||||
|
/// <value><c>true</c> if dead; otherwise, <c>false</c>.</value>
|
||||||
|
public bool Dead
|
||||||
|
{
|
||||||
|
get => playerEngine.IsDead(Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The player's selected block ID in their hand.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The selected block.</value>
|
||||||
|
public BlockIDs SelectedBlock
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (BlockIDs)playerEngine.GetSelectedBlock(Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The player's selected block color in their hand.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The selected block's color.</value>
|
||||||
|
public BlockColors SelectedColor
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (BlockColors)playerEngine.GetSelectedColor(Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The player's selected block colour in their hand.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The selected block's colour.</value>
|
||||||
|
public BlockColors SelectedColour
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (BlockColors)playerEngine.GetSelectedColor(Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// object methods
|
// object methods
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -6,18 +6,20 @@ using RobocraftX.Character.Movement;
|
||||||
using RobocraftX.Common.Players;
|
using RobocraftX.Common.Players;
|
||||||
using RobocraftX.Common.Input;
|
using RobocraftX.Common.Input;
|
||||||
using RobocraftX.Physics;
|
using RobocraftX.Physics;
|
||||||
|
using RobocraftX.Blocks.Ghost;
|
||||||
|
using RobocraftX.Character.Camera;
|
||||||
|
using RobocraftX.Character.Factories;
|
||||||
|
using Gamecraft.CharacterVulnerability;
|
||||||
|
using Gamecraft.CharacterVulnerability.Entities;
|
||||||
using Svelto.ECS;
|
using Svelto.ECS;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
using Unity.Physics;
|
using Unity.Physics;
|
||||||
|
|
||||||
using GamecraftModdingAPI.Engines;
|
using GamecraftModdingAPI.Engines;
|
||||||
using RobocraftX.Blocks.Ghost;
|
|
||||||
using RobocraftX.Character.Camera;
|
|
||||||
using RobocraftX.Character.Factories;
|
|
||||||
|
|
||||||
namespace GamecraftModdingAPI.Players
|
namespace GamecraftModdingAPI.Players
|
||||||
{
|
{
|
||||||
internal class PlayerEngine : IApiEngine
|
internal class PlayerEngine : IApiEngine, IFactoryEngine
|
||||||
{
|
{
|
||||||
public string Name { get; } = "GamecraftModdingAPIPlayerGameEngine";
|
public string Name { get; } = "GamecraftModdingAPIPlayerGameEngine";
|
||||||
|
|
||||||
|
@ -25,6 +27,8 @@ namespace GamecraftModdingAPI.Players
|
||||||
|
|
||||||
public bool isRemovable => false;
|
public bool isRemovable => false;
|
||||||
|
|
||||||
|
public IEntityFactory Factory { set; private get; }
|
||||||
|
|
||||||
private bool isReady = false;
|
private bool isReady = false;
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
@ -188,7 +192,7 @@ namespace GamecraftModdingAPI.Players
|
||||||
|
|
||||||
public float? GetLastPingTime(uint playerId, PlayerType type)
|
public float? GetLastPingTime(uint playerId, PlayerType type)
|
||||||
{
|
{
|
||||||
EGID egid = new EGID(playerId, GroupFromEnum(type));
|
EGID egid = new EGID(playerId, PlayerGroupFromEnum(type));
|
||||||
if (entitiesDB.Exists<PlayerNetworkStatsEntityStruct>(egid))
|
if (entitiesDB.Exists<PlayerNetworkStatsEntityStruct>(egid))
|
||||||
{
|
{
|
||||||
return entitiesDB.QueryEntity<PlayerNetworkStatsEntityStruct>(egid).lastPingTimeSinceLevelLoad;
|
return entitiesDB.QueryEntity<PlayerNetworkStatsEntityStruct>(egid).lastPingTimeSinceLevelLoad;
|
||||||
|
@ -196,10 +200,150 @@ namespace GamecraftModdingAPI.Players
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float GetInitialHealth(uint playerId)
|
||||||
|
{
|
||||||
|
if (GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out CharacterHealthEntityStruct c))
|
||||||
|
{
|
||||||
|
return c.initialHealth;
|
||||||
|
}
|
||||||
|
return -1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetInitialHealth(uint playerId, float val)
|
||||||
|
{
|
||||||
|
if (GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out CharacterHealthEntityStruct c))
|
||||||
|
{
|
||||||
|
c.initialHealth = val;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float GetCurrentHealth(uint playerId)
|
||||||
|
{
|
||||||
|
if (GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out CharacterHealthEntityStruct c))
|
||||||
|
{
|
||||||
|
return c.currentHealth;
|
||||||
|
}
|
||||||
|
return -1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetCurrentHealth(uint playerId, float val)
|
||||||
|
{
|
||||||
|
if (GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out CharacterHealthEntityStruct c))
|
||||||
|
{
|
||||||
|
c.currentHealth = val;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool DamagePlayer(uint playerId, float amount)
|
||||||
|
{
|
||||||
|
Factory.BuildEntity<DamageEntityDescriptor>(
|
||||||
|
new EGID(CharacterVulnerabilityExclusiveGroups.NextDamageEntityId, CharacterVulnerabilityExclusiveGroups.CharacterDamageExclusiveGroup)
|
||||||
|
).Init(new DamageEntityStruct
|
||||||
|
{
|
||||||
|
damage = amount,
|
||||||
|
targetPlayerEntityId = playerId,
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetDamageable(uint playerId)
|
||||||
|
{
|
||||||
|
if (GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out CharacterHealthEntityStruct c))
|
||||||
|
{
|
||||||
|
return c.canTakeDamageStat;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetDamageable(uint playerId, bool val)
|
||||||
|
{
|
||||||
|
if (GetCharacterStruct<CharacterHealthEntityStruct>(playerId, out CharacterHealthEntityStruct ches))
|
||||||
|
{
|
||||||
|
ches.canTakeDamage = val;
|
||||||
|
ches.canTakeDamage = val;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint GetInitialLives(uint playerId)
|
||||||
|
{
|
||||||
|
if (GetCharacterStruct<CharacterLivesEntityComponent>(playerId, out CharacterLivesEntityComponent c))
|
||||||
|
{
|
||||||
|
return c.initialLives;
|
||||||
|
}
|
||||||
|
return uint.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetInitialLives(uint playerId, uint val)
|
||||||
|
{
|
||||||
|
if (GetCharacterStruct<CharacterLivesEntityComponent>(playerId, out CharacterLivesEntityComponent c))
|
||||||
|
{
|
||||||
|
c.initialLives = val;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint GetCurrentLives(uint playerId)
|
||||||
|
{
|
||||||
|
if (GetCharacterStruct<CharacterLivesEntityComponent>(playerId, out CharacterLivesEntityComponent c))
|
||||||
|
{
|
||||||
|
return c.currentLives;
|
||||||
|
}
|
||||||
|
return uint.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetCurrentLives(uint playerId, uint val)
|
||||||
|
{
|
||||||
|
if (GetCharacterStruct<CharacterLivesEntityComponent>(playerId, out CharacterLivesEntityComponent c))
|
||||||
|
{
|
||||||
|
c.currentLives = val;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetGameOverScreen(uint playerId)
|
||||||
|
{
|
||||||
|
if (GetCharacterStruct<CharacterLivesEntityComponent>(playerId, out CharacterLivesEntityComponent c))
|
||||||
|
{
|
||||||
|
return c.gameOverScreen;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsDead(uint playerId)
|
||||||
|
{
|
||||||
|
return entitiesDB.Exists<RigidBodyEntityStruct>(playerId, CharacterExclusiveGroups.DeadGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetSelectedBlock(uint playerId)
|
||||||
|
{
|
||||||
|
if (GetCharacterStruct<EquippedPartStruct>(playerId, out EquippedPartStruct c))
|
||||||
|
{
|
||||||
|
return c.SelectedDBPartID;
|
||||||
|
}
|
||||||
|
return ushort.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte GetSelectedColor(uint playerId)
|
||||||
|
{
|
||||||
|
if (GetCharacterStruct<EquippedColourStruct>(playerId, out EquippedColourStruct c))
|
||||||
|
{
|
||||||
|
return c.indexInPalette;
|
||||||
|
}
|
||||||
|
return 255;
|
||||||
|
}
|
||||||
|
|
||||||
// reusable methods
|
// reusable methods
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private ExclusiveGroup GroupFromEnum(PlayerType type)
|
private ExclusiveGroup PlayerGroupFromEnum(PlayerType type)
|
||||||
{
|
{
|
||||||
return type == PlayerType.Local ? PlayersExclusiveGroups.LocalPlayers : PlayersExclusiveGroups.RemotePlayers;
|
return type == PlayerType.Local ? PlayersExclusiveGroups.LocalPlayers : PlayersExclusiveGroups.RemotePlayers;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ PROJECT_NAME = "GamecraftModdingAPI"
|
||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = "v1.1.0"
|
PROJECT_NUMBER = "v1.2.0"
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
|
|
Loading…
Reference in a new issue