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.")