fix: preserve name tag fast paths without native mods

Co-Authored-By: GPT-6.1 Sol <[email protected]>
This commit is contained in:
[email protected]andGPT-6.1 Sol committed 2026-11-02 16:53:03 +01:00
1 parent c193c2f18b
commit a8cdcce9d6
1 file changed
+68 -35
+68 -35
View File
@@ -8,8 +8,8 @@
//! and the player's own in third person with the `ownNameTag` extra.
use super::{Game, view_vector};
use horizon_client::{
block_entity_render::vertex_light, hud::HudBatch, mesher::Vertex, mobs::Mob, save::uuid_text,
scoreboard as sb, text::Text,
block_entity_render::vertex_light, hud::HudBatch, mesher::Vertex, mobs::Mob, mod_api,
save::uuid_text, scoreboard as sb, text::Text,
};
/// The world size of one text pixel in a name tag: `Matrix4f.scale(0.025F, -0.025F, 0.025F)`.
@@ -103,20 +103,28 @@ impl Game<'_> {
}
/// Each name tag this frame.
fn name_tags(&self, camera: glam::DVec3, alpha: f64) -> Vec<NameTag> {
let hooks = !mod_api::mods().is_empty();
let target = self.mob_hit().map(|(i, _)| self.mobs[i].id);
let viewer = self.player_team();
let mut tags = Vec::new();
let players = self.other_players();
let player_ids: std::collections::HashSet<u32> =
players.iter().map(|(player, _)| player.id).collect();
let player_ids = hooks.then(|| {
players
.iter()
.map(|(player, _)| player.id)
.collect::<std::collections::HashSet<u32>>()
});
let named = self.mobs.iter().filter_map(|m| {
if player_ids.contains(&m.id) {
if player_ids.as_ref().is_some_and(|ids| ids.contains(&m.id)) {
return None;
}
// A mannequin with no name still shows its description.
let name = match &m.custom_name {
Some(name) => name.clone(),
None => String::new(),
None if hooks || m.species() == horizon_client::mobs::Species::Mannequin => {
String::new()
}
None => return None,
};
// The tag's 64 block distance is measured to the entity: copy the
// name only for a mob the frame can show it on.
@@ -186,17 +194,19 @@ impl Game<'_> {
&& (player || m.custom_name.is_some());
let mut visible = name_shown;
let mut text = None;
self.native_render_name_tag(
m.id,
if player {
"minecraft:player"
} else {
&m.kind.id
},
name_shown,
&mut visible,
&mut text,
);
if hooks {
self.native_render_name_tag(
m.id,
if player {
"minecraft:player"
} else {
&m.kind.id
},
name_shown,
&mut visible,
&mut text,
);
}
if !visible {
if let Some(text) = description {
let l = self.world.light(
@@ -259,9 +269,18 @@ impl Game<'_> {
discrete,
});
}
drop(player_ids);
// Armor stands name themselves: an invisible one with a visible name
// is a hologram (its model is skipped, its name tag is not).
for a in &self.armor_stands {
if !hooks {
let Some(_) = &a.custom_name else {
continue;
};
if !a.name_visible {
continue;
}
}
let height = match (a.marker, a.small) {
(true, _) => 0.0,
(false, true) => 0.9875,
@@ -286,13 +305,15 @@ impl Game<'_> {
a.custom_name.is_some() && a.name_visible && sb::name_shown(team, viewer, view);
let mut visible = name_shown;
let mut text = None;
self.native_render_name_tag(
a.id,
"minecraft:armor_stand",
name_shown,
&mut visible,
&mut text,
);
if hooks {
self.native_render_name_tag(
a.id,
"minecraft:armor_stand",
name_shown,
&mut visible,
&mut text,
);
}
if !visible {
continue;
}
@@ -331,28 +352,40 @@ impl Game<'_> {
}
// ItemFrameRenderer.shouldShowName/getNameTag: only the targeted
// frame's custom-named item, with the HUD visible (also glow frames).
let targeted_frame = self
.frame_hit()
let targeted_frame = (hooks || !self.ui.hide_gui)
.then(|| self.frame_hit())
.flatten()
.filter(|(_, distance)| {
self.before_block(*distance) && self.mob_hit().is_none_or(|(_, d)| d > *distance)
})
.map(|(index, _)| index);
for (index, frame) in self.item_frames.iter().enumerate() {
let frames = if hooks {
0..self.item_frames.len()
} else {
targeted_frame.map_or(0..0, |index| index..index + 1)
};
for index in frames {
let frame = &self.item_frames[index];
let name = frame.item.as_ref().and_then(|item| item.custom_name());
if !hooks && name.is_none() {
continue;
}
let (lo, hi) = frame.bounds();
let center = glam::DVec3::from_array(std::array::from_fn(|a| (lo[a] + hi[a]) / 2.0));
if center.distance_squared(camera) < 64.0 * 64.0 {
let name = frame.item.as_ref().and_then(|item| item.custom_name());
let name_shown =
!self.ui.hide_gui && targeted_frame == Some(index) && name.is_some();
let mut visible = name_shown;
let mut text = None;
self.native_render_name_tag(
frame.id,
frame.kind(),
name_shown,
&mut visible,
&mut text,
);
if hooks {
self.native_render_name_tag(
frame.id,
frame.kind(),
name_shown,
&mut visible,
&mut text,
);
}
if !visible {
continue;
}