A stable modding interface between Techblox and mods https://mod.exmods.org/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

376 lines
10KB

  1. using System;
  2. using Unity.Mathematics;
  3. using RobocraftX.Common;
  4. using GamecraftModdingAPI.Players;
  5. using GamecraftModdingAPI.Blocks;
  6. namespace GamecraftModdingAPI
  7. {
  8. /// <summary>
  9. /// An in-game player character. Any Leo you see is a player.
  10. /// </summary>
  11. public class Player
  12. {
  13. // static functionality
  14. private static PlayerEngine playerEngine = new PlayerEngine();
  15. /// <summary>
  16. /// Checks if the specified player exists.
  17. /// </summary>
  18. /// <returns>Whether the player exists.</returns>
  19. /// <param name="player">Player type.</param>
  20. public static bool Exists(PlayerType player)
  21. {
  22. switch (player)
  23. {
  24. case PlayerType.Remote:
  25. return playerEngine.GetRemotePlayer() != uint.MaxValue;
  26. case PlayerType.Local:
  27. return playerEngine.GetLocalPlayer() != uint.MaxValue;
  28. }
  29. return false;
  30. }
  31. /// <summary>
  32. /// Checks if the specified player exists.
  33. /// </summary>
  34. /// <returns>Whether the player exists.</returns>
  35. /// <param name="player">The player's unique identifier.</param>
  36. public static bool Exists(uint player)
  37. {
  38. return playerEngine.ExistsById(player);
  39. }
  40. /// <summary>
  41. /// Initializes a new instance of the <see cref="T:GamecraftModdingAPI.Player"/> class.
  42. /// </summary>
  43. /// <param name="id">The player's unique identifier.</param>
  44. public Player(uint id)
  45. {
  46. this.Id = id;
  47. if (!Exists(id))
  48. {
  49. throw new PlayerNotFoundException($"No player with id {id} exists");
  50. }
  51. this.Type = playerEngine.GetLocalPlayer() == id ? PlayerType.Local : PlayerType.Remote;
  52. }
  53. /// <summary>
  54. /// Initializes a new instance of the <see cref="T:GamecraftModdingAPI.Player"/> class.
  55. /// </summary>
  56. /// <param name="player">The player type. Chooses the first available player matching the criteria.</param>
  57. public Player(PlayerType player)
  58. {
  59. uint localId = playerEngine.GetLocalPlayer();
  60. switch (player)
  61. {
  62. case PlayerType.Local:
  63. this.Id = playerEngine.GetLocalPlayer();
  64. break;
  65. case PlayerType.Remote:
  66. this.Id = playerEngine.GetRemotePlayer();
  67. break;
  68. }
  69. if (this.Id == uint.MaxValue)
  70. {
  71. throw new PlayerNotFoundException($"No player of {player} type exists");
  72. }
  73. this.Type = player;
  74. }
  75. // object fields & properties
  76. /// <summary>
  77. /// The player's type.
  78. /// The player type is always relative to the current client, not the game host.
  79. /// </summary>
  80. /// <value>The enumerated player type.</value>
  81. public PlayerType Type { get; }
  82. /// <summary>
  83. /// The player's unique identifier.
  84. /// </summary>
  85. /// <value>The identifier.</value>
  86. public uint Id { get; private set; }
  87. /// <summary>
  88. /// The player's current position.
  89. /// </summary>
  90. /// <value>The position.</value>
  91. public float3 Position
  92. {
  93. get
  94. {
  95. return playerEngine.GetLocation(Id);
  96. }
  97. set
  98. {
  99. playerEngine.SetLocation(Id, value, false);
  100. }
  101. }
  102. /// <summary>
  103. /// The player's current rotation.
  104. /// </summary>
  105. /// <value>The rotation.</value>
  106. public quaternion Rotation
  107. {
  108. get
  109. {
  110. return playerEngine.GetRotation(Id);
  111. }
  112. set
  113. {
  114. playerEngine.SetRotation(Id, value);
  115. }
  116. }
  117. /// <summary>
  118. /// The player's current velocity.
  119. /// </summary>
  120. /// <value>The velocity.</value>
  121. public float3 Velocity
  122. {
  123. get
  124. {
  125. return playerEngine.GetLinearVelocity(Id);
  126. }
  127. set
  128. {
  129. playerEngine.SetLinearVelocity(Id, value);
  130. }
  131. }
  132. /// <summary>
  133. /// The player's current angular velocity.
  134. /// </summary>
  135. /// <value>The angular velocity.</value>
  136. public float3 AngularVelocity
  137. {
  138. get
  139. {
  140. return playerEngine.GetAngularVelocity(Id);
  141. }
  142. set
  143. {
  144. playerEngine.SetAngularVelocity(Id, value);
  145. }
  146. }
  147. /// <summary>
  148. /// The player's mass.
  149. /// </summary>
  150. /// <value>The mass.</value>
  151. public float Mass
  152. {
  153. get
  154. {
  155. return 1f / playerEngine.GetMass(Id).InverseMass;
  156. }
  157. // FIXME: Setting mass doesn't do anything
  158. /*set
  159. {
  160. playerEngine.SetInverseMass(Id, 1f / value);
  161. }*/
  162. }
  163. private float _ping = -1f;
  164. /// <summary>
  165. /// The player's latest network ping time.
  166. /// </summary>
  167. /// <value>The ping (s).</value>
  168. public float Ping
  169. {
  170. get
  171. {
  172. float? temp = playerEngine.GetLastPingTime(Id, Type);
  173. if (temp.HasValue)
  174. {
  175. _ping = temp.Value;
  176. }
  177. return _ping;
  178. }
  179. }
  180. /// <summary>
  181. /// The player's initial health when entering Simulation (aka Time Running) mode.
  182. /// </summary>
  183. /// <value>The initial health.</value>
  184. public float InitialHealth
  185. {
  186. get => playerEngine.GetInitialHealth(Id);
  187. set
  188. {
  189. playerEngine.SetInitialHealth(Id, value);
  190. }
  191. }
  192. /// <summary>
  193. /// The player's current health in Simulation (aka Time Running) mode.
  194. /// </summary>
  195. /// <value>The current health.</value>
  196. public float CurrentHealth
  197. {
  198. get => playerEngine.GetCurrentHealth(Id);
  199. set
  200. {
  201. playerEngine.DamagePlayer(Id, CurrentHealth - value);
  202. }
  203. }
  204. /// <summary>
  205. /// Whether this <see cref="T:GamecraftModdingAPI.Player"/> is damageable.
  206. /// </summary>
  207. /// <value><c>true</c> if damageable; otherwise, <c>false</c>.</value>
  208. public bool Damageable
  209. {
  210. get => playerEngine.GetDamageable(Id);
  211. set
  212. {
  213. playerEngine.SetDamageable(Id, value);
  214. }
  215. }
  216. /// <summary>
  217. /// The player's lives when initially entering Simulation (aka Time Running) mode.
  218. /// </summary>
  219. /// <value>The initial lives.</value>
  220. public uint InitialLives
  221. {
  222. get => playerEngine.GetInitialLives(Id);
  223. set => playerEngine.SetInitialLives(Id, value);
  224. }
  225. /// <summary>
  226. /// The player's current lives in Simulation (aka Time Running) mode.
  227. /// </summary>
  228. /// <value>The current lives.</value>
  229. public uint CurrentLives
  230. {
  231. get => playerEngine.GetCurrentLives(Id);
  232. set => playerEngine.SetCurrentLives(Id, value);
  233. }
  234. /// <summary>
  235. /// Whether the Game Over screen is displayed for the player.
  236. /// </summary>
  237. /// <value><c>true</c> if game over; otherwise, <c>false</c>.</value>
  238. public bool GameOver
  239. {
  240. get => playerEngine.GetGameOverScreen(Id);
  241. }
  242. /// <summary>
  243. /// Whether the player is dead.
  244. /// If <c>true</c>, hopefully it was quick.
  245. /// </summary>
  246. /// <value><c>true</c> if dead; otherwise, <c>false</c>.</value>
  247. public bool Dead
  248. {
  249. get => playerEngine.IsDead(Id);
  250. }
  251. /// <summary>
  252. /// The player's selected block ID in their hand.
  253. /// </summary>
  254. /// <value>The selected block.</value>
  255. public BlockIDs SelectedBlock
  256. {
  257. get
  258. {
  259. return (BlockIDs)playerEngine.GetSelectedBlock(Id);
  260. }
  261. }
  262. /// <summary>
  263. /// The player's selected block color in their hand.
  264. /// </summary>
  265. /// <value>The selected block's color.</value>
  266. public BlockColors SelectedColor
  267. {
  268. get
  269. {
  270. return (BlockColors)playerEngine.GetSelectedColor(Id);
  271. }
  272. }
  273. /// <summary>
  274. /// The player's selected block colour in their hand.
  275. /// </summary>
  276. /// <value>The selected block's colour.</value>
  277. public BlockColors SelectedColour
  278. {
  279. get
  280. {
  281. return (BlockColors)playerEngine.GetSelectedColor(Id);
  282. }
  283. }
  284. // object methods
  285. /// <summary>
  286. /// Teleport the player to the specified coordinates.
  287. /// </summary>
  288. /// <param name="x">The x coordinate.</param>
  289. /// <param name="y">The y coordinate.</param>
  290. /// <param name="z">The z coordinate.</param>
  291. /// <param name="relative">If set to <c>true</c> teleport relative to the player's current position.</param>
  292. /// <param name="exitSeat">If set to <c>true</c> exit any seat the player is in.</param>
  293. public void Teleport(float x, float y, float z, bool relative = true, bool exitSeat = true)
  294. {
  295. float3 location = new float3(x, y, z);
  296. if (relative)
  297. {
  298. location += playerEngine.GetLocation(Id);
  299. }
  300. playerEngine.SetLocation(Id, location, exitSeat: exitSeat);
  301. }
  302. /// <summary>
  303. /// Returns the block the player is currently looking at in build mode.
  304. /// </summary>
  305. /// <param name="maxDistance">The maximum distance from the player (default is the player's building reach)</param>
  306. /// <returns>The block or null if not found</returns>
  307. public Block GetBlockLookedAt(float maxDistance = -1f)
  308. {
  309. var egid = playerEngine.GetThingLookedAt(Id, maxDistance);
  310. return egid.HasValue && egid.Value.groupID == CommonExclusiveGroups.OWNED_BLOCKS_GROUP
  311. ? new Block(egid.Value)
  312. : null;
  313. }
  314. /// <summary>
  315. /// Returns the rigid body the player is currently looking at during simulation.
  316. /// </summary>
  317. /// <param name="maxDistance">The maximum distance from the player (default is the player's building reach)</param>
  318. /// <returns>The block or null if not found</returns>
  319. public SimBody GetSimBodyLookedAt(float maxDistance = -1f)
  320. {
  321. var egid = playerEngine.GetThingLookedAt(Id, maxDistance);
  322. return egid.HasValue && egid.Value.groupID == CommonExclusiveGroups.SIMULATION_BODIES_GROUP
  323. ? new SimBody(egid.Value)
  324. : null;
  325. }
  326. // internal methods
  327. public static void Init()
  328. {
  329. Utility.GameEngineManager.AddGameEngine(playerEngine);
  330. }
  331. }
  332. }