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