upd
This commit is contained in:
@@ -1,6 +1,4 @@
|
||||
using Sandbox;
|
||||
|
||||
public sealed partial class Dedugan
|
||||
public sealed partial class Dedugan
|
||||
{
|
||||
void UpdateCustomAnimations()
|
||||
{
|
||||
|
||||
@@ -1,11 +1,27 @@
|
||||
public sealed partial class Dedugan
|
||||
using Sandbox.Citizen;
|
||||
|
||||
public sealed partial class Dedugan
|
||||
{
|
||||
private float anotherPivot;
|
||||
private Vector3 pivotOffset;
|
||||
private void RotateCamera()
|
||||
{
|
||||
if ( Input.Keyboard.Pressed( "Q" ) )
|
||||
{
|
||||
anotherPivot = 40f;
|
||||
}
|
||||
|
||||
if ( Input.Keyboard.Pressed( "E" ) )
|
||||
{
|
||||
anotherPivot = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (RagdollController.Enabled)
|
||||
{
|
||||
var offset = RagdollController.WorldRotation.Up * 20f - Camera.WorldRotation.Forward * 200f;
|
||||
Camera.WorldPosition = Vector3.Lerp(Camera.WorldPosition, RagdollController.WorldPosition + offset, Time.Delta * 5f);
|
||||
var off = RagdollController.WorldRotation.Up * 20f - Camera.WorldRotation.Forward * 200f;
|
||||
Camera.WorldPosition = Vector3.Lerp(Camera.WorldPosition, RagdollController.WorldPosition + off, Time.Delta * 5f);
|
||||
Camera.LocalRotation = Rotation.Lerp(Camera.LocalRotation, EyeAngles.ToRotation(), Time.Delta * 2f);
|
||||
}
|
||||
else
|
||||
@@ -15,11 +31,22 @@
|
||||
// Camera.LocalPosition = offset * Camera.LocalRotation;
|
||||
|
||||
Camera.LocalRotation = EyeAngles.ToRotation();
|
||||
var pivotOffset = CameraPivot.LocalRotation.Backward * CamOffsetX;
|
||||
|
||||
|
||||
var localPitchOffset = Camera.LocalRotation.Down * MathF.Max( 0f, EyeAngles.pitch ) * 0.32f +
|
||||
Camera.LocalRotation.Backward * MathF.Max( 0f, EyeAngles.pitch ) * 0.7f +
|
||||
Camera.LocalRotation.Up * MathF.Min( 0f, EyeAngles.pitch ) * 0.5f +
|
||||
Camera.LocalRotation.Backward * MathF.Min( 0f, EyeAngles.pitch ) * 0.8f;
|
||||
Camera.LocalRotation.Backward * MathF.Min( 0f, EyeAngles.pitch ) * 0.8f +
|
||||
Camera.LocalRotation.Right * -anotherPivot;
|
||||
|
||||
if ( AnimationHelper.HoldType == CitizenAnimationHelper.HoldTypes.Pistol )
|
||||
{
|
||||
pivotOffset = CameraPivot.LocalRotation.Backward * CamOffsetX * 0.5f + CameraPivot.LocalRotation.Up * 8f;
|
||||
}
|
||||
else
|
||||
{
|
||||
pivotOffset = CameraPivot.LocalRotation.Backward * CamOffsetX;
|
||||
}
|
||||
|
||||
var offset = (CameraPivot.LocalPosition + pivotOffset ) * EyeAngles.ToRotation() + localPitchOffset;
|
||||
Camera.LocalPosition = offset;
|
||||
|
||||
56
Code/Player/Dedugan.Footsteps.cs
Normal file
56
Code/Player/Dedugan.Footsteps.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
public sealed partial class Dedugan
|
||||
{
|
||||
public bool DebugFootsteps = false;
|
||||
public bool EnableFootstepSounds = true;
|
||||
private TimeSince _timeSinceStep;
|
||||
|
||||
private void OnFootstepEvent( SceneModel.FootstepEvent e )
|
||||
{
|
||||
if ( Controller.IsOnGround && EnableFootstepSounds && !(_timeSinceStep < 0.2f) )
|
||||
{
|
||||
_timeSinceStep = 0f;
|
||||
PlayFootstepSound( e.Transform.Position, e.Volume, e.FootId );
|
||||
}
|
||||
}
|
||||
|
||||
[Rpc.Broadcast]
|
||||
public void PlayFootstepSound( Vector3 worldPosition, float volume, int foot )
|
||||
{
|
||||
SceneTrace trace = Scene.Trace;
|
||||
Vector3 from = worldPosition + WorldRotation.Up * 10f;
|
||||
Vector3 to = worldPosition + WorldRotation.Down * 20f;
|
||||
SceneTraceResult sceneTraceResult = trace.Ray( in from, in to ).IgnoreGameObjectHierarchy( GameObject ).Run();
|
||||
if ( !sceneTraceResult.Hit || sceneTraceResult.Surface == null )
|
||||
{
|
||||
if ( DebugFootsteps )
|
||||
{
|
||||
DebugOverlay.Sphere( new Sphere( worldPosition, volume ), Color.Red, 10f, default, overlay: true );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
SoundEvent soundEvent = ResourceLibrary.Get<SoundEvent>( (foot == 0)
|
||||
? sceneTraceResult.Surface.Sounds.FootLeft
|
||||
: sceneTraceResult.Surface.Sounds.FootRight );
|
||||
if ( soundEvent == null )
|
||||
{
|
||||
if ( DebugFootsteps )
|
||||
{
|
||||
DebugOverlay.Sphere( new Sphere( worldPosition, volume ), Color.Orange, 10f, default, overlay: true );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
SoundHandle soundHandle = GameObject.PlaySound( soundEvent, 0f );
|
||||
// soundHandle.TargetMixer = FootstepMixer.GetOrDefault();
|
||||
// soundHandle.Volume *= volume * FootstepVolume;
|
||||
if ( DebugFootsteps )
|
||||
{
|
||||
DebugOverlay.Sphere( new Sphere( worldPosition, volume ), default, 10f, default, overlay: true );
|
||||
DebugOverlay.Text( worldPosition, soundEvent.ResourceName ?? "", 14f, TextFlag.LeftTop, default, 10f,
|
||||
default );
|
||||
}
|
||||
}
|
||||
}
|
||||
26
Code/Player/Dedugan.Hit.cs
Normal file
26
Code/Player/Dedugan.Hit.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public sealed partial class Dedugan
|
||||
{
|
||||
[Rpc.Broadcast]
|
||||
public void ReportHit( Vector3 dir, int boneIndex, int damage = 10 )
|
||||
{
|
||||
Renderer.Set( "hit", true );
|
||||
Renderer.Set( "hit_bone", boneIndex );
|
||||
Renderer.Set( "hit_direction", dir );
|
||||
Renderer.Set( "hit_offset", dir );
|
||||
Renderer.Set( "hit_strength", 1 );
|
||||
|
||||
Health -= damage;
|
||||
if ( Health <= 0 )
|
||||
{
|
||||
_ = RunReportHitAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RunReportHitAsync()
|
||||
{
|
||||
await GameTask.DelaySeconds( 0.1f );
|
||||
RagdollController.Enabled = true;
|
||||
}
|
||||
}
|
||||
@@ -5,215 +5,212 @@ using System.Linq;
|
||||
|
||||
public sealed partial class Dedugan : Component
|
||||
{
|
||||
public Component Pressed { get; set; }
|
||||
public bool EnablePressing { get; set; } = true;
|
||||
public Component Hovered { get; set; }
|
||||
public Component Pressed { get; set; }
|
||||
public bool EnablePressing { get; set; } = true;
|
||||
public Component Hovered { get; set; }
|
||||
|
||||
[Sync(SyncFlags.Interpolate)]
|
||||
public Vector3 TracedHitPos { get; set; }
|
||||
[Sync]
|
||||
public bool CameraTraceIsHit { get; set; }
|
||||
public Vector3 TracedHitNormal { get; set; }
|
||||
[Sync( SyncFlags.Interpolate )] public Vector3 TracedHitPos { get; set; }
|
||||
[Sync] public bool CameraTraceIsHit { get; set; }
|
||||
public Vector3 TracedHitNormal { get; set; }
|
||||
|
||||
// private TimeSince HoldTime = 0;
|
||||
// private bool Holding = false;
|
||||
// private bool HoldingInteractionHappened = false;
|
||||
// private TimeSince HoldTime = 0;
|
||||
// private bool Holding = false;
|
||||
// private bool HoldingInteractionHappened = false;
|
||||
|
||||
void InteractionsUpdate()
|
||||
{
|
||||
if (!EnablePressing)
|
||||
{
|
||||
// Holding = false;
|
||||
// HoldingInteractionHappened = false;
|
||||
return;
|
||||
}
|
||||
void InteractionsUpdate()
|
||||
{
|
||||
if ( !EnablePressing )
|
||||
{
|
||||
// Holding = false;
|
||||
// HoldingInteractionHappened = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Pressed.IsValid())
|
||||
{
|
||||
UpdatePressed();
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateHovered();
|
||||
}
|
||||
}
|
||||
if ( Pressed.IsValid() )
|
||||
{
|
||||
UpdatePressed();
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateHovered();
|
||||
}
|
||||
|
||||
private void UpdatePressed()
|
||||
{
|
||||
bool flag = Input.Down("use");
|
||||
if ( Input.Pressed( "Ragdoll" ) )
|
||||
{
|
||||
Health = 100;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag && Pressed.Components.TryGet<IPressable>(out var pressable))
|
||||
{
|
||||
flag = pressable.Pressing(new IPressable.Event
|
||||
{
|
||||
Ray = new Ray(Camera.WorldPosition, EyeAngles.ToRotation().Forward),
|
||||
Source = this
|
||||
});
|
||||
}
|
||||
private void UpdatePressed()
|
||||
{
|
||||
bool flag = Input.Down( "use" );
|
||||
|
||||
if (GetDistanceFromGameObject(Pressed.GameObject, Camera.WorldPosition) > InteractDistance)
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
if ( flag && Pressed.Components.TryGet<IPressable>( out var pressable ) )
|
||||
{
|
||||
flag = pressable.Pressing( new IPressable.Event
|
||||
{
|
||||
Ray = new Ray( Camera.WorldPosition, EyeAngles.ToRotation().Forward ), Source = this
|
||||
} );
|
||||
}
|
||||
|
||||
if (!flag)
|
||||
{
|
||||
StopPressing();
|
||||
}
|
||||
}
|
||||
if ( GetDistanceFromGameObject( Pressed.GameObject, Camera.WorldPosition ) > InteractDistance )
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
|
||||
private void UpdateHovered()
|
||||
{
|
||||
SwitchHovered(TryGetLookedAt());
|
||||
if ( !flag )
|
||||
{
|
||||
StopPressing();
|
||||
}
|
||||
}
|
||||
|
||||
if (Hovered is IPressable pressable)
|
||||
{
|
||||
pressable.Look(new IPressable.Event
|
||||
{
|
||||
Ray = new Ray(Camera.WorldPosition, EyeAngles.ToRotation().Forward),
|
||||
Source = this
|
||||
});
|
||||
}
|
||||
private void UpdateHovered()
|
||||
{
|
||||
SwitchHovered( TryGetLookedAt() );
|
||||
|
||||
if (Input.Down("use"))
|
||||
{
|
||||
StartPressing(Hovered);
|
||||
}
|
||||
}
|
||||
if ( Hovered is IPressable pressable )
|
||||
{
|
||||
pressable.Look( new IPressable.Event
|
||||
{
|
||||
Ray = new Ray( Camera.WorldPosition, EyeAngles.ToRotation().Forward ), Source = this
|
||||
} );
|
||||
}
|
||||
|
||||
public void StartPressing(Component obj)
|
||||
{
|
||||
StopPressing();
|
||||
if (!obj.IsValid())
|
||||
{
|
||||
ISceneEvent<PlayerController.IEvents>.PostToGameObject(GameObject, x => x.FailPressing());
|
||||
return;
|
||||
}
|
||||
if ( Input.Down( "use" ) )
|
||||
{
|
||||
StartPressing( Hovered );
|
||||
}
|
||||
}
|
||||
|
||||
var component = obj.Components.Get<IPressable>(FindMode.EnabledInSelfAndDescendants);
|
||||
if (component != null)
|
||||
{
|
||||
var pressEvent = new IPressable.Event
|
||||
{
|
||||
Ray = new Ray(Camera.WorldPosition, EyeAngles.ToRotation().Forward),
|
||||
Source = this
|
||||
};
|
||||
public void StartPressing( Component obj )
|
||||
{
|
||||
StopPressing();
|
||||
if ( !obj.IsValid() )
|
||||
{
|
||||
ISceneEvent<PlayerController.IEvents>.PostToGameObject( GameObject, x => x.FailPressing() );
|
||||
return;
|
||||
}
|
||||
|
||||
if (!component.CanPress(pressEvent))
|
||||
{
|
||||
ISceneEvent<PlayerController.IEvents>.PostToGameObject(GameObject, x => x.FailPressing());
|
||||
return;
|
||||
}
|
||||
var component = obj.Components.Get<IPressable>( FindMode.EnabledInSelfAndDescendants );
|
||||
if ( component != null )
|
||||
{
|
||||
var pressEvent = new IPressable.Event
|
||||
{
|
||||
Ray = new Ray( Camera.WorldPosition, EyeAngles.ToRotation().Forward ), Source = this
|
||||
};
|
||||
|
||||
component.Press(pressEvent);
|
||||
}
|
||||
if ( !component.CanPress( pressEvent ) )
|
||||
{
|
||||
ISceneEvent<PlayerController.IEvents>.PostToGameObject( GameObject, x => x.FailPressing() );
|
||||
return;
|
||||
}
|
||||
|
||||
Pressed = obj;
|
||||
component.Press( pressEvent );
|
||||
}
|
||||
|
||||
if (Pressed.IsValid())
|
||||
{
|
||||
ISceneEvent<PlayerController.IEvents>.PostToGameObject(GameObject, x => x.StartPressing(Pressed));
|
||||
}
|
||||
}
|
||||
Pressed = obj;
|
||||
|
||||
public void StopPressing()
|
||||
{
|
||||
if (Pressed.IsValid())
|
||||
{
|
||||
ISceneEvent<PlayerController.IEvents>.PostToGameObject(GameObject, x => x.StopPressing(Pressed));
|
||||
if ( Pressed.IsValid() )
|
||||
{
|
||||
ISceneEvent<PlayerController.IEvents>.PostToGameObject( GameObject, x => x.StartPressing( Pressed ) );
|
||||
}
|
||||
}
|
||||
|
||||
if (Pressed is IPressable pressable)
|
||||
{
|
||||
pressable.Release(new IPressable.Event
|
||||
{
|
||||
Ray = new Ray(Camera.WorldPosition, EyeAngles.ToRotation().Forward),
|
||||
Source = this
|
||||
});
|
||||
}
|
||||
public void StopPressing()
|
||||
{
|
||||
if ( Pressed.IsValid() )
|
||||
{
|
||||
ISceneEvent<PlayerController.IEvents>.PostToGameObject( GameObject, x => x.StopPressing( Pressed ) );
|
||||
|
||||
Pressed = null;
|
||||
}
|
||||
}
|
||||
if ( Pressed is IPressable pressable )
|
||||
{
|
||||
pressable.Release( new IPressable.Event
|
||||
{
|
||||
Ray = new Ray( Camera.WorldPosition, EyeAngles.ToRotation().Forward ), Source = this
|
||||
} );
|
||||
}
|
||||
|
||||
private void SwitchHovered(Component obj)
|
||||
{
|
||||
var e = new IPressable.Event
|
||||
{
|
||||
Ray = new Ray(Camera.WorldPosition, EyeAngles.ToRotation().Forward),
|
||||
Source = this
|
||||
};
|
||||
Pressed = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (Hovered == obj)
|
||||
{
|
||||
if (Hovered is IPressable pressable)
|
||||
pressable.Look(e);
|
||||
return;
|
||||
}
|
||||
private void SwitchHovered( Component obj )
|
||||
{
|
||||
var e = new IPressable.Event
|
||||
{
|
||||
Ray = new Ray( Camera.WorldPosition, EyeAngles.ToRotation().Forward ), Source = this
|
||||
};
|
||||
|
||||
if (Hovered is IPressable oldPressable)
|
||||
oldPressable.Blur(e);
|
||||
if ( Hovered == obj )
|
||||
{
|
||||
if ( Hovered is IPressable pressable )
|
||||
pressable.Look( e );
|
||||
return;
|
||||
}
|
||||
|
||||
Hovered = obj;
|
||||
if ( Hovered is IPressable oldPressable )
|
||||
oldPressable.Blur( e );
|
||||
|
||||
if (Hovered is IPressable newPressable)
|
||||
{
|
||||
newPressable.Hover(e);
|
||||
newPressable.Look(e);
|
||||
}
|
||||
}
|
||||
Hovered = obj;
|
||||
|
||||
private Component TryGetLookedAt()
|
||||
{
|
||||
for (float num = 0f; num <= 4f; num += 2f)
|
||||
{
|
||||
var from = Scene.Camera.WorldPosition + Scene.Camera.WorldRotation.Forward;
|
||||
var to = from + Scene.Camera.WorldRotation.Forward * (InteractDistance - num);
|
||||
var trace = Scene.Trace.Ray(from, to).IgnoreGameObjectHierarchy(GameObject).Radius(num).Run();
|
||||
if ( Hovered is IPressable newPressable )
|
||||
{
|
||||
newPressable.Hover( e );
|
||||
newPressable.Look( e );
|
||||
}
|
||||
}
|
||||
|
||||
TracedHitPos = trace.Hit ? trace.HitPosition : trace.EndPosition;
|
||||
CameraTraceIsHit = trace.Hit;
|
||||
TracedHitNormal = trace.Normal;
|
||||
private Component TryGetLookedAt()
|
||||
{
|
||||
for ( float num = 0f; num <= 4f; num += 2f )
|
||||
{
|
||||
var from = Scene.Camera.WorldPosition + Scene.Camera.WorldRotation.Forward;
|
||||
var to = from + Scene.Camera.WorldRotation.Forward * (InteractDistance - num);
|
||||
var trace = Scene.Trace.Ray( from, to ).IgnoreGameObjectHierarchy( GameObject ).Radius( num ).Run();
|
||||
|
||||
if (!trace.Hit || !trace.GameObject.IsValid()) continue;
|
||||
TracedHitPos = trace.Hit ? trace.HitPosition : trace.EndPosition;
|
||||
CameraTraceIsHit = trace.Hit;
|
||||
TracedHitNormal = trace.Normal;
|
||||
|
||||
Component foundComponent = null;
|
||||
if ( !trace.Hit || !trace.GameObject.IsValid() ) continue;
|
||||
|
||||
ISceneEvent<PlayerController.IEvents>.PostToGameObject(GameObject, x =>
|
||||
{
|
||||
foundComponent = x.GetUsableComponent(trace.GameObject) ?? foundComponent;
|
||||
});
|
||||
Component foundComponent = null;
|
||||
|
||||
if (foundComponent.IsValid()) return foundComponent;
|
||||
ISceneEvent<PlayerController.IEvents>.PostToGameObject( GameObject, x =>
|
||||
{
|
||||
foundComponent = x.GetUsableComponent( trace.GameObject ) ?? foundComponent;
|
||||
} );
|
||||
|
||||
foreach (var component in trace.GameObject.Components.GetAll<IPressable>())
|
||||
{
|
||||
if (component.CanPress(new IPressable.Event
|
||||
{
|
||||
Ray = new Ray(Camera.WorldPosition, EyeAngles.ToRotation().Forward),
|
||||
Source = this
|
||||
}))
|
||||
{
|
||||
return component as Component;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( foundComponent.IsValid() ) return foundComponent;
|
||||
|
||||
return null;
|
||||
}
|
||||
foreach ( var component in trace.GameObject.Components.GetAll<IPressable>() )
|
||||
{
|
||||
if ( component.CanPress( new IPressable.Event
|
||||
{
|
||||
Ray = new Ray( Camera.WorldPosition, EyeAngles.ToRotation().Forward ), Source = this
|
||||
} ) )
|
||||
{
|
||||
return component as Component;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float GetDistanceFromGameObject(GameObject obj, Vector3 point)
|
||||
{
|
||||
Vector3 closest = obj.WorldPosition;
|
||||
float minDist = Vector3.DistanceBetween(closest, point);
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (var col in Pressed.GetComponentsInChildren<Collider>())
|
||||
{
|
||||
Vector3 cp = col.FindClosestPoint(point);
|
||||
float dist = Vector3.DistanceBetween(cp, point);
|
||||
if (dist < minDist)
|
||||
minDist = dist;
|
||||
}
|
||||
private float GetDistanceFromGameObject( GameObject obj, Vector3 point )
|
||||
{
|
||||
Vector3 closest = obj.WorldPosition;
|
||||
float minDist = Vector3.DistanceBetween( closest, point );
|
||||
|
||||
return minDist;
|
||||
}
|
||||
foreach ( var col in Pressed.GetComponentsInChildren<Collider>() )
|
||||
{
|
||||
Vector3 cp = col.FindClosestPoint( point );
|
||||
float dist = Vector3.DistanceBetween( cp, point );
|
||||
if ( dist < minDist )
|
||||
minDist = dist;
|
||||
}
|
||||
|
||||
return minDist;
|
||||
}
|
||||
}
|
||||
|
||||
50
Code/Player/Dedugan.Player.cs
Normal file
50
Code/Player/Dedugan.Player.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Sandbox;
|
||||
partial class Dedugan
|
||||
{
|
||||
public static IReadOnlyList<Dedugan> All => InternalPlayers;
|
||||
public static List<Dedugan> InternalPlayers = new List<Dedugan>();
|
||||
|
||||
public static Dedugan Local { get; set; }
|
||||
|
||||
private Guid _guid;
|
||||
public static Dedugan FindLocalPlayer() => Local;
|
||||
|
||||
[Sync( SyncFlags.FromHost )]
|
||||
public Guid ConnectionID
|
||||
{
|
||||
get => _guid;
|
||||
set
|
||||
{
|
||||
_guid = value;
|
||||
Connection = Connection.Find( _guid );
|
||||
|
||||
if ( _guid == Connection.Local.Id )
|
||||
{
|
||||
Local = this;
|
||||
// ILocalPlayerEvent.Post( x => x.OnInitialized() );
|
||||
}
|
||||
|
||||
InternalPlayers.RemoveAll( x => !x.IsValid() );
|
||||
if ( !InternalPlayers.Contains( this ) )
|
||||
InternalPlayers.Add( this );
|
||||
}
|
||||
}
|
||||
|
||||
public Connection Connection { get; private set; }
|
||||
|
||||
public ulong SteamID => Connection.SteamId;
|
||||
public string Name => Connection.DisplayName;
|
||||
|
||||
public void SetupConnection( Connection connection )
|
||||
{
|
||||
ConnectionID = connection.Id;
|
||||
GameObject.Name = $"{Name} / {SteamID}";
|
||||
}
|
||||
|
||||
public static Dedugan GetByID( Guid id )
|
||||
=> InternalPlayers.FirstOrDefault( x => x.ConnectionID == id );
|
||||
|
||||
}
|
||||
51
Code/Player/Dedugan.Weapons.cs
Normal file
51
Code/Player/Dedugan.Weapons.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using Sandbox.Citizen;
|
||||
using Sandbox.Weapons;
|
||||
|
||||
public sealed partial class Dedugan
|
||||
{
|
||||
[Property] public GameObject Gun { get; set; }
|
||||
[Sync] private bool InAds { get; set; } = false;
|
||||
|
||||
private Weapon _weapon { get; set; }
|
||||
|
||||
void WeaponStart()
|
||||
{
|
||||
_weapon = Gun.Components.Get<Weapon>(FindMode.EverythingInSelfAndDescendants );
|
||||
|
||||
Log.Info( $"_weapon: {_weapon}, Network.IsOwner: {Network.IsOwner}" );
|
||||
}
|
||||
|
||||
[Rpc.Broadcast]
|
||||
void Attack()
|
||||
{
|
||||
Renderer.Set( "b_attack", true );
|
||||
}
|
||||
|
||||
void WeaponUpdate()
|
||||
{
|
||||
if ( InAds )
|
||||
{
|
||||
AnimationHelper.Handedness = CitizenAnimationHelper.Hand.Right;
|
||||
AnimationHelper.HoldType = CitizenAnimationHelper.HoldTypes.Pistol;
|
||||
|
||||
Gun.Enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AnimationHelper.Handedness = CitizenAnimationHelper.Hand.Both;
|
||||
AnimationHelper.HoldType = CitizenAnimationHelper.HoldTypes.None;
|
||||
|
||||
Gun.Enabled = false;
|
||||
}
|
||||
|
||||
if ( !Network.IsOwner ) return;
|
||||
|
||||
InAds = Input.Down( "Attack2" );
|
||||
|
||||
if ( Input.Pressed( "Attack1" ) && InAds )
|
||||
{
|
||||
_weapon.Attack();
|
||||
Attack();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,22 +8,23 @@ public sealed partial class Dedugan : Component
|
||||
[RequireComponent] public ShrimpleCharacterController.ShrimpleCharacterController Controller { get; set; }
|
||||
[RequireComponent] public CitizenAnimationHelper AnimationHelper { get; set; }
|
||||
// [Property] public SkinnedModelRenderer Anim {get; set;}
|
||||
|
||||
|
||||
public SkinnedModelRenderer Renderer { get; set; }
|
||||
[Property] public GameObject Camera { get; set; }
|
||||
[Property] public GameObject CameraPivot { get; set; }
|
||||
|
||||
[Property][Range(1f, 200f, 1f)] public float CamOffsetX { get; set; }
|
||||
[Property][Range(50f, 1200f, 10f)] public float WalkSpeed { get; set; } = 100f;
|
||||
[Property][Range(100f, 1500f, 20f)] public float RunSpeed { get; set; } = 300f;
|
||||
[Property][Range(25f, 1100f, 5f)] public float DuckSpeed { get; set; } = 50f;
|
||||
[Property][Range(200f, 1500f, 20f)] public float JumpStrength { get; set; } = 350f;
|
||||
[Property][Range(10f, 500f, 10f)] public float InteractDistance { get; set; } = 350f;
|
||||
[Property] [Range( 1f, 200f, 1f )] public float CamOffsetX { get; set; }
|
||||
[Property] [Range( 50f, 1200f, 10f )] public float WalkSpeed { get; set; } = 100f;
|
||||
[Property] [Range( 100f, 1500f, 20f )] public float RunSpeed { get; set; } = 300f;
|
||||
[Property] [Range( 25f, 1100f, 5f )] public float DuckSpeed { get; set; } = 50f;
|
||||
[Property] [Range( 200f, 1500f, 20f )] public float JumpStrength { get; set; } = 350f;
|
||||
[Property] [Range( 10f, 500f, 10f )] public float InteractDistance { get; set; } = 350f;
|
||||
|
||||
[Sync] public Angles NetworkedEyeAngles { get; set; }
|
||||
public Angles EyeAngles { get; set; }
|
||||
[Sync] private float IsDucking { get; set; } = 0f;
|
||||
[Sync] public bool IsDancing { get; set; } = false;
|
||||
[Sync] public int Health { get; set; } = 100;
|
||||
private RagdollController RagdollController { get; set; }
|
||||
|
||||
public Vector3 OverrideGravity { get; set; } = Vector3.Zero;
|
||||
@@ -34,65 +35,79 @@ public sealed partial class Dedugan : Component
|
||||
private Vector3 _right = Vector3.Right;
|
||||
|
||||
private Vector3 _wishDirection;
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
WeaponStart();
|
||||
|
||||
RagdollController = Components.Get<RagdollController>();
|
||||
Renderer = Components.Get<SkinnedModelRenderer>(FindMode.EverythingInSelfAndDescendants);
|
||||
Renderer = Components.Get<SkinnedModelRenderer>( FindMode.EverythingInSelfAndDescendants );
|
||||
|
||||
var cameraComponent = Camera.GetComponent<CameraComponent>();
|
||||
var listener = Components.Get<AudioListener>(true);
|
||||
cameraComponent.Enabled = false;
|
||||
listener.Enabled = false;
|
||||
|
||||
if ( !Network.IsOwner ) return;
|
||||
|
||||
if (!Network.IsOwner) return;
|
||||
cameraComponent.Enabled = true;
|
||||
listener.Enabled = true;
|
||||
|
||||
if ( Renderer is null )
|
||||
return;
|
||||
|
||||
Renderer.OnFootstepEvent += OnFootstepEvent;
|
||||
}
|
||||
|
||||
protected override void OnUpdate()
|
||||
{
|
||||
if (Network.IsOwner)
|
||||
UpdateCustomAnimations();
|
||||
WeaponUpdate();
|
||||
if ( Network.IsOwner )
|
||||
{
|
||||
EyeAngles += Input.AnalogLook;
|
||||
EyeAngles = EyeAngles.WithPitch(MathX.Clamp(EyeAngles.pitch, -89f, 89f));
|
||||
EyeAngles = EyeAngles.WithPitch( MathX.Clamp( EyeAngles.pitch, -89f, 89f ) );
|
||||
NetworkedEyeAngles = EyeAngles;
|
||||
|
||||
var targetRotation = Rotation.LookAt(Rotation.FromYaw(EyeAngles.yaw).Forward, -_directionToAxis);
|
||||
|
||||
var targetRotation = Rotation.LookAt( Rotation.FromYaw( EyeAngles.yaw ).Forward, -_directionToAxis );
|
||||
var currentForward = Renderer.LocalRotation.Forward;
|
||||
float angleDiff = currentForward.Angle(targetRotation.Forward);
|
||||
|
||||
if (angleDiff > 15f && Controller.Velocity.Length > 10f)
|
||||
float angleDiff = currentForward.Angle( targetRotation.Forward );
|
||||
|
||||
if ( angleDiff > 15f && Controller.Velocity.Length > 10f )
|
||||
{
|
||||
Renderer.LocalRotation = Rotation.Slerp(Renderer.LocalRotation, Rotation.FromYaw(EyeAngles.yaw), Time.Delta * 3f);
|
||||
Renderer.LocalRotation = Rotation.Slerp( Renderer.LocalRotation, Rotation.FromYaw( EyeAngles.yaw ),
|
||||
Time.Delta * 3f );
|
||||
}
|
||||
|
||||
|
||||
RotateCamera();
|
||||
InteractionsUpdate();
|
||||
}
|
||||
else
|
||||
{
|
||||
EyeAngles = NetworkedEyeAngles;
|
||||
|
||||
var targetRotation = Rotation.LookAt(Rotation.FromYaw(EyeAngles.yaw).Forward, -_directionToAxis);
|
||||
|
||||
var targetRotation = Rotation.LookAt( Rotation.FromYaw( EyeAngles.yaw ).Forward, -_directionToAxis );
|
||||
var currentForward = Renderer.LocalRotation.Forward;
|
||||
float angleDiff = currentForward.Angle(targetRotation.Forward);
|
||||
|
||||
if (angleDiff > 15f && Controller.Velocity.Length > 10f)
|
||||
float angleDiff = currentForward.Angle( targetRotation.Forward );
|
||||
|
||||
if ( angleDiff > 15f && Controller.Velocity.Length > 10f )
|
||||
{
|
||||
Renderer.LocalRotation = Rotation.Slerp(Renderer.LocalRotation, Rotation.FromYaw(EyeAngles.yaw), Time.Delta * 3f);
|
||||
Renderer.LocalRotation = Rotation.Slerp( Renderer.LocalRotation, Rotation.FromYaw( EyeAngles.yaw ),
|
||||
Time.Delta * 3f );
|
||||
}
|
||||
|
||||
|
||||
// Renderer.LocalRotation = Rotation.Slerp(Renderer.LocalRotation, Rotation.FromYaw(EyeAngles.yaw), Time.Delta * 5f);
|
||||
|
||||
|
||||
Camera.LocalRotation = EyeAngles.ToRotation();
|
||||
var pivotOffset = CameraPivot.LocalRotation.Backward * CamOffsetX;
|
||||
var localPitchOffset = Camera.LocalRotation.Down * MathF.Max( 0f, EyeAngles.pitch ) * 0.32f +
|
||||
Camera.LocalRotation.Backward * MathF.Max( 0f, EyeAngles.pitch ) * 0.7f +
|
||||
Camera.LocalRotation.Up * MathF.Min( 0f, EyeAngles.pitch ) * 0.5f +
|
||||
Camera.LocalRotation.Backward * MathF.Min( 0f, EyeAngles.pitch ) * 0.8f;
|
||||
|
||||
var offset = (CameraPivot.LocalPosition + pivotOffset ) * EyeAngles.ToRotation() + localPitchOffset;
|
||||
Camera.LocalRotation.Backward * MathF.Min( 0f, EyeAngles.pitch ) * 0.8f;
|
||||
|
||||
var offset = (CameraPivot.LocalPosition + pivotOffset) * EyeAngles.ToRotation() + localPitchOffset;
|
||||
Camera.LocalPosition = offset;
|
||||
}
|
||||
|
||||
UpdateCustomAnimations();
|
||||
}
|
||||
|
||||
protected override void OnFixedUpdate()
|
||||
|
||||
@@ -7,11 +7,19 @@ public class PlayerDresser : Component, Component.INetworkSpawn
|
||||
[Property]
|
||||
public SkinnedModelRenderer BodyRenderer { get; set; }
|
||||
|
||||
// public void OnNetworkSpawn( Connection owner )
|
||||
// {
|
||||
// Log.Info( $"Hello {owner.Name}" );
|
||||
// var clothing = new ClothingContainer();
|
||||
// clothing.Deserialize( owner.GetUserData( "avatar" ) );
|
||||
// clothing.Apply( BodyRenderer );
|
||||
// }
|
||||
|
||||
public void OnNetworkSpawn( Connection owner )
|
||||
{
|
||||
{
|
||||
Log.Info( $"Hello {owner.Name}" );
|
||||
var clothing = new ClothingContainer();
|
||||
clothing.Deserialize( owner.GetUserData( "avatar" ) );
|
||||
var clothing = ClothingContainer.CreateFromJson( owner.GetUserData( "avatar" ) );
|
||||
clothing.Height = 1;
|
||||
clothing.Apply( BodyRenderer );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,48 +1,58 @@
|
||||
using Sandbox;
|
||||
|
||||
public sealed class RagdollController : Component
|
||||
{
|
||||
[Group("Setup"), Order(-100), Property] public ModelPhysics bodyPhysics { get; set; }
|
||||
[Group("Setup"), Order(-100), Property] public SkinnedModelRenderer bodyRenderer { get; set; }
|
||||
[Group("Config"), Order(0), Property] public bool isLocked { get; set; }
|
||||
|
||||
// [Property] public Collider Collider;
|
||||
[Group( "Setup" ), Order( -100 ), Property]
|
||||
public ModelPhysics bodyPhysics { get; private set; }
|
||||
|
||||
[Group( "Setup" ), Order( -100 ), Property]
|
||||
public SkinnedModelRenderer bodyRenderer { get; private set; }
|
||||
|
||||
[Group( "Config" ), Order( 0 ), Property]
|
||||
public bool isLocked { get; set; }
|
||||
|
||||
[Sync]
|
||||
public new bool Enabled
|
||||
{
|
||||
get => bodyPhysics.Enabled;
|
||||
private set
|
||||
get => bodyPhysics.IsValid() && bodyPhysics.Enabled;
|
||||
set
|
||||
{
|
||||
bodyPhysics.Enabled = value;
|
||||
bodyPhysics.MotionEnabled = value;
|
||||
bodyRenderer.UseAnimGraph = !value;
|
||||
if ( bodyPhysics.IsValid() )
|
||||
{
|
||||
bodyPhysics.Enabled = value;
|
||||
bodyPhysics.MotionEnabled = value;
|
||||
bodyRenderer.UseAnimGraph = !value;
|
||||
}
|
||||
// Collider.Enabled = !value;
|
||||
|
||||
|
||||
if ( !value )
|
||||
{
|
||||
WorldPosition = bodyRenderer.WorldPosition;
|
||||
bodyRenderer.LocalPosition = Vector3.Zero;
|
||||
|
||||
bodyRenderer.ClearParameters();
|
||||
bodyRenderer.ClearPhysicsBones();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// protected override void OnStart()
|
||||
// {
|
||||
// Collider = GetComponent<Collider>();
|
||||
//
|
||||
// Log.Info(Collider.Enabled);
|
||||
// }
|
||||
|
||||
protected override void OnUpdate()
|
||||
{
|
||||
if ( Network.IsOwner )
|
||||
{
|
||||
if (Input.Pressed( "Ragdoll" ))
|
||||
if ( Input.Pressed( "Ragdoll" ) )
|
||||
{
|
||||
Enabled = !Enabled;
|
||||
}
|
||||
|
||||
if ( Enabled )
|
||||
{
|
||||
// Components.GetInChildren<SkinnedModelRenderer>().GameObject.WorldPosition += Vector3.Forward;
|
||||
bodyPhysics.WorldPosition += Vector3.Forward * Time.Delta * 100f;
|
||||
// GameObject.WorldPosition += Vector3.Forward;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var bodyLock = new PhysicsLock();
|
||||
bodyLock.Pitch = isLocked;
|
||||
bodyLock.Yaw = isLocked;
|
||||
@@ -50,7 +60,7 @@ public sealed class RagdollController : Component
|
||||
bodyLock.X = isLocked;
|
||||
bodyLock.Y = isLocked;
|
||||
bodyLock.Z = isLocked;
|
||||
|
||||
|
||||
bodyPhysics.Locking = bodyLock;
|
||||
bodyPhysics.MotionEnabled = !isLocked;
|
||||
WorldPosition = bodyRenderer.WorldPosition;
|
||||
|
||||
Reference in New Issue
Block a user