derive default layers, armor wearers, arms/chest pose flags and mob variant textures from the vanilla dump, drop the hardcoded lists
This commit is contained in:
1 parent
022b080fce
commit
a743dc32c7
14 files changed
+720
-162
No files matched your search
@@ -117,6 +117,17 @@ public class PPTest extends JavaPlugin {
|
||||
scenes.put("be_items", new Scene("be_items", this::beItems, 4.5, 2.6, 11, 4.5, 0.8, 3));
|
||||
scenes.put("be_items_back", new Scene("be_items_back", this::beItems, 4.5, 2.6, -5, 4.5, 0.8, 3));
|
||||
scenes.put("proj_stuck_sw", new Scene("proj_stuck_sw", this::projStuck, -3, 6, 10, 8, 1.5, 2));
|
||||
// Data-driven variants / pose flags / armor wearers (vanilla dump: asset_id, setupAnim flags, armor layers).
|
||||
scenes.put("rf_cats", new Scene("rf_cats", this::rfCats, 6.5, 2.6, -4.5, 6.5, 0.2, 1.2));
|
||||
scenes.put("rf_wolves", new Scene("rf_wolves", this::rfWolves, 5.5, 3.2, -5.5, 5.5, 0.2, 1.8));
|
||||
scenes.put("rf_farm", new Scene("rf_farm", this::rfFarm, 6, 3.4, -6, 6, 0.3, 1.8));
|
||||
scenes.put("rf_stands", new Scene("rf_stands", this::rfStands, 5, 2.4, -4.5, 5, 0.9, 0));
|
||||
scenes.put("rf_stands_back", new Scene("rf_stands_back", this::rfStands, 5, 2.4, 4.5, 5, 0.9, 0));
|
||||
scenes.put("rf_chests", new Scene("rf_chests", this::rfChests, 7, 4, -7, 7, 0.8, 1));
|
||||
scenes.put("rf_chests_side", new Scene("rf_chests_side", this::rfChests, 7, 2.5, 7, 7, 0.8, 1));
|
||||
// Needs a datapack cat variant "pptest:ocelotcat" (asset_id entity/cat/ocelot) in the world's datapacks.
|
||||
scenes.put("rf_dpcat", new Scene("rf_dpcat", this::rfDatapackCat, 1.2, 1.4, -2.2, 1.2, 0.2, 0.5));
|
||||
scenes.put("rf_armor", new Scene("rf_armor", this::rfArmor, 7, 3.2, -6.5, 7, 1.0, 1.5));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -154,7 +165,7 @@ public class PPTest extends JavaPlugin {
|
||||
Location eye = o.clone().add(sc.camX, sc.camY, sc.camZ);
|
||||
Vector look = o.clone().add(sc.lookX, sc.lookY, sc.lookZ).toVector().subtract(eye.toVector());
|
||||
eye.setDirection(look);
|
||||
RenderJob job = r.prepare(eye, sc.name.startsWith("proj_") ? new Resolution(960, 640) : new Resolution(480, 320), null);
|
||||
RenderJob job = r.prepare(eye, sc.name.startsWith("proj_") || sc.name.startsWith("rf_") ? new Resolution(960, 640) : new Resolution(480, 320), null);
|
||||
if (sc.name.equals("dbg")) {
|
||||
try {
|
||||
java.lang.reflect.Field f = DefaultScreenRenderer.class.getDeclaredField("objectBaker");
|
||||
@@ -690,6 +701,209 @@ public class PPTest extends JavaPlugin {
|
||||
for (Entity e : w.getNearbyEntities(o, 12, 8, 8)) if (e instanceof Wither wi) wi.setBodyYaw(180);
|
||||
}
|
||||
|
||||
// --- data-driven variants / pose flags / armor wearers ------------------------------------------
|
||||
|
||||
private static <T extends Keyed> List<T> registry(io.papermc.paper.registry.RegistryKey<T> key) {
|
||||
List<T> out = new ArrayList<>();
|
||||
io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(key).forEach(out::add);
|
||||
out.sort(Comparator.comparing(k -> k.getKey().toString()));
|
||||
return out;
|
||||
}
|
||||
|
||||
/** Spawn without vanilla's random spawn data (baby chance, jockeys, gear, biome variants): reproducible. */
|
||||
private <T extends Entity> T rfSpawn(Location o, double x, double y, double z, float yaw, Class<T> type) {
|
||||
Location l = o.clone().add(x, y, z);
|
||||
l.setYaw(yaw);
|
||||
T e = w.spawn(l, type, false, en -> {
|
||||
if (en instanceof Mob m) m.setAI(false);
|
||||
en.setPersistent(false);
|
||||
});
|
||||
if (e instanceof LivingEntity le) le.setRemoveWhenFarAway(false);
|
||||
return e;
|
||||
}
|
||||
|
||||
private Entity rfSpawn(Location o, double x, double y, double z, float yaw, EntityType type) {
|
||||
Location l = o.clone().add(x, y, z);
|
||||
l.setYaw(yaw);
|
||||
Entity e = w.spawnEntity(l, type, false);
|
||||
if (e instanceof Mob m) m.setAI(false);
|
||||
return e;
|
||||
}
|
||||
|
||||
private void faceNorth(Location o) {
|
||||
for (Entity e : w.getNearbyEntities(o.clone().add(6, 0, 0), 14, 4, 12))
|
||||
if (e instanceof LivingEntity le && !(e instanceof Player)) le.setBodyYaw(180);
|
||||
}
|
||||
|
||||
private void rfCats(Location o) {
|
||||
List<Cat.Type> types = registry(io.papermc.paper.registry.RegistryKey.CAT_VARIANT);
|
||||
for (int i = 0; i < types.size(); i++) {
|
||||
rfSpawn(o, i * 1.2, 0, 0, 180, Cat.class).setCatType(types.get(i));
|
||||
Cat kit = rfSpawn(o, i * 1.2, 0, 1.6, 180, Cat.class);
|
||||
kit.setCatType(types.get(i));
|
||||
kit.setBaby();
|
||||
if (i % 2 == 0) tame(kit, DyeColor.values()[i % 16]);
|
||||
}
|
||||
faceNorth(o);
|
||||
}
|
||||
|
||||
private void rfDatapackCat(Location o) {
|
||||
Cat.Type custom = io.papermc.paper.registry.RegistryAccess.registryAccess()
|
||||
.getRegistry(io.papermc.paper.registry.RegistryKey.CAT_VARIANT)
|
||||
.get(new NamespacedKey("pptest", "ocelotcat"));
|
||||
if (custom == null) throw new IllegalStateException("datapack variant pptest:ocelotcat missing");
|
||||
rfSpawn(o, 0, 0, 0, 180, Cat.class).setCatType(custom);
|
||||
Cat kit = rfSpawn(o, 1.2, 0, 0, 180, Cat.class);
|
||||
kit.setCatType(custom);
|
||||
kit.setBaby();
|
||||
rfSpawn(o, 2.4, 0, 0, 180, Cat.class).setCatType(Cat.Type.TABBY);
|
||||
faceNorth(o);
|
||||
}
|
||||
|
||||
private void rfWolves(Location o) {
|
||||
List<Wolf.Variant> vs = registry(io.papermc.paper.registry.RegistryKey.WOLF_VARIANT);
|
||||
for (int i = 0; i < vs.size(); i++) {
|
||||
rfSpawn(o, i * 1.3, 0, 0, 180, Wolf.class).setVariant(vs.get(i));
|
||||
Wolf t = rfSpawn(o, i * 1.3, 0, 1.6, 180, Wolf.class);
|
||||
t.setVariant(vs.get(i));
|
||||
tame(t, DyeColor.values()[i % 16]);
|
||||
Wolf pup = rfSpawn(o, i * 1.3, 0, 3.0, 180, Wolf.class);
|
||||
pup.setVariant(vs.get(i));
|
||||
pup.setBaby();
|
||||
if (i % 2 == 1) tame(pup, DyeColor.BLUE);
|
||||
}
|
||||
faceNorth(o);
|
||||
}
|
||||
|
||||
private void rfFarm(Location o) {
|
||||
List<Cow.Variant> cows = registry(io.papermc.paper.registry.RegistryKey.COW_VARIANT);
|
||||
List<Pig.Variant> pigs = registry(io.papermc.paper.registry.RegistryKey.PIG_VARIANT);
|
||||
List<Chicken.Variant> chickens = registry(io.papermc.paper.registry.RegistryKey.CHICKEN_VARIANT);
|
||||
List<Frog.Variant> frogs = registry(io.papermc.paper.registry.RegistryKey.FROG_VARIANT);
|
||||
List<ZombieNautilus.Variant> nautili = registry(io.papermc.paper.registry.RegistryKey.ZOMBIE_NAUTILUS_VARIANT);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
double x = i * 4;
|
||||
setVar(rfSpawn(o, x, 0, 0, 180, Cow.class), cows.get(i));
|
||||
Cow cb = rfSpawn(o, x + 1.6, 0, 0, 180, Cow.class);
|
||||
setVar(cb, cows.get(i));
|
||||
cb.setBaby();
|
||||
setVar(rfSpawn(o, x, 0, 1.8, 180, Pig.class), pigs.get(i));
|
||||
Pig pb = rfSpawn(o, x + 1.4, 0, 1.8, 180, Pig.class);
|
||||
setVar(pb, pigs.get(i));
|
||||
pb.setBaby();
|
||||
setVar(rfSpawn(o, x + 2.6, 0, 1.8, 180, Chicken.class), chickens.get(i));
|
||||
Chicken chb = rfSpawn(o, x + 3.3, 0, 1.8, 180, Chicken.class);
|
||||
setVar(chb, chickens.get(i));
|
||||
chb.setBaby();
|
||||
setVar(rfSpawn(o, x + 0.5, 0, 3.4, 180, Frog.class), frogs.get(i));
|
||||
}
|
||||
for (int i = 0; i < nautili.size(); i++)
|
||||
setVar(rfSpawn(o, 2.5 + i * 3, 0, 4.8, 180, ZombieNautilus.class), nautili.get(i));
|
||||
faceNorth(o);
|
||||
}
|
||||
|
||||
/** setVariant via reflection (the variant setters' declaring interface differs between API and server). */
|
||||
private static void setVar(Entity e, Object variant) {
|
||||
for (java.lang.reflect.Method m : e.getClass().getMethods())
|
||||
if (m.getName().equals("setVariant") && m.getParameterCount() == 1
|
||||
&& m.getParameterTypes()[0].isInstance(variant)) {
|
||||
try {
|
||||
m.invoke(e, variant);
|
||||
return;
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("no setVariant for " + variant);
|
||||
}
|
||||
|
||||
private void rfStands(Location o) {
|
||||
rfSpawn(o, 0, 0, 0, 180, ArmorStand.class);
|
||||
rfSpawn(o, 1.5, 0, 0, 180, ArmorStand.class).setArms(true);
|
||||
rfSpawn(o, 3, 0, 0, 180, ArmorStand.class).setSmall(true);
|
||||
ArmorStand sa = rfSpawn(o, 4.2, 0, 0, 180, ArmorStand.class);
|
||||
sa.setSmall(true);
|
||||
sa.setArms(true);
|
||||
ArmorStand full = rfSpawn(o, 5.7, 0, 0, 180, ArmorStand.class);
|
||||
full.setArms(true);
|
||||
diamondArmor(full);
|
||||
hands(full, Material.IRON_SWORD, Material.SHIELD);
|
||||
ArmorStand sfull = rfSpawn(o, 7.2, 0, 0, 180, ArmorStand.class);
|
||||
sfull.setSmall(true);
|
||||
sfull.setArms(true);
|
||||
diamondArmor(sfull);
|
||||
hands(sfull, Material.TORCH, null);
|
||||
ArmorStand noArmsHeld = rfSpawn(o, 8.6, 0, 0, 180, ArmorStand.class);
|
||||
hands(noArmsHeld, Material.DIAMOND, null);
|
||||
ArmorStand inv = rfSpawn(o, 10, 0, 0, 180, ArmorStand.class);
|
||||
inv.setArms(true);
|
||||
inv.setInvisible(true);
|
||||
diamondArmor(inv);
|
||||
}
|
||||
|
||||
private static void diamondArmor(LivingEntity e) {
|
||||
e.getEquipment().setHelmet(it(Material.DIAMOND_HELMET));
|
||||
e.getEquipment().setChestplate(it(Material.DIAMOND_CHESTPLATE));
|
||||
e.getEquipment().setLeggings(it(Material.DIAMOND_LEGGINGS));
|
||||
e.getEquipment().setBoots(it(Material.DIAMOND_BOOTS));
|
||||
}
|
||||
|
||||
private void rfChests(Location o) {
|
||||
rfSpawn(o, 0, 0, 0, 180, Llama.class).setColor(Llama.Color.CREAMY);
|
||||
Llama lc = rfSpawn(o, 1.6, 0, 0, 180, Llama.class);
|
||||
lc.setColor(Llama.Color.BROWN);
|
||||
lc.setCarryingChest(true);
|
||||
Llama lcc = rfSpawn(o, 3.2, 0, 0, 180, Llama.class);
|
||||
lcc.setColor(Llama.Color.GRAY);
|
||||
lcc.setCarryingChest(true);
|
||||
lcc.getInventory().setDecor(it(Material.RED_CARPET));
|
||||
TraderLlama tl = rfSpawn(o, 4.8, 0, 0, 180, TraderLlama.class);
|
||||
tl.setColor(Llama.Color.WHITE);
|
||||
tl.setCarryingChest(true);
|
||||
Llama bl = rfSpawn(o, 6.2, 0, 0, 180, Llama.class);
|
||||
bl.setColor(Llama.Color.CREAMY);
|
||||
bl.setBaby();
|
||||
rfSpawn(o, 8, 0, 0, 180, Donkey.class);
|
||||
Donkey dc = rfSpawn(o, 9.6, 0, 0, 180, Donkey.class);
|
||||
dc.setCarryingChest(true);
|
||||
Donkey dcs = rfSpawn(o, 11.2, 0, 0, 180, Donkey.class);
|
||||
dcs.setCarryingChest(true);
|
||||
dcs.getInventory().setSaddle(it(Material.SADDLE));
|
||||
Mule mc = rfSpawn(o, 12.8, 0, 0, 180, Mule.class);
|
||||
mc.setCarryingChest(true);
|
||||
Mule mcs = rfSpawn(o, 14.4, 0, 0, 180, Mule.class);
|
||||
mcs.setCarryingChest(true);
|
||||
mcs.getInventory().setSaddle(it(Material.SADDLE));
|
||||
faceNorth(o);
|
||||
}
|
||||
|
||||
private void rfArmor(Location o) {
|
||||
Class<?>[] wearers = {Zombie.class, Husk.class, Drowned.class, ZombieVillager.class, PigZombie.class,
|
||||
Skeleton.class, Stray.class, WitherSkeleton.class, Bogged.class, Parched.class, Piglin.class, PiglinBrute.class};
|
||||
for (int i = 0; i < wearers.length; i++) {
|
||||
@SuppressWarnings("unchecked")
|
||||
LivingEntity e = rfSpawn(o, i * 1.25, 0, 0, 180, (Class<LivingEntity>) wearers[i]);
|
||||
diamondArmor(e);
|
||||
}
|
||||
LivingEntity m = (LivingEntity) rfSpawn(o, 0, 0, 2.2, 180, EntityType.MANNEQUIN);
|
||||
diamondArmor(m);
|
||||
Zombie bz = rfSpawn(o, 1.3, 0, 2.2, 180, Zombie.class);
|
||||
bz.setBaby();
|
||||
diamondArmor(bz);
|
||||
Piglin bp = rfSpawn(o, 2.5, 0, 2.2, 180, Piglin.class);
|
||||
bp.setBaby();
|
||||
diamondArmor(bp);
|
||||
// Non-wearers given armor: vanilla draws nothing.
|
||||
Class<?>[] others = {Villager.class, Pillager.class, Vindicator.class, Witch.class, Evoker.class,
|
||||
Creeper.class, Enderman.class, Cow.class, Fox.class};
|
||||
for (int i = 0; i < others.length; i++) {
|
||||
@SuppressWarnings("unchecked")
|
||||
LivingEntity e = rfSpawn(o, 4 + i * 1.25, 0, 2.2, 180, (Class<LivingEntity>) others[i]);
|
||||
diamondArmor(e);
|
||||
}
|
||||
faceNorth(o);
|
||||
}
|
||||
|
||||
// --- projectiles -----------------------------------------------------------------------------
|
||||
|
||||
/** Spawns a projectile at p moving along dir, rotated like vanilla Projectile#shoot (yaw atan2(x,z), pitch up). */
|
||||
|
||||
Reference in new issue
Block a user