@@ -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> | |||
@@ -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 | |||
} | |||
@@ -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 | |||
@@ -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 | |||
@@ -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() | |||