Add support for flipped blocks and auto-wiring, other fixes

This commit is contained in:
Norbi Peti 2021-04-19 03:13:00 +02:00
parent 9a4ff858f3
commit 1f688195af
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
5 changed files with 47 additions and 34 deletions

View file

@ -13,6 +13,7 @@ using Gamecraft.Blocks.GUI;
using GamecraftModdingAPI.Blocks;
using GamecraftModdingAPI.Utility;
using RobocraftX.Rendering.GPUI;
namespace GamecraftModdingAPI
{
@ -45,13 +46,15 @@ namespace GamecraftModdingAPI
/// <param name="rotation">The block's rotation in degrees</param>
/// <param name="uscale">The block's uniform scale - default scale is 1 (with 0.2 width)</param>
/// <param name="scale">The block's non-uniform scale - 0 means <paramref name="uscale"/> is used</param>
/// <param name="isFlipped">Whether the block should be flipped</param>
/// <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, Player player = null)
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, player);
return PlaceNew<Block>(block, position, rotation, color, material, uscale, scale, isFlipped, autoWire, player);
}
/// <summary>
@ -66,16 +69,19 @@ namespace GamecraftModdingAPI
/// <param name="rotation">The block's rotation in degrees</param>
/// <param name="uscale">The block's uniform scale - default scale is 1 (with 0.2 width)</param>
/// <param name="scale">The block's non-uniform scale - 0 means <paramref name="uscale"/> is used</param>
/// <param name="isFlipped">Whether the block should be flipped</param>
/// <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, Player player = null) where T : Block
int uscale = 1, float3 scale = default, bool isFlipped = false, 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, out var initializer);
position, uscale, scale, player, rotation, isFlipped, autoWire, out var initializer);
var bl = New<T>(egid.entityID, egid.groupID);
bl.InitData.Group = BlockEngine.InitGroup(initializer);
Placed += bl.OnPlacedInit;
@ -293,6 +299,24 @@ namespace GamecraftModdingAPI
}
}
/**
* Whether the block is fipped.
*/
public bool Flipped
{
get => BlockEngine.GetBlockInfo(this, (ScalingEntityStruct st) => st.scale.x < 0);
set
{
BlockEngine.SetBlockInfo(this, (ref ScalingEntityStruct st, bool val) =>
st.scale.x = math.abs(st.scale.x) * (val ? -1 : 1), value);
BlockEngine.SetBlockInfo(this, (ref GFXPrefabEntityStructGPUI st, bool val) =>
{
uint prefabId = PrefabsID.GetOrCreatePrefabID((ushort) Type, (byte) Material, 0, value);
st.prefabID = prefabId;
}, value);
}
}
/// <summary>
/// The block's type (ID). Returns BlockIDs.Invalid if the block doesn't exist anymore.
/// </summary>

View file

@ -80,17 +80,7 @@ namespace GamecraftModdingAPI.Blocks
public ref T GetBlockInfoViewStruct<T>(EGID blockID) where T : struct, INeedEGID, IEntityViewComponent
{
if (entitiesDB.Exists<T>(blockID))
{
// TODO: optimize by using EntitiesDB internal calls instead of iterating over everything
BT<MB<T>> entities = entitiesDB.QueryEntities<T>(blockID.groupID).ToBuffer();
for (int i = 0; i < entities.count; i++)
{
if (entities.buffer[i].ID == blockID)
{
return ref entities.buffer[i];
}
}
}
return ref entitiesDB.QueryEntity<T>(blockID);
T[] structHolder = new T[1]; //Create something that can be referenced
return ref structHolder[0]; //Gets a default value automatically
}

View file

@ -2,6 +2,7 @@
using RobocraftX.Common;
using HarmonyLib;
using Svelto.DataStructures;
namespace GamecraftModdingAPI.Blocks
{
@ -12,8 +13,8 @@ namespace GamecraftModdingAPI.Blocks
{
/// <summary>
/// Blocks placed by the player
/// </summary> - TODO
//public static ExclusiveGroup OWNED_BLOCKS { get { return CommonExclusiveGroups.REAL_BLOCKS_GROUPS_DON_T_USE_IN_NEW_CODE; } }
/// </summary>
public static FasterReadOnlyList<ExclusiveGroupStruct> OWNED_BLOCKS { get { return CommonExclusiveGroups.REAL_BLOCKS_GROUPS_DON_T_USE_IN_NEW_CODE; } }
/// <summary>
/// Extra parts used in functional blocks

View file

@ -2,6 +2,7 @@ using System;
using System.Reflection;
using DataLoader;
using Gamecraft.Wires;
using HarmonyLib;
using RobocraftX.Blocks;
using RobocraftX.Blocks.Scaling;
@ -41,16 +42,16 @@ namespace GamecraftModdingAPI.Blocks
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, out EntityInitializer initializer)
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
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,
(player ?? new Player(PlayerType.Local)).Id);
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, uint playerId)
private EntityInitializer BuildBlock(ushort block, byte color, byte materialId, float3 position, int uscale, float3 scale, float3 rot, bool isFlipped, bool autoWire, uint playerId)
{
if (_blockEntityFactory == null)
throw new BlockException("The factory is null.");
@ -63,7 +64,7 @@ namespace GamecraftModdingAPI.Blocks
if (!PrefabsID.PrefabIDByResourceIDMap.ContainsKey(resourceId))
throw new BlockException("Block with ID " + block + " not found!");
//RobocraftX.CR.MachineEditing.PlaceSingleBlockEngine
ScalingEntityStruct scaling = new ScalingEntityStruct {scale = scale};
ScalingEntityStruct scaling = new ScalingEntityStruct {scale = scale * (isFlipped ? -1 : 1)};
Quaternion rotQ = Quaternion.Euler(rot);
RotationEntityStruct rotation = new RotationEntityStruct {rotation = rotQ};
GridRotationStruct gridRotation = new GridRotationStruct
@ -86,7 +87,7 @@ namespace GamecraftModdingAPI.Blocks
{
materialId = materialId
});
uint prefabId = PrefabsID.GetOrCreatePrefabID(block, 0, 0, false); //TODO
uint prefabId = PrefabsID.GetOrCreatePrefabID(block, materialId, 0, isFlipped);
structInitializer.Init(new GFXPrefabEntityStructGPUI(prefabId));
structInitializer.Init(new PhysicsPrefabEntityStruct(prefabId));
structInitializer.Init(dbEntity);
@ -102,7 +103,7 @@ namespace GamecraftModdingAPI.Blocks
{
loadedFromDisk = false,
placedBy = playerId,
triggerAutoWiring = false //TODO
triggerAutoWiring = autoWire && structInitializer.Has<BlockPortsStruct>()
});
/*structInitializer.Init(new CollisionFilterOverride

View file

@ -11,6 +11,8 @@ using Svelto.ECS;
using GamecraftModdingAPI.Blocks;
using GamecraftModdingAPI.Utility;
using GamecraftModdingAPI.Engines;
using RobocraftX.Blocks;
using Techblox.FlyCam;
namespace GamecraftModdingAPI.Inventory
{
@ -36,18 +38,13 @@ namespace GamecraftModdingAPI.Inventory
public bool SelectBlock(int block, uint playerID, bool cubeSelectedByPick = false)
{
var inputs = entitiesDB.QueryEntities<LocalInputEntityStruct>(InputExclusiveGroups.LocalPlayers).ToBuffer();
if (inputs.count == 0) return false;
for (int i = 0; i < inputs.count; i++)
{
if (inputs.buffer[i].ID.entityID == playerID) {
/*inputs.buffer[i].cubeSelectedByPick = cubeSelectedByPick; - TODO
inputs.buffer[i].selectedCube = block;*/
return true;
}
}
if (!entitiesDB.TryQueryEntitiesAndIndex<EquippedPartStruct>(playerID, Techblox.FlyCam.FlyCam.Group,
out var index, out var inputs))
return false;
inputs[index].CubeSelectedByPick = cubeSelectedByPick;
inputs[index].SelectedDBPartID = block;
// TODO: expose the rest of the input functionality
return false;
return true;
}
public uint GetLocalPlayerID()