NorbiPeti
9609187cff
Removed GameState methods from block APIs Created a BlockUtility class to get the block the player is looking at Changed the return type of PlaceBlock, returning the ID of the newly placed block or null
146 lines
No EOL
6 KiB
C#
146 lines
No EOL
6 KiB
C#
using System;
|
|
using System.Reflection;
|
|
|
|
using DataLoader;
|
|
using Harmony;
|
|
using RobocraftX.Blocks;
|
|
using RobocraftX.Blocks.Ghost;
|
|
using RobocraftX.Blocks.Scaling;
|
|
using RobocraftX.Character;
|
|
using RobocraftX.CommandLine.Custom;
|
|
using RobocraftX.Common;
|
|
using RobocraftX.Common.Input;
|
|
using RobocraftX.Common.Utilities;
|
|
using RobocraftX.CR.MachineEditing;
|
|
using RobocraftX.StateSync;
|
|
using Svelto.ECS;
|
|
using Svelto.ECS.EntityStructs;
|
|
using Unity.Jobs;
|
|
using Unity.Mathematics;
|
|
using UnityEngine;
|
|
using uREPL;
|
|
|
|
using GamecraftModdingAPI.Utility;
|
|
|
|
namespace GamecraftModdingAPI.Blocks
|
|
{
|
|
/// <summary>
|
|
/// Engine which executes block placement actions
|
|
/// </summary>
|
|
public class PlacementEngine : IApiEngine
|
|
{
|
|
public bool IsInGame = false;
|
|
|
|
public void Dispose()
|
|
{
|
|
IsInGame = false;
|
|
}
|
|
|
|
public void Ready()
|
|
{
|
|
IsInGame = true;
|
|
}
|
|
|
|
public EntitiesDB entitiesDB { get; set; }
|
|
private static BlockEntityFactory _blockEntityFactory; //Injected from PlaceBlockEngine
|
|
|
|
public EGID PlaceBlock(BlockIDs block, BlockColors color, byte darkness, float3 position, int uscale,
|
|
float3 scale, uint playerId, float3 rotation)
|
|
{ //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 (darkness > 9)
|
|
throw new Exception("That is too dark. Make sure to use 0-9 as darkness. (0 is default.)");
|
|
return BuildBlock((ushort) block, (byte) (color + darkness * 10), position, uscale, scale, rotation, playerId);
|
|
}
|
|
|
|
private EGID BuildBlock(ushort block, byte color, float3 position, int uscale, float3 scale, float3 rot, uint playerId)
|
|
{
|
|
if (_blockEntityFactory == null)
|
|
throw new Exception("The factory is null.");
|
|
if (uscale < 1)
|
|
throw new Exception("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 dbid = block;
|
|
if (!PrefabsID.DBIDMAP.ContainsKey(dbid))
|
|
throw new Exception("Block with ID " + dbid + " not found!");
|
|
//RobocraftX.CR.MachineEditing.PlaceBlockEngine
|
|
ScalingEntityStruct scaling = new ScalingEntityStruct {scale = scale};
|
|
Quaternion rotQ = Quaternion.Euler(rot);
|
|
RotationEntityStruct rotation = new RotationEntityStruct {rotation = rotQ};
|
|
GridRotationStruct gridRotation = new GridRotationStruct
|
|
{position = position, rotation = rotQ};
|
|
CubeCategoryStruct category = new CubeCategoryStruct
|
|
{category = CubeCategory.General, type = CubeType.Block};
|
|
DBEntityStruct dbEntity = new DBEntityStruct {DBID = dbid};
|
|
BlockPlacementScaleEntityStruct placementScale = new BlockPlacementScaleEntityStruct
|
|
{
|
|
blockPlacementHeight = uscale, blockPlacementWidth = uscale, desiredScaleFactor = uscale,
|
|
snapGridScale = uscale,
|
|
unitSnapOffset = 0, isUsingUnitSize = true
|
|
};
|
|
EquippedColourStruct colour = new EquippedColourStruct {indexInPalette = color};
|
|
EGID newBlockID;
|
|
switch (category.category)
|
|
{
|
|
case CubeCategory.SpawnPoint:
|
|
case CubeCategory.BuildingSpawnPoint:
|
|
newBlockID = MachineEditingGroups.NewSpawnPointBlockID;
|
|
break;
|
|
default:
|
|
newBlockID = MachineEditingGroups.NewBlockID;
|
|
break;
|
|
}
|
|
|
|
EntityStructInitializer
|
|
structInitializer =
|
|
_blockEntityFactory.Build(newBlockID, dbid); //The ghost block index is only used for triggers
|
|
if (colour.indexInPalette != byte.MaxValue)
|
|
structInitializer.Init(new ColourParameterEntityStruct
|
|
{
|
|
indexInPalette = colour.indexInPalette,
|
|
needsUpdate = true
|
|
});
|
|
uint prefabId = PrefabsID.GetPrefabId(dbid, 0);
|
|
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,
|
|
placedBy = playerId
|
|
});
|
|
PrimaryRotationUtility.InitialisePrimaryDirection(rotation.rotation, ref structInitializer);
|
|
EGID playerEGID = new EGID(playerId, CharacterExclusiveGroups.OnFootGroup);
|
|
ref PickedBlockExtraDataStruct pickedBlock = ref entitiesDB.QueryEntity<PickedBlockExtraDataStruct>(playerEGID);
|
|
pickedBlock.placedBlockEntityID = playerEGID;
|
|
pickedBlock.placedBlockWasAPickedBlock = false;
|
|
return newBlockID;
|
|
}
|
|
|
|
public string Name { get; } = "GamecraftModdingAPIPlacementGameEngine";
|
|
|
|
[HarmonyPatch]
|
|
public class FactoryObtainerPatch
|
|
{
|
|
static void Postfix(BlockEntityFactory blockEntityFactory)
|
|
{
|
|
_blockEntityFactory = blockEntityFactory;
|
|
Logging.MetaDebugLog("Block entity factory injected.");
|
|
}
|
|
|
|
static MethodBase TargetMethod(HarmonyInstance instance)
|
|
{
|
|
return AccessTools.TypeByName("RobocraftX.CR.MachineEditing.PlaceBlockEngine").GetConstructors()[0];
|
|
}
|
|
}
|
|
}
|
|
} |