From 6d38a73a43db7eec57cecf980eebe6e610df4de4 Mon Sep 17 00:00:00 2001 From: Leonardo Bishop Date: Mon, 31 Jul 2023 02:37:57 +0100 Subject: Add character names --- code/pawn/Player.Character.cs | 17 +++ code/pawn/Player.cs | 12 +-- code/pawn/component/camera/BaseCameraComponent.cs | 17 ++- .../pawn/component/camera/PlayerCameraComponent.cs | 16 --- .../component/camera/SpectatorCameraComponent.cs | 17 ++- .../component/movement/WalkControllerComponent.cs | 2 +- code/phase/AssignPhase.cs | 114 +++++++++++++++++---- code/phase/PlayPhase.cs | 38 +++---- code/phase/WaitPhase.cs | 2 +- code/team/Team.cs | 4 +- code/ui/PlayerInfo.razor | 43 ++++++-- code/ui/character/NameInfo.razor | 37 +++++++ code/ui/health/Health.razor | 2 +- code/ui/overlay/RoleOverlay.razor | 6 +- code/ui/team/TeamInfo.razor | 2 +- 15 files changed, 249 insertions(+), 80 deletions(-) create mode 100644 code/pawn/Player.Character.cs create mode 100644 code/ui/character/NameInfo.razor (limited to 'code') 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(); public BaseControllerComponent Controller => Components.Get(); @@ -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(); Components.Create(); Components.Create(); @@ -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(); } 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, 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 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 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 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 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()) { entity.Delete(); } + // cleanup -- end var detectivesNeeded = 1; var murderersNeeded = 1; - + Random random = new(); - List spawnpoints = Entity.All.OfType().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().OrderBy( _ => random.Next() ).ToList(); + var clients = Game.Clients.ToList().OrderBy( _ => random.Next() ); + var natoNamesRemaining = new List(NatoNames.OrderBy( _ => random.Next() )); + var coloursRemaining = new List(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(NatoNames); + } + if (coloursRemaining.Count == 0) + { + coloursRemaining = new List(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 @@ - - +
+ + +
+
+ +
@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 + + + +
+@GetName() +
+ +@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 @@