diff --git a/ClassicalSharp/2D/Screens/Menu/OptionsScreen.cs b/ClassicalSharp/2D/Screens/Menu/OptionsScreen.cs
index 06d7cb234..f7d8833f9 100644
--- a/ClassicalSharp/2D/Screens/Menu/OptionsScreen.cs
+++ b/ClassicalSharp/2D/Screens/Menu/OptionsScreen.cs
@@ -63,7 +63,7 @@ namespace ClassicalSharp {
// Extra stuff
!network.IsSinglePlayer ? null :
- Make( -140, -150, "Singleplayer physics", Anchor.Centre, OnWidgetClick,
+ Make( -140, -200, "Singleplayer physics", Anchor.Centre, OnWidgetClick,
g => ((SinglePlayerServer)network).physics.Enabled ? "yes" : "no",
(g, v) => {
((SinglePlayerServer)network).physics.Enabled = v == "yes";
@@ -72,8 +72,17 @@ namespace ClassicalSharp {
Make( 140, -150, "Pushback block placing", Anchor.Centre, OnWidgetClick,
g => g.LocalPlayer.PushbackBlockPlacing
&& g.LocalPlayer.CanPushbackBlocks ? "yes" : "no",
- (g, v) => { if( g.LocalPlayer.CanPushbackBlocks)
- g.LocalPlayer.PushbackBlockPlacing = v == "yes"; }),
+ (g, v) => {
+ if( g.LocalPlayer.CanPushbackBlocks)
+ g.LocalPlayer.PushbackBlockPlacing = v == "yes";
+ }),
+
+ Make( -140, -150, "Show hover names", Anchor.Centre, OnWidgetClick,
+ g => g.Players.ShowHoveredNames ? "yes" : "no",
+ (g, v) => {
+ g.Players.ShowHoveredNames = v == "yes";
+ Options.Set( OptionsKey.ShowHoveredNames, v == "yes" );
+ }),
Make( 0, 5, "Back to menu", Anchor.BottomOrRight,
(g, w) => g.SetNewScreen( new PauseScreen( g ) ), null, null ),
@@ -91,7 +100,8 @@ namespace ClassicalSharp {
new BooleanValidator(),
network.IsSinglePlayer ? new BooleanValidator() : null,
- new BooleanValidator()
+ new BooleanValidator(),
+ new BooleanValidator(),
};
okayIndex = buttons.Length - 1;
}
diff --git a/ClassicalSharp/Entities/EntityList.cs b/ClassicalSharp/Entities/EntityList.cs
index 16a18b5de..06b76a34f 100644
--- a/ClassicalSharp/Entities/EntityList.cs
+++ b/ClassicalSharp/Entities/EntityList.cs
@@ -9,18 +9,23 @@ namespace ClassicalSharp {
public const int MaxCount = 256;
public Player[] Players = new Player[MaxCount];
public Game game;
+ uint[] doIntersect;
+
+ /// Whether the names of entities that the player is looking at
+ /// should be rendered through everything else without depth testing.
+ public bool ShowHoveredNames;
public EntityList( Game game ) {
this.game = game;
game.Events.ChatFontChanged += ChatFontChanged;
+ doIntersect = new uint[MaxCount / 32];
}
/// Performs a tick call for all player entities contained in this list.
public void Tick( double delta ) {
for( int i = 0; i < Players.Length; i++ ) {
- if( Players[i] != null ) {
- Players[i].Tick( delta );
- }
+ if( Players[i] == null ) continue;
+ Players[i].Tick( delta );
}
}
@@ -29,23 +34,57 @@ namespace ClassicalSharp {
api.Texturing = true;
api.AlphaTest = true;
for( int i = 0; i < Players.Length; i++ ) {
- if( Players[i] != null )
- Players[i].RenderModel( delta, t );
+ if( Players[i] == null ) continue;
+ Players[i].RenderModel( delta, t );
}
api.Texturing = false;
api.AlphaTest = false;
}
- /// Renders the names of all player entities contained in this list.
+ /// Renders the names of all player entities contained in this list.
+ /// If ShowHoveredNames is false, this method only renders names of entities that are
+ /// not currently being looked at by the user.
public void RenderNames( IGraphicsApi api, double delta, float t ) {
api.Texturing = true;
api.AlphaTest = true;
+ LocalPlayer localP = game.LocalPlayer;
+ Vector3 eyePos = localP.EyePosition;
+ Vector3 dir = Utils.GetDirVector( localP.YawRadians, localP.PitchRadians );
+ for( int i = 0; i < doIntersect.Length; i++ )
+ doIntersect[i] = 0;
+
for( int i = 0; i < Players.Length; i++ ) {
- if( Players[i] != null )
+ if( Players[i] == null ) continue;
+ float t0, t1;
+ Player p = Players[i];
+
+ if( !ShowHoveredNames ||
+ !Intersection.RayIntersectsRotatedBox( eyePos, dir, p, out t0, out t1 ) ) {
+ Players[i].RenderName();
+ } else {
+ doIntersect[i >> 5] |= (uint)(1 << (i & 0x1F));
+ }
+ }
+ api.Texturing = false;
+ api.AlphaTest = false;
+ }
+
+ public void RenderHoveredNames( IGraphicsApi api, double delta, float t ) {
+ if( !ShowHoveredNames ) return;
+ api.Texturing = true;
+ api.AlphaTest = true;
+ api.DepthTest = false;
+
+ for( int i = 0; i < Players.Length; i++ ) {
+ if( Players[i] == null ) continue;
+
+ bool draw = (doIntersect[i >> 5] & (uint)(1 << (i & 0x1F))) != 0;
+ if( draw )
Players[i].RenderName();
}
api.Texturing = false;
api.AlphaTest = false;
+ api.DepthTest = true;
}
void ChatFontChanged( object sender, EventArgs e ) {
@@ -74,6 +113,7 @@ namespace ClassicalSharp {
for( int i = 0; i < Players.Length - 1; i++ ) { // -1 because we don't want to pick against local player
Player p = Players[i];
if( p == null ) continue;
+
float t0, t1;
if( Intersection.RayIntersectsRotatedBox( eyePos, dir, p, out t0, out t1 ) ) {
if( t0 < closestDist && closestDist < localP.ReachDistance ) {
@@ -88,7 +128,7 @@ namespace ClassicalSharp {
/// Gets or sets the player entity for the specified id.
public Player this[int id] {
get { return Players[id]; }
- set {
+ set {
Players[id] = value;
if( value != null )
value.ID = (byte)id;
diff --git a/ClassicalSharp/Game/Game.cs b/ClassicalSharp/Game/Game.cs
index 2ce669871..824aaff5e 100644
--- a/ClassicalSharp/Game/Game.cs
+++ b/ClassicalSharp/Game/Game.cs
@@ -113,6 +113,7 @@ namespace ClassicalSharp {
Options.Load();
AcceptedUrls.Load();
+ Players.ShowHoveredNames = Options.GetBool( OptionsKey.ShowHoveredNames, true );
ViewDistance = Options.GetInt( OptionsKey.ViewDist, 16, 4096, 512 );
InputHandler = new InputHandler( this );
Chat = new ChatLog( this );
@@ -244,6 +245,7 @@ namespace ClassicalSharp {
MapRenderer.Render( e.Time );
SelectionManager.Render( e.Time );
WeatherRenderer.Render( e.Time );
+ Players.RenderHoveredNames( Graphics, e.Time, t );
bool left = IsMousePressed( MouseButton.Left );
bool middle = IsMousePressed( MouseButton.Middle );
diff --git a/ClassicalSharp/Utils/Options.cs b/ClassicalSharp/Utils/Options.cs
index 4f741b815..2d99bd199 100644
--- a/ClassicalSharp/Utils/Options.cs
+++ b/ClassicalSharp/Utils/Options.cs
@@ -15,6 +15,7 @@ namespace ClassicalSharp {
public const string ArialChatFont = "arialchatfont";
public const string DefaultTexturePack = "defaulttexpack";
public const string SingleplayerPhysics = "singleplayerphysics";
+ public const string ShowHoveredNames = "showhoverednames";
public const string MouseLeft = "mouseleft";
public const string MouseMiddle = "mousemiddle";