2020-01-03 01:14:26 +01:00
using System ;
using System.Reflection ;
2020-01-03 19:54:35 -05:00
2020-01-03 01:14:26 +01:00
using DataLoader ;
2020-05-03 15:31:09 -04:00
using HarmonyLib ;
2020-01-03 01:14:26 +01:00
using RobocraftX.Blocks ;
using RobocraftX.Blocks.Scaling ;
using RobocraftX.Character ;
using RobocraftX.Common ;
using RobocraftX.CR.MachineEditing ;
using Svelto.ECS ;
using Svelto.ECS.EntityStructs ;
using Unity.Mathematics ;
using UnityEngine ;
2020-01-03 19:54:35 -05:00
using GamecraftModdingAPI.Utility ;
2020-05-11 20:28:26 -04:00
using GamecraftModdingAPI.Engines ;
2020-05-13 14:02:36 +02:00
using GamecraftModdingAPI.Players ;
2020-11-09 16:18:25 -05:00
using RobocraftX.Rendering.GPUI ;
2020-01-03 19:54:35 -05:00
namespace GamecraftModdingAPI.Blocks
2020-01-03 01:14:26 +01:00
{
2020-01-03 19:54:35 -05:00
/// <summary>
/// Engine which executes block placement actions
/// </summary>
2020-01-03 01:14:26 +01:00
public class PlacementEngine : IApiEngine
{
2020-05-27 17:20:53 +02:00
public bool IsInGame ;
2020-01-03 01:14:26 +01:00
public void Dispose ( )
{
IsInGame = false ;
}
public void Ready ( )
{
IsInGame = true ;
}
2020-03-12 23:36:23 +01:00
public EntitiesDB entitiesDB { get ; set ; }
2021-04-10 02:02:47 +02:00
private static BlockEntityFactory _blockEntityFactory ; //Injected from PlaceSingleBlockEngine
2020-01-03 01:14:26 +01:00
2020-04-13 02:03:23 +02:00
public EGID PlaceBlock ( BlockIDs block , BlockColors color , byte darkness , float3 position , int uscale ,
2021-04-10 02:02:47 +02:00
float3 scale , Player player , float3 rotation , out EntityInitializer initializer )
2020-01-03 01:14:26 +01:00
{ //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
2020-01-03 19:54:35 -05:00
if ( darkness > 9 )
throw new Exception ( "That is too dark. Make sure to use 0-9 as darkness. (0 is default.)" ) ;
2020-07-15 21:58:24 +02:00
initializer = BuildBlock ( ( ushort ) block , ( byte ) ( color + darkness * 10 ) , position , uscale , scale , rotation ,
2020-05-13 14:02:36 +02:00
( player ? ? new Player ( PlayerType . Local ) ) . Id ) ;
2020-07-15 21:58:24 +02:00
return initializer . EGID ;
2020-01-03 01:14:26 +01:00
}
2021-04-10 02:02:47 +02:00
private EntityInitializer BuildBlock ( ushort block , byte color , float3 position , int uscale , float3 scale , float3 rot , uint playerId )
2020-01-03 01:14:26 +01:00
{
if ( _blockEntityFactory = = null )
2020-11-12 02:39:58 +01:00
throw new BlockException ( "The factory is null." ) ;
2020-01-03 01:14:26 +01:00
if ( uscale < 1 )
2020-11-12 02:39:58 +01:00
throw new BlockException ( "Scale needs to be at least 1" ) ;
2020-01-03 14:38:59 +01:00
if ( scale . x < 4e-5 ) scale . x = uscale ;
if ( scale . y < 4e-5 ) scale . y = uscale ;
if ( scale . z < 4e-5 ) scale . z = uscale ;
2021-04-10 02:02:47 +02:00
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
2020-01-03 01:14:26 +01:00
ScalingEntityStruct scaling = new ScalingEntityStruct { scale = scale } ;
2020-01-15 20:41:50 +01:00
Quaternion rotQ = Quaternion . Euler ( rot ) ;
RotationEntityStruct rotation = new RotationEntityStruct { rotation = rotQ } ;
2020-01-03 01:14:26 +01:00
GridRotationStruct gridRotation = new GridRotationStruct
2020-01-15 20:41:50 +01:00
{ position = position , rotation = rotQ } ;
2021-04-10 02:02:47 +02:00
DBEntityStruct dbEntity = new DBEntityStruct { DBID = block } ;
2020-01-03 01:14:26 +01:00
BlockPlacementScaleEntityStruct placementScale = new BlockPlacementScaleEntityStruct
{
2020-10-29 00:37:47 +01:00
blockPlacementHeight = uscale , blockPlacementWidth = uscale , desiredScaleFactor = uscale
2020-01-03 01:14:26 +01:00
} ;
2021-04-10 02:02:47 +02:00
EntityInitializer structInitializer = _blockEntityFactory . Build ( CommonExclusiveGroups . nextBlockEntityID , block ) ; //The ghost block index is only used for triggers
if ( color ! = byte . MaxValue )
2020-01-03 01:14:26 +01:00
structInitializer . Init ( new ColourParameterEntityStruct
{
2021-04-10 02:02:47 +02:00
indexInPalette = color ,
2020-11-09 16:18:25 -05:00
hasNetworkChange = true
2020-01-03 01:14:26 +01:00
} ) ;
2021-04-10 02:02:47 +02:00
structInitializer . Init ( new CubeMaterialStruct
{
materialId = 0 , //TODO
cosmeticallyPaintedOnly = true //TODO
} ) ;
uint prefabId = PrefabsID . GetOrCreatePrefabID ( block , 0 , 0 , false ) ; //TODO
2020-04-09 01:14:21 +02:00
structInitializer . Init ( new GFXPrefabEntityStructGPUI ( prefabId ) ) ;
structInitializer . Init ( new PhysicsPrefabEntityStruct ( prefabId ) ) ;
2020-01-03 01:14:26 +01:00
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
} ) ;
2020-04-13 01:31:06 +02:00
structInitializer . Init ( new BlockPlacementInfoStruct ( )
{
loadedFromDisk = false ,
2021-04-10 02:02:47 +02:00
placedBy = playerId ,
triggerAutoWiring = false //TODO
2020-04-13 01:31:06 +02:00
} ) ;
2021-04-10 02:02:47 +02:00
2020-11-13 23:59:37 +01:00
/ * structInitializer . Init ( new CollisionFilterOverride
{
belongsTo = 32 U ,
collidesWith = 239532 U
} ) ; * /
2020-11-14 22:43:45 +01:00
2020-04-09 01:14:21 +02:00
EGID playerEGID = new EGID ( playerId , CharacterExclusiveGroups . OnFootGroup ) ;
ref PickedBlockExtraDataStruct pickedBlock = ref entitiesDB . QueryEntity < PickedBlockExtraDataStruct > ( playerEGID ) ;
2020-07-11 00:30:58 +02:00
pickedBlock . placedBlockEntityID = structInitializer . EGID ;
2020-04-09 01:14:21 +02:00
pickedBlock . placedBlockWasAPickedBlock = false ;
2020-07-15 21:58:24 +02:00
return structInitializer ;
2020-01-03 01:14:26 +01:00
}
2020-01-03 19:54:35 -05:00
public string Name { get ; } = "GamecraftModdingAPIPlacementGameEngine" ;
2020-01-03 01:14:26 +01:00
2021-04-10 02:02:47 +02:00
public bool isRemovable = > false ;
2020-05-11 20:28:26 -04:00
2020-05-27 17:20:53 +02:00
[HarmonyPatch]
2020-01-03 01:14:26 +01:00
public class FactoryObtainerPatch
{
static void Postfix ( BlockEntityFactory blockEntityFactory )
{
_blockEntityFactory = blockEntityFactory ;
2020-01-03 19:54:35 -05:00
Logging . MetaDebugLog ( "Block entity factory injected." ) ;
2020-01-03 01:14:26 +01:00
}
2020-05-03 15:31:09 -04:00
static MethodBase TargetMethod ( Harmony instance )
2020-01-03 01:14:26 +01:00
{
2021-04-10 02:02:47 +02:00
return AccessTools . TypeByName ( "RobocraftX.CR.MachineEditing.PlaceSingleBlockEngine" ) . GetConstructors ( ) [ 0 ] ;
2020-01-03 01:14:26 +01:00
}
}
}
}