2020-06-03 01:12:03 +00:00
using System ;
2020-06-04 23:00:03 +00:00
using System.Collections.Generic ;
2020-06-03 01:12:03 +00:00
using System.Linq ;
2020-06-04 23:00:03 +00:00
using Gamecraft.Wires.ChannelsCommon ;
2020-06-03 01:12:03 +00:00
using GamecraftModdingAPI ;
2020-06-04 23:00:03 +00:00
using GamecraftModdingAPI.Blocks ;
2020-06-03 01:12:03 +00:00
using GamecraftModdingAPI.Commands ;
using GamecraftModdingAPI.Engines ;
using GamecraftModdingAPI.Players ;
using GamecraftModdingAPI.Utility ;
using HarmonyLib ;
using IllusionPlugin ;
using RobocraftX.Character.Weapons ;
2020-06-04 23:00:03 +00:00
using RobocraftX.CommandLine.Custom ;
2020-06-03 01:12:03 +00:00
using RobocraftX.Common.Players ;
using Svelto.ECS ;
using Svelto.ECS.Internal ;
using Unity.Mathematics ;
2020-06-06 00:47:53 +00:00
using uREPL ;
2020-06-04 23:00:03 +00:00
using Main = GamecraftModdingAPI . Main ;
2020-06-03 01:12:03 +00:00
namespace BlockMod
{
public class BlockMod : IPlugin
{
2020-06-06 00:47:53 +00:00
private Block [ ] blocks = new Block [ 0 ] ;
private Block refBlock ;
2020-06-03 01:12:03 +00:00
public void OnApplicationStart ( )
{
Main . Init ( ) ;
GameClient . SetDebugInfo ( "BlockModInfo" , GetBlockInfo ) ;
2020-06-06 00:47:53 +00:00
RegisterBlockCommand ( "scaleBlocks" ,
"Scales the blocks you're looking at, relative to current size (current scale * new scale)." +
" The block you're looking at stays where it is, everything else is moved next to it." ,
( scaleX , scaleY , scaleZ , blocks , refBlock ) = >
2020-06-03 01:12:03 +00:00
{
2020-06-06 00:47:53 +00:00
if ( ! GameState . IsBuildMode ( ) ) return ; //Scaling & positioning is weird in simulation
if ( CheckNoBlocks ( blocks ) ) return ;
2020-06-04 23:00:03 +00:00
// ReSharper disable once PossibleNullReferenceException
float3 reference = refBlock . Position ;
2020-06-03 01:12:03 +00:00
float3 scale = new float3 ( scaleX , scaleY , scaleZ ) ;
2020-06-04 23:00:03 +00:00
foreach ( var block in blocks )
2020-06-03 01:12:03 +00:00
{
block . Scale * = scale ;
block . Position = reference + ( block . Position - reference ) * scale ;
}
Logging . CommandLog ( "Blocks scaled." ) ;
2020-06-06 00:47:53 +00:00
} ) ;
RegisterBlockCommand ( "scaleIndividually" , "Scales the blocks you're looking at, but doesn't move them." +
"The scale is relative, 1 means no change. Look at a block previously scaled to scale all of the blocks that were connected to it." ,
( scaleX , scaleY , scaleZ , blocks , refBlock ) = >
2020-06-03 01:12:03 +00:00
{
2020-06-06 00:47:53 +00:00
if ( ! GameState . IsBuildMode ( ) ) return ; //Scaling & positioning is weird in simulation
2020-06-03 01:12:03 +00:00
float3 scale = new float3 ( scaleX , scaleY , scaleZ ) ;
2020-06-04 23:00:03 +00:00
foreach ( var block in blocks )
2020-06-03 01:12:03 +00:00
block . Scale * = scale ;
2020-06-06 00:47:53 +00:00
} ) ;
RegisterBlockCommand ( "moveBlocks" , "Moves the blocks around." , ( x , y , z , blocks , refBlock ) = >
{
if ( GameState . IsBuildMode ( ) )
foreach ( var block in blocks )
block . Position + = new float3 ( x , y , z ) ;
else if ( GameState . IsSimulationMode ( ) )
foreach ( var body in GetSimBodies ( blocks ) )
body . Position + = new float3 ( x , y , z ) ;
} ) ;
RegisterBlockCommand ( "colorBlocks" , "Colors the blocks you're looking at" ,
( color , darkness , blocks , refBlock ) = >
2020-06-04 23:00:03 +00:00
{
if ( ! Enum . TryParse ( color , true , out BlockColors clr ) )
{
Logging . CommandLogWarning ( "Color " + color + " not found" ) ;
}
2020-06-06 00:47:53 +00:00
2020-06-04 23:00:03 +00:00
foreach ( var block in blocks )
block . Color = new BlockColor { Color = clr , Darkness = darkness } ;
2020-06-06 00:47:53 +00:00
} ) ;
2020-06-04 23:00:03 +00:00
CommandBuilder . Builder ( "selectBlocksLookedAt" , "Selects blocks (1 or more) to change. Only works in build mode, however the blocks can be changed afterwards." +
" Paramter: whether one (true) or all connected (false) blocks should be selected." )
. Action < bool > ( single = >
{
refBlock = new Player ( PlayerType . Local ) . GetBlockLookedAt ( ) ;
blocks = single ? new [ ] { refBlock } : refBlock ? . GetConnectedCubes ( ) ? ? new Block [ 0 ] ;
Logging . CommandLog ( blocks = = null ? "Selection cleared." : blocks . Length + " blocks selected." ) ;
} ) . Build ( ) ;
CommandBuilder . Builder ( "selectBlocksWithID" , "Selects blocks with a specific object ID." )
. Action < char > ( id = >
blocks = ( refBlock = ObjectIdentifier . GetByID ( id ) . FirstOrDefault ( ) ) ? . GetConnectedCubes ( ) ? ?
new Block [ 0 ] ) . Build ( ) ;
2020-06-06 00:47:53 +00:00
RegisterBlockCommand ( "pushBlocks" , "Adds velocity to the selected blocks. Only works in simulation." ,
( x , y , z , blocks , refBlock ) = >
2020-06-04 23:00:03 +00:00
{
foreach ( var block in GetSimBodies ( blocks ) )
block . Velocity + = new float3 ( x , y , z ) ;
2020-06-06 00:47:53 +00:00
} ) ;
RegisterBlockCommand ( "pushRotateBlocks" ,
"Adds angular velocity to the selected blocks. Only works in simulation." ,
( x , y , z , blocks , refBlock ) = >
2020-06-04 23:00:03 +00:00
{
foreach ( var block in GetSimBodies ( blocks ) )
block . AngularVelocity + = new float3 ( x , y , z ) ;
2020-06-06 00:47:53 +00:00
} ) ;
2020-06-04 23:00:03 +00:00
CommandBuilder . Builder ( "pushPlayer" , "Adds velocity to the player." )
. Action < float , float , float > ( ( x , y , z ) = >
{
new Player ( PlayerType . Local ) . Velocity + = new float3 ( x , y , z ) ;
} ) . Build ( ) ;
CommandBuilder . Builder ( "pushRotatePlayer" , "Adds angular velocity to the player." )
. Action < float , float , float > ( ( x , y , z ) = >
{
new Player ( PlayerType . Local ) . AngularVelocity + = new float3 ( x , y , z ) ;
2020-06-03 01:12:03 +00:00
} ) . Build ( ) ;
}
2020-06-06 00:47:53 +00:00
2020-06-03 01:12:03 +00:00
private string GetBlockInfo ( )
{
if ( GameState . IsBuildMode ( ) )
{
var block = new Player ( PlayerType . Local ) . GetBlockLookedAt ( ) ;
float3 pos = block . Position ;
float3 rot = block . Rotation ;
float3 scale = block . Scale ;
return $"Block: {block.Type} at {pos.x:F} {pos.y:F} {pos.z:F}\n" +
$"- Rotation: {rot.x:F}° {rot.y:F}° {rot.z:F}°\n" +
$"- Color: {block.Color.Color} darkness: {block.Color.Darkness}\n" +
$"- Scale: {scale.x:F} {scale.y:F} {scale.z:F}\n" +
$"- Label: {block.Label}" ;
}
if ( GameState . IsSimulationMode ( ) )
{
var body = new Player ( PlayerType . Local ) . GetSimBodyLookedAt ( ) ;
float3 pos = body . Position ;
float3 rot = body . Rotation ;
float3 vel = body . Velocity ;
float3 ave = body . AngularVelocity ;
float3 com = body . CenterOfMass ;
return $"Body at {pos.x:F} {pos.y:F} {pos.z:F}\n" +
$"- Rotation: {rot.x:F}° {rot.y:F}° {rot.z:F}°\n" +
$"- Velocity: {vel.x:F} {vel.y:F} {vel.z:F}\n" +
$"- Angular velocity: {ave.x:F} {ave.y:F} {ave.z:F}\n" +
$"- {(body.Static ? " Static body " : $" Mass : { body . Mass : F } center : { com . x : F } { com . y : F } { com . z : F } ")}" ;
}
return "Switching modes..." ;
}
2020-06-04 23:00:03 +00:00
private bool CheckNoBlocks ( Block [ ] blocks )
2020-06-03 01:12:03 +00:00
{
2020-06-04 23:00:03 +00:00
if ( blocks . Length = = 0 )
{
Logging . CommandLogWarning ( "No blocks selected. Use selectBlocks first." ) ;
return true ;
}
2020-06-03 01:12:03 +00:00
2020-06-04 23:00:03 +00:00
return false ;
2020-06-03 01:12:03 +00:00
}
2020-06-06 00:47:53 +00:00
private IEnumerable < SimBody > GetSimBodies ( Block [ ] blocks )
2020-06-04 23:00:03 +00:00
= > blocks . Select ( block = > block . GetSimBody ( ) ) . Distinct ( ) ;
2020-06-06 00:47:53 +00:00
private Block [ ] SelectBlocks ( byte id )
{
var blocks = ObjectIdentifier . GetBySimID ( id ) . SelectMany ( block = > block . GetConnectedCubes ( ) ) . ToArray ( ) ;
return blocks ;
}
//private void RegisterBlockCommand<T>(string name, string desc, T action) where T : Delegate
private void RegisterBlockCommand ( string name , string desc , Action < string , byte , Block [ ] , Block > action )
{
/ * switch ( action )
{
case Action < Block [ ] , Block > act
break ;
case Action < float , float , float , Block [ ] , Block > act :
break ;
default :
Logging . LogWarning ( "Unexpected parameters for command: " + name ) ;
break ;
} * /
RuntimeCommands . Register < string , byte > ( name , ( a1 , a2 ) = >
{
if ( CheckNoBlocks ( blocks ) ) return ;
action ( a1 , a2 , blocks , refBlock ) ;
} , desc ) ;
ConsoleCommands . RegisterWithChannel < string , byte > ( name , ( a1 , a2 , ch ) = >
{
var blks = SelectBlocks ( ch ) ;
if ( CheckNoBlocks ( blks ) ) return ;
action ( a1 , a2 , blks , blks [ 0 ] ) ;
} , BinaryChannelUtilities . ChannelType . Object , desc ) ;
}
private void RegisterBlockCommand ( string name , string desc , Action < float , float , float , Block [ ] , Block > action )
{
RuntimeCommands . Register < float , float , float > ( name , ( x , y , z ) = >
{
if ( CheckNoBlocks ( blocks ) ) return ;
action ( x , y , z , blocks , refBlock ) ;
} ,
desc ) ;
ConsoleCommands . RegisterWithChannel < float , float , float > ( name , ( x , y , z , ch ) = >
{
var blks = SelectBlocks ( ch ) ;
if ( CheckNoBlocks ( blks ) ) return ;
action ( x , y , z , blks , blks [ 0 ] ) ;
} , BinaryChannelUtilities . ChannelType . Object , desc ) ;
}
2020-06-03 01:12:03 +00:00
public void OnApplicationQuit ( )
{
}
public void OnLevelWasLoaded ( int level )
{
}
public void OnLevelWasInitialized ( int level )
{
}
public void OnUpdate ( )
{
}
public void OnFixedUpdate ( )
{
}
public string Name { get ; } = "BlockMod" ;
public string Version { get ; } = "v1.0.0" ;
}
}