6 Commits

Author SHA1 Message Date
mccarreon
5647e33dd9 merge with master 2023-08-09 17:56:35 -07:00
mccarreon
bbf0a765d5 added nametags 2023-08-09 17:50:57 -07:00
mccarreon
bce1f8e1f7 got racers animated and racing 2023-08-06 21:12:28 -07:00
mccarreon
3e9d64cb00 making racers 2023-08-06 18:41:00 -07:00
mccarreon
b9dbe07e1f fixed camera with lookat functions 2023-08-04 21:16:49 -07:00
mccarreon
4a338d9502 initial file creation 2023-08-03 19:34:23 -07:00
9 changed files with 303 additions and 5 deletions

View File

@@ -3,10 +3,10 @@ using Sandbox;
namespace LuckerGame.Components.Lucker.Cameras; namespace LuckerGame.Components.Lucker.Cameras;
public abstract class AbstractCamera : EntityComponent<Entities.Lucker>, ISingletonComponent public abstract partial class AbstractCamera : EntityComponent<Entities.Lucker>, ISingletonComponent
{ {
public virtual bool ShouldShowCursor => false; public virtual bool ShouldShowCursor => false;
protected Vector3 CameraPosition { get; set; } public Vector3 CameraPosition { get; set; }
protected Rotation CameraRotation { get; set; } protected Rotation CameraRotation { get; set; }
protected float FieldOfView { get; set; } protected float FieldOfView { get; set; }
protected IEntity FirstPersonViewer { get; set; } protected IEntity FirstPersonViewer { get; set; }
@@ -16,11 +16,11 @@ public abstract class AbstractCamera : EntityComponent<Entities.Lucker>, ISingle
/// Handles any input-independent camera updates (ie following a pawn) /// Handles any input-independent camera updates (ie following a pawn)
/// </summary> /// </summary>
protected abstract void UpdateCameraParameters(); protected abstract void UpdateCameraParameters();
/// <summary> /// <summary>
/// Handles any input dependent camera updates (ie moving around a top down cam) /// Handles any input dependent camera updates (ie moving around a top down cam)
/// </summary> /// </summary>
public abstract void BuildInput(); public virtual void BuildInput() { }
/// <summary> /// <summary>
/// Applies Camera parameters to the static Camera /// Applies Camera parameters to the static Camera

View File

@@ -0,0 +1,41 @@
using Sandbox;
namespace LuckerGame.Components.Lucker.Cameras;
public partial class FixedCamera : AbstractCamera, ISingletonComponent
{
[Net] public float FieldOfViewValue { get; set; } = 70f;
public override bool ShouldShowCursor => true;
protected override void UpdateCameraParameters()
{
FieldOfView = FieldOfViewValue;
FirstPersonViewer = null;
SoundSource = new Transform { Position = CameraPosition };
}
/// <summary>
/// ClientRpc doesn't allow for nullable versions of non-nullable types
/// so here we are
/// </summary>
public void UpdateCameraPositionRotation( Vector3? position = null, Rotation? rotation = null )
{
CameraPosition = (Vector3)(position.Equals( null ) ? CameraPosition : position);
CameraRotation = (Rotation)(rotation.Equals( null ) ? CameraRotation : rotation);
}
[ClientRpc]
public void LookAt( Vector3 position )
{
UpdateCameraPositionRotation( position );
}
[ClientRpc]
public void LookAt( Rotation rotation )
{
UpdateCameraPositionRotation( rotation: rotation );
}
[ClientRpc]
public void LookAt( Vector3 position, Rotation rotation )
{
UpdateCameraPositionRotation( position, rotation );
}
}

View File

@@ -0,0 +1,23 @@
using LuckerGame.UI;
using Sandbox;
public class HoveringTextCreator : Entity
{
private string Text { get; set; }
private Entity TargetEntity { get; set; }
public HoveringTextCreator()
{
}
public HoveringTextCreator(string text, Entity targetEntity)
{
Text = text;
TargetEntity = targetEntity;
}
public override void ClientSpawn()
{
base.ClientSpawn();
var hoveringText = new HoveringText(Text, TargetEntity);
}
}

View File

@@ -0,0 +1,64 @@
using LuckerGame.Entities;
using LuckerGame.UI;
using Sandbox;
using System;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Reflection.Metadata.Ecma335;
public class Racer : Pawn
{
public float Speed;
private float SpeedModifier = 1f;
private Random Random { get; set; }
private HoveringText NameTag { get; set; }
public Racer()
{
}
public Racer( Random random )
{
Random = random;
}
public override void ClientSpawn()
{
base.ClientSpawn();
NameTag = new( Name, this );
}
public void ContinueRacing()
{
SetAnimParameter( "move_x", Speed * 500f * SpeedModifier );
ModifySpeed();
Position = Position.WithY( Position.y - (Speed * SpeedModifier) );
}
private void ModifySpeed()
{
var roll = Random.NextDouble();
switch ( roll )
{
case >= .90 and < .95:
SpeedModifier = 2f;
break;
case >= .95:
SpeedModifier = 0.5f;
break;
}
}
public void StopRacing()
{
SetAnimParameter( "move_x", 0 );
}
public void GenerateSpeed( double minSpeed, double maxSpeed )
{
Speed = (float)(RandomExtensions.NextDouble( Random, minSpeed, maxSpeed ));
}
}

View File

@@ -0,0 +1,123 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Reflection.Metadata.Ecma335;
using LuckerGame.Components.Lucker.Cameras;
using LuckerGame.Components.Pawn;
using LuckerGame.Entities;
using Sandbox;
using Sandbox.UI;
namespace LuckerGame.Minigames.TerryRaces;
[Library( "mg_terry_races" )]
public class TerryRaces : Minigame
{
public override string Name => "Terry Races";
private Random random = new Random();
private HoveringTextCreator NameTag { get; set; }
private Racer WinningRacer = null;
private FixedCamera Camera;
private List<Lucker> Players { get; set; }
private List<Racer> Racers { get; set; } = new List<Racer>();
private List<string> RacerNames = new List<string>
{
"Terrance",
"Terrie",
"TearBear",
"Theresa"
};
private float StartingY = 290f;
private float FinishLineY = -300f;
private float StartingX = 90f;
private float RacerXOffset = 60f;
private float MinimumSpeed = .90f;
private float MaximumSpeed = 1.1f;
public override void Initialize( List<Lucker> players )
{
Players = players;
// Setup cameras for players
Players.ForEach( player =>
{
Camera = player.Components.Create<FixedCamera>();
Camera.LookAt( new Vector3(0f, 0f, 400f), Rotation.FromPitch( -270 ) );
Camera.FieldOfViewValue = 100f;
} );
SpawnRacers();
}
public override void Tick()
{
Racers.ForEach( racer =>
{
if (WinningRacer == null)
{
GetWinningRacer();
racer.ContinueRacing();
}
else
{
racer.StopRacing();
}
} );
}
public override void Cleanup()
{
}
private void SpawnRacers()
{
for ( int i = 0; i < RacerNames.Count; i++ )
{
var clothing = new ClothingContainer();
var racer = new Racer(random);
var x = StartingX - RacerXOffset * i;
clothing.Toggle( GetRandomBottomClothing() );
clothing.Toggle( GetRandomHatClothing() );
clothing.DressEntity( racer );
racer.Name = RacerNames[i];
racer.Position = new Vector3( x, StartingY, 0 );
racer.Rotation = Rotation.FromYaw( -90 );
racer.GenerateSpeed(MinimumSpeed, MaximumSpeed );
Racers.Add( racer );
}
}
private Clothing GetRandomBottomClothing()
{
return ResourceLibrary
.GetAll<Clothing>()
.Where( c => c.Category == Clothing.ClothingCategory.Bottoms )
.OrderBy( _ => Guid.NewGuid() )
.FirstOrDefault();
}
private Clothing GetRandomHatClothing()
{
return ResourceLibrary
.GetAll<Clothing>()
.Where( c => c.Category == Clothing.ClothingCategory.Hat )
.OrderBy( _ => Guid.NewGuid() )
.FirstOrDefault();
}
private void GetWinningRacer()
{
foreach ( Racer racer in Racers )
{
if ( racer.Position.y <= FinishLineY )
{
WinningRacer = racer;
Log.Info( $"Winning racer: {racer.Name}" );
}
}
}
}

11
code/RandomExtensions.cs Normal file
View File

@@ -0,0 +1,11 @@
using System;
public static class RandomExtensions
{
public static double NextDouble(
this Random random,
double minValue,
double maxValue )
{
return random.NextDouble() * (maxValue - minValue) + minValue;
}
}

View File

@@ -0,0 +1,30 @@
@using Sandbox;
@using Sandbox.UI;
@namespace LuckerGame.UI
@attribute [StyleSheet]
@inherits WorldPanel
<root class="card">
<label class="text">@Text</label>
</root>
@code {
private Entity TargetEntity;
private string Text;
public HoveringText(string text, Entity targetEntity)
{
Text = text;
TargetEntity = targetEntity;
}
[GameEvent.Client.Frame]
private void OnFrame()
{
if (!TargetEntity.IsValid()) return;
Log.Info($"{Text} to {TargetEntity.Position}");
Position = TargetEntity.Position + Vector3.Up * 65f;
Rotation = Rotation.LookAt(-Screen.GetDirection(new Vector2(Screen.Width * 0.5f, Screen.Height * 0.5f)));
}
}

View File

@@ -0,0 +1,7 @@
hoveringtext {
white-space: nowrap;
.text {
font-size: 150px;
color: white;
}
}

View File

@@ -12,7 +12,6 @@
<VoiceList/> <VoiceList/>
<VotingLobby/> <VotingLobby/>
<Scoreboard/> <Scoreboard/>
<CameraCursor/>
</root> </root>
@code @code