mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-09 02:29:50 -10:00
Save a dolphin's fish and moistness
Dolphin.addAdditionalSaveData writes GotFish and Moistness; Horizon kept both in the mob but wrote neither, so a fed dolphin forgot it was fed and a wet one came back from a reload dry and drowned.
This commit is contained in:
1 parent
80dfb5f357
commit
82de324266
2 files changed
+56
No files matched your search
@@ -796,6 +796,11 @@ pub fn mob_to_nbt(
|
||||
put_memories(map, m);
|
||||
crate::mobs::villager::write_nbt(m, map);
|
||||
}
|
||||
// Dolphin.addAdditionalSaveData: the fish it was fed, and how wet it is.
|
||||
"minecraft:dolphin" => {
|
||||
map.insert("GotFish".into(), Tag::Byte(i8::from(m.extra.flag)));
|
||||
map.insert("Moistness".into(), Tag::Int(m.extra.counter));
|
||||
}
|
||||
"minecraft:wandering_trader" => {
|
||||
put_offers(map, m);
|
||||
// WanderingTrader.addAdditionalSaveData: the visit's countdown and
|
||||
@@ -1761,6 +1766,12 @@ pub fn mob_from_nbt(
|
||||
}
|
||||
crate::mobs::zombie_villager::read_nbt(&mut m, tag);
|
||||
}
|
||||
if m.species() == crate::mobs::Species::Dolphin {
|
||||
// Dolphin.readAdditionalSaveData: a save that names neither field is an
|
||||
// unfed dolphin at full moistness.
|
||||
m.extra.flag = flag(tag, "GotFish");
|
||||
m.extra.counter = number(tag.get("Moistness")).unwrap_or(2400) as i32;
|
||||
}
|
||||
if m.species() == crate::mobs::Species::Axolotl {
|
||||
restore_axolotl_memories(&mut m, tag);
|
||||
}
|
||||
@@ -3965,6 +3976,49 @@ mod sheep_nbt_tests {
|
||||
assert_eq!(number(tag.get("VillagerDataFinalized")), Some(1));
|
||||
}
|
||||
|
||||
/// `Dolphin.addAdditionalSaveData`: a fed dolphin stays fed and a wet one
|
||||
/// stays wet across a reload; a save with neither field reads as an unfed
|
||||
/// dolphin at full moistness.
|
||||
#[test]
|
||||
fn a_dolphins_moistness_and_fish_survive_a_save() {
|
||||
let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("../../.local/horizon-client")
|
||||
.join(horizon_core::VANILLA_VERSION);
|
||||
if !root.join("items.json").exists() {
|
||||
return;
|
||||
}
|
||||
let data = crate::mobs::MobTypes::load(&root).unwrap();
|
||||
let types: HashMap<String, Arc<MobType>> = data
|
||||
.types
|
||||
.iter()
|
||||
.map(|(k, v)| (k.clone(), Arc::new(v.clone())))
|
||||
.collect();
|
||||
// A fresh dolphin starts full, as `Dolphin`'s field does.
|
||||
let mut m = Mob::new(
|
||||
1,
|
||||
types["minecraft:dolphin"].clone(),
|
||||
Vec3::new(0.5, 64.0, 0.5),
|
||||
0.0,
|
||||
);
|
||||
assert_eq!(m.extra.counter, 2400);
|
||||
m.extra.flag = true;
|
||||
m.extra.counter = 123;
|
||||
let tag = mob_to_nbt(&m, [1, 2, 3, 4], None, None);
|
||||
assert_eq!(number(tag.get("Moistness")), Some(123));
|
||||
assert_eq!(number(tag.get("GotFish")), Some(1));
|
||||
let back = mob_from_nbt(&tag, &types, 2, None).unwrap();
|
||||
assert!(back.extra.flag, "fed");
|
||||
assert_eq!(back.extra.counter, 123);
|
||||
// A save with neither field: unfed, full.
|
||||
let bare = Tag::compound([
|
||||
("id", string("minecraft:dolphin")),
|
||||
("Pos", doubles(&[0.5, 64.0, 0.5])),
|
||||
]);
|
||||
let back = mob_from_nbt(&bare, &types, 3, None).unwrap();
|
||||
assert!(!back.extra.flag);
|
||||
assert_eq!(back.extra.counter, 2400);
|
||||
}
|
||||
|
||||
/// `WanderingTrader.addAdditionalSaveData`: the visit's countdown and the
|
||||
/// place it is walking to (a `BlockPos` codec, so an int array), which the
|
||||
/// despawn and stroll goals read back after a reload.
|
||||
|
||||
@@ -159,6 +159,8 @@ pub fn register(m: &mut Mob) {
|
||||
m.ai.nav.kind = NavKind::Water { breach: false };
|
||||
}
|
||||
S::Dolphin => {
|
||||
// `Dolphin`'s `moistness` field starts full.
|
||||
m.extra.counter = 2400;
|
||||
let g = &mut m.ai.goals;
|
||||
g.add(0, BreathAir);
|
||||
g.add(0, TryFindWater::default());
|
||||
|
||||
Reference in new issue
Block a user