From fb841b65426a97fca8a3e5192729e4b713af28b2 Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Wed, 20 May 2020 20:42:02 -0400 Subject: [PATCH] Add Timer and spawn point block properties --- GamecraftModdingAPI/Block.cs | 10 +- GamecraftModdingAPI/Blocks/SpawnPoint.cs | 132 +++++++++++++++++++++++ GamecraftModdingAPI/Blocks/Timer.cs | 127 ++++++++++++++++++++++ 3 files changed, 268 insertions(+), 1 deletion(-) create mode 100644 GamecraftModdingAPI/Blocks/SpawnPoint.cs create mode 100644 GamecraftModdingAPI/Blocks/Timer.cs diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index 6a5b2a1..88932da 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -14,6 +14,7 @@ namespace GamecraftModdingAPI { /// /// A single (perhaps scaled) block. Properties may return default values if the block is removed and then setting them is ignored. + /// For specific block type operations, use the specialised block classes in the GamecraftModdingAPI.Blocks namespace. /// public class Block { @@ -81,7 +82,7 @@ namespace GamecraftModdingAPI DeterministicStepCompositionRootPatch.SubmitEntitiesNow(); } - public EGID Id { get; } + public EGID Id { get; protected set; } /// /// The block's current position or zero if the block no longer exists. @@ -213,6 +214,13 @@ namespace GamecraftModdingAPI GameEngineManager.AddGameEngine(BlockEngine); } + /// + /// Convert the block to a specialised block class. + /// + /// The block. + /// Force an entity sync when true. + /// Only set this to false when the block was not placed the same tick this was called. + /// The specialised block type. public T Specialise(bool sameTick = true) where T : Block { // What have I gotten myself into? diff --git a/GamecraftModdingAPI/Blocks/SpawnPoint.cs b/GamecraftModdingAPI/Blocks/SpawnPoint.cs new file mode 100644 index 0000000..8fd1fda --- /dev/null +++ b/GamecraftModdingAPI/Blocks/SpawnPoint.cs @@ -0,0 +1,132 @@ +using System; + +using RobocraftX.Blocks; +using Gamecraft.CharacterVulnerability; +using Svelto.ECS; +using Unity.Mathematics; + +using GamecraftModdingAPI; +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Blocks +{ + public class SpawnPoint : Block + { + /// + /// Places a new spawn point. + /// Any valid spawn block type is accepted. + /// This re-implements Block.PlaceNew(...) + /// + public static new SpawnPoint PlaceNew(BlockIDs block, float3 position, + float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0, + int uscale = 1, float3 scale = default, Player player = null) + { + if (!(block == BlockIDs.LargeSpawn || block == BlockIDs.SmallSpawn || block == BlockIDs.MediumSpawn || block == BlockIDs.PlayerSpawn)) + { + throw new BlockTypeException($"Block is not a {typeof(SpawnPoint).Name} block"); + } + if (PlacementEngine.IsInGame && GameState.IsBuildMode()) + { + try + { + EGID id = PlacementEngine.PlaceBlock(block, color, darkness, + position, uscale, scale, player, rotation); + Sync(); + return new SpawnPoint(id); + } + catch (Exception e) + { + Logging.MetaDebugLog(e); + } + } + + return null; + } + + public SpawnPoint(EGID id) : base(id) + { + if (!BlockEngine.GetBlockInfoExists(this.Id)) + { + throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); + } + } + + public SpawnPoint(uint id) : base(id) + { + if (!BlockEngine.GetBlockInfoExists(this.Id)) + { + throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); + } + } + + // custom spawn point properties + + /// + /// The lives the player spawns in with. + /// + public uint Lives + { + get + { + return BlockEngine.GetBlockInfo(Id).lives; + } + + set + { + ref SpawnPointStatsEntityStruct spses = ref BlockEngine.GetBlockInfo(Id); + spses.lives = value; + } + } + + /// + /// Whether the spawned player can take damage. + /// + public bool Damageable + { + get + { + return BlockEngine.GetBlockInfo(Id).canTakeDamage; + } + + set + { + ref SpawnPointStatsEntityStruct spses = ref BlockEngine.GetBlockInfo(Id); + spses.canTakeDamage = value; + } + } + + /// + /// Whether the game over screen will be displayed + /// + public bool GameOverEnabled + { + get + { + return BlockEngine.GetBlockInfo(Id).gameOverScreen; + } + + set + { + ref SpawnPointStatsEntityStruct spses = ref BlockEngine.GetBlockInfo(Id); + spses.gameOverScreen = value; + } + } + + /// + /// The team id for players who spawn here. + /// + public byte Team + { + get + { + return BlockEngine.GetBlockInfo(Id).teamId; + } + + set + { + ref SpawnPointIdsEntityStruct spses = ref BlockEngine.GetBlockInfo(Id); + spses.teamId = value; + } + } + } +} diff --git a/GamecraftModdingAPI/Blocks/Timer.cs b/GamecraftModdingAPI/Blocks/Timer.cs new file mode 100644 index 0000000..b31f9f8 --- /dev/null +++ b/GamecraftModdingAPI/Blocks/Timer.cs @@ -0,0 +1,127 @@ +using System; + +using RobocraftX.Blocks; +using Gamecraft.Blocks.TimerBlock; +using Svelto.ECS; +using Unity.Mathematics; + +using GamecraftModdingAPI; +using GamecraftModdingAPI.Utility; + +namespace GamecraftModdingAPI.Blocks +{ + public class Timer : Block + { + /// + /// Places a new timer block. + /// + public static Timer PlaceNew(float3 position, + float3 rotation = default, BlockColors color = BlockColors.Default, byte darkness = 0, + int uscale = 1, float3 scale = default, Player player = null) + { + if (PlacementEngine.IsInGame && GameState.IsBuildMode()) + { + + try + { + EGID id = PlacementEngine.PlaceBlock(BlockIDs.Timer, color, darkness, + position, uscale, scale, player, rotation); + Sync(); + return new Timer(id); + } + catch (Exception e) + { + Logging.MetaDebugLog(e); + } + } + + return null; + } + + public Timer(EGID id) : base(id) + { + if (!BlockEngine.GetBlockInfoExists(this.Id)) + { + throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); + } + } + + public Timer(uint id) : base(id) + { + if (!BlockEngine.GetBlockInfoExists(this.Id)) + { + throw new BlockTypeException($"Block is not a {this.GetType().Name} block"); + } + } + + // custom timer properties + + /// + /// The player-specified start time. + /// + public float Start + { + get + { + return BlockEngine.GetBlockInfo(Id).startTime; + } + + set + { + ref TimerBlockDataStruct tbds = ref BlockEngine.GetBlockInfo(Id); + tbds.startTime = value; + } + } + + /// + /// The player-specified end time. + /// + public float End + { + get + { + return BlockEngine.GetBlockInfo(Id).endTime; + } + + set + { + ref TimerBlockDataStruct tbds = ref BlockEngine.GetBlockInfo(Id); + tbds.endTime = value; + } + } + + /// + /// Whether to display time with millisecond precision. + /// + public bool DisplayMilliseconds + { + get + { + return BlockEngine.GetBlockInfo(Id).outputFormatHasMS; + } + + set + { + ref TimerBlockDataStruct tbds = ref BlockEngine.GetBlockInfo(Id); + tbds.outputFormatHasMS = value; + } + } + + /// + /// Current time (as of the last video frame), in milliseconds. + /// + public int CurrentTime + { + get + { + return BlockEngine.GetBlockInfo(Id).timeLastRenderFrameMS; + } + + set + { + ref TimerBlockLabelCacheEntityStruct tblces = ref BlockEngine.GetBlockInfo(Id); + tblces.timeLastRenderFrameMS = value; + } + } + } +}