diff --git a/GamecraftModdingAPI/Blocks/BlockTests.cs b/GamecraftModdingAPI/Blocks/BlockTests.cs
index 8fb40be..418fa43 100644
--- a/GamecraftModdingAPI/Blocks/BlockTests.cs
+++ b/GamecraftModdingAPI/Blocks/BlockTests.cs
@@ -6,6 +6,9 @@ using GamecraftModdingAPI.Tests;
namespace GamecraftModdingAPI.Blocks
{
#if TEST
+ ///
+ /// Block test cases. Not accessible in release versions.
+ ///
[APITestClass]
public static class BlockTests
{
diff --git a/GamecraftModdingAPI/Player.cs b/GamecraftModdingAPI/Player.cs
index 3d80e7b..cff13ff 100644
--- a/GamecraftModdingAPI/Player.cs
+++ b/GamecraftModdingAPI/Player.cs
@@ -413,7 +413,7 @@ namespace GamecraftModdingAPI
// internal methods
- public static void Init()
+ internal static void Init()
{
Utility.GameEngineManager.AddGameEngine(playerEngine);
}
diff --git a/GamecraftModdingAPI/Players/PlayerEngine.cs b/GamecraftModdingAPI/Players/PlayerEngine.cs
index 1bcce50..d30993c 100644
--- a/GamecraftModdingAPI/Players/PlayerEngine.cs
+++ b/GamecraftModdingAPI/Players/PlayerEngine.cs
@@ -67,6 +67,7 @@ namespace GamecraftModdingAPI.Players
public uint GetAllPlayerCount()
{
+ if (entitiesDB == null) return 0;
uint count = 0;
foreach (ExclusiveGroupStruct eg in PlayersExclusiveGroups.AllPlayers)
{
@@ -77,22 +78,26 @@ namespace GamecraftModdingAPI.Players
public uint GetLocalPlayerCount()
{
+ if (entitiesDB == null) return 0;
return entitiesDB.Count(PlayersExclusiveGroups.LocalPlayers);
}
public uint GetRemotePlayerCount()
{
+ if (entitiesDB == null) return 0;
return entitiesDB.Count(PlayersExclusiveGroups.RemotePlayers);
}
public bool ExistsById(uint playerId)
{
+ if (entitiesDB == null) return false;
return entitiesDB.Exists(playerId, PlayersExclusiveGroups.LocalPlayers)
|| entitiesDB.Exists(playerId, PlayersExclusiveGroups.RemotePlayers);
}
public float3 GetLocation(uint playerId)
{
+ if (entitiesDB == null) return float3.zero;
ref var rbes = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -103,6 +108,7 @@ namespace GamecraftModdingAPI.Players
public bool SetLocation(uint playerId, float3 location, bool exitSeat = true)
{
+ if (entitiesDB == null) return false;
var characterGroups = CharacterExclusiveGroups.AllCharacters;
for (int i = 0; i < characterGroups.count; i++)
{
@@ -124,6 +130,7 @@ namespace GamecraftModdingAPI.Players
public float3 GetRotation(uint playerId)
{
+ if (entitiesDB == null) return float3.zero;
ref var rbes = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -134,6 +141,7 @@ namespace GamecraftModdingAPI.Players
public bool SetRotation(uint playerId, float3 value)
{
+ if (entitiesDB == null) return false;
ref var rbes = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -147,6 +155,7 @@ namespace GamecraftModdingAPI.Players
public float3 GetLinearVelocity(uint playerId)
{
+ if (entitiesDB == null) return float3.zero;
ref var rbes = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -157,6 +166,7 @@ namespace GamecraftModdingAPI.Players
public bool SetLinearVelocity(uint playerId, float3 value)
{
+ if (entitiesDB == null) return false;
ref var rbes = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -168,6 +178,7 @@ namespace GamecraftModdingAPI.Players
public float3 GetAngularVelocity(uint playerId)
{
+ if (entitiesDB == null) return float3.zero;
ref var rbes = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -178,6 +189,7 @@ namespace GamecraftModdingAPI.Players
public bool SetAngularVelocity(uint playerId, float3 value)
{
+ if (entitiesDB == null) return false;
ref var rbes = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -189,6 +201,7 @@ namespace GamecraftModdingAPI.Players
public PhysicsMass GetMass(uint playerId)
{
+ if (entitiesDB == null) return default(PhysicsMass);
ref var rbes = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -199,6 +212,7 @@ namespace GamecraftModdingAPI.Players
public bool SetInverseMass(uint playerId, float inverseMass)
{
+ if (entitiesDB == null) return false;
ref var rbes = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -210,6 +224,7 @@ namespace GamecraftModdingAPI.Players
public float? GetLastPingTime(uint playerId, PlayerType type)
{
+ if (entitiesDB == null) return null;
EGID egid = new EGID(playerId, PlayerGroupFromEnum(type));
if (entitiesDB.Exists(egid))
{
@@ -220,6 +235,7 @@ namespace GamecraftModdingAPI.Players
public float GetInitialHealth(uint playerId)
{
+ if (entitiesDB == null) return 0;
ref var c = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -230,6 +246,7 @@ namespace GamecraftModdingAPI.Players
public bool SetInitialHealth(uint playerId, float val)
{
+ if (entitiesDB == null) return false;
ref var c = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -241,6 +258,7 @@ namespace GamecraftModdingAPI.Players
public float GetCurrentHealth(uint playerId)
{
+ if (entitiesDB == null) return 0;
ref var c = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -251,6 +269,7 @@ namespace GamecraftModdingAPI.Players
public bool SetCurrentHealth(uint playerId, float val)
{
+ if (entitiesDB == null) return false;
ref var c = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -262,6 +281,7 @@ namespace GamecraftModdingAPI.Players
public bool DamagePlayer(uint playerId, float amount)
{
+ if (entitiesDB == null) return false;
Factory.BuildEntity(
new EGID(CharacterVulnerabilityExclusiveGroups.NextDamageEntityId, CharacterVulnerabilityExclusiveGroups.CharacterDamageExclusiveGroup)
).Init(new DamageEntityStruct
@@ -274,6 +294,7 @@ namespace GamecraftModdingAPI.Players
public bool GetDamageable(uint playerId)
{
+ if (entitiesDB == null) return false;
ref var c = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -284,6 +305,7 @@ namespace GamecraftModdingAPI.Players
public bool SetDamageable(uint playerId, bool val)
{
+ if (entitiesDB == null) return false;
ref var ches = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -296,6 +318,7 @@ namespace GamecraftModdingAPI.Players
public uint GetInitialLives(uint playerId)
{
+ if (entitiesDB == null) return 0;
ref var c = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -306,6 +329,7 @@ namespace GamecraftModdingAPI.Players
public bool SetInitialLives(uint playerId, uint val)
{
+ if (entitiesDB == null) return false;
ref var c = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -317,6 +341,7 @@ namespace GamecraftModdingAPI.Players
public uint GetCurrentLives(uint playerId)
{
+ if (entitiesDB == null) return 0;
ref var c = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -327,6 +352,7 @@ namespace GamecraftModdingAPI.Players
public bool SetCurrentLives(uint playerId, uint val)
{
+ if (entitiesDB == null) return false;
ref var c = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -338,6 +364,7 @@ namespace GamecraftModdingAPI.Players
public bool GetGameOverScreen(uint playerId)
{
+ if (entitiesDB == null) return false;
ref var c = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -348,11 +375,13 @@ namespace GamecraftModdingAPI.Players
public bool IsDead(uint playerId)
{
+ if (entitiesDB == null) return true;
return entitiesDB.Exists(playerId, CharacterExclusiveGroups.DeadCharacters);
}
public int GetSelectedBlock(uint playerId)
{
+ if (entitiesDB == null) return 0;
ref var c = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
@@ -363,6 +392,7 @@ namespace GamecraftModdingAPI.Players
public byte GetSelectedColor(uint playerId)
{
+ if (entitiesDB == null) return 0;
ref var c = ref GetCharacterStruct(playerId, out bool exists);
if (exists)
{
diff --git a/GamecraftModdingAPI/Players/PlayerTests.cs b/GamecraftModdingAPI/Players/PlayerTests.cs
new file mode 100644
index 0000000..1af7992
--- /dev/null
+++ b/GamecraftModdingAPI/Players/PlayerTests.cs
@@ -0,0 +1,42 @@
+using System;
+
+using Unity.Mathematics;
+
+using GamecraftModdingAPI;
+using GamecraftModdingAPI.Tests;
+
+namespace GamecraftModdingAPI.Players
+{
+#if TEST
+ ///
+ /// Player test cases. Not accessible in release versions.
+ ///
+ [APITestClass]
+ public static class PlayerTests
+ {
+ [APITestCase(TestType.EditMode)]
+ public static void ExistsTest()
+ {
+ if (!Assert.Equal(Player.Exists(PlayerType.Local), true, "Local player does not exist.", "Local player detected.")) return;
+ Assert.Equal(Player.Count(), 1u, "Player.Count() is not one, possibly because it failed silently.", "Player count is one for single player game.");
+ }
+
+ [APITestCase(TestType.EditMode)]
+ public static void PositionTest()
+ {
+ Player p = new Player(PlayerType.Local);
+ if (!Assert.Errorless(() => { p.Teleport(0, 0, 0, relative: false); }, "Player.Teleport(origin) errored: ", "Player teleported to origin successfully.")) return;
+ if (!Assert.CloseTo(p.Position, float3.zero, "Player is not close to origin despite being teleported there.", "Player.Position is at origin.")) return;
+ if (!Assert.Errorless(() => { p.Position = float3.zero + 1; }, "Player.Position = origin+1 errored: ", "Player moved to origin+1.")) return;
+ Assert.CloseTo(p.Position, float3.zero + 1, "Player is not close to origin+1 despite being teleported there.", "Player.Position is at origin+1.");
+ }
+
+ [APITestCase(TestType.Menu)]
+ public static void InvalidStateTest()
+ {
+ if (!Assert.Errorless(() => { Player.Count(); }, "Player.Count() errored in menu.", "Player.Count() succeeded in menu.")) return;
+ Assert.Equal(Player.Count(), 0u, "Player.Count() is not zero in menu.", "Player count is zero in menu as expected.");
+ }
+ }
+#endif
+}