From 677c8b0907601032cdbaecf2c8e6a371a3d84a8c Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 19 Apr 2021 19:32:14 +0200 Subject: [PATCH] Add constructor for placing block, remove most PlaceNew args --- GamecraftModdingAPI/Block.cs | 52 +++++++++++---- GamecraftModdingAPI/Blocks/PlacementEngine.cs | 64 ++++--------------- .../Tests/GamecraftModdingAPIPluginTest.cs | 15 ++--- 3 files changed, 59 insertions(+), 72 deletions(-) diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index 234ee6e..99574ff 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -50,11 +50,9 @@ namespace GamecraftModdingAPI /// Whether the block should be auto-wired (if functional) /// The player who placed the block /// The placed block or null if failed - public static Block PlaceNew(BlockIDs block, float3 position, float3 rotation = default, - BlockColors color = BlockColors.Default, BlockMaterial material = BlockMaterial.Default, - int uscale = 1, float3 scale = default, bool isFlipped = false, bool autoWire = false, Player player = null) + public static Block PlaceNew(BlockIDs block, float3 position, bool autoWire = false, Player player = null) { - return PlaceNew(block, position, rotation, color, material, uscale, scale, isFlipped, autoWire, player); + return PlaceNew(block, position, autoWire, player); } /// @@ -73,15 +71,13 @@ namespace GamecraftModdingAPI /// Whether the block should be auto-wired (if functional) /// The player who placed the block /// The placed block or null if failed - public static T PlaceNew(BlockIDs block, float3 position, - float3 rotation = default, BlockColor? color = null, BlockMaterial material = BlockMaterial.Default, - int uscale = 1, float3 scale = default, bool isFlipped = false, bool autoWire = false, Player player = null) + public static T PlaceNew(BlockIDs block, float3 position, bool autoWire = false, Player player = null) where T : Block { if (PlacementEngine.IsInGame && GameState.IsBuildMode()) { - var egid = PlacementEngine.PlaceBlock(block, color ?? BlockColors.Default, material, - position, uscale, scale, player, rotation, isFlipped, autoWire, out var initializer); + var initializer = PlacementEngine.PlaceBlock(block, position, player, autoWire); + var egid = initializer.EGID; var bl = New(egid.entityID, egid.groupID); bl.InitData.Group = BlockEngine.InitGroup(initializer); Placed += bl.OnPlacedInit; @@ -232,6 +228,23 @@ namespace GamecraftModdingAPI Id = BlockEngine.FindBlockEGID(id) ?? throw new BlockTypeException("Could not find the appropriate group for the block. The block probably doesn't exist or hasn't been submitted."); } + /// + /// Places a new block in the world. + /// + /// The block's type + /// The block's position (a block is 0.2 wide in terms of position) + /// Whether the block should be auto-wired (if functional) + /// The player who placed the block + public Block(BlockIDs type, float3 position, bool autoWire = false, Player player = null) + { + if (!PlacementEngine.IsInGame || !GameState.IsBuildMode()) + throw new BlockException("Blocks can only be placed in build mode."); + var initializer = PlacementEngine.PlaceBlock(type, position, player, autoWire); + Id = initializer.EGID; + InitData.Group = BlockEngine.InitGroup(initializer); + Placed += OnPlacedInit; + } + public EGID Id { get; } internal BlockEngine.BlockInitData InitData; @@ -277,6 +290,10 @@ namespace GamecraftModdingAPI get => BlockEngine.GetBlockInfo(this, (ScalingEntityStruct st) => st.scale); set { + int uscale = UniformScale; + if (value.x < 4e-5) value.x = uscale; + if (value.y < 4e-5) value.y = uscale; + if (value.z < 4e-5) value.z = uscale; BlockEngine.SetBlockInfo(this, (ref ScalingEntityStruct st, float3 val) => st.scale = val, value); if (!Exists) return; //UpdateCollision needs the block to exist ScalingEngine.UpdateCollision(Id); @@ -293,6 +310,7 @@ namespace GamecraftModdingAPI get => BlockEngine.GetBlockInfo(this, (UniformBlockScaleEntityStruct st) => st.scaleFactor); set { + if (value < 1) value = 1; BlockEngine.SetBlockInfo(this, (ref UniformBlockScaleEntityStruct st, int val) => st.scaleFactor = val, value); Scale = new float3(value, value, value); @@ -300,7 +318,7 @@ namespace GamecraftModdingAPI } /** - * Whether the block is fipped. + * Whether the block is flipped. */ public bool Flipped { @@ -342,7 +360,7 @@ namespace GamecraftModdingAPI set { BlockEngine.SetBlockInfo(this, (ref ColourParameterEntityStruct color, BlockColor val) => - { + { //TODO: Check if setting to 255 works color.indexInPalette = val.Index; color.hasNetworkChange = true; color.paletteColour = BlockEngine.ConvertBlockColor(color.indexInPalette); @@ -366,9 +384,12 @@ namespace GamecraftModdingAPI } } + /** + * The block's material. + */ public BlockMaterial Material { - get => BlockEngine.GetBlockInfo(this, (CubeMaterialStruct cmst) => (BlockMaterial) cmst.materialId); + get => BlockEngine.GetBlockInfo(this, (CubeMaterialStruct cmst) => (BlockMaterial) cmst.materialId, BlockMaterial.Default); set => BlockEngine.SetBlockInfo(this, (ref CubeMaterialStruct cmst, BlockMaterial val) => cmst.materialId = (byte) val, value); } @@ -460,7 +481,12 @@ namespace GamecraftModdingAPI /// public T Copy() where T : Block { - var block = PlaceNew(Type, Position, Rotation, Color, Material, UniformScale, Scale); + var block = PlaceNew(Type, Position); + block.Rotation = Rotation; + block.Color = Color; + block.Material = Material; + block.UniformScale = UniformScale; + block.Scale = Scale; block.copiedFrom = Id; return block; } diff --git a/GamecraftModdingAPI/Blocks/PlacementEngine.cs b/GamecraftModdingAPI/Blocks/PlacementEngine.cs index cbc49e2..1d01ae8 100644 --- a/GamecraftModdingAPI/Blocks/PlacementEngine.cs +++ b/GamecraftModdingAPI/Blocks/PlacementEngine.cs @@ -41,64 +41,27 @@ namespace GamecraftModdingAPI.Blocks public EntitiesDB entitiesDB { get; set; } private static BlockEntityFactory _blockEntityFactory; //Injected from PlaceSingleBlockEngine - public EGID PlaceBlock(BlockIDs block, BlockColor color, BlockMaterial materialId, float3 position, int uscale, - float3 scale, Player player, float3 rotation, bool isFlipped, bool autoWire, out EntityInitializer initializer) + public EntityInitializer PlaceBlock(BlockIDs block, float3 position, Player player, bool autoWire) { //It appears that only the non-uniform scale has any visible effect, but if that's not given here it will be set to the uniform one - if (color.Darkness > 9) - throw new Exception("That is too dark. Make sure to use 0-9 as darkness. (0 is default.)"); - initializer = BuildBlock((ushort) block, color.Index, (byte) materialId, position, uscale, scale, rotation, - isFlipped, autoWire, (player ?? new Player(PlayerType.Local)).Id); - return initializer.EGID; + return BuildBlock((ushort) block, position, autoWire, (player ?? Player.LocalPlayer).Id); } - private EntityInitializer BuildBlock(ushort block, byte color, byte materialId, float3 position, int uscale, float3 scale, float3 rot, bool isFlipped, bool autoWire, uint playerId) + private EntityInitializer BuildBlock(ushort block, float3 position, bool autoWire, uint playerId) { if (_blockEntityFactory == null) throw new BlockException("The factory is null."); - if (uscale < 1) - throw new BlockException("Scale needs to be at least 1"); - if (scale.x < 4e-5) scale.x = uscale; - if (scale.y < 4e-5) scale.y = uscale; - if (scale.z < 4e-5) scale.z = uscale; uint resourceId = (uint) PrefabsID.GenerateResourceID(0, block); if (!PrefabsID.PrefabIDByResourceIDMap.ContainsKey(resourceId)) throw new BlockException("Block with ID " + block + " not found!"); //RobocraftX.CR.MachineEditing.PlaceSingleBlockEngine - ScalingEntityStruct scaling = new ScalingEntityStruct {scale = scale * (isFlipped ? -1 : 1)}; - Quaternion rotQ = Quaternion.Euler(rot); - RotationEntityStruct rotation = new RotationEntityStruct {rotation = rotQ}; - GridRotationStruct gridRotation = new GridRotationStruct - {position = position, rotation = rotQ}; DBEntityStruct dbEntity = new DBEntityStruct {DBID = block}; - BlockPlacementScaleEntityStruct placementScale = new BlockPlacementScaleEntityStruct - { - blockPlacementHeight = uscale, blockPlacementWidth = uscale, desiredScaleFactor = uscale - }; EntityInitializer structInitializer = _blockEntityFactory.Build(CommonExclusiveGroups.nextBlockEntityID, block); //The ghost block index is only used for triggers - if (color != byte.MaxValue) - structInitializer.Init(new ColourParameterEntityStruct - { - indexInPalette = color, - hasNetworkChange = true - }); - if (materialId != byte.MaxValue) - structInitializer.Init(new CubeMaterialStruct - { - materialId = materialId - }); - uint prefabId = PrefabsID.GetOrCreatePrefabID(block, materialId, 0, isFlipped); + uint prefabId = PrefabsID.GetOrCreatePrefabID(block, (byte) BlockMaterial.SteelBodywork, 0, false); structInitializer.Init(new GFXPrefabEntityStructGPUI(prefabId)); structInitializer.Init(new PhysicsPrefabEntityStruct(prefabId)); structInitializer.Init(dbEntity); structInitializer.Init(new PositionEntityStruct {position = position}); - structInitializer.Init(rotation); - structInitializer.Init(scaling); - structInitializer.Init(gridRotation); - structInitializer.Init(new UniformBlockScaleEntityStruct - { - scaleFactor = placementScale.desiredScaleFactor - }); structInitializer.Init(new BlockPlacementInfoStruct() { loadedFromDisk = false, @@ -106,20 +69,19 @@ namespace GamecraftModdingAPI.Blocks triggerAutoWiring = autoWire && structInitializer.Has() }); - /*structInitializer.Init(new CollisionFilterOverride + foreach (var group in CharacterExclusiveGroups.AllCharacters) { - belongsTo = 32U, - collidesWith = 239532U - });*/ - - EGID playerEGID = new EGID(playerId, CharacterExclusiveGroups.OnFootGroup); - ref PickedBlockExtraDataStruct pickedBlock = ref entitiesDB.QueryEntity(playerEGID); - pickedBlock.placedBlockEntityID = structInitializer.EGID; - pickedBlock.placedBlockWasAPickedBlock = false; + EGID playerEGID = new EGID(playerId, group); + if (!entitiesDB.TryQueryEntitiesAndIndex(playerEGID, out uint index, + out var array)) continue; + ref PickedBlockExtraDataStruct pickedBlock = ref array[index]; + pickedBlock.placedBlockEntityID = structInitializer.EGID; + pickedBlock.placedBlockWasAPickedBlock = false; + } return structInitializer; } - public string Name { get; } = "GamecraftModdingAPIPlacementGameEngine"; + public string Name => "GamecraftModdingAPIPlacementGameEngine"; public bool isRemovable => false; diff --git a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs index 92b1d7a..973cd4a 100644 --- a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs +++ b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs @@ -294,14 +294,13 @@ namespace GamecraftModdingAPI.Tests .Action((float x, float y, float z) => { var pos = new float3(x, y, z); - var group = BlockGroup.Create(Block.PlaceNew(BlockIDs.Cube, pos, - color: BlockColors.Aqua)); - Block.PlaceNew(BlockIDs.Cube, pos += new float3(1, 0, 0), color: BlockColors.Blue) - .BlockGroup = group; - Block.PlaceNew(BlockIDs.Cube, pos += new float3(1, 0, 0), color: BlockColors.Green) - .BlockGroup = group; - Block.PlaceNew(BlockIDs.Cube, pos += new float3(1, 0, 0), color: BlockColors.Lime) - .BlockGroup = group; + var group = BlockGroup.Create(new Block(BlockIDs.Cube, pos) {Color = BlockColors.Aqua}); + new Block(BlockIDs.Cube, pos += new float3(1, 0, 0)) + {Color = BlockColors.Blue, BlockGroup = group}; + new Block(BlockIDs.Cube, pos += new float3(1, 0, 0)) + {Color = BlockColors.Green, BlockGroup = group}; + new Block(BlockIDs.Cube, pos + new float3(1, 0, 0)) + {Color = BlockColors.Lime, BlockGroup = group}; }).Build(); CommandBuilder.Builder("placeCustomBlock", "Places a custom block, needs a custom catalog and assets.")