mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-08 08:07:53 -10:00
Keep item_name as its component: translate it when drawn
The decoded plain string replaced the component on save and on the way to LAN guests, so a translatable name (explorer maps' filled_map.*, the ominous banner in tests without a language) came back as its key, and spill's ominous banner test failed. The component now stays in the patch as loaded and is resolved in the current language when a name is drawn. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
ad7203fc8a
commit
d983ef89b4
6 files changed
+25
-20
No files matched your search
@@ -1657,7 +1657,7 @@ impl Game<'_> {
|
||||
let name = if let Some(n) = stack.custom_name() {
|
||||
n.to_owned()
|
||||
} else if let Some(n) = stack.item_name() {
|
||||
n.to_owned()
|
||||
n
|
||||
} else if stack.data().is_some_and(|d| d.ominous_banner) {
|
||||
self.translate("block.minecraft.ominous_banner", "Ominous Banner")
|
||||
} else if stack.data().and_then(|d| d.potion.as_ref()).is_some()
|
||||
@@ -1684,8 +1684,9 @@ impl Game<'_> {
|
||||
// ItemContainerContents.addToTooltip.
|
||||
let hover_name = |s: &ItemStack| {
|
||||
s.custom_name()
|
||||
.map(str::to_owned)
|
||||
.or_else(|| s.item_name())
|
||||
.map_or_else(|| self.pack.names.display_item(&s.item), str::to_owned)
|
||||
.unwrap_or_else(|| self.pack.names.display_item(&s.item))
|
||||
};
|
||||
if display.shows("minecraft:container") {
|
||||
for text in
|
||||
|
||||
@@ -18,8 +18,6 @@ pub struct StackData {
|
||||
pub repair_cost: u32,
|
||||
/// `minecraft:custom_name` as plain text.
|
||||
pub custom_name: Option<String>,
|
||||
/// `minecraft:item_name` as plain text.
|
||||
pub item_name: Option<String>,
|
||||
/// `minecraft:potion_contents.potion`.
|
||||
pub potion: Option<Arc<str>>,
|
||||
/// `minecraft:trim`: (material, pattern).
|
||||
@@ -75,7 +73,6 @@ const MODELLED: &[&str] = &[
|
||||
"minecraft:enchantments",
|
||||
"minecraft:firework_explosion",
|
||||
"minecraft:fireworks",
|
||||
"minecraft:item_name",
|
||||
"minecraft:map_id",
|
||||
"minecraft:map_post_processing",
|
||||
"minecraft:ominous_bottle_amplifier",
|
||||
@@ -207,8 +204,13 @@ impl ItemStack {
|
||||
pub fn custom_name(&self) -> Option<&str> {
|
||||
self.data().and_then(|d| d.custom_name.as_deref())
|
||||
}
|
||||
pub fn item_name(&self) -> Option<&str> {
|
||||
self.data().and_then(|d| d.item_name.as_deref())
|
||||
/// `minecraft:item_name` in the current language (`getItemName`'s
|
||||
/// component). It stays in the patch as loaded, so a translatable name
|
||||
/// saves and reaches clients unchanged; the ominous banner's is modelled
|
||||
/// by `ominous_banner` instead.
|
||||
pub fn item_name(&self) -> Option<String> {
|
||||
let name = self.data()?.other("minecraft:item_name")?;
|
||||
Some(crate::entity_nbt::name_text(name).plain())
|
||||
}
|
||||
pub fn potion(&self) -> Option<&str> {
|
||||
self.data().and_then(|d| d.potion.as_deref())
|
||||
@@ -479,11 +481,6 @@ pub fn components_tag(damage: u32, data: Option<&StackData>) -> Option<Tag> {
|
||||
if let Some(name) = &d.custom_name {
|
||||
entries.push(("minecraft:custom_name", Tag::String(name.as_str().into())));
|
||||
}
|
||||
if let Some(name) = &d.item_name
|
||||
&& !d.ominous_banner
|
||||
{
|
||||
entries.push(("minecraft:item_name", Tag::String(name.as_str().into())));
|
||||
}
|
||||
if let Some(potion) = &d.potion {
|
||||
entries.push((
|
||||
"minecraft:potion_contents",
|
||||
@@ -686,7 +683,6 @@ pub fn decode_components(components: Option<&Tag>) -> (u32, Option<Box<StackData
|
||||
.unwrap_or(0)
|
||||
.max(0) as u32,
|
||||
custom_name: c.get("minecraft:custom_name").and_then(read_text),
|
||||
item_name: c.get("minecraft:item_name").and_then(read_text),
|
||||
potion,
|
||||
map_id: c.get("minecraft:map_id").and_then(int).map(|v| v as i32),
|
||||
banner_patterns: crate::banner::layers_from_nbt(c.get("minecraft:banner_patterns")),
|
||||
|
||||
@@ -306,7 +306,10 @@ mod tests {
|
||||
.push((Arc::from("minecraft:sharpness"), 2));
|
||||
d.repair_cost = 9;
|
||||
d.custom_name = Some("Keeper".to_owned());
|
||||
d.item_name = Some("Fine Diamond Chestplate".to_owned());
|
||||
// A translatable item name reaches the client as the same component.
|
||||
let item_name = Tag::compound([("translate", Tag::String("filled_map.monument".into()))]);
|
||||
d.other
|
||||
.push(("minecraft:item_name".into(), item_name.clone()));
|
||||
d.trim = Some((Arc::from("minecraft:gold"), Arc::from("minecraft:sentry")));
|
||||
let id = |registry: &str, name: &str| {
|
||||
builtin
|
||||
@@ -336,7 +339,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(d.repair_cost, 9);
|
||||
assert_eq!(d.custom_name.as_deref(), Some("Keeper"));
|
||||
assert_eq!(d.item_name.as_deref(), Some("Fine Diamond Chestplate"));
|
||||
assert_eq!(d.other("minecraft:item_name"), Some(&item_name));
|
||||
assert_eq!(
|
||||
d.trim,
|
||||
Some((Arc::from("minecraft:gold"), Arc::from("minecraft:sentry")))
|
||||
|
||||
@@ -190,7 +190,7 @@ pub fn name_line(stack: &ItemStack, translate: &dyn Fn(&str) -> Option<String>)
|
||||
return name.to_owned();
|
||||
}
|
||||
if let Some(name) = stack.item_name() {
|
||||
return name.to_owned();
|
||||
return name;
|
||||
}
|
||||
if stack.data().is_some_and(|d| d.ominous_banner) {
|
||||
return translate("block.minecraft.ominous_banner")
|
||||
@@ -616,7 +616,10 @@ mod tests {
|
||||
banner.data_mut().custom_name = Some("Captain's Standard".into());
|
||||
assert_eq!(name_line(&banner, &translate), "Captain's Standard");
|
||||
let mut custom_item = ItemStack::new("minecraft:diamond_sword", 1);
|
||||
custom_item.data_mut().item_name = Some("Excalibur".into());
|
||||
custom_item.data_mut().other.push((
|
||||
"minecraft:item_name".into(),
|
||||
Tag::String("Excalibur".into()),
|
||||
));
|
||||
assert_eq!(name_line(&custom_item, &translate), "Excalibur");
|
||||
custom_item.data_mut().custom_name = Some("Custom Blade".into());
|
||||
assert_eq!(name_line(&custom_item, &translate), "Custom Blade");
|
||||
|
||||
@@ -633,10 +633,11 @@ fn network_stack(
|
||||
horizon_protocol::item::Component::Text(horizon_protocol::text::literal(name)),
|
||||
));
|
||||
}
|
||||
if let Some(name) = s.item_name() {
|
||||
// The component as loaded, so a translatable name stays one.
|
||||
if let Some(name) = s.data().and_then(|d| d.other("minecraft:item_name")) {
|
||||
stack.added.push((
|
||||
horizon_protocol::item::component::ITEM_NAME,
|
||||
horizon_protocol::item::Component::Text(horizon_protocol::text::literal(name)),
|
||||
horizon_protocol::item::Component::Text(name.clone()),
|
||||
));
|
||||
}
|
||||
Some(stack)
|
||||
|
||||
@@ -174,8 +174,9 @@ pub fn increased_repair_cost(cost: u32) -> u32 {
|
||||
pub fn hover_name(names: &dyn Fn(&str) -> String, stack: &ItemStack) -> String {
|
||||
stack
|
||||
.custom_name()
|
||||
.map(str::to_owned)
|
||||
.or_else(|| stack.item_name())
|
||||
.map_or_else(|| names(&stack.item), str::to_owned)
|
||||
.unwrap_or_else(|| names(&stack.item))
|
||||
}
|
||||
/// `AnvilMenu.createResult`. `name` is the rename box text (None = untouched).
|
||||
pub fn anvil_result(
|
||||
|
||||
Reference in new issue
Block a user