mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-10 02:21:33 -10:00
fix: preserve name tag fast paths without native mods
Co-Authored-By: GPT-6.1 Sol <[email protected]>
This commit is contained in:
1 parent
c193c2f18b
commit
a8cdcce9d6
1 file changed
+68
-35
@@ -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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user