Skip to content

Add customisable crosshairs! Woo. Necessary, no. Cool? Maybe lol. #72

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Assets/particles/physgun_beam.vpcf_c
Git LFS file not shown
2 changes: 1 addition & 1 deletion Assets/particles/physgun_end_nohit.vpcf_c
Git LFS file not shown
2 changes: 1 addition & 1 deletion Assets/particles/physgun_hitsmoke.vpcf_c
Git LFS file not shown
2 changes: 1 addition & 1 deletion Assets/particles/physgun_light.vpcf_c
Git LFS file not shown
2 changes: 1 addition & 1 deletion Assets/particles/physgun_start.vpcf_c
Git LFS file not shown
153 changes: 153 additions & 0 deletions Code/Components/Player/Player.Crosshair.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
using System.Security.AccessControl;
using System.Text.RegularExpressions;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace PlayerCrosshair
{
public class HudObject
{
public virtual void Draw( CameraComponent camera, Vector2 centerPos ) { }
}
public class Circle : HudObject
{
Color Color { get; set; } = Color.White;
Vector2 Location { get; set; } = Vector2.Zero;
Vector2 Size { get; set; } = Vector2.Zero;

public Circle( Color color, Vector2 loc, Vector2 size )
{
Color = color;
Location = Location;
Size = size;
}

public override void Draw( CameraComponent camera, Vector2 centerPos)
{
camera.Hud.DrawCircle(centerPos + Location, Size, Color);
}
}
public class Line : HudObject
{
Color Color { get; set; } = Color.White;
Vector2 Start { get; set; } = Vector2.Zero;
Vector2 End { get; set; } = Vector2.Zero;
int Thickness { get; set; } = 0;

public Line( Color color, Vector2 startLoc, Vector2 endLoc, int thickness )
{
Color = color;
Start = startLoc;
End = endLoc;
Thickness = thickness;
}


public override void Draw( CameraComponent camera, Vector2 centerPos )
{
camera.Hud.DrawLine( centerPos + Start, centerPos + End, Thickness, Color );
}
}
public class Rectangle : HudObject
{
Color Color { get; set; } = Color.White;
int Left { get; set; } = 0;
int Top { get; set; } = 0;
int Width { get; set; } = 0;
int Height { get; set; } = 0;
int Thickness { get; set; } = 0;

public Rectangle( Color color, int left, int top, int width, int height, int thickness )
{
Color = color;
Left = left;
Top = top;
Width = width;
Height = height;
Thickness = thickness;
}


public override void Draw( CameraComponent camera, Vector2 centerPos )
{
camera.Hud.DrawRect( new Rect( centerPos.x + Left, centerPos.y + Top, Width, Height ), Color, borderWidth: new Vector4( Thickness ) );
}
}


public class Crosshair
{
private static string Pattern = @"\((.*?)\)";
public static List<HudObject> ConfigToHudObjects( string config )
{
List<HudObject> objects = new();

foreach ( Match match in Regex.Matches( config, Pattern ) )
{
string group = match.Groups[1].Value;
var items = new List<string>( group.Split( ';' ) );

string type = items.First();

List<int> values = new();
for(int i = 1; i < items.Count; i++)
{
if ( int.TryParse( items[i], out var val ) ) values.Add( val );
}

if (type == "circle" && values.Count >= 7 )
{
// (circle;255;255;255;-2;-2;4;4)
objects.Add(
new Circle( new Color( values[0], values[1], values[2] ), new Vector2( values[3], values[4] ), new Vector2( values[5], values[6] ) )
);
}
else if (type == "line" && values.Count >= 8 )
{
// (line;255;255;255;-25;-25;-4;-4;1)
objects.Add(
new Line( new Color( values[0], values[1], values[2] ), new Vector2( values[3], values[4] ), new Vector2( values[5], values[6] ), values[7] )
);
}
else if (type == "rect")
{
if (values.Count >= 9)
{
// (rect;255;255;0;-25;-25;50;50;1;1) Solid square
if ( values[8] == 1 )
{
objects.Add(
new Rectangle( new Color( values[0], values[1], values[2] ), values[3], values[4], values[5], values[6], values[7] )
);
}
else
{
// (rect;255;255;0;-25;-25;50;50;1;1) Hollow square
// Left, Top, Width, Height
// Left: values[3]
// Top: values[4]
// Width: values[5]
// Height: values[6]

// Top left: values[3], values[4]
// Top right: values[3] + values[5], values[4]
// Bottom left: values[3], values[4] + values[6]
// Bottom right: values[3] + values[5], values[4] + values[6]

objects.Add( new Line( new Color( values[0], values[1], values[2] ), new Vector2( values[3], values[4] ), new Vector2( values[3] + values[5], values[4] ), values[7] ) );
objects.Add( new Line( new Color( values[0], values[1], values[2] ), new Vector2( values[3], values[4] ), new Vector2( values[3], values[4] + values[6] ), values[7] ) );
objects.Add( new Line( new Color( values[0], values[1], values[2] ), new Vector2( values[3] + values[5], values[4] + values[6] ), new Vector2( values[3], values[4] + values[6] ), values[7] ) );
objects.Add( new Line( new Color( values[0], values[1], values[2] ), new Vector2( values[3] + values[5], values[4] + values[6] ), new Vector2( values[3] + values[5], values[4] ), values[7] ) );
}
}
else
{

}
}

}

return objects;
}
}
}
26 changes: 24 additions & 2 deletions Code/Components/Player/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public PlayerSettings Settings
public Ray AimRay => new( EyeTransform.Position, EyeTransform.Rotation.Forward );
public bool SuppressScrollWheelInventory { get; set; } = false;

private List<PlayerCrosshair.HudObject> hudObjects = new();

public bool isInParty()
{
return PartyId != 0UL;
Expand All @@ -59,13 +61,33 @@ protected override void OnUpdate()
}

// Crosshair
DrawCrosshair();
}

/// <summary>
/// Draws the player's crosshair based on what they've defined
/// </summary>
private void DrawCrosshair()
{
if ( IsProxy ) return;
if ( hudObjects.Count == 0 ) RegenerateCrosshair();

Vector3 trace = Vector3.Zero;
if ( Controller.ThirdPerson ) trace = Player.DoBasicTrace().HitPosition;

if ( !Controller.ThirdPerson || trace == Vector3.Zero) trace = AimRay.Position + AimRay.Forward * 5000;
if ( !Controller.ThirdPerson || trace == Vector3.Zero ) trace = AimRay.Position + AimRay.Forward * 5000;

Vector2 loc = Scene.Camera.PointToScreenPixels( trace );
Scene.Camera.Hud.DrawCircle( new Vector2( loc.x, loc.y ), new Vector2( 5, 5 ), Color.White );

foreach(var obj in hudObjects)
{
obj.Draw( Scene.Camera, loc );
}
}

public void RegenerateCrosshair()
{
hudObjects = PlayerCrosshair.Crosshair.ConfigToHudObjects( Settings.CustomCrosshair );
}

/// <summary>
Expand Down
16 changes: 16 additions & 0 deletions Code/Components/Player/PlayerSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@ public bool UseHumanModel
}
}

public static string CustomCrosshairDefault = "(circle;255;255;255;-3;-3;6;6)";
private string customCrosshair = CustomCrosshairDefault;
public string CustomCrosshair
{
get => customCrosshair;
set
{
if ( customCrosshair == value ) return;
customCrosshair = value;
SetDirty();

if (player != null) player.RegenerateCrosshair();
}
}

private bool usePhysgunSound = true;
public bool UsePhysgunSound
{
Expand Down Expand Up @@ -60,6 +75,7 @@ public static void Save()
public static PlayerSettings Load()
{
var loaded = FileSystem.Data.ReadJson<PlayerSettings>( "playersettings.json" ) ?? new PlayerSettings();
loaded.player = Player.FindLocalPlayer();
loaded.SetDirty( false );
return loaded;
}
Expand Down
22 changes: 20 additions & 2 deletions Code/UI/Utilities/PlayerSettingsPage.razor
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@

<label class="description">Physgun Sound</label>
<button class="btn" onclick=@(TogglePhysgunSound)>Toggle Physgun Sound (@(Player.Local.Settings.UsePhysgunSound ? "On" : "Off"))</button>

<label class="description">Custom Crosshairs</label>
<TextEntry @ref="CrosshairEntryPanel" Value="@Player.Local.Settings.CustomCrosshair"></TextEntry>
<button class="btn" onclick=@ResetCrosshairs>Reset to Default</button>
<button class="btn" onclick=@UpdateCrosshairs>Save Custom Crosshairs</button>
</root>

@code
{
private TextEntry CrosshairEntryPanel { get; set; }
PlayerDresser dresser { get; set; } = Player.Local.Body.GetComponent<PlayerDresser>();

void TogglePlayerModelType()
Expand All @@ -22,7 +28,19 @@
dresser.ChangePlayerModelType(!dresser.UseHumanModel);
}

void TogglePhysgunSound() {
void TogglePhysgunSound()
{
Player.Local.Settings.UsePhysgunSound = !Player.Local.Settings.UsePhysgunSound;
}
}
void ResetCrosshairs()
{
Player.Local.Settings.CustomCrosshair = PlayerSettings.CustomCrosshairDefault;
CrosshairEntryPanel.Blur();
}

void UpdateCrosshairs()
{
Player.Local.Settings.CustomCrosshair = CrosshairEntryPanel.Text;
CrosshairEntryPanel.Blur();
}
}