Weapons/ToolGun/Modes/BaseConstraintToolMode.cs
public abstract class BaseConstraintToolMode : ToolMode
{
protected SelectionPoint Point1;
protected SelectionPoint Point2;
protected int Stage = 0;
public virtual bool CanConstraintToSelf => false;
public override bool UseSnapGrid => true;
protected override void OnDisabled()
{
base.OnDisabled();
Stage = 0;
Point1 = default;
Point2 = default;
}
public override void OnControl()
{
base.OnControl();
var select = TraceSelect();
if ( Input.Pressed( "attack2" ) )
{
// Some constraint tools can one-shot with secondary, like sliders.
if ( Stage == 0 && GetSecondaryPoint( select ) is SelectionPoint point2 )
{
if ( !select.IsValid() )
return;
if ( !UpdateValidity( select, point2 ) )
return;
if ( !FireToolAction( ToolInput.Secondary ) )
return;
Point1 = select;
Point2 = point2;
Create( Point1, Point2 );
ShootEffects( select );
FirePostToolAction( ToolInput.Secondary );
return;
}
Stage = 0;
IsValidState = false;
return;
}
if ( !select.IsValid() )
return;
if ( Input.Pressed( "reload" ) )
{
if ( !FireToolAction( ToolInput.Reload ) )
return;
var go = select.GameObject.Network.RootGameObject ?? select.GameObject;
RemoveConstraints( go );
ShootEffects( select );
FirePostToolAction( ToolInput.Reload );
}
IsValidState = true;
if ( Stage == 0 )
{
IsValidState = UpdateValidity( select );
}
if ( Stage == 1 )
{
IsValidState = UpdateValidity( Point1, select );
}
if ( !IsValidState ) return;
if ( Input.Pressed( "attack1" ) )
{
if ( Stage == 0 )
{
Point1 = select;
Stage++;
ShootEffects( select );
return;
}
if ( Stage == 1 )
{
if ( !FireToolAction( ToolInput.Primary ) )
{
Stage = 0;
return;
}
Point2 = select;
Create( Point1, Point2 );
ShootEffects( select );
FirePostToolAction( ToolInput.Primary );
}
Stage = 0;
}
}
bool UpdateValidity( SelectionPoint point1, SelectionPoint point2 )
{
if ( !point1.GameObject.IsValid() ) return false;
if ( !point2.GameObject.IsValid() ) return false;
if ( !CanConstraintToSelf )
{
if ( point1.GameObject == point2.GameObject )
{
return false;
}
}
return true;
}
bool UpdateValidity( SelectionPoint point1 )
{
if ( !point1.GameObject.IsValid() ) return false;
return true;
}
[Rpc.Host( NetFlags.OwnerOnly )]
private void Create( SelectionPoint point1, SelectionPoint point2 )
{
if ( !UpdateValidity( point1, point2 ) )
{
Log.Warning( "Tried to create invalid constraint" );
return;
}
CreateConstraint( point1, point2 );
CheckContraptionStats( point1.GameObject );
}
[Rpc.Host( NetFlags.OwnerOnly )]
private void RemoveConstraints( GameObject go )
{
var builder = new LinkedGameObjectBuilder();
builder.AddConnected( go );
var toRemove = new List<GameObject>();
foreach ( var linked in builder.Objects )
toRemove.AddRange( FindConstraints( linked, go ) );
foreach ( var host in toRemove )
host.Destroy();
}
/// <summary>
/// Lets tools define what constraints should be removed when removing constraints from a game object.
/// </summary>
/// <param name="linked"></param>
/// <param name="target"></param>
/// <returns></returns>
protected virtual IEnumerable<GameObject> FindConstraints( GameObject linked, GameObject target ) => [];
protected abstract void CreateConstraint( SelectionPoint point1, SelectionPoint point2 );
protected virtual SelectionPoint? GetSecondaryPoint( SelectionPoint select ) => default;
}