render entities from vanilla client models, add items, displays and leashes
- dump entity models straight from the unobfuscated client jar (tools/VanillaModelDump.java, tools/update-vanilla-models.sh): models posed by vanilla setupAnim, baby/variant/layer models, renderer transforms, default textures, pose variants (sitting, holding items, illager arms) and all layer definitions; the old CEM template is only a fallback now - fix adult zombies captured as babies, zero-thickness planes (wings, fins) and back faces in the entity intersector - held items, head items (pumpkins, skulls), shields, elytra, saddles and body equipment for every mount, armor following the pose - block/item/text display entities, dropped items, falling blocks, primed TNT, minecart contents, block entities inside displays, leash ropes - item models resolved from the 26.x item definitions with display transforms; generated items extruded like vanilla - bundle the vanilla font definitions as fallback so sign/text rendering works with packs that lack font/*.json - one failing entity no longer aborts the whole photo - edge-case test plugin (tools/edgecase-plugin) and offline harnesses
This commit is contained in:
1 parent
5904814e69
commit
32afe08f03
41 files changed
+3761
-370
No files matched your search
@@ -0,0 +1,395 @@
|
||||
package pptest;
|
||||
|
||||
import eu.mhsl.minecraft.pixelpics.Main;
|
||||
import eu.mhsl.minecraft.pixelpics.render.render.DefaultScreenRenderer;
|
||||
import eu.mhsl.minecraft.pixelpics.render.render.RenderJob;
|
||||
import eu.mhsl.minecraft.pixelpics.render.render.Resolution;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import javax.imageio.ImageIO;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.type.Bed;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.Transformation;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.joml.AxisAngle4f;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
/** Test-only plugin: builds edge-case scenes and renders them through PixelPics into PNGs. */
|
||||
public class PPTest extends JavaPlugin {
|
||||
|
||||
record Scene(String name, Consumer<Location> build, double camX, double camY, double camZ, double lookX, double lookY, double lookZ) {}
|
||||
|
||||
private final Map<String, Scene> scenes = new LinkedHashMap<>();
|
||||
private World w;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
// Each scene sits on its own stone platform; the camera is placed relative to the platform origin.
|
||||
scenes.put("held", new Scene("held", this::held, 4.4, 2.6, -8.5, 4.4, 1.0, 1));
|
||||
scenes.put("equip", new Scene("equip", this::equip, 4, 3, -8.5, 4, 1.0, 1.5));
|
||||
scenes.put("riding", new Scene("riding", this::riding, 5, 3, -7.5, 5, 1.2, 1));
|
||||
scenes.put("leash", new Scene("leash", this::leash, 5, 4, -9, 5, 2.5, 2));
|
||||
scenes.put("displays", new Scene("displays", this::displays, 5, 3, -9, 5, 1.0, 1.5));
|
||||
scenes.put("pixelblock", new Scene("pixelblock", this::pixelblock, 1.5, 1.9, -1.3, 0.5, 0.5, 0.5));
|
||||
scenes.put("misc", new Scene("misc", this::misc, 5, 3, -7, 5, 0.8, 1.5));
|
||||
scenes.put("dbg", new Scene("dbg", this::dbg, 1, 1.6, -3, 1, 0.8, 0.5));
|
||||
scenes.put("vehicles", new Scene("vehicles", this::vehicles, 5, 3, -7, 5, 0.6, 1.5));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
w = Bukkit.getWorlds().getFirst();
|
||||
w.setTime(6000);
|
||||
w.setStorm(false);
|
||||
List<String> todo = args.length == 0 || args[0].equals("all") ? new ArrayList<>(scenes.keySet()) : List.of(args);
|
||||
int i = 0;
|
||||
for (String n : todo) {
|
||||
Scene sc = scenes.get(n);
|
||||
if (sc == null) { getLogger().warning("unknown scene " + n); continue; }
|
||||
int idx = new ArrayList<>(scenes.keySet()).indexOf(n);
|
||||
Location origin = new Location(w, 5000 + idx * 64, 200, 5000);
|
||||
Bukkit.getScheduler().runTaskLater(this, () -> run(sc, origin), 1 + i * 60L);
|
||||
i++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void run(Scene sc, Location o) {
|
||||
try {
|
||||
prepareArea(o);
|
||||
sc.build.accept(o.clone());
|
||||
} catch (Throwable t) {
|
||||
getLogger().severe("build " + sc.name + " failed: " + t);
|
||||
t.printStackTrace();
|
||||
}
|
||||
// Let one tick pass (passengers/leashes settle), then render.
|
||||
Bukkit.getScheduler().runTaskLater(this, () -> render(sc, o), 10);
|
||||
}
|
||||
|
||||
private void render(Scene sc, Location o) {
|
||||
DefaultScreenRenderer r = Main.getInstance().getScreenRenderer();
|
||||
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, new Resolution(480, 320), null);
|
||||
if (sc.name.equals("dbg")) {
|
||||
try {
|
||||
java.lang.reflect.Field f = DefaultScreenRenderer.class.getDeclaredField("objectBaker");
|
||||
f.setAccessible(true);
|
||||
var ob = (eu.mhsl.minecraft.pixelpics.render.entity.ObjectBaker) f.get(r);
|
||||
for (var st : job.objects()) {
|
||||
double[] pos = st.toWorld().t;
|
||||
if (Math.abs(pos[0] - o.getX()) > 5 || Math.abs(pos[2] - o.getZ()) > 5) continue;
|
||||
try {
|
||||
var re = ob.bake(st);
|
||||
getLogger().info("dbg obj " + st.kind() + " item=" + st.item() + " ctx=" + st.context() + " -> "
|
||||
+ (re == null ? "null" : re.cubes.size() + " cubes " + java.util.Arrays.toString(re.aabbMin)));
|
||||
} catch (Throwable t) {
|
||||
getLogger().warning("dbg bake failed: " + t);
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
getLogger().warning("dbg: " + t);
|
||||
}
|
||||
}
|
||||
getLogger().info("scene " + sc.name + ": " + job.entities().size() + " entities, " + job.objects().size()
|
||||
+ " objects, " + job.blockEntities().size() + " block entities");
|
||||
Bukkit.getScheduler().runTaskAsynchronously(this, () -> {
|
||||
try {
|
||||
BufferedImage img = r.execute(job);
|
||||
File f = new File(getDataFolder(), sc.name + ".png");
|
||||
f.getParentFile().mkdirs();
|
||||
ImageIO.write(img, "png", f);
|
||||
getLogger().info("WROTE " + f);
|
||||
} catch (Throwable t) {
|
||||
getLogger().severe("render " + sc.name + " failed: " + t);
|
||||
t.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Clears the area (entities + blocks) and lays a 14x14 stone floor at the origin's y-1. */
|
||||
private void prepareArea(Location o) {
|
||||
for (int cx = -1; cx <= 2; cx++)
|
||||
for (int cz = -2; cz <= 2; cz++) {
|
||||
Chunk c = w.getChunkAt((o.getBlockX() >> 4) + cx, (o.getBlockZ() >> 4) + cz);
|
||||
c.load(true);
|
||||
c.addPluginChunkTicket(this);
|
||||
}
|
||||
for (Entity e : w.getNearbyEntities(o.clone().add(6, 5, 2), 20, 20, 20)) if (!(e instanceof Player)) e.remove();
|
||||
for (int x = -6; x < 18; x++)
|
||||
for (int z = -12; z < 12; z++)
|
||||
for (int y = -1; y < 12; y++)
|
||||
w.getBlockAt(o.getBlockX() + x, o.getBlockY() + y, o.getBlockZ() + z)
|
||||
.setType(y == -1 ? Material.SMOOTH_STONE : Material.AIR, false);
|
||||
}
|
||||
|
||||
// --- helpers ---------------------------------------------------------------------------------
|
||||
|
||||
private <T extends Entity> T spawn(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, en -> {
|
||||
if (en instanceof Mob m) m.setAI(false);
|
||||
en.setPersistent(false);
|
||||
});
|
||||
if (e instanceof LivingEntity le) le.setRemoveWhenFarAway(false);
|
||||
return e;
|
||||
}
|
||||
|
||||
private Entity spawn(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);
|
||||
if (e instanceof Mob m) m.setAI(false);
|
||||
return e;
|
||||
}
|
||||
|
||||
private static ItemStack it(Material m) {
|
||||
return new ItemStack(m);
|
||||
}
|
||||
|
||||
private static void hands(Entity e, Material main, Material off) {
|
||||
if (!(e instanceof LivingEntity le) || le.getEquipment() == null) return;
|
||||
if (main != null) le.getEquipment().setItemInMainHand(it(main));
|
||||
if (off != null) le.getEquipment().setItemInOffHand(it(off));
|
||||
}
|
||||
|
||||
// --- scenes ----------------------------------------------------------------------------------
|
||||
|
||||
private void held(Location o) {
|
||||
hands(spawn(o, 0, 0, 0, 180, Zombie.class), Material.IRON_SWORD, Material.SHIELD);
|
||||
hands(spawn(o, 1.6, 0, 0, 180, Skeleton.class), Material.BOW, null);
|
||||
hands(spawn(o, 3.2, 0, 0, 180, Piglin.class), Material.GOLDEN_SWORD, null);
|
||||
hands(spawn(o, 4.8, 0, 0, 180, EntityType.MANNEQUIN), Material.DIAMOND_PICKAXE, Material.TORCH);
|
||||
ArmorStand as = spawn(o, 6.4, 0, 0, 180, ArmorStand.class);
|
||||
as.setArms(true);
|
||||
hands(as, Material.TRIDENT, Material.GRASS_BLOCK);
|
||||
hands(spawn(o, 8.0, 0, 0, 180, Drowned.class), Material.TRIDENT, null);
|
||||
hands(spawn(o, 0.8, 0, 2, 180, Pillager.class), Material.CROSSBOW, null);
|
||||
hands(spawn(o, 2.4, 0, 2, 180, Vindicator.class), Material.IRON_AXE, null);
|
||||
hands(spawn(o, 4.0, 0, 2, 180, Fox.class), Material.SWEET_BERRIES, null);
|
||||
hands(spawn(o, 5.6, 0.5, 2, 180, Allay.class), Material.DIAMOND, null);
|
||||
hands(spawn(o, 7.2, 0, 2, 180, Witch.class), Material.POTION, null);
|
||||
hands(spawn(o, 8.8, 0, 2, 180, Villager.class), Material.EMERALD, null);
|
||||
}
|
||||
|
||||
private void equip(Location o) {
|
||||
LivingEntity m = (LivingEntity) spawn(o, 0, 0, 0, 180, EntityType.MANNEQUIN);
|
||||
m.getEquipment().setChestplate(it(Material.ELYTRA));
|
||||
m.getEquipment().setHelmet(it(Material.IRON_HELMET));
|
||||
LivingEntity m2 = (LivingEntity) spawn(o, 1.6, 0, 0, 0, EntityType.MANNEQUIN); // back view: elytra
|
||||
m2.getEquipment().setChestplate(it(Material.ELYTRA));
|
||||
ArmorStand pumpkin = spawn(o, 3.2, 0, 0, 180, ArmorStand.class);
|
||||
pumpkin.getEquipment().setHelmet(it(Material.CARVED_PUMPKIN));
|
||||
pumpkin.getEquipment().setChestplate(it(Material.CHAINMAIL_CHESTPLATE));
|
||||
ArmorStand head = spawn(o, 4.8, 0, 0, 180, ArmorStand.class);
|
||||
head.getEquipment().setHelmet(it(Material.CREEPER_HEAD));
|
||||
head.setInvisible(true);
|
||||
Zombie z = spawn(o, 6.4, 0, 0, 180, Zombie.class);
|
||||
z.getEquipment().setHelmet(it(Material.GOLDEN_HELMET));
|
||||
z.getEquipment().setChestplate(it(Material.COPPER_CHESTPLATE));
|
||||
z.getEquipment().setLeggings(it(Material.NETHERITE_LEGGINGS));
|
||||
z.getEquipment().setBoots(it(Material.LEATHER_BOOTS));
|
||||
spawn(o, 8.0, 0, 0, 180, Snowman.class);
|
||||
Wolf wolf = spawn(o, 1, 0, 2.5, 180, Wolf.class);
|
||||
wolf.getEquipment().setItem(EquipmentSlot.BODY, it(Material.WOLF_ARMOR));
|
||||
Horse h = spawn(o, 4, 0, 3, 90, Horse.class);
|
||||
h.getInventory().setSaddle(it(Material.SADDLE));
|
||||
h.getInventory().setArmor(it(Material.GOLDEN_HORSE_ARMOR));
|
||||
Zombie baby = spawn(o, 7.5, 0, 2.5, 180, Zombie.class);
|
||||
baby.setBaby();
|
||||
baby.getEquipment().setHelmet(it(Material.DIAMOND_HELMET));
|
||||
hands(baby, Material.STONE_SWORD, null);
|
||||
}
|
||||
|
||||
private void riding(Location o) {
|
||||
Spider sp = spawn(o, 0, 0, 0, 180, Spider.class);
|
||||
sp.addPassenger(spawn(o, 0, 1, 0, 180, Skeleton.class));
|
||||
Chicken ch = spawn(o, 2, 0, 0, 180, Chicken.class);
|
||||
Zombie bz = spawn(o, 2, 1, 0, 180, Zombie.class);
|
||||
bz.setBaby();
|
||||
ch.addPassenger(bz);
|
||||
Horse h = spawn(o, 4.5, 0, 0.5, 180, Horse.class);
|
||||
h.getInventory().setSaddle(it(Material.SADDLE));
|
||||
h.addPassenger(spawn(o, 4.5, 2, 0.5, 180, EntityType.MANNEQUIN));
|
||||
Minecart mc = spawn(o, 7, 0, 0, 0, Minecart.class);
|
||||
mc.addPassenger(spawn(o, 7, 1, 0, 180, Villager.class));
|
||||
Boat b = (Boat) spawn(o, 9.5, 0, 0, 180, EntityType.OAK_BOAT);
|
||||
b.addPassenger(spawn(o, 9.5, 1, 0, 180, Zombie.class));
|
||||
b.addPassenger(spawn(o, 9.5, 1, 0, 180, Pig.class));
|
||||
Camel c = spawn(o, 2, 0, 3.5, 90, Camel.class);
|
||||
c.getInventory().setSaddle(it(Material.SADDLE));
|
||||
c.addPassenger(spawn(o, 2, 2, 3.5, 90, EntityType.MANNEQUIN));
|
||||
c.addPassenger(spawn(o, 2, 2, 3.5, 90, Villager.class));
|
||||
Strider st = spawn(o, 6, 0, 3.5, 180, Strider.class);
|
||||
st.setSaddle(true);
|
||||
st.addPassenger(spawn(o, 6, 2, 3.5, 180, Piglin.class));
|
||||
Boat cb = (Boat) spawn(o, 9, 0, 3.5, 180, EntityType.BIRCH_CHEST_BOAT);
|
||||
cb.addPassenger(spawn(o, 9, 1, 3.5, 180, EntityType.MANNEQUIN));
|
||||
}
|
||||
|
||||
private void leash(Location o) {
|
||||
Block fence = o.clone().add(0, 0, 0).getBlock();
|
||||
fence.setType(Material.OAK_FENCE);
|
||||
LeashHitch knot = w.spawn(fence.getLocation(), LeashHitch.class);
|
||||
Cow cow = spawn(o, 2.5, 0, 0.5, 180, Cow.class);
|
||||
cow.setLeashHolder(knot);
|
||||
LivingEntity holder = (LivingEntity) spawn(o, 5, 0, 0, 180, EntityType.MANNEQUIN);
|
||||
Wolf wolf = spawn(o, 7, 0, 0.5, 180, Wolf.class);
|
||||
wolf.setLeashHolder(holder);
|
||||
HappyGhast g = spawn(o, 4, 4, 5, 180, HappyGhast.class);
|
||||
g.getEquipment().setItem(EquipmentSlot.BODY, it(Material.BLUE_HARNESS));
|
||||
Boat boat = (Boat) spawn(o, 4, 0, 4, 180, EntityType.OAK_BOAT);
|
||||
try {
|
||||
boat.getClass().getMethod("setLeashHolder", Entity.class).invoke(boat, g);
|
||||
} catch (Throwable t) {
|
||||
getLogger().warning("boat not leashable: " + t);
|
||||
}
|
||||
Llama l1 = spawn(o, 9, 0, 2, 180, Llama.class);
|
||||
Llama l2 = spawn(o, 10.5, 0, 3.5, 180, Llama.class);
|
||||
l2.setLeashHolder(l1);
|
||||
l1.getInventory().setDecor(it(Material.RED_CARPET));
|
||||
l1.setCarryingChest(true);
|
||||
}
|
||||
|
||||
private void displays(Location o) {
|
||||
// Text displays: default background, coloured + shadowed + billboard center, multi-line wrapped.
|
||||
TextDisplay t1 = spawn(o, 0.5, 1.5, 0, 0, TextDisplay.class);
|
||||
t1.text(Component.text("Default Text"));
|
||||
TextDisplay t2 = spawn(o, 2.5, 1.5, 0, 0, TextDisplay.class);
|
||||
t2.text(Component.text("Billboard CENTER", NamedTextColor.GOLD));
|
||||
t2.setBillboard(Display.Billboard.CENTER);
|
||||
t2.setShadowed(true);
|
||||
t2.setBackgroundColor(Color.fromARGB(255, 30, 30, 90));
|
||||
TextDisplay t3 = spawn(o, 5, 1.5, 0, 180, TextDisplay.class);
|
||||
t3.text(Component.text("Dies ist ein langer Text, der umgebrochen werden sollte weil er breit ist"));
|
||||
t3.setLineWidth(80);
|
||||
// Item displays.
|
||||
ItemDisplay i1 = spawn(o, 7, 1, 0, 0, ItemDisplay.class);
|
||||
i1.setItemStack(it(Material.DIAMOND_SWORD));
|
||||
i1.setTransformation(new Transformation(new Vector3f(), new AxisAngle4f((float) Math.toRadians(45), 0, 0, 1),
|
||||
new Vector3f(1, 1, 1), new AxisAngle4f()));
|
||||
ItemDisplay i2 = spawn(o, 8.5, 0.5, 0, 30, ItemDisplay.class);
|
||||
i2.setItemStack(it(Material.CHEST));
|
||||
ItemDisplay i3 = spawn(o, 0.5, 0.5, 2.5, 0, ItemDisplay.class);
|
||||
i3.setItemStack(it(Material.PLAYER_HEAD));
|
||||
ItemDisplay i4 = spawn(o, 2, 0.5, 2.5, 0, ItemDisplay.class);
|
||||
i4.setItemStack(it(Material.SHIELD));
|
||||
// Block displays: rotated stairs, scaled chest (block entity!), banner, bed, glass.
|
||||
BlockDisplay b1 = spawn(o, 3.5, 0, 2.5, 0, BlockDisplay.class);
|
||||
b1.setBlock(Bukkit.createBlockData("minecraft:oak_stairs[facing=east]"));
|
||||
b1.setTransformation(new Transformation(new Vector3f(), new Quaternionf().rotateY(0.6f), new Vector3f(0.8f), new Quaternionf()));
|
||||
BlockDisplay b2 = spawn(o, 5, 0, 2.5, 0, BlockDisplay.class);
|
||||
b2.setBlock(Bukkit.createBlockData("minecraft:chest[facing=north]"));
|
||||
BlockDisplay b3 = spawn(o, 6.5, 0, 2.5, 0, BlockDisplay.class);
|
||||
b3.setBlock(Bukkit.createBlockData("minecraft:red_banner"));
|
||||
BlockDisplay b4 = spawn(o, 8, 0, 2.5, 0, BlockDisplay.class);
|
||||
b4.setBlock(Bukkit.createBlockData("minecraft:light_blue_stained_glass"));
|
||||
BlockDisplay b5 = spawn(o, 9.5, 0, 2.5, 0, BlockDisplay.class);
|
||||
b5.setBlock(Bukkit.createBlockData("minecraft:oak_sign"));
|
||||
}
|
||||
|
||||
/** Mimics PixelBlocks: 1/16-scaled block displays forming a mini build + the placeholder displays. */
|
||||
private void pixelblock(Location o) {
|
||||
float s = 1 / 16f;
|
||||
String[] palette = {"minecraft:oak_planks", "minecraft:stone_bricks", "minecraft:glass", "minecraft:red_wool",
|
||||
"minecraft:chest[facing=north]", "minecraft:red_bed[part=head,facing=north]", "minecraft:oak_stairs[facing=south]",
|
||||
"minecraft:torch", "minecraft:grass_block"};
|
||||
Random rnd = new Random(1);
|
||||
for (int x = 0; x < 16; x++)
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int h = 1 + (int) (3 * Math.abs(Math.sin(x * 0.4) * Math.cos(z * 0.3)));
|
||||
for (int y = 0; y < h; y++) {
|
||||
String b = y == h - 1 ? palette[rnd.nextInt(palette.length)] : "minecraft:stone_bricks";
|
||||
pixel(o, x, y, z, s, Bukkit.createBlockData(b));
|
||||
}
|
||||
}
|
||||
// Placeholder look (small pixel blocks): end-crystal item cores + glass container, next to it.
|
||||
Location p = o.clone().add(-1.5, 0.5, 0.5);
|
||||
for (int i = 0; i <= 90; i += 90) {
|
||||
ItemDisplay core = w.spawn(p, ItemDisplay.class);
|
||||
core.setRotation(i, 0);
|
||||
core.setItemStack(it(Material.END_CRYSTAL));
|
||||
Transformation t = core.getTransformation();
|
||||
t.getScale().set(0.5);
|
||||
core.setTransformation(t);
|
||||
}
|
||||
ItemDisplay glass = w.spawn(p, ItemDisplay.class);
|
||||
glass.setItemStack(it(Material.WHITE_STAINED_GLASS));
|
||||
Interaction hit = w.spawn(o.clone().add(0.5, 0, 0.5), Interaction.class);
|
||||
hit.setInteractionWidth(1);
|
||||
hit.setInteractionHeight(1);
|
||||
}
|
||||
|
||||
private void pixel(Location o, int x, int y, int z, float s, BlockData data) {
|
||||
Location l = o.clone().add(x * s + s / 2, y * s + s / 2, z * s + s / 2);
|
||||
BlockDisplay d = w.spawn(l, BlockDisplay.class);
|
||||
d.setBlock(data);
|
||||
Transformation t = d.getTransformation();
|
||||
t.getScale().set(s);
|
||||
t.getTranslation().set(-s / 2, -s / 2, -s / 2);
|
||||
d.setTransformation(t);
|
||||
}
|
||||
|
||||
private void misc(Location o) {
|
||||
w.dropItem(o.clone().add(0, 0.2, 0), it(Material.DIAMOND_SWORD), i -> i.setVelocity(new Vector()));
|
||||
w.dropItem(o.clone().add(1, 0.2, 0), it(Material.OAK_LOG), i -> i.setVelocity(new Vector()));
|
||||
w.dropItem(o.clone().add(2, 0.2, 0), new ItemStack(Material.COBBLESTONE, 32), i -> i.setVelocity(new Vector()));
|
||||
w.dropItem(o.clone().add(3, 0.2, 0), it(Material.APPLE), i -> i.setVelocity(new Vector()));
|
||||
FallingBlock fb = w.spawn(o.clone().add(4.5, 0.5, 0.5), FallingBlock.class, f -> f.setGravity(false));
|
||||
fb.setBlockData(Bukkit.createBlockData("minecraft:sand"));
|
||||
TNTPrimed tnt = w.spawn(o.clone().add(6, 0, 0.5), TNTPrimed.class);
|
||||
tnt.setFuseTicks(10000);
|
||||
tnt.setGravity(false);
|
||||
w.spawn(o.clone().add(8, 0, 0.5), EnderCrystal.class);
|
||||
Sheep sh = spawn(o, 0.5, 0, 3, 180, Sheep.class);
|
||||
sh.setSheared(true);
|
||||
Sheep sh2 = spawn(o, 2.5, 0, 3, 180, Sheep.class);
|
||||
sh2.setColor(DyeColor.LIME);
|
||||
ArmorStand small = spawn(o, 4.5, 0, 3, 180, ArmorStand.class);
|
||||
small.setSmall(true);
|
||||
small.getEquipment().setHelmet(it(Material.LEATHER_HELMET));
|
||||
spawn(o, 6, 0, 3, 180, EntityType.EXPERIENCE_ORB);
|
||||
Arrow a = w.spawn(o.clone().add(7, 0.5, 3), Arrow.class, ar -> ar.setGravity(false));
|
||||
a.setVelocity(new Vector(1, -0.4, 0));
|
||||
Trident tr = w.spawn(o.clone().add(9, 0.5, 3), Trident.class, ar -> ar.setGravity(false));
|
||||
tr.setVelocity(new Vector(0, -1, 0.2));
|
||||
spawn(o, 10, 0, 0, 180, TropicalFish.class);
|
||||
}
|
||||
|
||||
private void dbg(Location o) {
|
||||
TextDisplay t1 = spawn(o, 0, 1.2, 0, 0, TextDisplay.class);
|
||||
t1.text(Component.text("Default Text"));
|
||||
ItemDisplay i4 = spawn(o, 2, 0.5, 0.5, 0, ItemDisplay.class);
|
||||
i4.setItemStack(it(Material.SHIELD));
|
||||
getLogger().info("dbg text=" + t1.isValid() + " opacity=" + t1.getTextOpacity() + " shield=" + i4.getItemStack());
|
||||
}
|
||||
|
||||
private void vehicles(Location o) {
|
||||
spawn(o, 0, 0, 0, 0, EntityType.CHEST_MINECART);
|
||||
spawn(o, 1.8, 0, 0, 90, EntityType.FURNACE_MINECART);
|
||||
spawn(o, 3.6, 0, 0, 0, EntityType.HOPPER_MINECART);
|
||||
spawn(o, 5.4, 0, 0, 0, EntityType.TNT_MINECART);
|
||||
spawn(o, 7.2, 0, 0, 0, EntityType.SPAWNER_MINECART);
|
||||
spawn(o, 9, 0, 0, 0, EntityType.COMMAND_BLOCK_MINECART);
|
||||
spawn(o, 0.5, 0, 3, 30, EntityType.PALE_OAK_BOAT);
|
||||
spawn(o, 3, 0, 3, 60, EntityType.BAMBOO_CHEST_RAFT);
|
||||
spawn(o, 6, 0, 3, 90, EntityType.CHERRY_CHEST_BOAT);
|
||||
spawn(o, 9, 0, 3, 120, EntityType.MANGROVE_BOAT);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user