feature/Lucker-misc_RoundFramework #2

Merged
para merged 8 commits from feature/Lucker-misc_RoundFramework into master 2023-08-07 05:13:13 +00:00
4 changed files with 59 additions and 8 deletions
Showing only changes of commit 686edc85a3 - Show all commits

View File

@@ -14,6 +14,7 @@ public partial class MinigameManager : Entity
{
[Net] public Minigame LoadedMinigame { get; private set; }
private List<Minigame> AvailableMinigames { get; set; }
private List<Lucker> InvolvedPlayers { get; set; }
public override void Spawn()
{
@@ -23,6 +24,7 @@ public partial class MinigameManager : Entity
public void StartMinigame(List<Lucker> players, string minigameName = null)
{
InvolvedPlayers = players.ToList();
if (CheckForMinigames())
Outdated
Review

I think this correctly caches the Lucker list when the minigame is created, which is nice. Although I'm wondering how we deal with Luckers who leave before a minigame is ended. If there's other logic that deletes a Lucker in response to the client disconnecting, will the logic in CleanupPlayerPawns() fail / crash?

Also, I feel like it'd be nice to standardize the naming of these variables to disambiguate references to Players and Luckers. Might as well just name variables after the type to avoid clashing the names.

I think this correctly caches the `Lucker` list when the minigame is created, which is nice. Although I'm wondering how we deal with Luckers who leave before a minigame is ended. If there's other logic that deletes a `Lucker` in response to the client disconnecting, will the logic in `CleanupPlayerPawns()` fail / crash? Also, I feel like it'd be nice to standardize the naming of these variables to disambiguate references to `Player`s and `Lucker`s. Might as well just name variables after the type to avoid clashing the names.
Outdated
Review

I agree with the variable naming, and will go through and do that.

I think an investigation into handling client disconnects should be done in another ticket however, as I believe there's both an investigation in how S&box handles a client disconnect by default, and also a discussion in how we handle it, such as keeping the player around for the remainder of the round but assigning them to a bot, only a minigame, leave it up to the minigames, etc.

I agree with the variable naming, and will go through and do that. I think an investigation into handling client disconnects should be done in another ticket however, as I believe there's both an investigation in how S&box handles a client disconnect by default, and also a discussion in how we handle it, such as keeping the player around for the remainder of the round but assigning them to a bot, only a minigame, leave it up to the minigames, etc.
Outdated
Review

Variables should be renamed now based on the naming of 'Lucker' as opposed to player for the most part

Variables should be renamed now based on the naming of 'Lucker' as opposed to player for the most part
{
LoadedMinigame = string.IsNullOrEmpty( minigameName ) ? AvailableMinigames.OrderBy( _ => Guid.NewGuid() ).FirstOrDefault() : TypeLibrary.Create<Minigame>( minigameName );
@@ -55,12 +57,34 @@ public partial class MinigameManager : Entity
FindMinigames();
}
public void Tick()
private void cleanupPlayerPawns()
{
InvolvedPlayers.ForEach( player =>
{
player.Pawn.Delete();
player.Pawn = null;
} );
}
/// <summary>
/// Called once per tick by the RoundManager. Ticks any running minigame.
/// </summary>
/// <returns>true if the current minigame has ended, else false</returns>
public bool Tick()
{
if ( LoadedMinigame is not { IsValid: true } )
{
return;
return false;
}
LoadedMinigame.Tick();
var ended = LoadedMinigame.Tick();
if ( !ended )
{
return false;
}
LoadedMinigame.Cleanup();
LoadedMinigame = null;
return true;
}
}

View File

@@ -76,7 +76,19 @@ public partial class RoundManager : Entity
if ( RoundState == RoundState.InProgress )
{
MinigameManager.Tick();
var ended = MinigameManager.Tick();
if ( ended )
{
MinigamesLeftInRound--;
if ( MinigamesLeftInRound > 0 )
{
MinigameManager.StartMinigame( Players );
}
else
{
RoundState = RoundState.NotStarted;
}
Review

Can we iron out the definition of Round now?

A Round is not one instance of a Minigame, but rather multiple different Minigames, right?

Before a round: settings are configured and the lobby is populated with players waiting to start playing
During a round: multiple different minigames will be played (started and stopped)
After a round: we will show the scoreboard and announce a winner.

Can we iron out the definition of `Round` now? A `Round` is not one instance of a `Minigame`, but rather multiple different `Minigame`s, right? Before a round: settings are configured and the lobby is populated with players waiting to start playing During a round: multiple different minigames will be played (started and stopped) After a round: we will show the scoreboard and announce a winner.
Review

I'd prefer setting up a round structure in a separate PR due to it moving logic around, but I agree with the definition, along with the idea that after a round ends a new one begins at the first stage again.

I'd prefer setting up a round structure in a separate PR due to it moving logic around, but I agree with the definition, along with the idea that after a round ends a new one begins at the first stage again.
}
}
}
@@ -120,6 +132,11 @@ public partial class RoundManager : Entity
RoundState = RoundState.InProgress;
Players = All.OfType<Lucker>().ToList();
Players.ForEach( player =>
{
player.Ready = false;
} );
MinigamesLeftInRound = MinigamesPerRound;
MinigameManager.StartMinigame( Players, minigameName );
}

View File

@@ -21,7 +21,8 @@ public abstract class Minigame : Entity
/// <summary>
/// Once a minigame is loaded and initialized, this method is called once per server tick.
/// </summary>
public abstract void Tick();
/// <returns>true if the minigame has ended, false otherwise</returns>
public abstract bool Tick();
/// <summary>
/// Cleans up any entities and components created by this minigame.

View File

@@ -16,8 +16,10 @@ public class RussianRouletteMinigame : Minigame
public override string Name => "Russian Roulette";
private List<Lucker> Players { get; set; }
private Pawn Shooter { get; set; }
private const float ShooterDistance = 80f;
private const float TimeBetweenShots = 7f;
private const float TimeBetweenDeathAndEnd = 5f;
private int Taunted = 0;
private List<Pawn> DeadVictims => Players
@@ -26,6 +28,7 @@ public class RussianRouletteMinigame : Minigame
.ToList();
private TimeSince TimeSinceShot { get; set; }
private TimeSince TimeSinceDeadVictim { get; set; }
public override void Initialize( List<Lucker> players )
{
@@ -60,7 +63,7 @@ public class RussianRouletteMinigame : Minigame
TimeSinceShot = 0;
}
public override void Tick()
public override bool Tick()
{
if ( DeadVictims.Any() )
{
@@ -68,10 +71,14 @@ public class RussianRouletteMinigame : Minigame
{
ChatBox.AddChatEntry( To.Everyone, "Shooter", "Heh, nothing personnel, kid." );
Taunted = int.MaxValue;
TimeSinceDeadVictim = 0;
}
return;
else if(TimeSinceDeadVictim > TimeBetweenDeathAndEnd)
{
return true;
}
if ( TimeSinceShot > TimeBetweenShots )
}
else if ( TimeSinceShot > TimeBetweenShots )
{
TimeSinceShot = 0;
Taunted = 0;
@@ -95,6 +102,8 @@ public class RussianRouletteMinigame : Minigame
ChatBox.AddChatEntry( To.Everyone, "Shooter", "Im gettin' ready!" );
Taunted++;
}
return false;
}
public override void Cleanup()