Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ csharp_new_line_before_else = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = all
csharp_new_line_before_open_brace = none
csharp_new_line_between_query_expression_clauses = true

# Indentation preferences
Expand Down
13 changes: 13 additions & 0 deletions code/.idea/.idea.code.dir/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

140 changes: 140 additions & 0 deletions code/Base/BaseCarriable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
using Sandbox.Systems.Inventory;

namespace Sandbox.Base;

/// <summary>
/// An entity that can be carried in the player's inventory and hands.
/// </summary>
[Title( "Carriable" ), Icon( "luggage" )]
public partial class BaseCarriable : AnimatedEntity, ICariable {
public virtual string ViewModelPath => null;
public BaseViewModel ViewModelEntity { get; protected set; }

public CariableHoldTypes HoldType { get; protected set; } = CariableHoldTypes.Pistol;
public CariableHandedness Handedness { get; protected set; } = CariableHandedness.Both;

public float AimBodyWeight { get; protected set; } = 1.0f;

public override void Spawn() {
base.Spawn();

PhysicsEnabled = true;
UsePhysicsCollision = true;
EnableHideInFirstPerson = true;
EnableShadowInFirstPerson = true;
}

public virtual bool CanCarry( Entity carrier ) {
return true;
}

public virtual bool CanDrop( Entity carrier ) {
return true;
}

public virtual void OnCarry( Entity carrier ) {
if ( Game.IsClient ) return;

SetParent( carrier, true );
Owner = carrier;
EnableAllCollisions = false;
EnableDrawing = false;
}

public virtual void OnDrop( Entity dropper ) {
if ( Game.IsClient ) return;

SetParent( null );
Owner = null;
EnableDrawing = true;
EnableAllCollisions = true;
}

/// <summary>
/// This entity has become the active entity. This most likely
/// means a player was carrying it in their inventory and now
/// has it in their hands.
/// </summary>
public virtual void ActiveStart( Entity ent ) {
EnableDrawing = true;

//
// If we're the local player (clientside) create viewmodel
// and any HUD elements that this weapon wants
//
if ( IsLocalPawn ) {
DestroyViewModel();
DestroyHudElements();

CreateViewModel();
CreateHudElements();
}
}

/// <summary>
/// This entity has stopped being the active entity. This most
/// likely means a player was holding it but has switched away
/// or dropped it (in which case dropped = true)
/// </summary>
public virtual void ActiveEnd( Entity ent, bool dropped ) {
//
// If we're just holstering, then hide us
//
if ( !dropped ) {
EnableDrawing = false;
}

if ( Game.IsClient ) {
DestroyViewModel();
DestroyHudElements();
}
}

protected override void OnDestroy() {
base.OnDestroy();

if ( Game.IsClient && ViewModelEntity.IsValid() ) {
DestroyViewModel();
DestroyHudElements();
}
}

/// <summary>
/// Create the viewmodel. You can override this in your base classes if you want
/// to create a certain viewmodel entity.
/// </summary>
public virtual void CreateViewModel() {
Game.AssertClient();

if ( string.IsNullOrEmpty( ViewModelPath ) )
return;

ViewModelEntity = new BaseViewModel();
ViewModelEntity.Position = Position;
ViewModelEntity.Owner = Owner;
ViewModelEntity.EnableViewmodelRendering = true;
ViewModelEntity.SetModel( ViewModelPath );
}

/// <summary>
/// We're done with the viewmodel - delete it
/// </summary>
public virtual void DestroyViewModel() {
ViewModelEntity?.Delete();
ViewModelEntity = null;
}

public virtual void CreateHudElements() {
}

public virtual void DestroyHudElements() {

}

/// <summary>
/// Utility - return the entity we should be spawning particles from etc
/// </summary>
public virtual ModelEntity EffectEntity =>
(ViewModelEntity.IsValid() && IsFirstPersonMode) ? ViewModelEntity : this;

}
144 changes: 144 additions & 0 deletions code/Base/BaseWeapon.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
namespace Sandbox.Base
{
/// <summary>
/// A common base we can use for weapons so we don't have to implement the logic over and over
/// again. Feel free to not use this and to implement it however you want to.
/// </summary>
[Title( "Base Weapon" ), Icon( "sports_martial_arts" )]
public partial class BaseWeapon : BaseCarriable
{
public virtual float PrimaryRate => 5.0f;
public virtual float SecondaryRate => 15.0f;

public override void Spawn()
{
base.Spawn();

Tags.Add( "item" );
}

[Net, Predicted]
public TimeSince TimeSincePrimaryAttack { get; set; }

[Net, Predicted]
public TimeSince TimeSinceSecondaryAttack { get; set; }

public override void Simulate( IClient player )
{
if ( CanReload() )
{
Reload();
}

//
// Reload could have changed our owner
//
if ( !Owner.IsValid() )
return;

if ( CanPrimaryAttack() )
{
using ( LagCompensation() )
{
TimeSincePrimaryAttack = 0;
AttackPrimary();
}
}

//
// AttackPrimary could have changed our owner
//
if ( !Owner.IsValid() )
return;

if ( CanSecondaryAttack() )
{
using ( LagCompensation() )
{
TimeSinceSecondaryAttack = 0;
AttackSecondary();
}
}
}

public virtual bool CanReload()
{
if ( !Owner.IsValid() || !Input.Down( "reload" ) ) return false;

return true;
}

public virtual void Reload()
{

}

public virtual bool CanPrimaryAttack()
{
if ( !Owner.IsValid() || !Input.Down( "attack1" ) ) return false;

var rate = PrimaryRate;
if ( rate <= 0 ) return true;

return TimeSincePrimaryAttack > (1 / rate);
}

public virtual void AttackPrimary()
{

}

public virtual bool CanSecondaryAttack()
{
if ( !Owner.IsValid() || !Input.Down( "attack2" ) ) return false;

var rate = SecondaryRate;
if ( rate <= 0 ) return true;

return TimeSinceSecondaryAttack > (1 / rate);
}

public virtual void AttackSecondary()
{

}

/// <summary>
/// Does a trace from start to end, does bullet impact effects. Coded as an IEnumerable so you can return multiple
/// hits, like if you're going through layers or ricocheting or something.
/// </summary>
public virtual IEnumerable<TraceResult> TraceBullet( Vector3 start, Vector3 end, float radius = 2.0f )
{
bool underWater = Trace.TestPoint( start, "water" );

var trace = Trace.Ray( start, end )
.UseHitboxes()
.WithAnyTags( "solid", "player", "npc" )
.Ignore( this )
.Size( radius );

//
// If we're not underwater then we can hit water
//
if ( !underWater )
trace = trace.WithAnyTags( "water" );

var tr = trace.Run();

if ( tr.Hit )
yield return tr;

//
// Another trace, bullet going through thin material, penetrating water surface?
//
}

public override Sound PlaySound( string soundName, string attachment )
{
if ( Owner.IsValid() )
return Owner.PlaySound( soundName, attachment );

return base.PlaySound( soundName, attachment );
}
}
}
18 changes: 18 additions & 0 deletions code/Carriable.cs → code/Base/Carriable.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Sandbox;
using Sandbox.Systems.Inventory;
using BaseCarriable = Sandbox.Base.BaseCarriable;

public partial class Carriable : BaseCarriable, IUse
{
Expand Down Expand Up @@ -28,4 +30,20 @@ public virtual bool IsUsable( Entity user )
{
return Owner == null;
}

public virtual bool CanUnequip( Entity owner ) {
return true;
}

public void OnUnEquip( Entity owner ) {
OnDrop(owner);
}

public bool CanEquip( Entity owner ) {
return CanCarry( owner );
}

public void OnEquip( Entity owner ) {
OnCarry( owner );
}
}
File renamed without changes.
5 changes: 3 additions & 2 deletions code/Tool.CanTool.cs → code/Base/Tools/Tool.CanTool.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
using Sandmod.Permission;
using Sandbox.Systems.Player;

namespace Sandbox
{
public class CanToolParams
{
public Player player;
public BasePlayer player;
public string toolName;
public TraceResult tr;
public Entity entity;
public bool preventDefault = false;

public static TraceResult RunCanTool( Player player, string toolName, TraceResult tr )
public static TraceResult RunCanTool( BasePlayer player, string toolName, TraceResult tr )
{
if ( Game.IsClient )
{
Expand Down
File renamed without changes.
File renamed without changes.
Loading