diff options
| author | Leonardo Bishop <me@leonardobishop.com> | 2023-08-01 01:31:25 +0100 |
|---|---|---|
| committer | Leonardo Bishop <me@leonardobishop.com> | 2023-08-01 01:31:25 +0100 |
| commit | dbf0218371ce006b674b0ede8e6a4d97932ff2c6 (patch) | |
| tree | a865e7ff8e9f65579435b951a0c2ceffd8237c61 | |
| parent | ca0d44610b6216f82fcf8f5830d445963654db64 (diff) | |
Add footprints
| -rw-r--r-- | code/Game.cs | 9 | ||||
| -rw-r--r-- | code/entity/Footprint.cs | 55 | ||||
| -rw-r--r-- | code/pawn/Player.Character.cs | 11 | ||||
| -rw-r--r-- | code/pawn/Player.cs | 2 | ||||
| -rw-r--r-- | code/pawn/component/FootprintTrackerComponent.cs | 51 | ||||
| -rw-r--r-- | code/phase/AssignPhase.cs | 49 | ||||
| -rw-r--r-- | code/team/Team.cs | 1 | ||||
| -rw-r--r-- | materials/left_shoe_footprint.png | bin | 0 -> 6424 bytes | |||
| -rw-r--r-- | materials/left_shoe_footprint.vmat | 49 | ||||
| -rw-r--r-- | materials/right_shoe_footprint.png | bin | 0 -> 6696 bytes | |||
| -rw-r--r-- | materials/right_shoe_footprint.vmat | 49 |
11 files changed, 251 insertions, 25 deletions
diff --git a/code/Game.cs b/code/Game.cs index ad04fc8..356cd38 100644 --- a/code/Game.cs +++ b/code/Game.cs @@ -23,14 +23,17 @@ public partial class MurderGame : Sandbox.GameManager }
- [ConVar.Server( "mm_min_players", Help = "The minimum number of players required to start a round." )]
+ [ConVar.Server( "mu_min_players", Help = "The minimum number of players required to start a round." )]
public static int MinPlayers { get; set; } = 2;
- [ConVar.Server( "mm_allow_suicide", Help = "Allow players to kill themselves during a round." )]
+ [ConVar.Server( "mu_allow_suicide", Help = "[INOP] Allow players to kill themselves during a round." )]
public static bool AllowSuicide { get; set; } = true;
- [ConVar.Server( "mm_round_time", Help = "The amount of time in a round." )]
+ [ConVar.Server( "mu_round_time", Help = "The amount of time, in seconds, in a round." )]
public static int RoundTime { get; set; } = 600;
+
+ [ConVar.Client( "mu_max_footprint_time", Help = "The amount of time, in seconds, footprints are visible for. Max 30 seconds." )]
+ public static int MaxFootprintTime { get; set; } = 30;
[Net]
public BasePhase CurrentPhase { get; set; } = new WaitPhase() { CountIn = true };
diff --git a/code/entity/Footprint.cs b/code/entity/Footprint.cs new file mode 100644 index 0000000..8941e95 --- /dev/null +++ b/code/entity/Footprint.cs @@ -0,0 +1,55 @@ +using System;
+
+namespace MurderGame;
+
+using Sandbox;
+// It's just a square with a material slapped onto it.
+public class Footprint : RenderEntity
+{
+ public Material SpriteMaterial { get; set; }
+
+ public float SpriteScale { get; set; } = 18f;
+
+ public bool Enabled { get; set; } = true;
+
+ public Color Color { get; set; }
+
+ private TimeSince TimeSinceCreated = 0;
+
+ [GameEvent.Tick.Client]
+ public void OnTick()
+ {
+ if ( !(TimeSinceCreated > Math.Clamp(MurderGame.MaxFootprintTime, 0, 30)) )
+ {
+ return;
+ }
+
+ Enabled = false;
+ Delete();
+ }
+
+ public override void DoRender(SceneObject obj)
+ {
+ if (!Enabled) return;
+
+ // Allow lights to affect the sprite
+ Graphics.SetupLighting(obj);
+ // Create the vertex buffer for the sprite
+ var vb = new VertexBuffer();
+ vb.Init(true);
+
+ // Vertex buffers are in local space, so we need the camera position in local space too
+ var normal = new Vector3( 0, 0.01f, 100 );
+ var w = normal.Cross(Vector3.Down).Normal;
+ var h = normal.Cross(w).Normal;
+ float halfSpriteSize = SpriteScale / 2;
+
+ // Add a single quad to our vertex buffer
+ vb.AddQuad(new Ray(default, normal), halfSpriteSize*w, h*halfSpriteSize);
+
+ Graphics.Attributes.Set( "color", Color);
+
+ // Draw the sprite
+ vb.Draw( SpriteMaterial );
+ }
+}
diff --git a/code/pawn/Player.Character.cs b/code/pawn/Player.Character.cs index a8fc19c..579107a 100644 --- a/code/pawn/Player.Character.cs +++ b/code/pawn/Player.Character.cs @@ -5,10 +5,17 @@ namespace MurderGame; public partial class Player
{
[Net] public Team Team { get; set; }
-
+
[Net] public string CharacterName { get; set; }
- [Net] public string HexColor { get; set; }
+ [Net] public Color Color { get; set; } = Color.White;
+
+ public string HexColor {
+ get
+ {
+ return Color.Hex;
+ }
+ }
public string GetTeamName()
{
diff --git a/code/pawn/Player.cs b/code/pawn/Player.cs index 7073bb1..7254023 100644 --- a/code/pawn/Player.cs +++ b/code/pawn/Player.cs @@ -47,6 +47,7 @@ public partial class Player : AnimatedEntity [BindComponent] public AnimatorComponent Animator { get; }
[BindComponent] public InventoryComponent Inventory { get; }
[BindComponent] public FallDamageComponent FallDamage { get; }
+ [BindComponent] public FootprintTrackerComponent FootprintTracker { get; }
[Net]
public Ragdoll PlayerRagdoll { get; set; }
@@ -179,6 +180,7 @@ public partial class Player : AnimatedEntity Animator?.Simulate();
Inventory?.Simulate( cl );
FallDamage?.Simulate( cl );
+ FootprintTracker?.Simulate( cl );
if (Game.IsServer && Camera is not SpectatorCameraComponent && LifeState == LifeState.Dead && TimeSinceDeath > 3.5)
{
diff --git a/code/pawn/component/FootprintTrackerComponent.cs b/code/pawn/component/FootprintTrackerComponent.cs new file mode 100644 index 0000000..7a396d1 --- /dev/null +++ b/code/pawn/component/FootprintTrackerComponent.cs @@ -0,0 +1,51 @@ +using System.Linq;
+using Sandbox;
+
+namespace MurderGame;
+
+public class FootprintTrackerComponent : EntityComponent<Player>, ISingletonComponent
+{
+ private TimeSince TimeSinceFootstep = 0;
+ private bool FootstepLeft = true;
+
+ public void Simulate( IClient cl )
+ {
+ if (!Game.IsClient || TimeSinceFootstep < 0.25) return;
+ TimeSinceFootstep = 0;
+ FootstepLeft = !FootstepLeft;
+
+ var bystanders = Game.Clients.Where(c => (c.Pawn as Player)?.Team is Team.Bystander or Team.Detective);
+
+ foreach (var bystander in bystanders)
+ {
+ if (bystander.Pawn is not Player player) continue;
+ if (player.Velocity.Length < 1) continue;
+ var start = player.Position + Vector3.Up;
+ var end = start + Vector3.Down * 20;
+
+ var tr = Trace.Ray( start, end )
+ .Size( 2)
+ .WithAnyTags( "solid" )
+ .Ignore( Entity )
+ .Run();
+
+ if ( !tr.Hit )
+ {
+ continue;
+ }
+
+ var material = FootstepLeft
+ ? "materials/left_shoe_footprint.vmat"
+ : "materials/right_shoe_footprint.vmat";
+ var _ = new Footprint
+ {
+ SpriteMaterial = Material.Load(material),
+ SpriteScale = 24f,
+ Position = player.Position + (Vector3.Up * 1f),
+ Rotation = Rotation.LookAt(player.Velocity, tr.Normal).RotateAroundAxis( tr.Normal, 270 ),
+ Color = player.Color
+ };
+ }
+ }
+
+}
diff --git a/code/phase/AssignPhase.cs b/code/phase/AssignPhase.cs index f29aa62..f69ca7b 100644 --- a/code/phase/AssignPhase.cs +++ b/code/phase/AssignPhase.cs @@ -3,11 +3,10 @@ using Sandbox.UI; using System;
using System.Collections.Generic;
using System.Linq;
-using System.Net.Http.Headers;
namespace MurderGame;
-public class AssignPhase : BasePhase
+public partial class AssignPhase : BasePhase
{
public override string Title => "Assigning teams";
public int TicksElapsed;
@@ -42,18 +41,18 @@ public class AssignPhase : BasePhase "Zulu"
};
- private List<string> HexColours = new()
+ private List<uint> Colors = new()
{
- "#0074D9", // blue
- "#7FDBFF", // aqua
- "#39CCCC", // teal
- "#F012BE", // fuchsia
- "#FF4136", // red
- "#FF851B", // orange
- "#FFDC00", // yellow
- "#3D9970", // olive
- "#2ECC40", // lime
- "#01FF70" // green
+ 0x0074D9, // blue
+ 0x7FDBFF, // aqua
+ 0x39CCCC, // teal
+ 0xF012BE, // fuchsia
+ 0xFF4136, // red
+ 0xFF851B, // orange
+ 0xFFDC00, // yellow
+ 0x3D9970, // olive
+ 0x2ECC40, // lime
+ 0x01FF70 // green
};
public override void Activate()
@@ -63,17 +62,18 @@ public class AssignPhase : BasePhase {
entity.Delete();
}
+ DeleteFootprints();
// cleanup -- end
var detectivesNeeded = 1;
var murderersNeeded = 1;
- Random random = new();
+ Random random = new(Guid.NewGuid().GetHashCode());
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() ));
+ var colorsRemaining = new List<uint>(Colors.OrderBy( _ => random.Next() ));
foreach ( var client in clients )
{
@@ -99,9 +99,9 @@ public class AssignPhase : BasePhase {
natoNamesRemaining = new List<string>(NatoNames);
}
- if (coloursRemaining.Count == 0)
+ if (colorsRemaining.Count == 0)
{
- coloursRemaining = new List<string>(HexColours);
+ colorsRemaining = new List<uint>(Colors);
}
// assign team
@@ -134,15 +134,24 @@ public class AssignPhase : BasePhase pawn.CharacterName = natoName;
// assign nato name
- var hexColour = coloursRemaining[0];
- coloursRemaining.RemoveAt( 0 );
- pawn.HexColor = hexColour;
+ var hexColor = colorsRemaining[0];
+ colorsRemaining.RemoveAt( 0 );
+ pawn.Color = Color.FromRgb(hexColor);
RoleOverlay.Show( To.Single( client ) );
}
base.TimeLeft = 5;
}
+ [ClientRpc]
+ public static void DeleteFootprints()
+ {
+ foreach (var entity in Entity.All.OfType<Footprint>())
+ {
+ entity.Delete();
+ }
+ }
+
public override void Deactivate()
{
foreach (var client in Game.Clients)
diff --git a/code/team/Team.cs b/code/team/Team.cs index 189840b..ef065a4 100644 --- a/code/team/Team.cs +++ b/code/team/Team.cs @@ -54,6 +54,7 @@ public static class TeamCapabilities private static void GiveMurdererWeapon(Player pawn)
{
pawn.Inventory.SetPrimaryWeapon( new Knife() );
+ pawn.Components.Create<FootprintTrackerComponent>();
}
}
public static class TeamOperations
diff --git a/materials/left_shoe_footprint.png b/materials/left_shoe_footprint.png Binary files differnew file mode 100644 index 0000000..ef4e0e0 --- /dev/null +++ b/materials/left_shoe_footprint.png diff --git a/materials/left_shoe_footprint.vmat b/materials/left_shoe_footprint.vmat new file mode 100644 index 0000000..5c5a56e --- /dev/null +++ b/materials/left_shoe_footprint.vmat @@ -0,0 +1,49 @@ +// THIS FILE IS AUTO-GENERATED
+
+Layer0
+{
+ shader "shaders/static_overlay.shader"
+
+ //---- Blend Mode ----
+ F_BLEND_MODE 1 // Translucent
+
+ //---- Ambient Occlusion ----
+ TextureAmbientOcclusion "materials/default/default_ao.tga"
+
+ //---- Color ----
+ g_flModelTintAmount "1.000"
+ g_vColorTint "[1.000000 1.000000 1.000000 0.000000]"
+ TextureColor "materials/left_shoe_footprint.png"
+
+ //---- Fade ----
+ g_flFadeExponent "1.000"
+
+ //---- Fog ----
+ g_bFogEnabled "1"
+
+ //---- Metalness ----
+ g_flMetalness "0.000"
+
+ //---- Normal ----
+ TextureNormal "materials/default/default_normal.tga"
+
+ //---- Roughness ----
+ g_flRoughnessScaleFactor "1.000"
+ TextureRoughness "materials/default/default_rough.tga"
+
+ //---- Texture Coordinates ----
+ g_nScaleTexCoordUByModelScaleAxis "0"
+ g_nScaleTexCoordVByModelScaleAxis "0"
+ g_vTexCoordOffset "[0.000 0.000]"
+ g_vTexCoordScale "[1.000 1.000]"
+ g_vTexCoordScrollSpeed "[0.000 0.000]"
+
+ //---- Translucent ----
+ g_flOpacityScale "1.000"
+ TextureTranslucency "materials/left_shoe_footprint.png"
+
+ DynamicParams
+ {
+ g_vColorTint "color"
+ }
+}
\ No newline at end of file diff --git a/materials/right_shoe_footprint.png b/materials/right_shoe_footprint.png Binary files differnew file mode 100644 index 0000000..9bb5137 --- /dev/null +++ b/materials/right_shoe_footprint.png diff --git a/materials/right_shoe_footprint.vmat b/materials/right_shoe_footprint.vmat new file mode 100644 index 0000000..b58586f --- /dev/null +++ b/materials/right_shoe_footprint.vmat @@ -0,0 +1,49 @@ +// THIS FILE IS AUTO-GENERATED
+
+Layer0
+{
+ shader "shaders/static_overlay.shader"
+
+ //---- Blend Mode ----
+ F_BLEND_MODE 1 // Translucent
+
+ //---- Ambient Occlusion ----
+ TextureAmbientOcclusion "materials/default/default_ao.tga"
+
+ //---- Color ----
+ g_flModelTintAmount "1.000"
+ g_vColorTint "[0.925490 0.925490 0.925490 1.000000]"
+ TextureColor "materials/right_shoe_footprint.png"
+
+ //---- Fade ----
+ g_flFadeExponent "1.000"
+
+ //---- Fog ----
+ g_bFogEnabled "1"
+
+ //---- Metalness ----
+ g_flMetalness "0.000"
+
+ //---- Normal ----
+ TextureNormal "materials/default/default_normal.tga"
+
+ //---- Roughness ----
+ g_flRoughnessScaleFactor "1.000"
+ TextureRoughness "materials/default/default_rough.tga"
+
+ //---- Texture Coordinates ----
+ g_nScaleTexCoordUByModelScaleAxis "0"
+ g_nScaleTexCoordVByModelScaleAxis "0"
+ g_vTexCoordOffset "[0.000 0.000]"
+ g_vTexCoordScale "[1.000 1.000]"
+ g_vTexCoordScrollSpeed "[0.000 0.000]"
+
+ //---- Translucent ----
+ g_flOpacityScale "1.000"
+ TextureTranslucency "materials/right_shoe_footprint.png"
+
+ DynamicParams
+ {
+ g_vColorTint "color"
+ }
+}
\ No newline at end of file |
