Add constructor for placing block, remove most PlaceNew args

This commit is contained in:
Norbi Peti 2021-04-19 19:32:14 +02:00
parent 1f688195af
commit 677c8b0907
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
3 changed files with 59 additions and 72 deletions

View file

@ -50,11 +50,9 @@ namespace GamecraftModdingAPI
/// <param name="autoWire">Whether the block should be auto-wired (if functional)</param> /// <param name="autoWire">Whether the block should be auto-wired (if functional)</param>
/// <param name="player">The player who placed the block</param> /// <param name="player">The player who placed the block</param>
/// <returns>The placed block or null if failed</returns> /// <returns>The placed block or null if failed</returns>
public static Block PlaceNew(BlockIDs block, float3 position, float3 rotation = default, public static Block PlaceNew(BlockIDs block, float3 position, bool autoWire = false, Player player = null)
BlockColors color = BlockColors.Default, BlockMaterial material = BlockMaterial.Default,
int uscale = 1, float3 scale = default, bool isFlipped = false, bool autoWire = false, Player player = null)
{ {
return PlaceNew<Block>(block, position, rotation, color, material, uscale, scale, isFlipped, autoWire, player); return PlaceNew<Block>(block, position, autoWire, player);
} }
/// <summary> /// <summary>
@ -73,15 +71,13 @@ namespace GamecraftModdingAPI
/// <param name="autoWire">Whether the block should be auto-wired (if functional)</param> /// <param name="autoWire">Whether the block should be auto-wired (if functional)</param>
/// <param name="player">The player who placed the block</param> /// <param name="player">The player who placed the block</param>
/// <returns>The placed block or null if failed</returns> /// <returns>The placed block or null if failed</returns>
public static T PlaceNew<T>(BlockIDs block, float3 position, public static T PlaceNew<T>(BlockIDs block, float3 position, bool autoWire = false, Player player = null)
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)
where T : Block where T : Block
{ {
if (PlacementEngine.IsInGame && GameState.IsBuildMode()) if (PlacementEngine.IsInGame && GameState.IsBuildMode())
{ {
var egid = PlacementEngine.PlaceBlock(block, color ?? BlockColors.Default, material, var initializer = PlacementEngine.PlaceBlock(block, position, player, autoWire);
position, uscale, scale, player, rotation, isFlipped, autoWire, out var initializer); var egid = initializer.EGID;
var bl = New<T>(egid.entityID, egid.groupID); var bl = New<T>(egid.entityID, egid.groupID);
bl.InitData.Group = BlockEngine.InitGroup(initializer); bl.InitData.Group = BlockEngine.InitGroup(initializer);
Placed += bl.OnPlacedInit; 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."); 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.");
} }
/// <summary>
/// Places a new block in the world.
/// </summary>
/// <param name="type">The block's type</param>
/// <param name="position">The block's position (a block is 0.2 wide in terms of position)</param>
/// <param name="autoWire">Whether the block should be auto-wired (if functional)</param>
/// <param name="player">The player who placed the block</param>
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; } public EGID Id { get; }
internal BlockEngine.BlockInitData InitData; internal BlockEngine.BlockInitData InitData;
@ -277,6 +290,10 @@ namespace GamecraftModdingAPI
get => BlockEngine.GetBlockInfo(this, (ScalingEntityStruct st) => st.scale); get => BlockEngine.GetBlockInfo(this, (ScalingEntityStruct st) => st.scale);
set 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); BlockEngine.SetBlockInfo(this, (ref ScalingEntityStruct st, float3 val) => st.scale = val, value);
if (!Exists) return; //UpdateCollision needs the block to exist if (!Exists) return; //UpdateCollision needs the block to exist
ScalingEngine.UpdateCollision(Id); ScalingEngine.UpdateCollision(Id);
@ -293,6 +310,7 @@ namespace GamecraftModdingAPI
get => BlockEngine.GetBlockInfo(this, (UniformBlockScaleEntityStruct st) => st.scaleFactor); get => BlockEngine.GetBlockInfo(this, (UniformBlockScaleEntityStruct st) => st.scaleFactor);
set set
{ {
if (value < 1) value = 1;
BlockEngine.SetBlockInfo(this, (ref UniformBlockScaleEntityStruct st, int val) => st.scaleFactor = val, BlockEngine.SetBlockInfo(this, (ref UniformBlockScaleEntityStruct st, int val) => st.scaleFactor = val,
value); value);
Scale = new float3(value, value, 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 public bool Flipped
{ {
@ -342,7 +360,7 @@ namespace GamecraftModdingAPI
set set
{ {
BlockEngine.SetBlockInfo(this, (ref ColourParameterEntityStruct color, BlockColor val) => BlockEngine.SetBlockInfo(this, (ref ColourParameterEntityStruct color, BlockColor val) =>
{ { //TODO: Check if setting to 255 works
color.indexInPalette = val.Index; color.indexInPalette = val.Index;
color.hasNetworkChange = true; color.hasNetworkChange = true;
color.paletteColour = BlockEngine.ConvertBlockColor(color.indexInPalette); color.paletteColour = BlockEngine.ConvertBlockColor(color.indexInPalette);
@ -366,9 +384,12 @@ namespace GamecraftModdingAPI
} }
} }
/**
* The block's material.
*/
public BlockMaterial 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, set => BlockEngine.SetBlockInfo(this,
(ref CubeMaterialStruct cmst, BlockMaterial val) => cmst.materialId = (byte) val, value); (ref CubeMaterialStruct cmst, BlockMaterial val) => cmst.materialId = (byte) val, value);
} }
@ -460,7 +481,12 @@ namespace GamecraftModdingAPI
/// <returns></returns> /// <returns></returns>
public T Copy<T>() where T : Block public T Copy<T>() where T : Block
{ {
var block = PlaceNew<T>(Type, Position, Rotation, Color, Material, UniformScale, Scale); var block = PlaceNew<T>(Type, Position);
block.Rotation = Rotation;
block.Color = Color;
block.Material = Material;
block.UniformScale = UniformScale;
block.Scale = Scale;
block.copiedFrom = Id; block.copiedFrom = Id;
return block; return block;
} }

View file

@ -41,64 +41,27 @@ namespace GamecraftModdingAPI.Blocks
public EntitiesDB entitiesDB { get; set; } public EntitiesDB entitiesDB { get; set; }
private static BlockEntityFactory _blockEntityFactory; //Injected from PlaceSingleBlockEngine private static BlockEntityFactory _blockEntityFactory; //Injected from PlaceSingleBlockEngine
public EGID PlaceBlock(BlockIDs block, BlockColor color, BlockMaterial materialId, float3 position, int uscale, public EntityInitializer PlaceBlock(BlockIDs block, float3 position, Player player, bool autoWire)
float3 scale, Player player, float3 rotation, bool isFlipped, bool autoWire, out EntityInitializer initializer)
{ //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 { //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) return BuildBlock((ushort) block, position, autoWire, (player ?? Player.LocalPlayer).Id);
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;
} }
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) if (_blockEntityFactory == null)
throw new BlockException("The factory is 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); uint resourceId = (uint) PrefabsID.GenerateResourceID(0, block);
if (!PrefabsID.PrefabIDByResourceIDMap.ContainsKey(resourceId)) if (!PrefabsID.PrefabIDByResourceIDMap.ContainsKey(resourceId))
throw new BlockException("Block with ID " + block + " not found!"); throw new BlockException("Block with ID " + block + " not found!");
//RobocraftX.CR.MachineEditing.PlaceSingleBlockEngine //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}; 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 EntityInitializer structInitializer = _blockEntityFactory.Build(CommonExclusiveGroups.nextBlockEntityID, block); //The ghost block index is only used for triggers
if (color != byte.MaxValue) uint prefabId = PrefabsID.GetOrCreatePrefabID(block, (byte) BlockMaterial.SteelBodywork, 0, false);
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);
structInitializer.Init(new GFXPrefabEntityStructGPUI(prefabId)); structInitializer.Init(new GFXPrefabEntityStructGPUI(prefabId));
structInitializer.Init(new PhysicsPrefabEntityStruct(prefabId)); structInitializer.Init(new PhysicsPrefabEntityStruct(prefabId));
structInitializer.Init(dbEntity); structInitializer.Init(dbEntity);
structInitializer.Init(new PositionEntityStruct {position = position}); 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() structInitializer.Init(new BlockPlacementInfoStruct()
{ {
loadedFromDisk = false, loadedFromDisk = false,
@ -106,20 +69,19 @@ namespace GamecraftModdingAPI.Blocks
triggerAutoWiring = autoWire && structInitializer.Has<BlockPortsStruct>() triggerAutoWiring = autoWire && structInitializer.Has<BlockPortsStruct>()
}); });
/*structInitializer.Init(new CollisionFilterOverride foreach (var group in CharacterExclusiveGroups.AllCharacters)
{ {
belongsTo = 32U, EGID playerEGID = new EGID(playerId, group);
collidesWith = 239532U if (!entitiesDB.TryQueryEntitiesAndIndex<PickedBlockExtraDataStruct>(playerEGID, out uint index,
});*/ out var array)) continue;
ref PickedBlockExtraDataStruct pickedBlock = ref array[index];
EGID playerEGID = new EGID(playerId, CharacterExclusiveGroups.OnFootGroup);
ref PickedBlockExtraDataStruct pickedBlock = ref entitiesDB.QueryEntity<PickedBlockExtraDataStruct>(playerEGID);
pickedBlock.placedBlockEntityID = structInitializer.EGID; pickedBlock.placedBlockEntityID = structInitializer.EGID;
pickedBlock.placedBlockWasAPickedBlock = false; pickedBlock.placedBlockWasAPickedBlock = false;
}
return structInitializer; return structInitializer;
} }
public string Name { get; } = "GamecraftModdingAPIPlacementGameEngine"; public string Name => "GamecraftModdingAPIPlacementGameEngine";
public bool isRemovable => false; public bool isRemovable => false;

View file

@ -294,14 +294,13 @@ namespace GamecraftModdingAPI.Tests
.Action((float x, float y, float z) => .Action((float x, float y, float z) =>
{ {
var pos = new float3(x, y, z); var pos = new float3(x, y, z);
var group = BlockGroup.Create(Block.PlaceNew(BlockIDs.Cube, pos, var group = BlockGroup.Create(new Block(BlockIDs.Cube, pos) {Color = BlockColors.Aqua});
color: BlockColors.Aqua)); new Block(BlockIDs.Cube, pos += new float3(1, 0, 0))
Block.PlaceNew(BlockIDs.Cube, pos += new float3(1, 0, 0), color: BlockColors.Blue) {Color = BlockColors.Blue, BlockGroup = group};
.BlockGroup = group; new Block(BlockIDs.Cube, pos += new float3(1, 0, 0))
Block.PlaceNew(BlockIDs.Cube, pos += new float3(1, 0, 0), color: BlockColors.Green) {Color = BlockColors.Green, BlockGroup = group};
.BlockGroup = group; new Block(BlockIDs.Cube, pos + new float3(1, 0, 0))
Block.PlaceNew(BlockIDs.Cube, pos += new float3(1, 0, 0), color: BlockColors.Lime) {Color = BlockColors.Lime, BlockGroup = group};
.BlockGroup = group;
}).Build(); }).Build();
CommandBuilder.Builder("placeCustomBlock", "Places a custom block, needs a custom catalog and assets.") CommandBuilder.Builder("placeCustomBlock", "Places a custom block, needs a custom catalog and assets.")