Skip to content

Commit

Permalink
Add the pitcher crop and calibrated sculk sensor. (chunky-dev#1608)
Browse files Browse the repository at this point in the history
* Add the pitcher crop block.

* Add calibrated sculk sensor.

* Fix inconsistencies in the pitcher crop top model.

* Fix inactive amethyst emitting light by default.
  • Loading branch information
leMaik committed Sep 9, 2023
1 parent 4c0cbe2 commit 0591621
Show file tree
Hide file tree
Showing 12 changed files with 945 additions and 11 deletions.
43 changes: 43 additions & 0 deletions chunky/src/java/se/llbit/chunky/block/CalibratedSculkSensor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package se.llbit.chunky.block;

import se.llbit.chunky.entity.CalibratedSculkSensorAmethyst;
import se.llbit.chunky.entity.Entity;
import se.llbit.chunky.model.CalibratedSculkSensorModel;
import se.llbit.chunky.resources.Texture;
import se.llbit.math.Vector3;

public class CalibratedSculkSensor extends AbstractModelBlock {
private final String phase;
private final String facing;

public CalibratedSculkSensor(String phase, String facing) {
super("calibrated_sculk_sensor", Texture.calibratedSculkSensorTop);
this.phase = phase;
this.facing = facing;
this.model = new CalibratedSculkSensorModel(isActive(), facing);
}

public boolean isActive() {
return phase.equals("active") || phase.equals("cooldown");
}

@Override
public String description() {
return "sculk_sensor_phase=" + phase + ", facing=" + facing;
}

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

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

@Override
public Entity toEntity(Vector3 position) {
return new CalibratedSculkSensorAmethyst(position, this.facing, isActive(), this);
}
}
11 changes: 11 additions & 0 deletions chunky/src/java/se/llbit/chunky/block/MinecraftBlockProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -1037,6 +1037,17 @@ private static void addBlocks(Texture texture, String... names) {
addBlock("sniffer_egg", (name, tag) -> new SnifferEgg(name, BlockProvider.stringToInt(tag.get("Properties").get("hatch"), 0)));
addBlock("pink_petals", (name, tag) -> new PinkPetals(name, BlockProvider.stringToInt(tag.get("Properties").get("flower_amount"), 1), BlockProvider.facing(tag)));
addBlock("pitcher_plant", (name, tag) -> new PitcherPlant(name, tag.get("Properties").get("half").stringValue("lower")));
addBlock("pitcher_crop", (name, tag) -> {
int age = BlockProvider.stringToInt(tag.get("Properties").get("age"), 0);
String half = tag.get("Properties").get("half").stringValue("lower");
if (half.equals("upper") && age < 2) {
return Air.INSTANCE;
}
return new PitcherCrop(age, half);
});
addBlock("calibrated_sculk_sensor", (name, tag) -> new CalibratedSculkSensor(
tag.get("Properties").get("sculk_sensor_phase").stringValue("cooldown"),
tag.get("Properties").get("facing").stringValue("north")));
}

@Override
Expand Down
24 changes: 24 additions & 0 deletions chunky/src/java/se/llbit/chunky/block/PitcherCrop.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package se.llbit.chunky.block;

import se.llbit.chunky.model.PitcherCropBottomModel;
import se.llbit.chunky.model.PitcherCropTopModel;
import se.llbit.chunky.resources.Texture;

public class PitcherCrop extends AbstractModelBlock {
private final String description;

public PitcherCrop(int age, String half) {
super("pitcher_crop", Texture.pitcherCropTop);
localIntersect = true;
opaque = false;
this.model = half.equals("upper")
? new PitcherCropTopModel(age)
: new PitcherCropBottomModel(age);
this.description = String.format("age=%d, half=%s", age, half);
}

@Override
public String description() {
return description;
}
}
1 change: 0 additions & 1 deletion chunky/src/java/se/llbit/chunky/block/SculkSensor.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import se.llbit.chunky.resources.Texture;

public class SculkSensor extends AbstractModelBlock {

private final String phase;

public SculkSensor(String phase) {
Expand Down
5 changes: 5 additions & 0 deletions chunky/src/java/se/llbit/chunky/chunk/BlockPalette.java
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,11 @@ public static Map<String, Consumer<Block>> getDefaultMaterialProperties() {
block.emittance = 1.0f / 15f;
}
});
materialProperties.put("minecraft:calibrated_sculk_sensor", block -> {
if (block instanceof CalibratedSculkSensor && ((CalibratedSculkSensor) block).isActive()) {
block.emittance = 1.0f / 15f;
}
});
materialProperties.put("minecraft:glow_lichen", block -> {
block.emittance = 1.0f / 15f * 7;
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package se.llbit.chunky.entity;

import se.llbit.chunky.block.CalibratedSculkSensor;
import se.llbit.chunky.model.Model;
import se.llbit.chunky.resources.Texture;
import se.llbit.chunky.world.Material;
import se.llbit.chunky.world.material.TextureMaterial;
import se.llbit.json.JsonObject;
import se.llbit.json.JsonValue;
import se.llbit.log.Log;
import se.llbit.math.*;
import se.llbit.math.primitive.Primitive;
import se.llbit.util.JsonUtil;

import java.util.Collection;
import java.util.LinkedList;

public class CalibratedSculkSensorAmethyst extends Entity {
private static final Quad[] quadsNorth = Model.join(
Model.rotateY(
new Quad[]{
new Quad(
new Vector3(8 / 16.0, 20 / 16.0, 16 / 16.0),
new Vector3(8 / 16.0, 20 / 16.0, 0 / 16.0),
new Vector3(8 / 16.0, 8 / 16.0, 16 / 16.0),
new Vector4(16 / 16.0, 0 / 16.0, 12 / 16.0, 0 / 16.0)
),
new Quad(
new Vector3(8 / 16.0, 20 / 16.0, 0 / 16.0),
new Vector3(8 / 16.0, 20 / 16.0, 16 / 16.0),
new Vector3(8 / 16.0, 8 / 16.0, 0 / 16.0),
new Vector4(16 / 16.0, 0 / 16.0, 12 / 16.0, 0 / 16.0)
)
},
Math.toRadians(45)
),
Model.rotateY(
new Quad[]{
new Quad(
new Vector3(0 / 16.0, 20 / 16.0, 8 / 16.0),
new Vector3(16 / 16.0, 20 / 16.0, 8 / 16.0),
new Vector3(0 / 16.0, 8 / 16.0, 8 / 16.0),
new Vector4(16 / 16.0, 0 / 16.0, 12 / 16.0, 0 / 16.0)
),
new Quad(
new Vector3(16 / 16.0, 20 / 16.0, 8 / 16.0),
new Vector3(0 / 16.0, 20 / 16.0, 8 / 16.0),
new Vector3(16 / 16.0, 8 / 16.0, 8 / 16.0),
new Vector4(16 / 16.0, 0 / 16.0, 12 / 16.0, 0 / 16.0)
)
},
Math.toRadians(45)
)
);
private static final Quad[] quadsEast = Model.rotateY(quadsNorth);
private static final Quad[] quadsSouth = Model.rotateY(quadsEast);
private static final Quad[] quadsWest = Model.rotateNegY(quadsNorth);

private final String facing;
private final boolean active;
private final CalibratedSculkSensor block;

public static final Material activeMaterial = new TextureMaterial(Texture.calibratedSculkSensorAmethyst);
public static final Material inactiveMaterial = new TextureMaterial(Texture.calibratedSculkSensorAmethyst);

public CalibratedSculkSensorAmethyst(Vector3 position, String facing, boolean active, CalibratedSculkSensor block) {
super(position);
this.facing = facing;
this.active = active;
this.block = block;
}

public CalibratedSculkSensorAmethyst(JsonObject json) {
super(JsonUtil.vec3FromJsonObject(json.get("position")));
this.facing = json.get("facing").stringValue("north");
this.active = json.get("active").boolValue(true);
this.block = null;
}

@Override
public Collection<Primitive> primitives(Vector3 offset) {
Collection<Primitive> faces = new LinkedList<>();
Transform transform = Transform.NONE
.translate(position.x + offset.x, position.y + offset.y, position.z + offset.z);

Quad[] quads;
if (facing.equals("east")) {
quads = quadsEast;
} else if (facing.equals("south")) {
quads = quadsSouth;
} else if (facing.equals("west")) {
quads = quadsWest;
} else {
quads = quadsNorth;
}

Material material = active ? activeMaterial : inactiveMaterial;
for (Quad quad : quads) {
quad.addTriangles(faces, material, transform);
}

return faces;
}

@Override
public JsonValue toJson() {
JsonObject json = new JsonObject();
json.add("kind", "calibratedSculkSensorAmethyst");
json.add("position", position.toJson());
json.add("facing", facing);
json.add("active", active);
return json;
}

public static Entity fromJson(JsonObject json) {
return new CalibratedSculkSensorAmethyst(json);
}

@Override
public Grid.EmitterPosition[] getEmitterPosition() {
if (block == null) {
Log.warn("Attempted to build emitter grid from unassociated campfire entity.");
return new Grid.EmitterPosition[0];
}

if (active) {
Grid.EmitterPosition[] pos = new Grid.EmitterPosition[1];
pos[0] = new Grid.EmitterPosition((int) position.x, (int) position.y, (int) position.z, block);
return pos;
} else {
return new Grid.EmitterPosition[0];
}
}
}
18 changes: 11 additions & 7 deletions chunky/src/java/se/llbit/chunky/entity/Entity.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@
*/
package se.llbit.chunky.entity;

import java.util.Collection;

import se.llbit.chunky.PersistentSettings;
import se.llbit.chunky.chunk.BlockPalette;
import se.llbit.chunky.model.DecoratedPotModel;
import se.llbit.json.JsonObject;
Expand All @@ -30,6 +27,8 @@
import se.llbit.math.Vector3i;
import se.llbit.math.primitive.Primitive;

import java.util.Collection;

/**
* Represents Minecraft entities that are not stored in the octree.
*
Expand All @@ -45,16 +44,19 @@ protected Entity(Vector3 position) {

abstract public Collection<Primitive> primitives(Vector3 offset);

public Grid.EmitterPosition[] getEmitterPosition() { return new Grid.EmitterPosition[0]; }
public Grid.EmitterPosition[] getEmitterPosition() {
return new Grid.EmitterPosition[0];
}

/**
* Called on every entity in a scene to allow it to load it's data from other blocks in the Octree.
*
* @param octree The scene's worldOctree
* @param octree The scene's worldOctree
* @param palette The scene's block palate
* @param origin The Octree's origin
* @param origin The Octree's origin
*/
public void loadDataFromOctree(Octree octree, BlockPalette palette, Vector3i origin) {}
public void loadDataFromOctree(Octree octree, BlockPalette palette, Vector3i origin) {
}

/**
* Marshalls this entity to JSON.
Expand Down Expand Up @@ -110,6 +112,8 @@ public static Entity fromJson(JsonObject json) {
return SporeBlossom.fromJson(json);
case "decoratedPotSpout":
return DecoratedPotModel.DecoratedPotSpoutEntity.fromJson(json);
case "calibratedSculkSensorAmethyst":
return CalibratedSculkSensorAmethyst.fromJson(json);
}
return null;
}
Expand Down
Loading

0 comments on commit 0591621

Please sign in to comment.