diff --git a/chunky/src/java/se/llbit/chunky/block/Block.java b/chunky/src/java/se/llbit/chunky/block/Block.java index 3a8f3a7e7..72ac8a121 100644 --- a/chunky/src/java/se/llbit/chunky/block/Block.java +++ b/chunky/src/java/se/llbit/chunky/block/Block.java @@ -13,6 +13,7 @@ import se.llbit.nbt.CompoundTag; import se.llbit.nbt.Tag; +import java.util.Collection; import java.util.Random; public abstract class Block extends Material { @@ -25,13 +26,6 @@ public abstract class Block extends Material { */ public boolean localIntersect = false; - /** - * Invisible blocks are not rendered as regular voxels (they are not added to the voxel octree). - * This is used for blocks that are rendered as entities, and blocks that are not implemented - * yet. - */ - public boolean invisible = false; - public Block(String name, Texture texture) { super(name, texture); } @@ -97,31 +91,67 @@ public String toString() { return name; } + /** + * Check if this block is a block entity, i.e. {@link #createBlockEntity(Vector3, CompoundTag)} should be invoked to + * create an entity from this block and its entity data tag. This is used for blocks that need to create a new entity + * that needs the block entity data, e.g. signs. + *

+ * This is mutually exclusive with {@link #hasEntities()}, use that one if you don't need block entity data. + * + * @return True if this block is a block entity, false otherwise + */ public boolean isBlockEntity() { return false; } - public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) { - throw new Error("This block type can not be converted to a block entity: " + /** + * Create a block entity from this block and the given block entity tag at the specified position. + * + * @param position Position + * @param entityTag Block entity tag + * @return The block entity created from this block's data and the entity tag + * @throws UnsupportedOperationException If this block is not a block entity (i.e. {@link #isBlockEntity()} returns false + */ + public Entity createBlockEntity(Vector3 position, CompoundTag entityTag) { + throw new UnsupportedOperationException("This block type can not be converted to a block entity: " + getClass().getSimpleName()); } - public boolean isEntity() { + /** + * Check if this block has entities, i.e. {@link #createEntities(Vector3)} should be invoked to create entities from this + * block. A block can create multiple entities (e.g. the lectern may create a lectern and a book entity). + *

+ * This is mutually exclusive with {@link #isBlockEntity()}, use that one if you need block entity data. + * + * @return True if this block has entities, false otherwise + */ + public boolean hasEntities() { return false; } /** - * If this returns true, the block won't be removed from the octree even if this is an entity - * (i.e. {@link #isEntity()} returns true). This can be used for blocks that also contain - * entities, e.g. candle (where the candle flame is an entity). + * Create entities from this block at the specified position. + *

+ * This may return multiple entities, e.g. the lectern has a lectern entity and an optional book entity. + * + * @param position Position + * @return The entities created from this block's data + * @throws UnsupportedOperationException If this block is not a block entity (i.e. {@link #hasEntities()} returns false */ - public boolean isBlockWithEntity() { - return false; + public Collection createEntities(Vector3 position) { + throw new UnsupportedOperationException("This block type can not be converted to entities: " + + getClass().getSimpleName()); } - public Entity toEntity(Vector3 position) { - throw new Error("This block type can not be converted to an entity: " - + getClass().getSimpleName()); + /** + * Whether to remove this block from the octree if it contains entities (i.e. {@link #hasEntities()} or {@link #isBlockEntity()} + * return true). + *

+ * Most blocks are replaced by their entities (eg. signs create a sign entity that does the rendering and the block itself + * does nothing, but some blocks use block model and entities, e.g. candle (where the candle flame is an entity but the candle is a block). + */ + public boolean isReplacedByEntities() { + return true; } /** diff --git a/chunky/src/java/se/llbit/chunky/block/legacy/blocks/LegacyBanner.java b/chunky/src/java/se/llbit/chunky/block/legacy/blocks/LegacyBanner.java index 864734b46..c44ff6eb1 100644 --- a/chunky/src/java/se/llbit/chunky/block/legacy/blocks/LegacyBanner.java +++ b/chunky/src/java/se/llbit/chunky/block/legacy/blocks/LegacyBanner.java @@ -46,7 +46,6 @@ public class LegacyBanner extends MinecraftBlockTranslucent { public LegacyBanner(String name, CompoundTag tag) { super(name, Texture.whiteWool); localIntersect = true; - invisible = true; rotation = tag.get("Data").intValue(0); } @@ -56,15 +55,10 @@ public boolean isBlockEntity() { } @Override - public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) { + public Entity createBlockEntity(Vector3 position, CompoundTag entityTag) { return new StandingBanner(position, rotation, parseDesign(entityTag)); } - @Override - public boolean intersect(Ray ray, Scene scene) { - return false; - } - /** * Parse a banner design from the given Minecraft 1.12 or older banner entity tag and convert the * colors to 1.13+ values. diff --git a/chunky/src/java/se/llbit/chunky/block/legacy/blocks/LegacySkull.java b/chunky/src/java/se/llbit/chunky/block/legacy/blocks/LegacySkull.java index 540cc01da..e42eae2f5 100644 --- a/chunky/src/java/se/llbit/chunky/block/legacy/blocks/LegacySkull.java +++ b/chunky/src/java/se/llbit/chunky/block/legacy/blocks/LegacySkull.java @@ -30,7 +30,6 @@ public LegacySkull(String name, CompoundTag tag) { super(name, Texture.steve); this.placement = tag.get("Data").intValue(0); localIntersect = true; - invisible = true; } @Override @@ -39,7 +38,7 @@ public boolean isBlockEntity() { } @Override - public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) { + public Entity createBlockEntity(Vector3 position, CompoundTag entityTag) { Kind kind = getSkullKind(entityTag.get("SkullType").byteValue(0)); int rotation = entityTag.get("Rot").byteValue(0); if (kind == Kind.PLAYER) { @@ -55,11 +54,6 @@ public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) { return new SkullEntity(position, kind, rotation, placement); } - @Override - public boolean intersect(Ray ray, Scene scene) { - return false; - } - private static Kind getSkullKind(int skullType) { switch (skullType) { case 0: diff --git a/chunky/src/java/se/llbit/chunky/block/legacy/blocks/LegacyWallBanner.java b/chunky/src/java/se/llbit/chunky/block/legacy/blocks/LegacyWallBanner.java index ff46332ae..7c68a6ecf 100644 --- a/chunky/src/java/se/llbit/chunky/block/legacy/blocks/LegacyWallBanner.java +++ b/chunky/src/java/se/llbit/chunky/block/legacy/blocks/LegacyWallBanner.java @@ -22,7 +22,6 @@ public class LegacyWallBanner extends MinecraftBlockTranslucent { public LegacyWallBanner(String name, CompoundTag tag) { super(name, Texture.whiteWool); localIntersect = true; - invisible = true; facing = tag.get("Data").intValue(2); } @@ -32,12 +31,7 @@ public boolean isBlockEntity() { } @Override - public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) { + public Entity createBlockEntity(Vector3 position, CompoundTag entityTag) { return new WallBanner(position, facing, LegacyBanner.parseDesign(entityTag)); } - - @Override - public boolean intersect(Ray ray, Scene scene) { - return false; - } } diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/Air.java b/chunky/src/java/se/llbit/chunky/block/minecraft/Air.java index a0e291ed8..481772cf5 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/Air.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/Air.java @@ -28,6 +28,5 @@ private Air() { super("air", Texture.air); solid = false; opaque = false; - invisible = true; } } diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/Banner.java b/chunky/src/java/se/llbit/chunky/block/minecraft/Banner.java index e9a204e6b..20c9a9c1d 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/Banner.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/Banner.java @@ -39,22 +39,16 @@ public class Banner extends MinecraftBlockTranslucent { public Banner(String name, Texture texture, int rotation, BannerDesign.Color color) { super(name, texture); - invisible = true; opaque = false; - localIntersect = true; this.rotation = rotation % 16; this.color = color; } - @Override public boolean intersect(Ray ray, Scene scene) { - return false; - } - @Override public boolean isBlockEntity() { return true; } - @Override public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) { + @Override public Entity createBlockEntity(Vector3 position, CompoundTag entityTag) { JsonObject design = StandingBanner.parseDesign(entityTag); design.set("base", Json.of(color.id)); // Base color is not included in the entity tag in Minecraft 1.13+. return new StandingBanner(position, rotation, design); diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/Beacon.java b/chunky/src/java/se/llbit/chunky/block/minecraft/Beacon.java index 3f6949024..73009fdce 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/Beacon.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/Beacon.java @@ -36,8 +36,8 @@ public Beacon() { } @Override - public boolean isBlockWithEntity() { - return true; + public boolean isReplacedByEntities() { + return false; } @Override @@ -46,7 +46,7 @@ public boolean isBlockEntity() { } @Override - public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) { + public Entity createBlockEntity(Vector3 position, CompoundTag entityTag) { if (entityTag.get("Levels").intValue(0) > 0) { return new BeaconBeam(position); } diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/CakeWithCandle.java b/chunky/src/java/se/llbit/chunky/block/minecraft/CakeWithCandle.java index c6cdb2f97..b692c55d1 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/CakeWithCandle.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/CakeWithCandle.java @@ -25,6 +25,8 @@ import se.llbit.chunky.resources.Texture; import se.llbit.math.Vector3; +import java.util.Collection; +import java.util.Collections; import java.util.Random; public class CakeWithCandle extends AbstractModelBlock { @@ -51,18 +53,18 @@ public String description() { } @Override - public boolean isEntity() { + public boolean hasEntities() { return isLit(); } @Override - public boolean isBlockWithEntity() { - return true; + public boolean isReplacedByEntities() { + return false; } @Override - public Entity toEntity(Vector3 position) { - return new FlameParticles(position, entity); + public Collection createEntities(Vector3 position) { + return Collections.singleton(new FlameParticles(position, entity)); } @Override diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/CalibratedSculkSensor.java b/chunky/src/java/se/llbit/chunky/block/minecraft/CalibratedSculkSensor.java index bb4e50365..d0425c294 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/CalibratedSculkSensor.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/CalibratedSculkSensor.java @@ -25,6 +25,9 @@ import se.llbit.chunky.resources.Texture; import se.llbit.math.Vector3; +import java.util.Collection; +import java.util.Collections; + public class CalibratedSculkSensor extends AbstractModelBlock { private final String phase; private final String facing; @@ -46,17 +49,17 @@ public String description() { } @Override - public boolean isEntity() { + public boolean hasEntities() { return true; } @Override - public boolean isBlockWithEntity() { - return true; + public boolean isReplacedByEntities() { + return false; } @Override - public Entity toEntity(Vector3 position) { - return new CalibratedSculkSensorAmethyst(position, this.facing, isActive(), this); + public Collection createEntities(Vector3 position) { + return Collections.singleton(new CalibratedSculkSensorAmethyst(position, this.facing, isActive(), this)); } } diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/Campfire.java b/chunky/src/java/se/llbit/chunky/block/minecraft/Campfire.java index 42c4d5949..3bb618aef 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/Campfire.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/Campfire.java @@ -35,26 +35,19 @@ public class Campfire extends MinecraftBlockTranslucent { public Campfire(String name, se.llbit.chunky.entity.Campfire.Kind kind, String facing, boolean lit) { super(name, Texture.campfireLog); - invisible = true; opaque = false; - localIntersect = true; this.kind = kind; this.facing = facing; this.isLit = lit; } - @Override - public boolean intersect(Ray ray, Scene scene) { - return false; - } - @Override public boolean isBlockEntity() { return true; } @Override - public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) { + public Entity createBlockEntity(Vector3 position, CompoundTag entityTag) { return new se.llbit.chunky.entity.Campfire(this.kind, position, this.facing, this.isLit, this); } diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/Candle.java b/chunky/src/java/se/llbit/chunky/block/minecraft/Candle.java index 6c41351fc..d236fa737 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/Candle.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/Candle.java @@ -27,6 +27,8 @@ import se.llbit.chunky.world.material.TextureMaterial; import se.llbit.math.Vector3; +import java.util.Collection; +import java.util.Collections; import java.util.Random; public class Candle extends AbstractModelBlock { @@ -79,21 +81,21 @@ public boolean isLit() { } @Override - public boolean isEntity() { + public boolean hasEntities() { return isLit(); } @Override - public boolean isBlockWithEntity() { - return true; + public boolean isReplacedByEntities() { + return false; } @Override - public Entity toEntity(Vector3 position) { + public Collection createEntities(Vector3 position) { if (entity != null) { - return new FlameParticles(position, entity); + return Collections.singleton(new FlameParticles(position, entity)); } else { - return new FlameParticles(position, this, new Vector3[0]); + return Collections.singleton(new FlameParticles(position, this, new Vector3[0])); } } diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/CoralFan.java b/chunky/src/java/se/llbit/chunky/block/minecraft/CoralFan.java index d68a3111c..bb449aaa4 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/CoralFan.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/CoralFan.java @@ -26,6 +26,9 @@ import se.llbit.math.Ray; import se.llbit.math.Vector3; +import java.util.Collection; +import java.util.Collections; + public class CoralFan extends MinecraftBlockTranslucent { private final String coralType; @@ -33,9 +36,7 @@ public class CoralFan extends MinecraftBlockTranslucent { public CoralFan(String name, String coralType) { super(name, coralTexture(coralType)); this.coralType = coralType; - localIntersect = true; solid = false; - invisible = true; } public static Texture coralTexture(String coralType) { @@ -64,15 +65,11 @@ public static Texture coralTexture(String coralType) { } } - @Override public boolean intersect(Ray ray, Scene scene) { - return false; - } - - @Override public boolean isEntity() { + @Override public boolean hasEntities() { return true; } - @Override public Entity toEntity(Vector3 position) { - return new CoralFanEntity(position, coralType); + @Override public Collection createEntities(Vector3 position) { + return Collections.singleton(new CoralFanEntity(position, coralType)); } } diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/DecoratedPot.java b/chunky/src/java/se/llbit/chunky/block/minecraft/DecoratedPot.java index 2d223fdb8..d2f75dd05 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/DecoratedPot.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/DecoratedPot.java @@ -64,7 +64,12 @@ public boolean isModifiedByBlockEntity() { } @Override - public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) { + public boolean isReplacedByEntities() { + return false; + } + + @Override + public Entity createBlockEntity(Vector3 position, CompoundTag entityTag) { return new DecoratedPotModel.DecoratedPotSpoutEntity(position, facing); } diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/EnchantingTable.java b/chunky/src/java/se/llbit/chunky/block/minecraft/EnchantingTable.java index 7b4a2bf51..fd4412e0e 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/EnchantingTable.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/EnchantingTable.java @@ -25,6 +25,9 @@ import se.llbit.chunky.resources.Texture; import se.llbit.math.Vector3; +import java.util.Collection; +import java.util.Collections; + public class EnchantingTable extends AbstractModelBlock { public EnchantingTable() { @@ -35,17 +38,17 @@ public EnchantingTable() { } @Override - public boolean isEntity() { + public boolean hasEntities() { return true; } @Override - public boolean isBlockWithEntity() { - return true; + public boolean isReplacedByEntities() { + return false; } @Override - public Entity toEntity(Vector3 position) { + public Collection createEntities(Vector3 position) { Vector3 newPosition = new Vector3(position); newPosition.add(0, 0.35, 0); Book book = new Book( @@ -55,6 +58,6 @@ public Entity toEntity(Vector3 position) { Math.toRadians(180 - 30)); book.setPitch(Math.toRadians(80)); book.setYaw(Math.toRadians(45)); - return book; + return Collections.singleton(book); } } diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/HangingSign.java b/chunky/src/java/se/llbit/chunky/block/minecraft/HangingSign.java index f669c87a7..005207669 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/HangingSign.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/HangingSign.java @@ -36,14 +36,7 @@ public HangingSign(String name, String material, int rotation, boolean attached) this.material = material; this.rotation = rotation; this.attached = attached; - invisible = true; solid = false; - localIntersect = true; - } - - @Override - public boolean intersect(Ray ray, Scene scene) { - return false; } @Override @@ -52,7 +45,7 @@ public boolean isBlockEntity() { } @Override - public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) { + public Entity createBlockEntity(Vector3 position, CompoundTag entityTag) { return new HangingSignEntity(position, entityTag, rotation, attached, material); } } diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/Head.java b/chunky/src/java/se/llbit/chunky/block/minecraft/Head.java index ff728b64f..1ae5edf71 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/Head.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/Head.java @@ -34,6 +34,8 @@ import se.llbit.util.mojangapi.MojangApi; import java.io.IOException; +import java.util.Collection; +import java.util.Collections; import java.util.Optional; public class Head extends MinecraftBlockTranslucent { @@ -44,40 +46,33 @@ public class Head extends MinecraftBlockTranslucent { public Head(String name, Texture texture, SkullEntity.Kind type, int rotation) { super(name, texture); - localIntersect = true; - invisible = true; description = "rotation=" + rotation; this.type = type; this.rotation = rotation; } - @Override - public boolean intersect(Ray ray, Scene scene) { - return false; - } - @Override public String description() { return description; } @Override - public boolean isEntity() { + public boolean hasEntities() { return type != Kind.PLAYER; } @Override - public Entity toEntity(Vector3 position) { - return new SkullEntity(position, type, rotation, 1); + public Collection createEntities(Vector3 position) { + return Collections.singleton(new SkullEntity(position, type, rotation, 1)); } @Override public boolean isBlockEntity() { - return true; + return type == Kind.PLAYER; } @Override - public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) { + public Entity createBlockEntity(Vector3 position, CompoundTag entityTag) { if (type == Kind.PLAYER) { try { String textureUrl = getTextureUrl(entityTag); diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/Lectern.java b/chunky/src/java/se/llbit/chunky/block/minecraft/Lectern.java index ee8071214..87c35fcaf 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/Lectern.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/Lectern.java @@ -25,6 +25,8 @@ import se.llbit.math.Ray; import se.llbit.math.Vector3; +import java.util.Collection; + public class Lectern extends MinecraftBlockTranslucent { private final String facing; private final boolean hasBook; @@ -33,23 +35,16 @@ public Lectern(String facing, boolean hasBook) { super("lectern", Texture.lecternFront); this.facing = facing; this.hasBook = hasBook; - invisible = true; opaque = false; - localIntersect = true; - } - - @Override - public boolean intersect(Ray ray, Scene scene) { - return false; } @Override - public boolean isEntity() { + public boolean hasEntities() { return true; } @Override - public Entity toEntity(Vector3 position) { - return new se.llbit.chunky.entity.Lectern(position, this.facing, this.hasBook); + public Collection createEntities(Vector3 position) { + return se.llbit.chunky.entity.Lectern.create(position, this.facing, this.hasBook); } } diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/LilyPad.java b/chunky/src/java/se/llbit/chunky/block/minecraft/LilyPad.java index 96d89236c..3331b856b 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/LilyPad.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/LilyPad.java @@ -26,23 +26,20 @@ import se.llbit.math.Ray; import se.llbit.math.Vector3; +import java.util.Collection; +import java.util.Collections; + public class LilyPad extends MinecraftBlockTranslucent { public LilyPad() { super("lily_pad", Texture.lilyPad); - invisible = true; opaque = false; - localIntersect = true; - } - - @Override public boolean intersect(Ray ray, Scene scene) { - return false; } - @Override public boolean isEntity() { + @Override public boolean hasEntities() { return true; } - @Override public Entity toEntity(Vector3 position) { - return new LilyPadEntity(position); + @Override public Collection createEntities(Vector3 position) { + return Collections.singleton(new LilyPadEntity(position)); } } diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/Sign.java b/chunky/src/java/se/llbit/chunky/block/minecraft/Sign.java index fd5ab1622..87fa3019a 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/Sign.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/Sign.java @@ -32,9 +32,7 @@ public class Sign extends MinecraftBlockTranslucent { public Sign(String name, String material, int rotation) { super(name, SignEntity.textureFromMaterial(material)); - invisible = true; solid = false; - localIntersect = true; this.rotation = rotation % 16; this.material = material; } @@ -47,7 +45,7 @@ public Sign(String name, String material, int rotation) { return true; } - @Override public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) { + @Override public Entity createBlockEntity(Vector3 position, CompoundTag entityTag) { return new SignEntity(position, entityTag, rotation, material); } } diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/SporeBlossom.java b/chunky/src/java/se/llbit/chunky/block/minecraft/SporeBlossom.java index c9a8ea0e0..986a16832 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/SporeBlossom.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/SporeBlossom.java @@ -25,27 +25,23 @@ import se.llbit.math.Ray; import se.llbit.math.Vector3; +import java.util.Collection; +import java.util.Collections; + public class SporeBlossom extends Block { public SporeBlossom() { super("spore_blossom", Texture.sporeBlossom); - invisible = true; opaque = false; - localIntersect = true; - } - - @Override - public boolean intersect(Ray ray, Scene scene) { - return false; } @Override - public boolean isEntity() { + public boolean hasEntities() { return true; } @Override - public Entity toEntity(Vector3 position) { - return new se.llbit.chunky.entity.SporeBlossom(position); + public Collection createEntities(Vector3 position) { + return Collections.singleton(new se.llbit.chunky.entity.SporeBlossom(position)); } } diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/WallBanner.java b/chunky/src/java/se/llbit/chunky/block/minecraft/WallBanner.java index 816a92618..cd373176e 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/WallBanner.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/WallBanner.java @@ -36,9 +36,7 @@ public class WallBanner extends MinecraftBlockTranslucent { public WallBanner(String name, Texture texture, String facing, BannerDesign.Color color) { super(name, texture); - invisible = true; opaque = false; - localIntersect = true; switch (facing) { default: case "north": @@ -57,15 +55,11 @@ public WallBanner(String name, Texture texture, String facing, BannerDesign.Colo this.color = color; } - @Override public boolean intersect(Ray ray, Scene scene) { - return false; - } - @Override public boolean isBlockEntity() { return true; } - @Override public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) { + @Override public Entity createBlockEntity(Vector3 position, CompoundTag entityTag) { JsonObject design = StandingBanner.parseDesign(entityTag); design.set("base", Json.of(color.id)); // Base color is not included in the entity tag in Minecraft 1.13+. return new se.llbit.chunky.entity.WallBanner(position, facing, design); diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/WallCoralFan.java b/chunky/src/java/se/llbit/chunky/block/minecraft/WallCoralFan.java index c1c1f1f60..cd95449cb 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/WallCoralFan.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/WallCoralFan.java @@ -25,6 +25,9 @@ import se.llbit.math.Ray; import se.llbit.math.Vector3; +import java.util.Collection; +import java.util.Collections; + public class WallCoralFan extends MinecraftBlockTranslucent { private final String coralType; @@ -34,20 +37,14 @@ public WallCoralFan(String name, String coralType, String facing) { super(name, CoralFan.coralTexture(coralType)); this.coralType = coralType; this.facing = facing; - localIntersect = true; solid = false; - invisible = true; - } - - @Override public boolean intersect(Ray ray, Scene scene) { - return false; } - @Override public boolean isEntity() { + @Override public boolean hasEntities() { return true; } - @Override public Entity toEntity(Vector3 position) { - return new WallCoralFanEntity(position, coralType, facing); + @Override public Collection createEntities(Vector3 position) { + return Collections.singleton(new WallCoralFanEntity(position, coralType, facing)); } } diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/WallHangingSign.java b/chunky/src/java/se/llbit/chunky/block/minecraft/WallHangingSign.java index 1afccff9f..0fe7ab662 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/WallHangingSign.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/WallHangingSign.java @@ -35,14 +35,7 @@ public WallHangingSign(String name, String material, String facing) { super(name, HangingSignEntity.textureFromMaterial(material)); this.material = material; this.facing = Facing.fromString(facing); - invisible = true; solid = false; - localIntersect = true; - } - - @Override - public boolean intersect(Ray ray, Scene scene) { - return false; } @Override @@ -51,7 +44,7 @@ public boolean isBlockEntity() { } @Override - public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) { + public Entity createBlockEntity(Vector3 position, CompoundTag entityTag) { return new WallHangingSignEntity(position, entityTag, facing, material); } diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/WallHead.java b/chunky/src/java/se/llbit/chunky/block/minecraft/WallHead.java index 8cd02a59c..bd61a86bd 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/WallHead.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/WallHead.java @@ -31,17 +31,16 @@ import se.llbit.nbt.CompoundTag; import java.io.IOException; +import java.util.Collection; +import java.util.Collections; public class WallHead extends MinecraftBlockTranslucent { - private final String description; private final int facing; private final SkullEntity.Kind type; public WallHead(String name, Texture texture, SkullEntity.Kind type, String facing) { super(name, texture); - localIntersect = true; - invisible = true; description = "facing=" + facing; this.type = type; switch (facing) { @@ -61,33 +60,28 @@ public WallHead(String name, Texture texture, SkullEntity.Kind type, String faci } } - @Override - public boolean intersect(Ray ray, Scene scene) { - return false; - } - @Override public String description() { return description; } @Override - public boolean isEntity() { + public boolean hasEntities() { return type != Kind.PLAYER; } @Override - public Entity toEntity(Vector3 position) { - return new SkullEntity(position, type, 0, facing); + public Collection createEntities(Vector3 position) { + return Collections.singleton(new SkullEntity(position, type, 0, facing)); } @Override public boolean isBlockEntity() { - return true;//return type == Kind.PLAYER; + return type == Kind.PLAYER; } @Override - public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) { + public Entity createBlockEntity(Vector3 position, CompoundTag entityTag) { if (type == Kind.PLAYER) { try { String textureUrl = Head.getTextureUrl(entityTag); diff --git a/chunky/src/java/se/llbit/chunky/block/minecraft/WallSign.java b/chunky/src/java/se/llbit/chunky/block/minecraft/WallSign.java index dd833d102..226bdfb5e 100644 --- a/chunky/src/java/se/llbit/chunky/block/minecraft/WallSign.java +++ b/chunky/src/java/se/llbit/chunky/block/minecraft/WallSign.java @@ -33,9 +33,7 @@ public class WallSign extends MinecraftBlockTranslucent { public WallSign(String name, String material, String facing) { super(name, SignEntity.textureFromMaterial(material)); - invisible = true; solid = false; - localIntersect = true; this.material = material; switch (facing) { default: @@ -62,7 +60,7 @@ public WallSign(String name, String material, String facing) { return true; } - @Override public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) { + @Override public Entity createBlockEntity(Vector3 position, CompoundTag entityTag) { return new WallSignEntity(position, entityTag, facing, material); } } diff --git a/chunky/src/java/se/llbit/chunky/entity/ArmorStand.java b/chunky/src/java/se/llbit/chunky/entity/ArmorStand.java index a4d8c76c5..8c89caea5 100644 --- a/chunky/src/java/se/llbit/chunky/entity/ArmorStand.java +++ b/chunky/src/java/se/llbit/chunky/entity/ArmorStand.java @@ -34,6 +34,7 @@ import se.llbit.util.JsonUtil; import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; public class ArmorStand extends Entity implements Poseable, Geared { @@ -586,8 +587,8 @@ public ArmorStand(Vector3 position, Tag tag) { * * @return deserialized entity, or {@code null} if it was not a valid entity */ - public static Entity fromJson(JsonObject json) { - return new ArmorStand(json); + public static Collection fromJson(JsonObject json) { + return Collections.singleton(new ArmorStand(json)); } @Override public String[] partNames() { diff --git a/chunky/src/java/se/llbit/chunky/entity/BeaconBeam.java b/chunky/src/java/se/llbit/chunky/entity/BeaconBeam.java index 9df60b648..3569919ce 100644 --- a/chunky/src/java/se/llbit/chunky/entity/BeaconBeam.java +++ b/chunky/src/java/se/llbit/chunky/entity/BeaconBeam.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -226,8 +227,8 @@ public JsonValue toJson() { return json; } - public static BeaconBeam fromJson(JsonObject json) { - return new BeaconBeam(json); + public static Collection fromJson(JsonObject json) { + return Collections.singleton(new BeaconBeam(json)); } @Override diff --git a/chunky/src/java/se/llbit/chunky/entity/Book.java b/chunky/src/java/se/llbit/chunky/entity/Book.java index 5179d9f79..936368c63 100644 --- a/chunky/src/java/se/llbit/chunky/entity/Book.java +++ b/chunky/src/java/se/llbit/chunky/entity/Book.java @@ -1,6 +1,7 @@ package se.llbit.chunky.entity; import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; import se.llbit.chunky.PersistentSettings; @@ -295,8 +296,8 @@ public JsonValue toJson() { return json; } - public static Book fromJson(JsonObject json) { - return new Book(json); + public static Collection fromJson(JsonObject json) { + return Collections.singleton(new Book(json)); } @Override diff --git a/chunky/src/java/se/llbit/chunky/entity/CalibratedSculkSensorAmethyst.java b/chunky/src/java/se/llbit/chunky/entity/CalibratedSculkSensorAmethyst.java index b6fe4591e..4972c1c49 100644 --- a/chunky/src/java/se/llbit/chunky/entity/CalibratedSculkSensorAmethyst.java +++ b/chunky/src/java/se/llbit/chunky/entity/CalibratedSculkSensorAmethyst.java @@ -13,6 +13,7 @@ import se.llbit.util.JsonUtil; import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; public class CalibratedSculkSensorAmethyst extends Entity { @@ -112,8 +113,8 @@ public JsonValue toJson() { return json; } - public static Entity fromJson(JsonObject json) { - return new CalibratedSculkSensorAmethyst(json); + public static Collection fromJson(JsonObject json) { + return Collections.singleton(new CalibratedSculkSensorAmethyst(json)); } @Override diff --git a/chunky/src/java/se/llbit/chunky/entity/Campfire.java b/chunky/src/java/se/llbit/chunky/entity/Campfire.java index 36c843686..321d54a71 100644 --- a/chunky/src/java/se/llbit/chunky/entity/Campfire.java +++ b/chunky/src/java/se/llbit/chunky/entity/Campfire.java @@ -1,6 +1,7 @@ package se.llbit.chunky.entity; import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; import java.util.Random; @@ -328,8 +329,8 @@ public JsonValue toJson() { return json; } - public static Entity fromJson(JsonObject json) { - return new Campfire(json); + public static Collection fromJson(JsonObject json) { + return Collections.singleton(new Campfire(json)); } private static int getOrientationIndex(String facing) { diff --git a/chunky/src/java/se/llbit/chunky/entity/ChickenEntity.java b/chunky/src/java/se/llbit/chunky/entity/ChickenEntity.java index dd3c56357..93667d574 100644 --- a/chunky/src/java/se/llbit/chunky/entity/ChickenEntity.java +++ b/chunky/src/java/se/llbit/chunky/entity/ChickenEntity.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; public class ChickenEntity extends Entity implements Poseable, Variant { @@ -242,8 +243,8 @@ public JsonValue toJson() { return json; } - public static ChickenEntity fromJson(JsonObject json) { - return new ChickenEntity(json); + public static Collection fromJson(JsonObject json) { + return Collections.singleton(new ChickenEntity(json)); } @Override diff --git a/chunky/src/java/se/llbit/chunky/entity/CoralFanEntity.java b/chunky/src/java/se/llbit/chunky/entity/CoralFanEntity.java index 5b39a00c1..c25af23d1 100644 --- a/chunky/src/java/se/llbit/chunky/entity/CoralFanEntity.java +++ b/chunky/src/java/se/llbit/chunky/entity/CoralFanEntity.java @@ -30,6 +30,7 @@ import se.llbit.math.primitive.Primitive; import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; /** @@ -106,10 +107,10 @@ public CoralFanEntity(Vector3 position, String coralType) { return json; } - public static Entity fromJson(JsonObject json) { + public static Collection fromJson(JsonObject json) { Vector3 position = new Vector3(); position.fromJson(json.get("position").object()); - return new CoralFanEntity(position, json.get("coral_type").stringValue("tube")); + return Collections.singleton(new CoralFanEntity(position, json.get("coral_type").stringValue("tube"))); } diff --git a/chunky/src/java/se/llbit/chunky/entity/CowEntity.java b/chunky/src/java/se/llbit/chunky/entity/CowEntity.java index 5bc48d628..3a0eae756 100644 --- a/chunky/src/java/se/llbit/chunky/entity/CowEntity.java +++ b/chunky/src/java/se/llbit/chunky/entity/CowEntity.java @@ -17,6 +17,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; public class CowEntity extends Entity implements Poseable, Variant { @@ -287,8 +288,8 @@ public JsonValue toJson() { return json; } - public static CowEntity fromJson(JsonObject json) { - return new CowEntity(json); + public static Collection fromJson(JsonObject json) { + return Collections.singleton(new CowEntity(json)); } @Override diff --git a/chunky/src/java/se/llbit/chunky/entity/Entity.java b/chunky/src/java/se/llbit/chunky/entity/Entity.java index 291e454fa..243306e4f 100644 --- a/chunky/src/java/se/llbit/chunky/entity/Entity.java +++ b/chunky/src/java/se/llbit/chunky/entity/Entity.java @@ -71,7 +71,7 @@ public void loadDataFromOctree(Octree octree, BlockPalette palette, Vector3i ori * @param json json data. * @return unmarshalled entity, or {@code null} if it was not a valid entity. */ - public static Entity fromJson(JsonObject json) { + public static Collection fromJson(JsonObject json) { String kind = json.get("kind").stringValue(""); switch (kind) { case "painting": diff --git a/chunky/src/java/se/llbit/chunky/entity/FlameParticles.java b/chunky/src/java/se/llbit/chunky/entity/FlameParticles.java index 1f0945d20..7fa19f8eb 100644 --- a/chunky/src/java/se/llbit/chunky/entity/FlameParticles.java +++ b/chunky/src/java/se/llbit/chunky/entity/FlameParticles.java @@ -1,6 +1,7 @@ package se.llbit.chunky.entity; import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; import java.util.Random; import java.util.stream.StreamSupport; @@ -119,8 +120,8 @@ public JsonValue toJson() { return json; } - public static Entity fromJson(JsonObject json) { - return new FlameParticles(json); + public static Collection fromJson(JsonObject json) { + return Collections.singleton(new FlameParticles(json)); } @Override diff --git a/chunky/src/java/se/llbit/chunky/entity/HangingSignEntity.java b/chunky/src/java/se/llbit/chunky/entity/HangingSignEntity.java index 5c85ba9d5..9d970da59 100644 --- a/chunky/src/java/se/llbit/chunky/entity/HangingSignEntity.java +++ b/chunky/src/java/se/llbit/chunky/entity/HangingSignEntity.java @@ -15,6 +15,7 @@ import se.llbit.nbt.CompoundTag; import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; public class HangingSignEntity extends Entity { @@ -329,7 +330,7 @@ public JsonValue toJson() { /** * Unmarshalls a sign entity from JSON data. */ - public static Entity fromJson(JsonObject json) { + public static Collection fromJson(JsonObject json) { Vector3 position = new Vector3(); position.fromJson(json.get("position").object()); JsonArray[] frontText = null; @@ -347,7 +348,7 @@ public static Entity fromJson(JsonObject json) { boolean glowing = json.get("glowing").boolValue(false); SignEntity.Color backDye = SignEntity.Color.getFromDyedSign(json.get("backDye").stringValue(null)); boolean backGlowing = json.get("backGlowing").boolValue(false); - return new HangingSignEntity(position, frontText, dye, glowing, backText, backDye, backGlowing, direction, attached, material); + return Collections.singleton(new HangingSignEntity(position, frontText, dye, glowing, backText, backDye, backGlowing, direction, attached, material)); } public static Texture textureFromMaterial(String material) { diff --git a/chunky/src/java/se/llbit/chunky/entity/HeadEntity.java b/chunky/src/java/se/llbit/chunky/entity/HeadEntity.java index deec5532b..ef98f626a 100644 --- a/chunky/src/java/se/llbit/chunky/entity/HeadEntity.java +++ b/chunky/src/java/se/llbit/chunky/entity/HeadEntity.java @@ -193,14 +193,14 @@ public JsonValue toJson() { return json; } - public static Entity fromJson(JsonObject json) { + public static Collection fromJson(JsonObject json) { Vector3 position = new Vector3(); position.fromJson(json.get("position").object()); //int type = json.get("type").intValue(0); int rotation = json.get("rotation").intValue(0); int placement = json.get("placement").intValue(0); String skin = json.get("skin").stringValue(""); - return new HeadEntity(position, skin, rotation, placement); + return Collections.singleton(new HeadEntity(position, skin, rotation, placement)); } diff --git a/chunky/src/java/se/llbit/chunky/entity/Lectern.java b/chunky/src/java/se/llbit/chunky/entity/Lectern.java index c2ab652e5..4bbfa35fc 100644 --- a/chunky/src/java/se/llbit/chunky/entity/Lectern.java +++ b/chunky/src/java/se/llbit/chunky/entity/Lectern.java @@ -1,7 +1,10 @@ package se.llbit.chunky.entity; +import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; +import java.util.List; + import se.llbit.chunky.model.Model; import se.llbit.chunky.resources.Texture; import se.llbit.chunky.world.material.TextureMaterial; @@ -14,7 +17,7 @@ import se.llbit.math.primitive.Primitive; import se.llbit.util.JsonUtil; -public class Lectern extends Entity implements Poseable { +public class Lectern extends Entity { private static final Quad[] quadsNorth = new Quad[]{ new Quad( @@ -145,28 +148,25 @@ public class Lectern extends Entity implements Poseable { }; private final String facing; - private final Book book; - public Lectern(Vector3 position, String facing, boolean hasBook) { + public Lectern(Vector3 position, String facing) { super(position); this.facing = facing; - if (hasBook) { - this.book = createBookEntity(position, facing); - } else { - this.book = null; - } } public Lectern(JsonObject json) { super(JsonUtil.vec3FromJsonObject(json.get("position"))); this.facing = json.get("facing").stringValue("north"); - if (json.get("book").isObject()) { - this.book = Book.fromJson(json.get("book").object()); - } else if (json.get("hasBook").asBoolean(false)) { - this.book = createBookEntity(getPosition(), facing); - } else { - this.book = null; + } + + public static Collection create(Vector3 position, String facing, boolean hasBook) { + List entities = new ArrayList<>(); + + entities.add(new se.llbit.chunky.entity.Lectern(position, facing)); + if (hasBook) { + entities.add(createBookEntity(position, facing)); } + return entities; } @Override @@ -184,10 +184,6 @@ public Collection primitives(Vector3 offset) { transform); } - if (book != null) { - faces.addAll(book.primitives(offset)); - } - return faces; } @@ -197,22 +193,21 @@ public JsonValue toJson() { json.add("kind", "lectern"); json.add("position", position.toJson()); json.add("facing", facing); - if (book != null) { - json.add("book", book.toJson()); - } return json; } - public Book getBook() { - return book; - } + public static Collection fromJson(JsonObject json) { + Lectern lectern = new Lectern(json); - public boolean hasBook() { - return book != null; - } + Collection entities = new ArrayList<>(); + entities.add(lectern); + if (json.get("book").isObject()) { // we still get the book from the lectern json to be compatible with the old format + entities.addAll(Book.fromJson(json.get("book").object())); + } else if (json.get("hasBook").asBoolean(false)) { + entities.add(createBookEntity(lectern.getPosition(), lectern.facing)); + } - public static Entity fromJson(JsonObject json) { - return new Lectern(json); + return entities; } private static int getOrientationIndex(String facing) { @@ -274,31 +269,4 @@ private static Book createBookEntity(Vector3 position, String facing) { return book; } - - @Override - public String[] partNames() { - return book != null ? book.partNames() : new String[0]; - } - - @Override - public double getScale() { - return book != null ? book.getScale() : 1; - } - - @Override - public void setScale(double value) { - if (book != null) { - book.setScale(value); - } - } - - @Override - public JsonObject getPose() { - return book != null ? book.getPose() : null; - } - - @Override - public boolean hasHead() { - return false; - } } diff --git a/chunky/src/java/se/llbit/chunky/entity/LilyPadEntity.java b/chunky/src/java/se/llbit/chunky/entity/LilyPadEntity.java index 1c934094b..d28e84da8 100644 --- a/chunky/src/java/se/llbit/chunky/entity/LilyPadEntity.java +++ b/chunky/src/java/se/llbit/chunky/entity/LilyPadEntity.java @@ -27,6 +27,7 @@ import se.llbit.util.MinecraftPRNG; import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; public class LilyPadEntity extends Entity { @@ -89,11 +90,11 @@ public LilyPadEntity(Vector3 position, int rotation) { /** * Unmarshall a lily pad entity from JSON data. */ - public static Entity fromJson(JsonObject json) { + public static Collection fromJson(JsonObject json) { Vector3 position = new Vector3(); position.fromJson(json.get("position").object()); int rotation = json.get("rotation").intValue(0); - return new LilyPadEntity(position, rotation); + return Collections.singleton(new LilyPadEntity(position, rotation)); } } diff --git a/chunky/src/java/se/llbit/chunky/entity/MooshroomEntity.java b/chunky/src/java/se/llbit/chunky/entity/MooshroomEntity.java index 7c03e6ac9..95af679b2 100644 --- a/chunky/src/java/se/llbit/chunky/entity/MooshroomEntity.java +++ b/chunky/src/java/se/llbit/chunky/entity/MooshroomEntity.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; public class MooshroomEntity extends Entity implements Poseable, Variant { @@ -257,8 +258,8 @@ public JsonValue toJson() { return json; } - public static MooshroomEntity fromJson(JsonObject json) { - return new MooshroomEntity(json); + public static Collection fromJson(JsonObject json) { + return Collections.singleton(new MooshroomEntity(json)); } @Override diff --git a/chunky/src/java/se/llbit/chunky/entity/PaintingEntity.java b/chunky/src/java/se/llbit/chunky/entity/PaintingEntity.java index fb86e1571..55fc6f09d 100644 --- a/chunky/src/java/se/llbit/chunky/entity/PaintingEntity.java +++ b/chunky/src/java/se/llbit/chunky/entity/PaintingEntity.java @@ -27,6 +27,7 @@ import se.llbit.math.primitive.Primitive; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; @@ -146,12 +147,12 @@ public JsonValue toJson() { * * @return deserialized entity, or {@code null} if it was not a valid entity */ - public static Entity fromJson(JsonObject json) { + public static Collection fromJson(JsonObject json) { Vector3 position = new Vector3(); position.fromJson(json.get("position").object()); String art = json.get("art").stringValue(""); double angle = json.get("angle").doubleValue(0.0); - return new PaintingEntity(position, art, angle); + return Collections.singleton(new PaintingEntity(position, art, angle)); } public static void resetPaintings() { diff --git a/chunky/src/java/se/llbit/chunky/entity/PigEntity.java b/chunky/src/java/se/llbit/chunky/entity/PigEntity.java index d0de10967..a61ae833b 100644 --- a/chunky/src/java/se/llbit/chunky/entity/PigEntity.java +++ b/chunky/src/java/se/llbit/chunky/entity/PigEntity.java @@ -17,6 +17,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; public class PigEntity extends Entity implements Poseable, Variant, Saddleable { @@ -225,8 +226,8 @@ public JsonValue toJson() { return json; } - public static PigEntity fromJson(JsonObject json) { - return new PigEntity(json); + public static Collection fromJson(JsonObject json) { + return Collections.singleton(new PigEntity(json)); } @Override diff --git a/chunky/src/java/se/llbit/chunky/entity/PlayerEntity.java b/chunky/src/java/se/llbit/chunky/entity/PlayerEntity.java index 5bd97a02f..2774d8905 100644 --- a/chunky/src/java/se/llbit/chunky/entity/PlayerEntity.java +++ b/chunky/src/java/se/llbit/chunky/entity/PlayerEntity.java @@ -905,8 +905,8 @@ private static TextureLoader leatherTexture(String id, int color, Texture textur new ColoredTexture(textureName, color, texture)); } - public static PlayerEntity fromJson(JsonObject json) { - return new PlayerEntity(json); + public static Collection fromJson(JsonObject json) { + return Collections.singleton(new PlayerEntity(json)); } @Override diff --git a/chunky/src/java/se/llbit/chunky/entity/SheepEntity.java b/chunky/src/java/se/llbit/chunky/entity/SheepEntity.java index 62c989995..c40cf3170 100644 --- a/chunky/src/java/se/llbit/chunky/entity/SheepEntity.java +++ b/chunky/src/java/se/llbit/chunky/entity/SheepEntity.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; public class SheepEntity extends Entity implements Poseable, Dyeable { @@ -371,8 +372,8 @@ public JsonValue toJson() { return json; } - public static SheepEntity fromJson(JsonObject json) { - return new SheepEntity(json); + public static Collection fromJson(JsonObject json) { + return Collections.singleton(new SheepEntity(json)); } @Override diff --git a/chunky/src/java/se/llbit/chunky/entity/SignEntity.java b/chunky/src/java/se/llbit/chunky/entity/SignEntity.java index 4ccbe059f..2bbeb7270 100644 --- a/chunky/src/java/se/llbit/chunky/entity/SignEntity.java +++ b/chunky/src/java/se/llbit/chunky/entity/SignEntity.java @@ -33,10 +33,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.Map; +import java.util.*; public class SignEntity extends Entity { @@ -570,7 +567,7 @@ public JsonValue toJson() { /** * Unmarshalls a sign entity from JSON data. */ - public static Entity fromJson(JsonObject json) { + public static Collection fromJson(JsonObject json) { Vector3 position = new Vector3(); position.fromJson(json.get("position").object()); JsonArray[] frontText = null; @@ -587,7 +584,7 @@ public static Entity fromJson(JsonObject json) { boolean glowing = json.get("glowing").boolValue(false); Color backDye = Color.getFromDyedSign(json.get("backDye").stringValue(null)); boolean backGlowing = json.get("backGlowing").boolValue(false); - return new SignEntity(position, frontText, dye, glowing, backText, backDye, backGlowing, direction, material); + return Collections.singleton(new SignEntity(position, frontText, dye, glowing, backText, backDye, backGlowing, direction, material)); } /** diff --git a/chunky/src/java/se/llbit/chunky/entity/SkullEntity.java b/chunky/src/java/se/llbit/chunky/entity/SkullEntity.java index 9800b64b2..f37a83fbe 100644 --- a/chunky/src/java/se/llbit/chunky/entity/SkullEntity.java +++ b/chunky/src/java/se/llbit/chunky/entity/SkullEntity.java @@ -33,6 +33,7 @@ import se.llbit.math.primitive.Primitive; import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; /** @@ -298,12 +299,12 @@ public JsonValue toJson() { return json; } - public static Entity fromJson(JsonObject json) { + public static Collection fromJson(JsonObject json) { Vector3 position = new Vector3(); position.fromJson(json.get("position").object()); Kind type = Kind.values()[json.get("type").intValue(0)]; int rotation = json.get("rotation").intValue(0); int placement = json.get("placement").intValue(0); - return new SkullEntity(position, type, rotation, placement); + return Collections.singleton(new SkullEntity(position, type, rotation, placement)); } } diff --git a/chunky/src/java/se/llbit/chunky/entity/SporeBlossom.java b/chunky/src/java/se/llbit/chunky/entity/SporeBlossom.java index 470e0736d..dc39bf071 100644 --- a/chunky/src/java/se/llbit/chunky/entity/SporeBlossom.java +++ b/chunky/src/java/se/llbit/chunky/entity/SporeBlossom.java @@ -5,6 +5,8 @@ import se.llbit.chunky.resources.Texture; import se.llbit.chunky.world.Material; import se.llbit.chunky.world.material.TextureMaterial; +import java.util.Collections; + import se.llbit.json.JsonObject; import se.llbit.json.JsonValue; import se.llbit.math.Transform; @@ -37,7 +39,7 @@ public JsonValue toJson() { return json; } - public static Entity fromJson(JsonObject json) { - return new SporeBlossom(json); + public static Collection fromJson(JsonObject json) { + return Collections.singleton(new SporeBlossom(json)); } } diff --git a/chunky/src/java/se/llbit/chunky/entity/SquidEntity.java b/chunky/src/java/se/llbit/chunky/entity/SquidEntity.java index 1d879da28..0315fe157 100644 --- a/chunky/src/java/se/llbit/chunky/entity/SquidEntity.java +++ b/chunky/src/java/se/llbit/chunky/entity/SquidEntity.java @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; public class SquidEntity extends Entity implements Poseable { @@ -188,8 +189,8 @@ public JsonValue toJson() { return json; } - public static SquidEntity fromJson(JsonObject json) { - return new SquidEntity(json); + public static Collection fromJson(JsonObject json) { + return Collections.singleton(new SquidEntity(json)); } @Override diff --git a/chunky/src/java/se/llbit/chunky/entity/StandingBanner.java b/chunky/src/java/se/llbit/chunky/entity/StandingBanner.java index e8badb5e4..30af4e588 100644 --- a/chunky/src/java/se/llbit/chunky/entity/StandingBanner.java +++ b/chunky/src/java/se/llbit/chunky/entity/StandingBanner.java @@ -35,6 +35,7 @@ import se.llbit.util.NbtUtil; import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; /** @@ -211,11 +212,11 @@ public JsonValue toJson() { return json; } - public static Entity fromJson(JsonObject json) { + public static Collection fromJson(JsonObject json) { Vector3 position = new Vector3(); position.fromJson(json.get("position").object()); int rotation = json.get("rotation").intValue(0); - return new StandingBanner(position, rotation, json.get("design").object()); + return Collections.singleton(new StandingBanner(position, rotation, json.get("design").object())); } public static Material getBannerTexture(JsonObject design) { diff --git a/chunky/src/java/se/llbit/chunky/entity/WallBanner.java b/chunky/src/java/se/llbit/chunky/entity/WallBanner.java index d432ccd19..bec443b89 100644 --- a/chunky/src/java/se/llbit/chunky/entity/WallBanner.java +++ b/chunky/src/java/se/llbit/chunky/entity/WallBanner.java @@ -29,6 +29,7 @@ import se.llbit.nbt.CompoundTag; import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; /** @@ -143,10 +144,10 @@ public WallBanner(Vector3 position, int rotation, CompoundTag entityTag) { return json; } - public static Entity fromJson(JsonObject json) { + public static Collection fromJson(JsonObject json) { Vector3 position = new Vector3(); position.fromJson(json.get("position").object()); int rotation = json.get("rotation").intValue(0); - return new WallBanner(position, rotation, json.get("design").object()); + return Collections.singleton(new WallBanner(position, rotation, json.get("design").object())); } } diff --git a/chunky/src/java/se/llbit/chunky/entity/WallCoralFanEntity.java b/chunky/src/java/se/llbit/chunky/entity/WallCoralFanEntity.java index c779bf802..014056649 100644 --- a/chunky/src/java/se/llbit/chunky/entity/WallCoralFanEntity.java +++ b/chunky/src/java/se/llbit/chunky/entity/WallCoralFanEntity.java @@ -31,6 +31,7 @@ import se.llbit.math.primitive.Primitive; import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; /** @@ -104,11 +105,11 @@ public WallCoralFanEntity(Vector3 position, String coralType, String facing) { return json; } - public static Entity fromJson(JsonObject json) { + public static Collection fromJson(JsonObject json) { Vector3 position = new Vector3(); position.fromJson(json.get("position").object()); String coralType = json.get("coral_type").stringValue("tube"); String facing = json.get("facing").stringValue("north"); - return new WallCoralFanEntity(position, coralType, facing); + return Collections.singleton(new WallCoralFanEntity(position, coralType, facing)); } } diff --git a/chunky/src/java/se/llbit/chunky/entity/WallHangingSignEntity.java b/chunky/src/java/se/llbit/chunky/entity/WallHangingSignEntity.java index ab2b75f2a..264c2afaf 100644 --- a/chunky/src/java/se/llbit/chunky/entity/WallHangingSignEntity.java +++ b/chunky/src/java/se/llbit/chunky/entity/WallHangingSignEntity.java @@ -16,6 +16,7 @@ import se.llbit.nbt.CompoundTag; import java.util.Collection; +import java.util.Collections; import java.util.LinkedHashSet; public class WallHangingSignEntity extends Entity { @@ -307,7 +308,7 @@ public JsonValue toJson() { /** * Unmarshalls a sign entity from JSON data. */ - public static Entity fromJson(JsonObject json) { + public static Collection fromJson(JsonObject json) { Vector3 position = new Vector3(); position.fromJson(json.get("position").object()); JsonArray[] frontText = null; @@ -324,6 +325,6 @@ public static Entity fromJson(JsonObject json) { boolean glowing = json.get("glowing").boolValue(false); SignEntity.Color backDye = SignEntity.Color.getFromDyedSign(json.get("backDye").stringValue(null)); boolean backGlowing = json.get("backGlowing").boolValue(false); - return new WallHangingSignEntity(position, frontText, dye, glowing, backText, backDye, backGlowing, direction, material); + return Collections.singleton(new WallHangingSignEntity(position, frontText, dye, glowing, backText, backDye, backGlowing, direction, material)); } } diff --git a/chunky/src/java/se/llbit/chunky/entity/WallSignEntity.java b/chunky/src/java/se/llbit/chunky/entity/WallSignEntity.java index 336b94965..9cbd88aa6 100644 --- a/chunky/src/java/se/llbit/chunky/entity/WallSignEntity.java +++ b/chunky/src/java/se/llbit/chunky/entity/WallSignEntity.java @@ -33,6 +33,7 @@ import java.util.Collection; import java.util.LinkedList; +import java.util.Collections; public class WallSignEntity extends Entity { @@ -154,7 +155,7 @@ public JsonValue toJson() { /** * Unmarshalls a wall sign entity from JSON data. */ - public static Entity fromJson(JsonObject json) { + public static Collection fromJson(JsonObject json) { Vector3 position = new Vector3(); position.fromJson(json.get("position").object()); JsonArray[] text = null; @@ -165,6 +166,6 @@ public static Entity fromJson(JsonObject json) { String material = json.get("material").stringValue("oak"); SignEntity.Color dye = SignEntity.Color.getFromDyedSign(json.get("dye").stringValue(null)); boolean glowing = json.get("glowing").boolValue(false); - return new WallSignEntity(position, text, dye, glowing, direction, material); + return Collections.singleton(new WallSignEntity(position, text, dye, glowing, direction, material)); } } diff --git a/chunky/src/java/se/llbit/chunky/model/minecraft/DecoratedPotModel.java b/chunky/src/java/se/llbit/chunky/model/minecraft/DecoratedPotModel.java index 63bcfadc6..66af45f92 100644 --- a/chunky/src/java/se/llbit/chunky/model/minecraft/DecoratedPotModel.java +++ b/chunky/src/java/se/llbit/chunky/model/minecraft/DecoratedPotModel.java @@ -34,6 +34,7 @@ import se.llbit.util.JsonUtil; import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; public class DecoratedPotModel extends TopBottomOrientedTexturedBlockModel { @@ -156,11 +157,11 @@ public Collection primitives(Vector3 offset) { return primitives; } - public static Entity fromJson(JsonObject json) { - return new DecoratedPotSpoutEntity( + public static Collection fromJson(JsonObject json) { + return Collections.singleton(new DecoratedPotSpoutEntity( JsonUtil.vec3FromJsonObject(json.get("position")), json.get("facing").stringValue("north") - ); + )); } @Override diff --git a/chunky/src/java/se/llbit/chunky/renderer/scene/Scene.java b/chunky/src/java/se/llbit/chunky/renderer/scene/Scene.java index 061c76da3..969fb5109 100644 --- a/chunky/src/java/se/llbit/chunky/renderer/scene/Scene.java +++ b/chunky/src/java/se/llbit/chunky/renderer/scene/Scene.java @@ -1001,33 +1001,35 @@ public synchronized void loadChunks(TaskTracker taskTracker, World world, Map entitiesFromBlock = block.createEntities(position); - if (entities.shouldLoad(entity)) { - if (entity instanceof Poseable && !(entity instanceof Lectern && !((Lectern) entity).hasBook())) { - entities.addActor(entity); - } else { - entities.addEntity(entity); - if (emitterGrid != null) { - for (Grid.EmitterPosition emitterPos : entity.getEmitterPosition()) { - emitterPos.x -= origin.x; - emitterPos.y -= origin.y; - emitterPos.z -= origin.z; - emitterGrid.addEmitter(emitterPos); + for (Entity entity : entitiesFromBlock) { + if (entities.shouldLoad(entity)) { + if (entity instanceof Poseable) { + entities.addActor(entity); + } else { + entities.addEntity(entity); + if (emitterGrid != null) { + for (Grid.EmitterPosition emitterPos : entity.getEmitterPosition()) { + emitterPos.x -= origin.x; + emitterPos.y -= origin.y; + emitterPos.z -= origin.z; + emitterGrid.addEmitter(emitterPos); + } } } } + } - if (!block.isBlockWithEntity()) { - if (block.waterlogged) { - block = palette.water; - octNode = palette.waterId; - } else { - block = Air.INSTANCE; - octNode = palette.airId; - } + if (block.isReplacedByEntities()) { + if (block.waterlogged) { + block = palette.water; + octNode = palette.waterId; + } else { + block = Air.INSTANCE; + octNode = palette.airId; } } } @@ -1189,7 +1191,7 @@ public synchronized void loadChunks(TaskTracker taskTracker, World world, Map entity = Entity.fromJson(element.object()); if (entity != null) { if (entity instanceof PlayerEntity) { - actors.add(entity); + actors.addAll(entity); } else { - entities.add(entity); + entities.addAll(entity); } } } for (JsonValue element : json.get("actors").array()) { - Entity entity = Entity.fromJson(element.object()); - actors.add(entity); + Collection entity = Entity.fromJson(element.object()); + actors.addAll(entity); } } diff --git a/chunky/src/java/se/llbit/chunky/ui/render/tabs/EntitiesTab.java b/chunky/src/java/se/llbit/chunky/ui/render/tabs/EntitiesTab.java index 5b58605e5..e313c9b59 100644 --- a/chunky/src/java/se/llbit/chunky/ui/render/tabs/EntitiesTab.java +++ b/chunky/src/java/se/llbit/chunky/ui/render/tabs/EntitiesTab.java @@ -90,7 +90,7 @@ public class EntitiesTab extends ScrollPane implements RenderControlsTab, Initia return player; }); entityTypes.put("Armor stand", (position, scene) -> new ArmorStand(position, new CompoundTag())); - entityTypes.put("Lectern", (position, scene) -> new Lectern(position, "north", true)); + entityTypes.put("Lectern", (position, scene) -> new Lectern(position, "north")); entityTypes.put("Book", (position, scene) -> new Book(position, Math.PI - Math.PI / 16, Math.toRadians(30), Math.toRadians(180 - 30))); entityTypes.put("Beacon beam", (position, scene) -> new BeaconBeam(position)); entityTypes.put("Sheep", (position, scene) -> new SheepEntity(position, new CompoundTag())); @@ -298,15 +298,9 @@ private void updateEntity(Entity entity) { controls.getChildren().addAll(modelBox, skinBox, layerBox); } - else if (entity instanceof Book || entity instanceof Lectern) { - Book book; - if (entity instanceof Lectern) { - book = ((Lectern) entity).getBook(); - } else { - book = (Book) entity; - } + else if (entity instanceof Book) { + Book book = (Book) entity; - if (book != null) { DoubleAdjuster openingAngle = new DoubleAdjuster(); openingAngle.setName("Opening angle"); openingAngle.setTooltip("Modifies the book's opening angle."); @@ -339,7 +333,6 @@ else if (entity instanceof Book || entity instanceof Lectern) { scene.rebuildActorBvh(); }); controls.getChildren().add(page2Angle); - } } else if (entity instanceof BeaconBeam) { BeaconBeam beam = (BeaconBeam) entity;