1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//! V1460 (18w01a+1) — schematic-relevant subset of
//! `DataConverterJava/.../versions/V1460.java`.
//!
//! `minecraft:painting` entities store a `Motive` string. It is lowercased
//! (Locale.ROOT), remapped via MOTIVE_REMAP (donkeykong->donkey_kong,
//! burningskull->burning_skull, skullandroses->skull_and_roses), then run
//! through `NamespaceUtil.correctNamespace`, and written back (V1460.java:25-35).
//! The Java comment notes the many redundant type redefinitions in this version
//! are no-ops (no data-structure change), so nothing else is ported.
use super::super::helpers::correct_namespace;
use super::super::loss::{report_loss, LossKind, Severity};
use super::super::registry::RegistryBuilder;
use super::super::types::MapExt;
const VERSION: i32 = 1460;
/// `MOTIVE_REMAP.getOrDefault(motive, motive)` (V1460.java:14-20).
fn motive_remap(motive: &str) -> &str {
match motive {
"donkeykong" => "donkey_kong",
"burningskull" => "burning_skull",
"skullandroses" => "skull_and_roses",
other => other,
}
}
/// Inverse of `MOTIVE_REMAP` — restore the pre-1460 un-namespaced motive name for
/// the three remapped paintings (V1460.java:17-19). All other names pass through.
fn motive_remap_inverse(motive: &str) -> &str {
match motive {
"donkey_kong" => "donkeykong",
"burning_skull" => "burningskull",
"skull_and_roses" => "skullandroses",
other => other,
}
}
pub fn register(reg: &mut RegistryBuilder) {
reg.entity.add_converter_for_id(
"minecraft:painting",
VERSION,
0,
Box::new(|data, _from, _to| {
if let Some(motive) = data.get_string("Motive") {
// toLowerCase(Locale.ROOT) -> remap -> correctNamespace.
let lowered = motive.to_lowercase();
let remapped = motive_remap(&lowered);
let corrected = correct_namespace(remapped);
data.set_string("Motive", &corrected);
}
}),
);
// Reverse: forward = toLowerCase -> MOTIVE_REMAP -> correctNamespace. We undo
// the two reversible steps — strip the `minecraft:` namespace `correctNamespace`
// added, and invert the three MOTIVE_REMAP renames — yielding the pre-1460
// lowercased un-namespaced motive (e.g. `minecraft:donkey_kong` -> `donkeykong`,
// `minecraft:kebab` -> `kebab`). The `toLowerCase` step is NOT invertible: the
// legacy motives were CamelCase (`Kebab`, `SkullAndRoses`, ...) and the original
// casing is gone from the modern data, so this is a best-effort approximation
// (the lowercased name is still a valid/recognized id in the old format).
reg.entity.add_reverse_converter_for_id(
"minecraft:painting",
VERSION,
0,
Box::new(|data, _from, _to| {
if let Some(motive) = data.get_string("Motive") {
// Strip a leading `minecraft:` namespace (added by correctNamespace);
// a non-minecraft namespace is preserved as-is.
let stripped = motive.strip_prefix("minecraft:").unwrap_or(motive);
let unmapped = motive_remap_inverse(stripped).to_string();
let changed = unmapped != motive;
if changed {
data.set_string("Motive", unmapped);
}
report_loss(
VERSION,
LossKind::RenameAmbiguous,
Severity::Approximated,
"painting Motive was lowercased by V1460; original CamelCase casing cannot be recovered",
);
}
}),
);
}