aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--code/pawn/Player.Character.cs17
-rw-r--r--code/pawn/Player.cs12
-rw-r--r--code/pawn/component/camera/BaseCameraComponent.cs17
-rw-r--r--code/pawn/component/camera/PlayerCameraComponent.cs16
-rw-r--r--code/pawn/component/camera/SpectatorCameraComponent.cs17
-rw-r--r--code/pawn/component/movement/WalkControllerComponent.cs2
-rw-r--r--code/phase/AssignPhase.cs114
-rw-r--r--code/phase/PlayPhase.cs38
-rw-r--r--code/phase/WaitPhase.cs2
-rw-r--r--code/team/Team.cs4
-rw-r--r--code/ui/PlayerInfo.razor43
-rw-r--r--code/ui/character/NameInfo.razor37
-rw-r--r--code/ui/health/Health.razor2
-rw-r--r--code/ui/overlay/RoleOverlay.razor6
-rw-r--r--code/ui/team/TeamInfo.razor2
15 files changed, 249 insertions, 80 deletions
diff --git a/code/pawn/Player.Character.cs b/code/pawn/Player.Character.cs
new file mode 100644
index 0000000..a8fc19c
--- /dev/null
+++ b/code/pawn/Player.Character.cs
@@ -0,0 +1,17 @@
+using Sandbox;
+
+namespace MurderGame;
+
+public partial class Player
+{
+ [Net] public Team Team { get; set; }
+
+ [Net] public string CharacterName { get; set; }
+
+ [Net] public string HexColor { get; set; }
+
+ public string GetTeamName()
+ {
+ return TeamOperations.GetTeamName( Team );
+ }
+}
diff --git a/code/pawn/Player.cs b/code/pawn/Player.cs
index 7462c6e..1d87d94 100644
--- a/code/pawn/Player.cs
+++ b/code/pawn/Player.cs
@@ -41,8 +41,6 @@ public partial class Player : AnimatedEntity
);
}
- [Net]
- public Team CurrentTeam { get; set; }
public BaseCameraComponent Camera => Components.Get<BaseCameraComponent>();
public BaseControllerComponent Controller => Components.Get<BaseControllerComponent>();
@@ -61,7 +59,7 @@ public partial class Player : AnimatedEntity
[Net, Predicted]
public TimeSince TimeSinceDeath { get; set; } = 0;
-
+
public override void Spawn()
{
SetModel( "models/citizen/citizen.vmdl" );
@@ -87,7 +85,6 @@ public partial class Player : AnimatedEntity
EnableAllCollisions = true;
EnableDrawing = true;
- Components.RemoveAll();
Components.Create<WalkControllerComponent>();
Components.Create<PlayerCameraComponent>();
Components.Create<AnimatorComponent>();
@@ -102,7 +99,6 @@ public partial class Player : AnimatedEntity
{
DisablePlayer();
DeleteRagdoll();
- Components.RemoveAll();
}
public void DeleteRagdoll()
@@ -185,7 +181,11 @@ public partial class Player : AnimatedEntity
if (Game.IsServer && Camera is not SpectatorCameraComponent && LifeState == LifeState.Dead && TimeSinceDeath > 3.5)
{
DeathOverlay.Hide( To.Single( Client ) );
- Components.RemoveAll();
+ Components.Remove( Controller );
+ Components.Remove( Camera );
+ Components.Remove( Animator );
+ Components.Remove( Inventory );
+ Components.Remove( FallDamage );
Components.Create<SpectatorCameraComponent>();
}
diff --git a/code/pawn/component/camera/BaseCameraComponent.cs b/code/pawn/component/camera/BaseCameraComponent.cs
index 029586a..401d702 100644
--- a/code/pawn/component/camera/BaseCameraComponent.cs
+++ b/code/pawn/component/camera/BaseCameraComponent.cs
@@ -20,16 +20,27 @@ public class BaseCameraComponent : EntityComponent<Player>, ISingletonComponent
public virtual InventoryComponent GetObservedInventory()
{
- return null;
+ return Entity.Inventory;
}
public virtual float GetObservedHealth()
{
- return 0;
+ return Entity.Health;
}
public virtual Team GetObservedTeam()
{
- return Team.Spectator;
+ return Entity.Team;
+ }
+
+ public virtual string GetObservedName()
+ {
+ var characterName = Entity.CharacterName;
+ return string.IsNullOrWhiteSpace( characterName ) ? Entity.Client.Name : characterName;
+ }
+
+ public virtual string GetObservedColour()
+ {
+ return Entity.HexColor;
}
}
diff --git a/code/pawn/component/camera/PlayerCameraComponent.cs b/code/pawn/component/camera/PlayerCameraComponent.cs
index 702f0c8..5ec9f7b 100644
--- a/code/pawn/component/camera/PlayerCameraComponent.cs
+++ b/code/pawn/component/camera/PlayerCameraComponent.cs
@@ -43,21 +43,5 @@ public class PlayerCameraComponent : BaseCameraComponent
var pl = Entity as Player;
var viewAngles = (pl.ViewAngles + Input.AnalogLook).Normal;
pl.ViewAngles = viewAngles.WithPitch( viewAngles.pitch.Clamp( -89f, 89f ) );
- return;
- }
-
- public override InventoryComponent GetObservedInventory()
- {
- return Entity.Inventory;
- }
-
- public override float GetObservedHealth()
- {
- return Entity.Health;
- }
-
- public override Team GetObservedTeam()
- {
- return Entity.CurrentTeam;
}
}
diff --git a/code/pawn/component/camera/SpectatorCameraComponent.cs b/code/pawn/component/camera/SpectatorCameraComponent.cs
index fba33a5..3baf1a9 100644
--- a/code/pawn/component/camera/SpectatorCameraComponent.cs
+++ b/code/pawn/component/camera/SpectatorCameraComponent.cs
@@ -47,7 +47,7 @@ public partial class SpectatorCameraComponent : BaseCameraComponent
private List<IClient> GetTargets()
{
- return Game.Clients.Where(c => c.Pawn is Player player && player.CurrentTeam != Team.Spectator && player.LifeState == LifeState.Alive).ToList();
+ return Game.Clients.Where(c => c.Pawn is Player player && player.Team != Team.Spectator && player.LifeState == LifeState.Alive).ToList();
}
private void FindNextTarget(List<IClient> targets, bool backwards)
@@ -70,11 +70,22 @@ public partial class SpectatorCameraComponent : BaseCameraComponent
public override float GetObservedHealth()
{
- return Target?.Health ?? Entity.Health;
+ return Target?.Health ?? base.GetObservedHealth();
}
public override Team GetObservedTeam()
{
- return Target?.CurrentTeam ?? Entity.CurrentTeam;
+ return Target?.Team ?? base.GetObservedTeam();
+ }
+
+ public override string GetObservedName()
+ {
+ var characterName = Entity.CharacterName;
+ return string.IsNullOrWhiteSpace( characterName ) ? (Target?.Client.Name ?? "Unknown") : characterName;
+ }
+
+ public override string GetObservedColour()
+ {
+ return Target?.HexColor ?? base.GetObservedColour();
}
}
diff --git a/code/pawn/component/movement/WalkControllerComponent.cs b/code/pawn/component/movement/WalkControllerComponent.cs
index 765437c..da4ad5b 100644
--- a/code/pawn/component/movement/WalkControllerComponent.cs
+++ b/code/pawn/component/movement/WalkControllerComponent.cs
@@ -10,7 +10,7 @@ public partial class WalkControllerComponent : BaseControllerComponent
{
get
{
- return TeamCapabilities.CanSprint( Entity.CurrentTeam );
+ return TeamCapabilities.CanSprint( Entity.Team );
}
}
[Net] public float SprintSpeed { get; set; } = 320.0f;
diff --git a/code/phase/AssignPhase.cs b/code/phase/AssignPhase.cs
index 0ae6bd2..04ebdb0 100644
--- a/code/phase/AssignPhase.cs
+++ b/code/phase/AssignPhase.cs
@@ -3,6 +3,7 @@ using Sandbox.UI;
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Net.Http.Headers;
namespace MurderGame;
@@ -10,59 +11,134 @@ public class AssignPhase : BasePhase
{
public override string Title => "Assigning teams";
public int TicksElapsed;
+
+ private List<string> NatoNames = new()
+ {
+ "Alpha",
+ "Bravo",
+ "Charlie",
+ "Delta",
+ "Echo",
+ "Foxtrot",
+ "Golf",
+ "Hotel",
+ "India",
+ "Juliet",
+ "Kilo",
+ "Lima",
+ "Mike",
+ "November",
+ "Oscar",
+ "Papa",
+ "Quebec",
+ "Romeo",
+ "Sierra",
+ "Tango",
+ "Uniform",
+ "Victor",
+ "Whiskey",
+ "X-Ray",
+ "Yankee",
+ "Zulu"
+ };
+
+ private List<string> HexColours = new()
+ {
+ "#0074D9", // blue
+ "#7FDBFF", // aqua
+ "#39CCCC", // teal
+ "#B10DC9", // purple
+ "#F012BE", // fuchsia
+ "#85144B", // maroon
+ "#FF4136", // red
+ "#FF851B", // orange
+ "#FFDC00", // yellow
+ "#3D9970", // olive
+ "#2ECC40", // lime
+ "#01FF70" // green
+ };
public override void Activate()
{
+ // cleanup -- start
foreach (var entity in Entity.All.OfType<DroppedWeapon>())
{
entity.Delete();
}
+ // cleanup -- end
var detectivesNeeded = 1;
var murderersNeeded = 1;
-
+
Random random = new();
- List<SpawnPoint> spawnpoints = Entity.All.OfType<SpawnPoint>().OrderBy( _ => random.Next() ).ToList();
- var clients = Game.Clients.ToList();
- foreach ( int i in Enumerable.Range( 0, clients.Count ).OrderBy( _ => random.Next() ) )
+
+ var spawnPoints = Entity.All.OfType<SpawnPoint>().OrderBy( _ => random.Next() ).ToList();
+ var clients = Game.Clients.ToList().OrderBy( _ => random.Next() );
+ var natoNamesRemaining = new List<string>(NatoNames.OrderBy( _ => random.Next() ));
+ var coloursRemaining = new List<string>(HexColours.OrderBy( _ => random.Next() ));
+
+ foreach ( var client in clients )
{
- 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)
+
+ if (spawnPoints.Count == 0)
{
ChatBox.Say( "Could not spawn " + client.Name + " as there are not enough spawn points." );
- pawn.CurrentTeam = Team.Spectator;
+ pawn.Team = Team.Spectator;
continue;
}
pawn.DressFromClient( client );
+
+ // re-use names and colours if needed
+ if (natoNamesRemaining.Count == 0)
+ {
+ natoNamesRemaining = new List<string>(NatoNames);
+ }
+ if (coloursRemaining.Count == 0)
+ {
+ coloursRemaining = new List<string>(HexColours);
+ }
+ // assign team
if (murderersNeeded > 0)
{
- pawn.CurrentTeam = Team.Murderer;
+ pawn.Team = Team.Murderer;
--murderersNeeded;
}
else if (detectivesNeeded > 0)
{
- pawn.CurrentTeam = Team.Detective;
+ pawn.Team = Team.Detective;
--detectivesNeeded;
}
else
{
- pawn.CurrentTeam = Team.Bystander;
+ pawn.Team = Team.Bystander;
}
- Log.Info( "Assigning " + client.Name + " to team " + TeamOperations.GetTeamName( pawn.CurrentTeam ) );
+ Log.Info( "Assigning " + client.Name + " to team " + pawn.GetTeamName() );
- var spawnpoint = spawnpoints[0];
- spawnpoints.RemoveAt( 0 );
- var tx = spawnpoint.Transform;
- tx.Position = tx.Position + Vector3.Up * 10.0f;
+ // position pawn
+ var spawnPoint = spawnPoints[0];
+ spawnPoints.RemoveAt( 0 );
+ var tx = spawnPoint.Transform;
+ tx.Position += Vector3.Up * 10.0f;
pawn.Transform = tx;
+
+ // assign nato name
+ var natoName = natoNamesRemaining[0];
+ natoNamesRemaining.RemoveAt( 0 );
+ pawn.CharacterName = natoName;
+
+ // assign nato name
+ var hexColour = coloursRemaining[0];
+ coloursRemaining.RemoveAt( 0 );
+ pawn.HexColor = hexColour;
RoleOverlay.Show( To.Single( client ) );
}
@@ -80,11 +156,13 @@ public class AssignPhase : BasePhase
public override void Tick()
{
++TicksElapsed;
- if ( base.TimeLeft != -1 && TicksElapsed % Game.TickRate == 0 && --base.TimeLeft == 0 )
+ if ( TimeLeft == -1 || TicksElapsed % Game.TickRate != 0 || --base.TimeLeft != 0 )
{
- base.IsFinished = true;
- base.NextPhase = new PlayPhase();
+ return;
}
+
+ IsFinished = true;
+ NextPhase = new PlayPhase();
}
}
diff --git a/code/phase/PlayPhase.cs b/code/phase/PlayPhase.cs
index 2a28fda..682cfe7 100644
--- a/code/phase/PlayPhase.cs
+++ b/code/phase/PlayPhase.cs
@@ -20,16 +20,15 @@ public class PlayPhase : BasePhase
Event.Register(this);
foreach ( var client in Game.Clients )
{
- if ( client.Pawn is Player pawn )
+ if ( client.Pawn is not Player pawn || pawn.Team == Team.Spectator )
{
- if (pawn.CurrentTeam != Team.Spectator)
- {
- pawn.Respawn();
- TeamCapabilities.GiveLoadouts( pawn );
- }
+ continue;
}
+
+ pawn.Respawn();
+ TeamCapabilities.GiveLoadouts( pawn );
}
- MurdererNames = string.Join( ',', Game.Clients.Where( c => ((Player)c.Pawn).CurrentTeam == Team.Murderer ).Select(c => c.Name));
+ MurdererNames = string.Join( ',', Game.Clients.Where( c => ((Player)c.Pawn).Team == Team.Murderer ).Select(c => c.Name));
}
public override void Deactivate()
@@ -48,12 +47,14 @@ public class PlayPhase : BasePhase
Log.Info( "Removing blind from " + entity.Name );
BlindedOverlay.Hide( To.Single( entity ) );
DeathOverlay.Hide( To.Single( entity ) );
- if (entity is Player pawn && pawn.IsValid() )
+ if ( entity is not Player pawn || !pawn.IsValid() )
{
- if (pawn.Controller is WalkControllerComponent controller) controller.SpeedMultiplier = 1;
- if (pawn.Inventory!= null) pawn.Inventory.AllowPickup = true;
+ return;
}
+ if (pawn.Controller is WalkControllerComponent controller) controller.SpeedMultiplier = 1;
+ if (pawn.Inventory!= null) pawn.Inventory.AllowPickup = true;
+
}
public override void Tick()
@@ -64,8 +65,8 @@ public class PlayPhase : BasePhase
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);
+ var bystandersAlive = Game.Clients.Any(c =>((Player)c.Pawn).Team == Team.Bystander || ((Player)c.Pawn).Team == Team.Detective);
+ var murderersAlive = Game.Clients.Any(c =>((Player)c.Pawn).Team == Team.Murderer);
if (!bystandersAlive || !murderersAlive)
{
TriggerEndOfGame();
@@ -89,7 +90,7 @@ public class PlayPhase : BasePhase
public void TriggerEndOfGame()
{
- bool bystandersWin = Game.Clients.Any(c =>((Player)c.Pawn).CurrentTeam == Team.Bystander || ((Player)c.Pawn).CurrentTeam == Team.Detective);
+ var bystandersWin = Game.Clients.Any(c =>((Player)c.Pawn).Team is Team.Bystander or Team.Detective);
ChatBox.Say( (bystandersWin ? "Bystanders" : "Murderers") +" win! The murderers were: " + MurdererNames );
base.NextPhase = new EndPhase();
base.IsFinished = true;
@@ -102,9 +103,9 @@ public class PlayPhase : BasePhase
{
return;
}
- Player victimPlayer = (Player)victim;
- Team victimTeam = victimPlayer.CurrentTeam;
- victimPlayer.CurrentTeam = Team.Spectator;
+ var victimPlayer = (Player)victim;
+ var victimTeam = victimPlayer.Team;
+ victimPlayer.Team = Team.Spectator;
if (killer == null)
{
@@ -112,9 +113,8 @@ public class PlayPhase : BasePhase
return;
}
-
- Player killerPlayer = (Player)killer;
- Team killerTeam = killerPlayer.CurrentTeam;
+ var killerPlayer = (Player)killer;
+ var killerTeam = killerPlayer.Team;
Log.Info( victimPlayer + " died to " + killerPlayer );
diff --git a/code/phase/WaitPhase.cs b/code/phase/WaitPhase.cs
index c3d0e16..e52c91c 100644
--- a/code/phase/WaitPhase.cs
+++ b/code/phase/WaitPhase.cs
@@ -67,7 +67,7 @@ public class WaitPhase : BasePhase
private void RespawnPlayer(Player pawn)
{
- pawn.CurrentTeam = Team.Spectator;
+ pawn.Team = Team.Spectator;
pawn.DressFromClient( pawn.Client );
pawn.Respawn();
}
diff --git a/code/team/Team.cs b/code/team/Team.cs
index 8c9a7d7..189840b 100644
--- a/code/team/Team.cs
+++ b/code/team/Team.cs
@@ -30,12 +30,14 @@ public static class TeamCapabilities
{
pawn.Inventory.Clear();
- switch (pawn.CurrentTeam)
+ switch (pawn.Team)
{
case Team.Detective:
GiveDetectiveWeapon(pawn); break;
case Team.Murderer:
GiveMurdererWeapon(pawn); break;
+ case Team.Spectator:
+ case Team.Bystander:
default: break;
}
}
diff --git a/code/ui/PlayerInfo.razor b/code/ui/PlayerInfo.razor
index fed61c0..9c23586 100644
--- a/code/ui/PlayerInfo.razor
+++ b/code/ui/PlayerInfo.razor
@@ -1,3 +1,4 @@
+@using System
@using Sandbox;
@using Sandbox.UI;
@@ -7,8 +8,10 @@
<style>
playerinfo {
position: absolute;
- left: 30px;
- bottom: 30px;
+ width: 100vw;
+ height: 100vh;
+}
+.box {
background-color: rgba(0, 0, 0, 0.20);
backdrop-filter-blur: 8px;
display: flex;
@@ -17,26 +20,52 @@ playerinfo {
gap: 10px;
padding: 10px;
}
+.playerinfo {
+ position: absolute;
+ left: 30px;
+ bottom: 30px;
+}
+.teaminfo {
+ position: absolute;
+ right: 30px;
+ bottom: 30px;
+}
</style>
-<Health Colour="@GetTeamColour()"></Health>
-<TeamInfo Colour="@GetTeamColour()"></TeamInfo>
+<div class="playerinfo box">
+ <Health Colour="@GetCharacterColour()"></Health>
+ <NameInfo Colour="@GetCharacterColour()"></NameInfo>
+</div>
+<div class="teaminfo box">
+ <TeamInfo Colour="@GetTeamColour()"></TeamInfo>
+</div>
@code
{
- public string GetTeamColour()
+ public string GetCharacterColour()
{
var clientPawn = Game.LocalPawn;
if (clientPawn is Player {Camera: not null } player)
{
- var colour = TeamOperations.GetTeamColour(player.Camera.GetObservedTeam());
+ var colour = player.Camera.GetObservedColour();
return string.IsNullOrWhiteSpace(colour) ? "white" : colour;
}
return "white";
}
+
+ public string GetTeamColour()
+ {
+ var clientPawn = Game.LocalPawn;
+ if (clientPawn is Player {Camera: not null } player)
+ {
+ var colour = TeamOperations.GetTeamColour(player.Camera.GetObservedTeam());
+ return string.IsNullOrWhiteSpace(colour) ? "white" : colour;
+ }
+ return "white";
+ }
protected override int BuildHash()
{
- return GetTeamColour().GetHashCode();
+ return HashCode.Combine(GetTeamColour().GetHashCode(), GetTeamColour().GetHashCode());
}
}
diff --git a/code/ui/character/NameInfo.razor b/code/ui/character/NameInfo.razor
new file mode 100644
index 0000000..8b6dce1
--- /dev/null
+++ b/code/ui/character/NameInfo.razor
@@ -0,0 +1,37 @@
+@using Sandbox;
+@using Sandbox.UI;
+
+@namespace MurderGame
+@inherits Panel
+
+<style>
+.team-info {
+ font-size: 30px;
+ font-weight: 700;
+ font-family: "Roboto";
+}
+</style>
+
+<div class="team-info" style="color: @(Colour)">
+@GetName()
+</div>
+
+@code
+{
+ public string Colour { get; set; }
+
+ public string GetName()
+ {
+ var clientPawn = Game.LocalPawn;
+ if (clientPawn is Player {Camera: not null } player)
+ {
+ return player.Camera.GetObservedName();
+ }
+ return "";
+ }
+
+ protected override int BuildHash()
+ {
+ return GetName().GetHashCode();
+ }
+}
diff --git a/code/ui/health/Health.razor b/code/ui/health/Health.razor
index 9600c8b..afef6ef 100644
--- a/code/ui/health/Health.razor
+++ b/code/ui/health/Health.razor
@@ -6,7 +6,7 @@
<style>
Health {
- width: 400px;
+ width: 350px;
height: 100%;
background-color: rgba(0, 0, 0, 0.90);
}
diff --git a/code/ui/overlay/RoleOverlay.razor b/code/ui/overlay/RoleOverlay.razor
index 40cbce0..cd3cd88 100644
--- a/code/ui/overlay/RoleOverlay.razor
+++ b/code/ui/overlay/RoleOverlay.razor
@@ -54,7 +54,7 @@ roleoverlay
{
if (Game.LocalPawn is Player player)
{
- return TeamOperations.GetTeamName(player.CurrentTeam);
+ return TeamOperations.GetTeamName(player.Team);
}
return "";
}
@@ -62,7 +62,7 @@ roleoverlay
{
if (Game.LocalPawn is Player player)
{
- return TeamOperations.GetTeamDescription(player.CurrentTeam);
+ return TeamOperations.GetTeamDescription(player.Team);
}
return "";
}
@@ -70,7 +70,7 @@ roleoverlay
{
if (Game.LocalPawn is Player player)
{
- return TeamOperations.GetTeamColour(player.CurrentTeam);
+ return TeamOperations.GetTeamColour(player.Team);
}
return "";
}
diff --git a/code/ui/team/TeamInfo.razor b/code/ui/team/TeamInfo.razor
index 4451810..cb2b55d 100644
--- a/code/ui/team/TeamInfo.razor
+++ b/code/ui/team/TeamInfo.razor
@@ -6,7 +6,7 @@
<style>
.team-info {
- font-size: 35px;
+ font-size: 30px;
font-weight: 700;
font-family: "Roboto";
}