Add player health and block-in-hand

This commit is contained in:
NGnius (Graham) 2020-05-29 21:30:24 -04:00
parent 0b8491cecf
commit 2d89b82759
4 changed files with 272 additions and 8 deletions

View file

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

View file

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

View file

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

View file

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