diff options
| author | Leonardo Bishop <me@leonardobishop.com> | 2023-07-28 22:06:03 +0100 |
|---|---|---|
| committer | Leonardo Bishop <me@leonardobishop.com> | 2023-07-28 22:06:03 +0100 |
| commit | 1e5c6393a6b29eb00dbb8fb137d86647cb0c356b (patch) | |
| tree | 95cbba0e7ade6bd97675480c2559c8e01f74a635 /code/pawn | |
| parent | f137095304f456b06229e4d17ee8249e974fceaf (diff) | |
Add TryUnstuck and death overlay
Diffstat (limited to 'code/pawn')
| -rw-r--r-- | code/pawn/Player.Use.cs | 117 | ||||
| -rw-r--r-- | code/pawn/Player.cs | 62 | ||||
| -rw-r--r-- | code/pawn/component/PlayerAnimator.cs (renamed from code/pawn/PlayerAnimator.cs) | 0 | ||||
| -rw-r--r-- | code/pawn/component/PlayerInventory.cs (renamed from code/pawn/PlayerInventory.cs) | 0 | ||||
| -rw-r--r-- | code/pawn/component/PlayerSpectator.cs (renamed from code/pawn/PlayerSpectator.cs) | 0 | ||||
| -rw-r--r-- | code/pawn/component/movement/BaseController.cs | 9 | ||||
| -rw-r--r-- | code/pawn/component/movement/PlayerController.cs (renamed from code/pawn/PlayerController.cs) | 11 |
7 files changed, 186 insertions, 13 deletions
diff --git a/code/pawn/Player.Use.cs b/code/pawn/Player.Use.cs new file mode 100644 index 0000000..3f35052 --- /dev/null +++ b/code/pawn/Player.Use.cs @@ -0,0 +1,117 @@ +using Sandbox;
+
+namespace MurderGame;
+
+public partial class Player
+{
+ public Entity Using { get; protected set; }
+
+ protected virtual void TickPlayerUse()
+ {
+ // This is serverside only
+ if ( !Game.IsServer ) return;
+
+ // Turn prediction off
+ using ( Prediction.Off() )
+ {
+ if ( Input.Pressed( "use" ) )
+ {
+ Using = FindUsable();
+
+ if ( Using == null )
+ {
+ UseFail();
+ return;
+ }
+ }
+
+ if ( !Input.Down( "use" ) )
+ {
+ StopUsing();
+ return;
+ }
+
+ if ( !Using.IsValid() )
+ return;
+
+ // If we move too far away or something we should probably ClearUse()?
+
+ //
+ // If use returns true then we can keep using it
+ //
+ if ( Using is IUse use && use.OnUse( this ) )
+ return;
+
+ StopUsing();
+ }
+ }
+
+ /// <summary>
+ /// Player tried to use something but there was nothing there.
+ /// Tradition is to give a disappointed boop.
+ /// </summary>
+ protected virtual void UseFail()
+ {
+ PlaySound( "player_use_fail" );
+ }
+
+ /// <summary>
+ /// If we're using an entity, stop using it
+ /// </summary>
+ protected virtual void StopUsing()
+ {
+ Using = null;
+ }
+
+ /// <summary>
+ /// Returns if the entity is a valid usable entity
+ /// </summary>
+ protected bool IsValidUseEntity( Entity e )
+ {
+ if ( e == null ) return false;
+ if ( e is not IUse use ) return false;
+ if ( !use.IsUsable( this ) ) return false;
+
+ return true;
+ }
+
+ /// <summary>
+ /// Find a usable entity for this player to use
+ /// </summary>
+ protected virtual Entity FindUsable()
+ {
+ // First try a direct 0 width line
+ var tr = Trace.Ray( EyePosition, EyePosition + EyeRotation.Forward * 85 )
+ .Ignore( this )
+ .Run();
+
+ // See if any of the parent entities are usable if we ain't.
+ var ent = tr.Entity;
+ while ( ent.IsValid() && !IsValidUseEntity( ent ) )
+ {
+ ent = ent.Parent;
+ }
+
+ // Nothing found, try a wider search
+ if ( !IsValidUseEntity( ent ) )
+ {
+ tr = Trace.Ray( EyePosition, EyePosition + EyeRotation.Forward * 85 )
+ .Radius( 2 )
+ .Ignore( this )
+ .Run();
+
+ // See if any of the parent entities are usable if we ain't.
+ ent = tr.Entity;
+ while ( ent.IsValid() && !IsValidUseEntity( ent ) )
+ {
+ ent = ent.Parent;
+ }
+ }
+
+ // Still no good? Bail.
+ if ( !IsValidUseEntity( ent ) ) return null;
+
+ return ent;
+ }
+}
+
diff --git a/code/pawn/Player.cs b/code/pawn/Player.cs index 68d383d..cd2f83a 100644 --- a/code/pawn/Player.cs +++ b/code/pawn/Player.cs @@ -36,8 +36,8 @@ public partial class Player : AnimatedEntity {
get => new
(
- new Vector3( -12, -12, 0 ),
- new Vector3( 12, 12, 64 )
+ new Vector3( -16, -16, 0 ),
+ new Vector3( 16, 16, 72 )
);
}
@@ -49,6 +49,7 @@ public partial class Player : AnimatedEntity [BindComponent] public PlayerInventory Inventory { get; }
[BindComponent] public PlayerSpectator Spectator { get; }
+ [Net]
public Ragdoll PlayerRagdoll { get; set; }
public ClothingContainer PlayerClothingContainer { get; set; }
@@ -57,6 +58,9 @@ public partial class Player : AnimatedEntity public override Ray AimRay => new Ray( EyePosition, EyeRotation.Forward );
+ [Net, Predicted]
+ public TimeSince TimeSinceDeath { get; set; } = 0;
+
public override void Spawn()
{
SetModel( "models/citizen/citizen.vmdl" );
@@ -66,21 +70,29 @@ public partial class Player : AnimatedEntity EnableDrawing = false;
EnableHideInFirstPerson = true;
EnableShadowInFirstPerson = true;
+
SetupPhysicsFromAABB( PhysicsMotionType.Keyframed, Hull.Mins, Hull.Maxs );
EnableSolidCollisions = false;
+
+ Health = 0f;
+ LifeState = LifeState.Dead;
}
public void Respawn()
{
+ DeleteRagdoll();
Tags.Add( "livingplayer" );
+
EnableAllCollisions = true;
EnableDrawing = true;
- Components.Remove( Spectator );
+
+ Components.RemoveAll();
Components.Create<PlayerController>();
Components.Create<PlayerAnimator>();
Components.Create<PlayerInventory>();
+
Health = 100f;
- DeleteRagdoll();
+ LifeState = LifeState.Alive;
}
public void Cleanup()
@@ -101,19 +113,27 @@ public partial class Player : AnimatedEntity public void DisablePlayer()
{
- EnableAllCollisions = false;
- LifeState = LifeState.Dead;
Tags.Remove( "livingplayer" );
+
+ EnableAllCollisions = false;
+ EnableDrawing = false;
+
Inventory?.Clear();
Components.RemoveAll();
- EnableDrawing = false;
+
+ LifeState = LifeState.Dead;
}
public override void OnKilled()
{
+ TimeSinceDeath = 0;
+
Inventory?.SpillContents(EyePosition, new Vector3(0,0,0));
+
DisablePlayer();
+
Event.Run( MurderEvent.Kill, LastAttacker, this );
+
var ragdoll = new Ragdoll();
ragdoll.Position = Position;
ragdoll.Rotation = Rotation;
@@ -121,7 +141,8 @@ public partial class Player : AnimatedEntity ragdoll.PhysicsGroup.AddVelocity(LastAttackForce / 100);
PlayerClothingContainer.DressEntity( ragdoll );
PlayerRagdoll = ragdoll;
- Components.Create<PlayerSpectator>();
+
+ DeathOverlay.Show( To.Single( Client ) );
}
public override void TakeDamage( DamageInfo info )
@@ -151,11 +172,22 @@ public partial class Player : AnimatedEntity public override void Simulate( IClient cl )
{
SimulateRotation();
- Controller?.Simulate( cl );
+ TickPlayerUse();
+
+ Controller?.Simulate( this );
Animator?.Simulate();
Inventory?.Simulate( cl );
Spectator?.Simulate();
+
EyeLocalPosition = Vector3.Up * (64f * Scale);
+
+ if (Game.IsServer && Spectator == null && LifeState == LifeState.Dead && TimeSinceDeath > 3)
+ {
+ Log.Info( "Spectator created" );
+ DeathOverlay.Hide( To.Single( Client ) );
+ Components.Create<PlayerSpectator>();
+ }
+
}
public override void BuildInput()
@@ -186,13 +218,23 @@ public partial class Player : AnimatedEntity Spectator.FrameSimulate(this);
return;
}
+ else if (Controller != null)
+ {
+ //TOOD move below logic to controller
+ }
SimulateRotation();
Camera.Rotation = ViewAngles.ToRotation();
Camera.FieldOfView = Screen.CreateVerticalFieldOfView( Game.Preferences.FieldOfView );
Camera.FirstPersonViewer = this;
- Camera.Position = EyePosition;
+ if (PlayerRagdoll != null && PlayerRagdoll.IsValid)
+ {
+ Camera.Position = PlayerRagdoll.Position;
+ } else
+ {
+ Camera.Position = EyePosition;
+ }
}
public TraceResult TraceBBox( Vector3 start, Vector3 end, float liftFeet = 0.0f )
diff --git a/code/pawn/PlayerAnimator.cs b/code/pawn/component/PlayerAnimator.cs index 4cd4e3f..4cd4e3f 100644 --- a/code/pawn/PlayerAnimator.cs +++ b/code/pawn/component/PlayerAnimator.cs diff --git a/code/pawn/PlayerInventory.cs b/code/pawn/component/PlayerInventory.cs index 55fa3ed..55fa3ed 100644 --- a/code/pawn/PlayerInventory.cs +++ b/code/pawn/component/PlayerInventory.cs diff --git a/code/pawn/PlayerSpectator.cs b/code/pawn/component/PlayerSpectator.cs index c468de0..c468de0 100644 --- a/code/pawn/PlayerSpectator.cs +++ b/code/pawn/component/PlayerSpectator.cs diff --git a/code/pawn/component/movement/BaseController.cs b/code/pawn/component/movement/BaseController.cs new file mode 100644 index 0000000..0b92c75 --- /dev/null +++ b/code/pawn/component/movement/BaseController.cs @@ -0,0 +1,9 @@ +using Sandbox;
+
+namespace MurderGame;
+
+//TODO make spectatro a controller
+public class BaseController : EntityComponent<Player>
+{
+ public Player Player { get; set; }
+}
diff --git a/code/pawn/PlayerController.cs b/code/pawn/component/movement/PlayerController.cs index d638bb0..5df9a33 100644 --- a/code/pawn/PlayerController.cs +++ b/code/pawn/component/movement/PlayerController.cs @@ -6,7 +6,7 @@ namespace MurderGame; public class PlayerController : EntityComponent<Player>
{
- public int StepSize => 12;
+ public int StepSize => 24;
public int GroundAngle => 45;
public int JumpSpeed => 300;
public float Gravity => 800f;
@@ -16,7 +16,7 @@ public class PlayerController : EntityComponent<Player> bool Grounded => Entity.GroundEntity.IsValid();
- public void Simulate( IClient cl )
+ public void Simulate( Player player )
{
ControllerEvents.Clear();
@@ -52,6 +52,12 @@ public class PlayerController : EntityComponent<Player> var mh = new MoveHelper( Entity.Position, Entity.Velocity );
mh.Trace = mh.Trace.Size( Entity.Hull ).Ignore( Entity );
+ if (mh.TryUnstuck())
+ {
+ Entity.Position = mh.Position;
+ Entity.Velocity = mh.Velocity;
+ }
+
if ( mh.TryMoveWithStep( Time.Delta, StepSize ) > 0 )
{
if ( Grounded )
@@ -61,7 +67,6 @@ public class PlayerController : EntityComponent<Player> Entity.Position = mh.Position;
Entity.Velocity = mh.Velocity;
}
-
Entity.GroundEntity = groundEntity;
}
|
