Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 47 additions & 11 deletions chunky/src/java/se/llbit/chunky/block/Block.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -99,31 +100,66 @@ 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.
* <p>
* 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).
* <p>
* 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.
* <p>
* 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<Entity> 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()} returns true).
* <p>
* 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;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ 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));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,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));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public Banner(String name, Texture texture, int rotation, BannerDesign.Color col
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);
Expand Down
6 changes: 3 additions & 3 deletions chunky/src/java/se/llbit/chunky/block/minecraft/Beacon.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ public Beacon() {
}

@Override
public boolean isBlockWithEntity() {
return true;
public boolean isReplacedByEntities() {
return false;
}

@Override
Expand All @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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<Entity> createEntities(Vector3 position) {
return Collections.singleton(new FlameParticles(position, entity));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<Entity> createEntities(Vector3 position) {
return Collections.singleton(new CalibratedSculkSensorAmethyst(position, this.facing, isActive(), this));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public boolean isBlockEntity() {
}

@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);
}

Expand Down
14 changes: 8 additions & 6 deletions chunky/src/java/se/llbit/chunky/block/minecraft/Candle.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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<Entity> 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]));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
import se.llbit.math.Ray;
import se.llbit.math.Vector3;

import java.util.Collection;
import java.util.Collections;

public class CopperGolemStatue extends MinecraftBlockTranslucent {
private final String facing;
private final String pose;
Expand Down Expand Up @@ -36,14 +39,14 @@ public boolean intersect(Ray ray, Scene scene) {
}

@Override
public boolean isEntity() {
public boolean hasEntities() {
return true;
}

@Override
public Entity toEntity(Vector3 position) {
public Collection<Entity> createEntities(Vector3 position) {
position = new Vector3(position);
position.add(0.5, 0, 0.5);
return new CopperGolemStatueEntity(position, pose, facing, oxidation);
return Collections.singleton(new CopperGolemStatueEntity(position, pose, facing, oxidation));
}
}
9 changes: 6 additions & 3 deletions chunky/src/java/se/llbit/chunky/block/minecraft/CoralFan.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -68,11 +71,11 @@ public static Texture coralTexture(String coralType) {
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<Entity> createEntities(Vector3 position) {
return Collections.singleton(new CoralFanEntity(position, coralType));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public boolean isModifiedByBlockEntity() {
}

@Override
public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) {
public Entity createBlockEntity(Vector3 position, CompoundTag entityTag) {
return new DecoratedPotModel.DecoratedPotSpoutEntity(position, facing);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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<Entity> createEntities(Vector3 position) {
Vector3 newPosition = new Vector3(position);
newPosition.add(0, 0.35, 0);
Book book = new Book(
Expand All @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,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);
}
}
10 changes: 6 additions & 4 deletions chunky/src/java/se/llbit/chunky/block/minecraft/Head.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -62,13 +64,13 @@ public String 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<Entity> createEntities(Vector3 position) {
return Collections.singleton(new SkullEntity(position, type, rotation, 1));
}

@Override
Expand All @@ -77,7 +79,7 @@ public boolean isBlockEntity() {
}

@Override
public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) {
public Entity createBlockEntity(Vector3 position, CompoundTag entityTag) {
if (type == Kind.PLAYER) {
try {
String textureUrl = getTextureUrl(entityTag);
Expand Down
Loading
Loading