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="player">The player who placed the block</param>
/// <returns>The placed block or null if failed</returns>
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>(block, position, rotation, color, material, uscale, scale, isFlipped, autoWire, player);
return PlaceNew<Block>(block, position, autoWire, player);
}
/// <summary>
@ -73,15 +71,13 @@ namespace GamecraftModdingAPI
/// <param name="autoWire">Whether the block should be auto-wired (if functional)</param>
/// <param name="player">The player who placed the block</param>
/// <returns>The placed block or null if failed</returns>
public static T PlaceNew<T>(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<T>(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<T>(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.");
}
/// <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; }
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
/// <returns></returns>
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;
return block;
}

View file

@ -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<BlockPortsStruct>()
});
/*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<PickedBlockExtraDataStruct>(playerEGID);
EGID playerEGID = new EGID(playerId, group);
if (!entitiesDB.TryQueryEntitiesAndIndex<PickedBlockExtraDataStruct>(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;

View file

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