diff options
Diffstat (limited to 'code/phase')
| -rw-r--r-- | code/phase/AssignPhase.cs | 89 | ||||
| -rw-r--r-- | code/phase/BasePhase.cs | 28 | ||||
| -rw-r--r-- | code/phase/EndPhase.cs | 26 | ||||
| -rw-r--r-- | code/phase/PlayPhase.cs | 133 | ||||
| -rw-r--r-- | code/phase/WaitPhase.cs | 43 |
5 files changed, 319 insertions, 0 deletions
diff --git a/code/phase/AssignPhase.cs b/code/phase/AssignPhase.cs new file mode 100644 index 0000000..26c9fc1 --- /dev/null +++ b/code/phase/AssignPhase.cs @@ -0,0 +1,89 @@ +using Sandbox;
+using Sandbox.UI;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace MurderGame;
+
+public class AssignPhase : BasePhase
+{
+ public override string Title => "Assigning teams";
+ public int TicksElapsed;
+
+ public override void Activate()
+ {
+ foreach (var entity in Entity.All.OfType<DroppedWeapon>())
+ {
+ entity.Delete();
+ }
+
+ var detectivesNeeded = 1;
+ var murderersNeeded = 1;
+
+ List<SpawnPoint> spawnpoints = Entity.All.OfType<SpawnPoint>().OrderBy( x => Guid.NewGuid() ).ToList();
+ var clients = Game.Clients.ToList();
+ foreach ( int i in Enumerable.Range( 0, clients.Count ).OrderBy( x => Guid.NewGuid() ) )
+ {
+ var client = clients[i];
+ if (client.Pawn != null)
+ {
+ ((Player) client.Pawn).Cleanup();
+ client.Pawn.Delete();
+ }
+ Player pawn = new();
+ client.Pawn = pawn;
+ if (spawnpoints.Count == 0)
+ {
+ ChatBox.Say( "Could not spawn " + client.Name + " as there are not enough spawn points." );
+ pawn.CurrentTeam = Team.Spectator;
+ continue;
+ }
+ pawn.DressFromClient( client );
+
+ if (murderersNeeded > 0)
+ {
+ pawn.CurrentTeam = Team.Murderer;
+ --murderersNeeded;
+ }
+ else if (detectivesNeeded > 0)
+ {
+ pawn.CurrentTeam = Team.Detective;
+ --detectivesNeeded;
+ }
+ else
+ {
+ pawn.CurrentTeam = Team.Bystander;
+ }
+ Log.Info( "Assigning " + client.Name + " to team " + TeamOperations.GetTeamName( pawn.CurrentTeam ) );
+
+ var spawnpoint = spawnpoints[0];
+ spawnpoints.RemoveAt( 0 );
+ var tx = spawnpoint.Transform;
+ tx.Position = tx.Position + Vector3.Up * 50.0f;
+ pawn.Transform = tx;
+
+ RoleOverlay.Show( To.Single( client ) );
+ }
+ base.TimeLeft = 5;
+ }
+
+ public override void Deactivate()
+ {
+ foreach (var client in Game.Clients)
+ {
+ RoleOverlay.Hide( To.Single( client ) );
+ }
+ }
+
+ public override void Tick()
+ {
+ ++TicksElapsed;
+ if ( base.TimeLeft != -1 && TicksElapsed % Game.TickRate == 0 && --base.TimeLeft == 0 )
+ {
+ base.IsFinished = true;
+ base.NextPhase = new PlayPhase();
+ }
+ }
+
+}
diff --git a/code/phase/BasePhase.cs b/code/phase/BasePhase.cs new file mode 100644 index 0000000..8f3d044 --- /dev/null +++ b/code/phase/BasePhase.cs @@ -0,0 +1,28 @@ +using Sandbox;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MurderGame;
+
+public abstract partial class BasePhase : BaseNetworkable
+{
+ public virtual string Title => "Name";
+
+ [Net]
+ public int TimeLeft { get; set; } = -1;
+
+ public BasePhase NextPhase { get; set;}
+
+ public bool IsFinished { get; set; }
+
+ public abstract void Tick();
+
+ public virtual void Activate() { }
+
+ public virtual void Deactivate() { }
+
+ public virtual void HandleClientJoin(ClientJoinedEvent e) { }
+}
diff --git a/code/phase/EndPhase.cs b/code/phase/EndPhase.cs new file mode 100644 index 0000000..904dc81 --- /dev/null +++ b/code/phase/EndPhase.cs @@ -0,0 +1,26 @@ +using Sandbox;
+using System.Linq;
+
+namespace MurderGame;
+
+public class EndPhase : BasePhase
+{
+ public override string Title => "Game over";
+ public int TicksElapsed;
+
+ public override void Activate()
+ {
+ base.TimeLeft = 7;
+ }
+
+ public override void Tick()
+ {
+ ++TicksElapsed;
+ if (base.TimeLeft != -1 && TicksElapsed % Game.TickRate == 0 && --base.TimeLeft == 0)
+ {
+ base.NextPhase = new WaitPhase() { CountIn = false };
+ base.IsFinished = true;
+ return;
+ }
+ }
+}
diff --git a/code/phase/PlayPhase.cs b/code/phase/PlayPhase.cs new file mode 100644 index 0000000..118529e --- /dev/null +++ b/code/phase/PlayPhase.cs @@ -0,0 +1,133 @@ +using Sandbox;
+using Sandbox.UI;
+using System;
+using System.Buffers;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace MurderGame;
+
+public class PlayPhase : BasePhase
+{
+ public override string Title => "Play";
+ public IDictionary<Entity, int> Blinded = new Dictionary<Entity, int>();
+ public int TicksElapsed;
+ private string MurdererNames { get; set; }
+
+ public override void Activate()
+ {
+ base.TimeLeft = MurderGame.RoundTime;
+ Event.Register(this);
+ foreach ( var client in Game.Clients )
+ {
+ if ( client.Pawn is Player pawn )
+ {
+ if (pawn.CurrentTeam != Team.Spectator)
+ {
+ pawn.Respawn();
+ TeamOperations.GiveLoadouts( pawn );
+ }
+ }
+ }
+ MurdererNames = string.Join( ',', Game.Clients.Where( c => ((Player)c.Pawn).CurrentTeam == Team.Murderer ).Select(c => c.Name));
+ }
+
+ public override void Deactivate()
+ {
+ base.TimeLeft = MurderGame.RoundTime;
+ Event.Unregister(this);
+ foreach(var item in Blinded)
+ {
+ ClearDebuffs( item.Key );
+ }
+ Blinded.Clear();
+ }
+
+ public void ClearDebuffs(Entity entity )
+ {
+ Log.Info( "Removing blind from " + entity.Name );
+ BlindedOverlay.Hide( To.Single( entity ) );
+ if (entity is Player pawn && pawn.IsValid() )
+ {
+ if (pawn.Controller != null) pawn.Controller.SpeedMultiplier = 1;
+ if (pawn.Inventory != null) pawn.Inventory.AllowPickup = true;
+ }
+
+ }
+
+ public override void Tick()
+ {
+ ++TicksElapsed;
+ if (base.TimeLeft != -1 && TicksElapsed % Game.TickRate == 0 && --base.TimeLeft == 0)
+ {
+ TriggerEndOfGame();
+ return;
+ }
+ bool bystandersAlive = Game.Clients.Any(c =>((Player)c.Pawn).CurrentTeam == Team.Bystander || ((Player)c.Pawn).CurrentTeam == Team.Detective);
+ bool murderersAlive = Game.Clients.Any(c =>((Player)c.Pawn).CurrentTeam == Team.Murderer);
+ if (!bystandersAlive || !murderersAlive)
+ {
+ TriggerEndOfGame();
+ }
+
+ foreach(var item in Blinded)
+ {
+ var blindLeft = item.Value - 1;
+ if (blindLeft < 0)
+ {
+ Blinded.Remove( item.Key );
+ ClearDebuffs( item.Key );
+ Log.Info( "Removing blind from " + item.Key.Name );
+ }
+ else
+ {
+ Blinded[item.Key] = blindLeft;
+ }
+ }
+ }
+
+ public void TriggerEndOfGame()
+ {
+ bool bystandersWin = Game.Clients.Any(c =>((Player)c.Pawn).CurrentTeam == Team.Bystander || ((Player)c.Pawn).CurrentTeam == Team.Detective);
+ ChatBox.Say( (bystandersWin ? "Bystanders" : "Murderers") +" win! The murderers were: " + MurdererNames );
+ base.NextPhase = new EndPhase();
+ base.IsFinished = true;
+ }
+
+ [MurderEvent.Kill]
+ public void OnKill(Entity killer, Entity victim)
+ {
+ if (killer == null || killer is not Player || victim == null || victim is not Player )
+ {
+ return;
+ }
+ Player victimPlayer = (Player)victim;
+ Player killerPlayer = (Player)killer;
+ Team victimTeam = victimPlayer.CurrentTeam;
+ Team killerTeam = killerPlayer.CurrentTeam;
+ victimPlayer.CurrentTeam = Team.Spectator;
+
+ Log.Info( victimPlayer + " died to " + killerPlayer );
+ if (victimTeam != Team.Murderer && killerTeam != Team.Murderer)
+ {
+ Log.Info( killerPlayer + " shot a bystander");
+ ChatBox.Say( killerPlayer.Client.Name + " killed an innocent bystander" );
+ BlindedOverlay.Show( To.Single( killer ) );
+ if (killerPlayer.Controller != null) killerPlayer.Controller.SpeedMultiplier = 0.3f;
+ if (killerPlayer.Inventory != null)
+ {
+ Log.Info( killerPlayer + "bonk");
+ killerPlayer.Inventory.AllowPickup = false;
+ killerPlayer.Inventory.SpillContents(killerPlayer.EyePosition, killerPlayer.AimRay.Forward);
+ }
+
+ Blinded[killer] = 20 * Game.TickRate;
+ }
+ else if (victimTeam == Team.Murderer )
+ {
+ Log.Info( killerPlayer + " killed a murderer");
+ ChatBox.Say( killerPlayer.Client.Name + " killed a murderer" );
+ }
+ }
+
+}
diff --git a/code/phase/WaitPhase.cs b/code/phase/WaitPhase.cs new file mode 100644 index 0000000..4f2e876 --- /dev/null +++ b/code/phase/WaitPhase.cs @@ -0,0 +1,43 @@ +using Sandbox;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MurderGame;
+
+public class WaitPhase : BasePhase
+{
+ public override string Title => "Waiting for players";
+ public bool CountIn { get; set; }
+ public int TicksElapsed { get; set; }
+
+ private bool _isCountDown { get; set; }
+
+ public override void Tick()
+ {
+ if (Game.Clients.Count >= MurderGame.MinPlayers)
+ {
+ if (!CountIn || (_isCountDown && ++TicksElapsed % Game.TickRate == 0 && --base.TimeLeft == 0))
+ {
+ base.NextPhase = new AssignPhase();
+ base.IsFinished = true;
+ }
+ else if (CountIn && !_isCountDown)
+ {
+ _isCountDown = true;
+ base.TimeLeft = 10;
+ }
+ } else if (CountIn && _isCountDown)
+ {
+ _isCountDown = false;
+ base.TimeLeft = -1;
+ }
+ }
+
+ public override void HandleClientJoin( ClientJoinedEvent e )
+ {
+
+ }
+}
|
