Updates based on PR feedback
This commit is contained in:
2
.sbproj
2
.sbproj
@@ -46,7 +46,7 @@
|
|||||||
"Choices": [],
|
"Choices": [],
|
||||||
"ConVarName": "lucker_minigames_per_round",
|
"ConVarName": "lucker_minigames_per_round",
|
||||||
"DisplayName": "Minigames Per Round",
|
"DisplayName": "Minigames Per Round",
|
||||||
"DefaultValue": "0",
|
"DefaultValue": "1",
|
||||||
"Description": "The number of minigames played per round",
|
"Description": "The number of minigames played per round",
|
||||||
"Group": "Other",
|
"Group": "Other",
|
||||||
"Minimum": 1,
|
"Minimum": 1,
|
||||||
|
|||||||
@@ -6,18 +6,18 @@ using Sandbox;
|
|||||||
namespace LuckerGame.Entities;
|
namespace LuckerGame.Entities;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a Player.
|
/// Represents a person playing the game.
|
||||||
/// This could belong to a Client or a Bot and represents a common entity to operate on for games and keeping score
|
/// This could belong to a Client or a Bot and represents a common entity to operate on for games and keeping score
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class Lucker : Entity
|
public partial class Lucker : Entity
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The entity this player controls. This value is networked and should be accessed through <see cref="Pawn"/>.
|
/// The entity this lucker controls. This value is networked and should be accessed through <see cref="Pawn"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Net] private Entity InternalPawn { get; set; }
|
[Net] private Entity InternalPawn { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Accesses or sets the entity this player current controls
|
/// Accesses or sets the entity this lucker currently controls
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Entity Pawn
|
public Entity Pawn
|
||||||
{
|
{
|
||||||
@@ -33,7 +33,7 @@ public partial class Lucker : Entity
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Before the round has started, this player indicated they were ready
|
/// Before the round has started, this lucker indicated they were ready
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Net] public bool Ready { get; set; }
|
[Net] public bool Ready { get; set; }
|
||||||
|
|
||||||
@@ -45,20 +45,20 @@ public partial class Lucker : Entity
|
|||||||
[BindComponent] public LuckerStats Stats { get; }
|
[BindComponent] public LuckerStats Stats { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates and properly sets up a Player entity for a given client
|
/// Creates and properly sets up a <see cref="Lucker"/> entity for a given client
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="client">the client to own the player</param>
|
/// <param name="client">the client to own the lucker</param>
|
||||||
/// <returns>the newly created player</returns>
|
/// <returns>the newly created lucker</returns>
|
||||||
public static Lucker CreateLuckerForClient( IClient client )
|
public static Lucker CreateLuckerForClient( IClient client )
|
||||||
{
|
{
|
||||||
var player = new Lucker();
|
var lucker = new Lucker();
|
||||||
client.Pawn = player;
|
client.Pawn = lucker;
|
||||||
player.Owner = client as Entity;
|
lucker.Owner = client as Entity;
|
||||||
player.Name = client.Name;
|
lucker.Name = client.Name;
|
||||||
var camera = player.Components.Create<RTSCamera>();
|
lucker.Components.Create<RTSCamera>();
|
||||||
var stats = player.Components.Create<LuckerStats>();
|
lucker.Components.Create<LuckerStats>();
|
||||||
|
|
||||||
return player;
|
return lucker;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -69,12 +69,12 @@ public partial class Lucker : Entity
|
|||||||
public static void ReadyUpCommand(bool readyState)
|
public static void ReadyUpCommand(bool readyState)
|
||||||
{
|
{
|
||||||
var client = ConsoleSystem.Caller;
|
var client = ConsoleSystem.Caller;
|
||||||
var player = client.Pawn as Lucker;
|
var lucker = client.Pawn as Lucker;
|
||||||
player.SetReady( readyState );
|
lucker.SetReady( readyState );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets this player's ready state
|
/// Sets this lucker's ready state
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ready">the ready state being set</param>
|
/// <param name="ready">the ready state being set</param>
|
||||||
public void SetReady(bool ready)
|
public void SetReady(bool ready)
|
||||||
@@ -82,7 +82,7 @@ public partial class Lucker : Entity
|
|||||||
Ready = ready;
|
Ready = ready;
|
||||||
if ( Game.IsServer )
|
if ( Game.IsServer )
|
||||||
{
|
{
|
||||||
Event.Run( LuckerEvent.PlayerReady, this, ready );
|
Event.Run( LuckerEvent.LuckerReady, this, ready );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ public partial class MinigameManager : Entity
|
|||||||
private List<TypeDescription> AvailableMinigames { get; set; }
|
private List<TypeDescription> AvailableMinigames { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The players involved in the current minigame
|
/// The luckers involved in the current minigame
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private List<Lucker> InvolvedPlayers { get; set; }
|
private List<Lucker> InvolvedLuckers { get; set; }
|
||||||
|
|
||||||
public override void Spawn()
|
public override void Spawn()
|
||||||
{
|
{
|
||||||
@@ -33,14 +33,17 @@ public partial class MinigameManager : Entity
|
|||||||
FindMinigames();
|
FindMinigames();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartMinigame(List<Lucker> players, string minigameName = null)
|
public void StartMinigame(List<Lucker> luckers, string minigameName = null)
|
||||||
{
|
{
|
||||||
InvolvedPlayers = players.ToList();
|
InvolvedLuckers = luckers.ToList();
|
||||||
if (CheckForMinigames())
|
if (CheckForMinigames())
|
||||||
{
|
{
|
||||||
LoadedMinigame = string.IsNullOrEmpty( minigameName ) ? TypeLibrary.Create<Minigame>(AvailableMinigames.OrderBy( _ => Guid.NewGuid() ).FirstOrDefault().TargetType) : TypeLibrary.Create<Minigame>( minigameName );
|
LoadedMinigame = string.IsNullOrEmpty( minigameName )
|
||||||
|
? TypeLibrary.Create<Minigame>( AvailableMinigames.OrderBy( _ => Guid.NewGuid() ).FirstOrDefault()
|
||||||
|
.TargetType )
|
||||||
|
: TypeLibrary.Create<Minigame>( minigameName );
|
||||||
ChatBox.AddInformation( To.Everyone, $"Starting {LoadedMinigame.Name}" );
|
ChatBox.AddInformation( To.Everyone, $"Starting {LoadedMinigame.Name}" );
|
||||||
LoadedMinigame.Initialize( players );
|
LoadedMinigame.Initialize( luckers );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,19 +72,19 @@ public partial class MinigameManager : Entity
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Goes through the players included in the loaded minigame and deletes and nulls out any pawns assigned to them
|
/// Goes through the luckers included in the loaded minigame and deletes and nulls out any pawns assigned to them
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void CleanupPlayerPawns()
|
private void CleanupLuckerPawns()
|
||||||
{
|
{
|
||||||
if ( LoadedMinigame is not { IsValid: true } || InvolvedPlayers == null)
|
if ( LoadedMinigame is not { IsValid: true } || InvolvedLuckers == null)
|
||||||
{
|
{
|
||||||
Log.Warning( "Attempted to clean up players without a minigame loaded!" );
|
Log.Warning( "Attempted to clean up players without a minigame loaded!" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
InvolvedPlayers.ForEach( player =>
|
InvolvedLuckers.ForEach( lucker =>
|
||||||
{
|
{
|
||||||
player.Pawn?.Delete();
|
lucker.Pawn?.Delete();
|
||||||
player.Pawn = null;
|
lucker.Pawn = null;
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,11 +103,16 @@ public partial class MinigameManager : Entity
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
EndMinigame();
|
||||||
LoadedMinigame.Cleanup();
|
|
||||||
CleanupPlayerPawns();
|
|
||||||
LoadedMinigame = null;
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EndMinigame()
|
||||||
|
{
|
||||||
|
LoadedMinigame.Cleanup();
|
||||||
|
CleanupLuckerPawns();
|
||||||
|
LoadedMinigame.Delete();
|
||||||
|
LoadedMinigame = null;
|
||||||
|
InvolvedLuckers = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public partial class RoundManager : Entity
|
|||||||
[ConVar.Replicated("lucker_minigames_per_round")]
|
[ConVar.Replicated("lucker_minigames_per_round")]
|
||||||
public static int MinigamesLeftInRound { get; set; }
|
public static int MinigamesLeftInRound { get; set; }
|
||||||
|
|
||||||
private List<Lucker> Players { get; set; }
|
private List<Lucker> Luckers { get; set; }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
@@ -83,7 +83,7 @@ public partial class RoundManager : Entity
|
|||||||
MinigamesLeftInRound--;
|
MinigamesLeftInRound--;
|
||||||
if ( MinigamesLeftInRound > 0 )
|
if ( MinigamesLeftInRound > 0 )
|
||||||
{
|
{
|
||||||
MinigameManager.StartMinigame( Players );
|
MinigameManager.StartMinigame( Luckers );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -94,11 +94,12 @@ public partial class RoundManager : Entity
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Is triggered whenever a player readies up
|
/// Is triggered whenever a lucker readies up or readies down
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="readyLucker">the player that readied up, discarded</param>
|
/// <param name="readyLucker">the lucker that readied up</param>
|
||||||
[LuckerEvent.PlayerReady]
|
/// <param name="ready">the lucker's ready state</param>
|
||||||
public void HandlePlayerReady( Lucker readyLucker, bool ready )
|
[LuckerEvent.LuckerReady]
|
||||||
|
public void HandleLuckerReady( Lucker readyLucker, bool ready )
|
||||||
{
|
{
|
||||||
if ( RoundState != RoundState.NotStarted && RoundState != RoundState.StartCountdown )
|
if ( RoundState != RoundState.NotStarted && RoundState != RoundState.StartCountdown )
|
||||||
{
|
{
|
||||||
@@ -107,9 +108,9 @@ public partial class RoundManager : Entity
|
|||||||
Log.Info( $"{readyLucker.Client.Name} set ready to {ready}" );
|
Log.Info( $"{readyLucker.Client.Name} set ready to {ready}" );
|
||||||
var message = $"{readyLucker.Client.Name} is {(ready ? "now ready." : "no longer ready.")}";
|
var message = $"{readyLucker.Client.Name} is {(ready ? "now ready." : "no longer ready.")}";
|
||||||
ChatBox.AddInformation( To.Everyone, message );
|
ChatBox.AddInformation( To.Everyone, message );
|
||||||
var players = All.OfType<Lucker>().ToList();
|
var luckers = All.OfType<Lucker>().ToList();
|
||||||
var readiedCount = players.Count( player => player.Ready );
|
var readiedCount = luckers.Count( lucker => lucker.Ready );
|
||||||
var totalCount = players.Count;
|
var totalCount = luckers.Count;
|
||||||
if ( (float)readiedCount / totalCount > RequiredReadyPercent && RoundState == RoundState.NotStarted )
|
if ( (float)readiedCount / totalCount > RequiredReadyPercent && RoundState == RoundState.NotStarted )
|
||||||
{
|
{
|
||||||
Log.Info( "Countdown started" );
|
Log.Info( "Countdown started" );
|
||||||
@@ -132,13 +133,13 @@ public partial class RoundManager : Entity
|
|||||||
}
|
}
|
||||||
|
|
||||||
RoundState = RoundState.InProgress;
|
RoundState = RoundState.InProgress;
|
||||||
Players = All.OfType<Lucker>().ToList();
|
Luckers = All.OfType<Lucker>().ToList();
|
||||||
Players.ForEach( player =>
|
Luckers.ForEach( lucker =>
|
||||||
{
|
{
|
||||||
player.Ready = false;
|
lucker.Ready = false;
|
||||||
} );
|
} );
|
||||||
MinigamesLeftInRound = MinigamesPerRound;
|
MinigamesLeftInRound = MinigamesPerRound;
|
||||||
MinigameManager.StartMinigame( Players, minigameName );
|
MinigameManager.StartMinigame( Luckers, minigameName );
|
||||||
}
|
}
|
||||||
|
|
||||||
[ConCmd.Server( "start_round" )]
|
[ConCmd.Server( "start_round" )]
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public partial class Weapon : AnimatedEntity
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when the weapon is either removed from the player, or holstered.
|
/// Called when the weapon is either removed from the pawn, or holstered.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void OnHolster()
|
public void OnHolster()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,16 +4,16 @@ namespace LuckerGame.Events;
|
|||||||
|
|
||||||
public static partial class LuckerEvent
|
public static partial class LuckerEvent
|
||||||
{
|
{
|
||||||
public const string PlayerReady = "lucker.playerReady";
|
public const string LuckerReady = "lucker.luckerReady";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event is run on the server whenever a player changes ready state
|
/// Event is run on the server whenever a lucker changes ready state
|
||||||
/// The event handler is given the player that readied up and their new ready state
|
/// The event handler is given the lucker that readied up and their new ready state
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MethodArguments(typeof(Entities.Lucker), typeof(bool))]
|
[MethodArguments(typeof(Entities.Lucker), typeof(bool))]
|
||||||
public class PlayerReadyAttribute : EventAttribute
|
public class LuckerReadyAttribute : EventAttribute
|
||||||
{
|
{
|
||||||
public PlayerReadyAttribute() : base(PlayerReady)
|
public LuckerReadyAttribute() : base(LuckerReady)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ public abstract class Minigame : Entity
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes the minigame with a list of luckers playing it.
|
/// Initializes the minigame with a list of luckers playing it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="players">the players who made it into the minigame</param>
|
/// <param name="luckers">the luckers who made it into the minigame</param>
|
||||||
public abstract void Initialize(List<Lucker> players);
|
public abstract void Initialize(List<Lucker> luckers);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Once a minigame is loaded and initialized, this method is called once per server tick.
|
/// Once a minigame is loaded and initialized, this method is called once per server tick.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace LuckerGame.Minigames.RussianRoulette;
|
|||||||
public class RussianRouletteMinigame : Minigame
|
public class RussianRouletteMinigame : Minigame
|
||||||
{
|
{
|
||||||
public override string Name => "Russian Roulette";
|
public override string Name => "Russian Roulette";
|
||||||
private List<Lucker> Players { get; set; }
|
private List<Lucker> Luckers { get; set; }
|
||||||
private Pawn Shooter { get; set; }
|
private Pawn Shooter { get; set; }
|
||||||
|
|
||||||
private const float ShooterDistance = 80f;
|
private const float ShooterDistance = 80f;
|
||||||
@@ -24,43 +24,43 @@ public class RussianRouletteMinigame : Minigame
|
|||||||
private int Taunted = 0;
|
private int Taunted = 0;
|
||||||
private Pawn ShooterTarget;
|
private Pawn ShooterTarget;
|
||||||
|
|
||||||
private List<Pawn> DeadVictims => Players
|
private List<Pawn> DeadVictims => Luckers
|
||||||
.Select( player => player.Pawn as Pawn )
|
.Select( lucker => lucker.Pawn as Pawn )
|
||||||
.Where( pawn => pawn is not { IsValid: true } || pawn.LifeState != LifeState.Alive )
|
.Where( pawn => pawn is not { IsValid: true } || pawn.LifeState != LifeState.Alive )
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
private TimeSince TimeSinceShot { get; set; }
|
private TimeSince TimeSinceShot { get; set; }
|
||||||
private TimeSince TimeSinceDeadVictim { get; set; }
|
private TimeSince TimeSinceDeadVictim { get; set; }
|
||||||
|
|
||||||
public override void Initialize( List<Lucker> players )
|
public override void Initialize( List<Lucker> luckers )
|
||||||
{
|
{
|
||||||
Players = players;
|
Luckers = luckers;
|
||||||
Shooter = new Pawn();
|
Shooter = new Pawn();
|
||||||
Shooter.Name = ShooterName;
|
Shooter.Name = ShooterName;
|
||||||
var shooterInventory = Shooter.Components.Create<PawnInventory>();
|
var shooterInventory = Shooter.Components.Create<PawnInventory>();
|
||||||
shooterInventory.AddWeapon( new RussianPistol() );
|
shooterInventory.AddWeapon( new RussianPistol() );
|
||||||
|
|
||||||
// Setup cameras for players
|
// Setup cameras for luckers
|
||||||
Players.ForEach( player =>
|
Luckers.ForEach( lucker =>
|
||||||
{
|
{
|
||||||
player.Components.Create<RTSCamera>();
|
lucker.Components.Create<RTSCamera>();
|
||||||
player.Position = Shooter.Position;
|
lucker.Position = Shooter.Position;
|
||||||
} );
|
} );
|
||||||
|
|
||||||
Players.Select((player, i) => (Player: player, Index: i) ).ToList().ForEach( pair =>
|
Luckers.Select((lucker, i) => (Lucker: lucker, Index: i) ).ToList().ForEach( pair =>
|
||||||
{
|
{
|
||||||
var player = pair.Player;
|
var lucker = pair.Lucker;
|
||||||
var index = pair.Index;
|
var index = pair.Index;
|
||||||
var pawn = new Pawn();
|
var pawn = new Pawn();
|
||||||
pawn.Name = player.Name;
|
pawn.Name = lucker.Name;
|
||||||
pawn.Tags.Add( "victim" );
|
pawn.Tags.Add( "victim" );
|
||||||
pawn.Health = 1;
|
pawn.Health = 1;
|
||||||
player.Pawn = pawn;
|
lucker.Pawn = pawn;
|
||||||
pawn.DressFromClient( player.Client );
|
pawn.DressFromClient( lucker.Client );
|
||||||
|
|
||||||
var pawnOffset = ShooterDistance * (index % 2 == 0 ? Vector3.Forward : Vector3.Right) * (index % 4 >= 2 ? -1 : 1);
|
var pawnOffset = ShooterDistance * (index % 2 == 0 ? Vector3.Forward : Vector3.Right) * (index % 4 >= 2 ? -1 : 1);
|
||||||
|
|
||||||
player.Pawn.Position = Shooter.Position + pawnOffset;
|
lucker.Pawn.Position = Shooter.Position + pawnOffset;
|
||||||
pawn.LookAt(Shooter.Position);
|
pawn.LookAt(Shooter.Position);
|
||||||
} );
|
} );
|
||||||
TimeSinceShot = 0;
|
TimeSinceShot = 0;
|
||||||
@@ -95,7 +95,7 @@ public class RussianRouletteMinigame : Minigame
|
|||||||
}
|
}
|
||||||
else if ( TimeSinceShot > TimeBetweenShots * .8f && Taunted == 1)
|
else if ( TimeSinceShot > TimeBetweenShots * .8f && Taunted == 1)
|
||||||
{
|
{
|
||||||
ShooterTarget = Players.Select( player => player.Pawn as Pawn )
|
ShooterTarget = Luckers.Select( lucker => lucker.Pawn as Pawn )
|
||||||
.OrderBy( _ => Guid.NewGuid() )
|
.OrderBy( _ => Guid.NewGuid() )
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
Shooter.LookAt( ShooterTarget.Position );
|
Shooter.LookAt( ShooterTarget.Position );
|
||||||
|
|||||||
@@ -10,9 +10,9 @@
|
|||||||
|
|
||||||
<root>
|
<root>
|
||||||
<div class="scoreboard-panel">
|
<div class="scoreboard-panel">
|
||||||
@foreach (var player in Luckers)
|
@foreach (var lucker in Luckers)
|
||||||
{
|
{
|
||||||
<label>@player.Name</label>
|
<label>@lucker.Name</label>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</root>
|
</root>
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
protected override int BuildHash()
|
protected override int BuildHash()
|
||||||
{
|
{
|
||||||
return HashCode.Combine(Luckers.Select(player => player.Name).ToList());
|
return HashCode.Combine(Luckers.Select(lucker => lucker.Name).ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
<div class="voting-panel primary-color-translucent-background">
|
<div class="voting-panel primary-color-translucent-background">
|
||||||
@if (RoundManager.RoundState == RoundState.NotStarted)
|
@if (RoundManager.RoundState == RoundState.NotStarted)
|
||||||
{
|
{
|
||||||
<label class="header">Waiting for players...</label>
|
<label class="header">Waiting for luckers...</label>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user