mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-12-22 14:34:59 +01:00
BlockState values can now be switched at runtime
E.G. Blocks.PISTON_HEAD.defaultBlockState().withValue(FACING, Direction.SOUTH) Some of the inspiration may be thanks to FerriteCore, at least with the shared property keys idea, so thank you to them.
This commit is contained in:
parent
db166ad8de
commit
0094fa1418
47 changed files with 1160 additions and 901 deletions
|
@ -28,7 +28,9 @@ package org.geysermc.geyser.entity.type;
|
|||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.level.block.type.FurnaceBlock;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.level.block.property.Properties;
|
||||
import org.geysermc.geyser.level.block.type.BlockState;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
|
@ -51,7 +53,8 @@ public class FurnaceMinecartEntity extends DefaultBlockMinecartEntity {
|
|||
|
||||
@Override
|
||||
public void updateDefaultBlockMetadata() {
|
||||
dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(FurnaceBlock.state(hasFuel)));
|
||||
BlockState furnace = Blocks.FURNACE.defaultBlockState().withValue(Properties.LIT, hasFuel);
|
||||
dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(furnace));
|
||||
dirtyMetadata.put(EntityDataTypes.DISPLAY_OFFSET, 6);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ package org.geysermc.geyser.entity.type;
|
|||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.level.block.type.SpawnerBlock;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -41,7 +41,7 @@ public class SpawnerMinecartEntity extends DefaultBlockMinecartEntity {
|
|||
|
||||
@Override
|
||||
public void updateDefaultBlockMetadata() {
|
||||
dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(SpawnerBlock.state()));
|
||||
dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(Blocks.SPAWNER.defaultBlockState()));
|
||||
dirtyMetadata.put(EntityDataTypes.DISPLAY_OFFSET, 6);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,6 @@ import org.geysermc.geyser.level.block.type.BlockState;
|
|||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
|
||||
import org.geysermc.geyser.util.BlockUtils;
|
||||
import org.geysermc.geyser.util.InventoryUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
|
@ -56,22 +55,24 @@ public class BlockInventoryHolder extends InventoryHolder {
|
|||
/**
|
||||
* The default Java block ID to translate as a fake block
|
||||
*/
|
||||
private final int defaultJavaBlockState;
|
||||
private final BlockState defaultJavaBlockState;
|
||||
private final ContainerType containerType;
|
||||
private final Set<String> validBlocks;
|
||||
private final Set<Block> validBlocks;
|
||||
|
||||
public BlockInventoryHolder(String javaBlockIdentifier, ContainerType containerType, Block... validBlocks) {
|
||||
this.defaultJavaBlockState = BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getInt(javaBlockIdentifier);
|
||||
public BlockInventoryHolder(Block defaultJavaBlock, ContainerType containerType, Block... validBlocks) {
|
||||
this(defaultJavaBlock.defaultBlockState(), containerType, validBlocks);
|
||||
}
|
||||
|
||||
public BlockInventoryHolder(BlockState defaultJavaBlockState, ContainerType containerType, Block... validBlocks) {
|
||||
this.defaultJavaBlockState = defaultJavaBlockState;
|
||||
this.containerType = containerType;
|
||||
if (validBlocks != null) {
|
||||
Set<String> validBlocksTemp = new HashSet<>(validBlocks.length + 1);
|
||||
for (Block block : validBlocks) {
|
||||
validBlocksTemp.add(block.javaIdentifier().toString());
|
||||
}
|
||||
validBlocksTemp.add(BlockUtils.getCleanIdentifier(javaBlockIdentifier));
|
||||
Set<Block> validBlocksTemp = new HashSet<>(validBlocks.length + 1);
|
||||
Collections.addAll(validBlocksTemp, validBlocks);
|
||||
validBlocksTemp.add(defaultJavaBlockState.block());
|
||||
this.validBlocks = Set.copyOf(validBlocksTemp);
|
||||
} else {
|
||||
this.validBlocks = Collections.singleton(BlockUtils.getCleanIdentifier(javaBlockIdentifier));
|
||||
this.validBlocks = Collections.singleton(defaultJavaBlockState.block());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,9 +86,7 @@ public class BlockInventoryHolder extends InventoryHolder {
|
|||
// and the bedrock block is vanilla
|
||||
BlockState state = session.getGeyser().getWorldManager().blockAt(session, session.getLastInteractionBlockPosition());
|
||||
if (!BlockRegistries.CUSTOM_BLOCK_STATE_OVERRIDES.get().containsKey(state.javaId())) {
|
||||
// TODO TODO TODO
|
||||
String[] javaBlockString = state.toString().split("\\[");
|
||||
if (isValidBlock(javaBlockString)) {
|
||||
if (isValidBlock(state)) {
|
||||
// We can safely use this block
|
||||
inventory.setHolderPosition(session.getLastInteractionBlockPosition());
|
||||
((Container) inventory).setUsingRealBlock(true, state.block());
|
||||
|
@ -111,7 +110,7 @@ public class BlockInventoryHolder extends InventoryHolder {
|
|||
session.sendUpstreamPacket(blockPacket);
|
||||
inventory.setHolderPosition(position);
|
||||
|
||||
setCustomName(session, position, inventory, BlockState.of(defaultJavaBlockState));
|
||||
setCustomName(session, position, inventory, defaultJavaBlockState);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -129,8 +128,8 @@ public class BlockInventoryHolder extends InventoryHolder {
|
|||
/**
|
||||
* @return true if this Java block ID can be used for player inventory.
|
||||
*/
|
||||
protected boolean isValidBlock(String[] javaBlockString) {
|
||||
return this.validBlocks.contains(javaBlockString[0]);
|
||||
protected boolean isValidBlock(BlockState blockState) {
|
||||
return this.validBlocks.contains(blockState.block());
|
||||
}
|
||||
|
||||
protected void setCustomName(GeyserSession session, Vector3i position, Inventory inventory, BlockState javaBlockState) {
|
||||
|
|
|
@ -25,17 +25,10 @@
|
|||
|
||||
package org.geysermc.geyser.level.block;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import org.geysermc.geyser.level.block.property.Properties;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
import org.geysermc.geyser.level.block.type.BlockState;
|
||||
import org.geysermc.geyser.level.block.type.PistonBlock;
|
||||
import org.geysermc.geyser.level.physics.Direction;
|
||||
import org.geysermc.geyser.level.physics.PistonBehavior;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
|
||||
|
@ -43,53 +36,8 @@ import org.geysermc.geyser.registry.BlockRegistries;
|
|||
* Used for block entities if the Java block state contains Bedrock block information.
|
||||
*/
|
||||
public final class BlockStateValues {
|
||||
private static final Object2IntMap<Direction> PISTON_HEADS = new Object2IntOpenHashMap<>();
|
||||
private static final IntSet ALL_PISTON_HEADS = new IntOpenHashSet();
|
||||
private static final Int2IntMap WATER_LEVEL = new Int2IntOpenHashMap();
|
||||
|
||||
public static int JAVA_WATER_ID;
|
||||
|
||||
public static final int NUM_WATER_LEVELS = 9;
|
||||
|
||||
/**
|
||||
* Determines if the block state contains Bedrock block information
|
||||
*
|
||||
* @param javaId The Java Identifier of the block
|
||||
* @param javaBlockState the Java Block State of the block
|
||||
*/
|
||||
public static void storeBlockStateValues(String javaId, int javaBlockState) {
|
||||
if (javaId.contains("piston[")) { // minecraft:moving_piston, minecraft:sticky_piston, minecraft:piston
|
||||
return;
|
||||
} else if (javaId.startsWith("minecraft:piston_head")) {
|
||||
ALL_PISTON_HEADS.add(javaBlockState);
|
||||
if (javaId.contains("short=false")) {
|
||||
PISTON_HEADS.put(getBlockDirection(javaId), javaBlockState);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (javaId.startsWith("minecraft:water") && !javaId.contains("cauldron")) {
|
||||
String strLevel = javaId.substring(javaId.lastIndexOf("level=") + 6, javaId.length() - 1);
|
||||
int level = Integer.parseInt(strLevel);
|
||||
WATER_LEVEL.put(javaBlockState, level);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isPistonHead(int state) {
|
||||
return ALL_PISTON_HEADS.contains(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Java Block State for a piston head for a specific direction
|
||||
* This is used in PistonBlockEntity to get the BlockCollision for the piston head.
|
||||
*
|
||||
* @param direction Direction the piston head points in
|
||||
* @return Block state for the piston head
|
||||
*/
|
||||
public static int getPistonHead(Direction direction) {
|
||||
return PISTON_HEADS.getOrDefault(direction, Block.JAVA_AIR_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a block sticks to other blocks
|
||||
* (Slime and honey blocks)
|
||||
|
@ -158,7 +106,11 @@ public final class BlockStateValues {
|
|||
* @return The water level or -1 if the block isn't water
|
||||
*/
|
||||
public static int getWaterLevel(int state) {
|
||||
return WATER_LEVEL.getOrDefault(state, -1);
|
||||
BlockState blockState = BlockState.of(state);
|
||||
if (!blockState.is(Blocks.WATER)) {
|
||||
return -1;
|
||||
}
|
||||
return blockState.getValue(Properties.LEVEL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -206,23 +158,6 @@ public final class BlockStateValues {
|
|||
return 0.6f;
|
||||
}
|
||||
|
||||
private static Direction getBlockDirection(String javaId) {
|
||||
if (javaId.contains("down")) {
|
||||
return Direction.DOWN;
|
||||
} else if (javaId.contains("up")) {
|
||||
return Direction.UP;
|
||||
} else if (javaId.contains("south")) {
|
||||
return Direction.SOUTH;
|
||||
} else if (javaId.contains("west")) {
|
||||
return Direction.WEST;
|
||||
} else if (javaId.contains("north")) {
|
||||
return Direction.NORTH;
|
||||
} else if (javaId.contains("east")) {
|
||||
return Direction.EAST;
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
private BlockStateValues() {
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2024 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.level.block.property;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents enums we don't need classes for in Geyser.
|
||||
*/
|
||||
public final class BasicEnumProperty extends Property<String> {
|
||||
private final List<String> values;
|
||||
|
||||
private BasicEnumProperty(String name, List<String> values) {
|
||||
super(name);
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int valuesCount() {
|
||||
return this.values.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(String value) {
|
||||
int index = this.values.indexOf(value);
|
||||
if (index == -1) {
|
||||
throw new IllegalStateException("Property " + this + " does not have value " + value);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T values() {
|
||||
return (T) this.values;
|
||||
}
|
||||
|
||||
public static BasicEnumProperty create(String name, String... values) {
|
||||
return new BasicEnumProperty(name, List.of(values));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2024 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.level.block.property;
|
||||
|
||||
public final class BooleanProperty extends Property<Boolean> {
|
||||
private BooleanProperty(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int valuesCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Boolean value) {
|
||||
return value ? 0 : 1;
|
||||
}
|
||||
|
||||
public static BooleanProperty create(String name) {
|
||||
return new BooleanProperty(name);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2024 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.level.block.property;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
|
||||
public final class EnumProperty<T extends Enum<T>> extends Property<T> {
|
||||
private final IntList ordinalValues;
|
||||
|
||||
/**
|
||||
* @param values all possible values of this enum.
|
||||
*/
|
||||
private EnumProperty(String name, T[] values) {
|
||||
super(name);
|
||||
this.ordinalValues = new IntArrayList(values.length);
|
||||
for (T anEnum : values) {
|
||||
this.ordinalValues.add(anEnum.ordinal());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int valuesCount() {
|
||||
return this.ordinalValues.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(T value) {
|
||||
return this.ordinalValues.indexOf(value.ordinal());
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T extends Enum<T>> EnumProperty<T> create(String name, T... values) {
|
||||
return new EnumProperty<>(name, values);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2024 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.level.block.property;
|
||||
|
||||
public final class IntegerProperty extends Property<Integer> {
|
||||
private final int offset;
|
||||
private final int valuesCount;
|
||||
|
||||
private IntegerProperty(String name, int low, int high) {
|
||||
super(name);
|
||||
this.offset = low;
|
||||
this.valuesCount = high - low;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int valuesCount() {
|
||||
return this.valuesCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Integer value) {
|
||||
return value - this.offset;
|
||||
}
|
||||
|
||||
public int low() {
|
||||
return this.offset;
|
||||
}
|
||||
|
||||
public int high() {
|
||||
return this.offset + this.valuesCount;
|
||||
}
|
||||
|
||||
public static IntegerProperty create(String name, int low, int high) {
|
||||
return new IntegerProperty(name, low, high);
|
||||
}
|
||||
}
|
|
@ -29,118 +29,118 @@ import org.geysermc.geyser.level.physics.Axis;
|
|||
import org.geysermc.geyser.level.physics.Direction;
|
||||
|
||||
public final class Properties {
|
||||
public static final Property<Boolean> ATTACHED = Property.create("attached");
|
||||
public static final Property<Boolean> BOTTOM = Property.create("bottom");
|
||||
public static final Property<Boolean> CONDITIONAL = Property.create("conditional");
|
||||
public static final Property<Boolean> DISARMED = Property.create("disarmed");
|
||||
public static final Property<Boolean> DRAG = Property.create("drag");
|
||||
public static final Property<Boolean> ENABLED = Property.create("enabled");
|
||||
public static final Property<Boolean> EXTENDED = Property.create("extended");
|
||||
public static final Property<Boolean> EYE = Property.create("eye");
|
||||
public static final Property<Boolean> FALLING = Property.create("falling");
|
||||
public static final Property<Boolean> HANGING = Property.create("hanging");
|
||||
public static final Property<Boolean> HAS_BOTTLE_0 = Property.create("has_bottle_0");
|
||||
public static final Property<Boolean> HAS_BOTTLE_1 = Property.create("has_bottle_1");
|
||||
public static final Property<Boolean> HAS_BOTTLE_2 = Property.create("has_bottle_2");
|
||||
public static final Property<Boolean> HAS_RECORD = Property.create("has_record");
|
||||
public static final Property<Boolean> HAS_BOOK = Property.create("has_book");
|
||||
public static final Property<Boolean> INVERTED = Property.create("inverted");
|
||||
public static final Property<Boolean> IN_WALL = Property.create("in_wall");
|
||||
public static final Property<Boolean> LIT = Property.create("lit");
|
||||
public static final Property<Boolean> LOCKED = Property.create("locked");
|
||||
public static final Property<Boolean> OCCUPIED = Property.create("occupied");
|
||||
public static final Property<Boolean> OPEN = Property.create("open");
|
||||
public static final Property<Boolean> PERSISTENT = Property.create("persistent");
|
||||
public static final Property<Boolean> POWERED = Property.create("powered");
|
||||
public static final Property<Boolean> SHORT = Property.create("short");
|
||||
public static final Property<Boolean> SIGNAL_FIRE = Property.create("signal_fire");
|
||||
public static final Property<Boolean> SNOWY = Property.create("snowy");
|
||||
public static final Property<Boolean> TRIGGERED = Property.create("triggered");
|
||||
public static final Property<Boolean> UNSTABLE = Property.create("unstable");
|
||||
public static final Property<Boolean> WATERLOGGED = Property.create("waterlogged");
|
||||
public static final Property<Boolean> BERRIES = Property.create("berries");
|
||||
public static final Property<Boolean> BLOOM = Property.create("bloom");
|
||||
public static final Property<Boolean> SHRIEKING = Property.create("shrieking");
|
||||
public static final Property<Boolean> CAN_SUMMON = Property.create("can_summon");
|
||||
public static final Property<Axis> HORIZONTAL_AXIS = Property.create("axis");
|
||||
public static final Property<Axis> AXIS = Property.create("axis");
|
||||
public static final Property<Boolean> UP = Property.create("up");
|
||||
public static final Property<Boolean> DOWN = Property.create("down");
|
||||
public static final Property<Boolean> NORTH = Property.create("north");
|
||||
public static final Property<Boolean> EAST = Property.create("east");
|
||||
public static final Property<Boolean> SOUTH = Property.create("south");
|
||||
public static final Property<Boolean> WEST = Property.create("west");
|
||||
public static final Property<Direction> FACING = Property.create("facing");
|
||||
public static final Property<Direction> FACING_HOPPER = Property.create("facing");
|
||||
public static final Property<Direction> HORIZONTAL_FACING = Property.create("facing");
|
||||
public static final Property<Integer> FLOWER_AMOUNT = Property.create("flower_amount");
|
||||
public static final Property<FrontAndTop> ORIENTATION = Property.create("orientation");
|
||||
public static final Property<String> ATTACH_FACE = Property.create("face");
|
||||
public static final Property<String> BELL_ATTACHMENT = Property.create("attachment");
|
||||
public static final Property<String> EAST_WALL = Property.create("east");
|
||||
public static final Property<String> NORTH_WALL = Property.create("north");
|
||||
public static final Property<String> SOUTH_WALL = Property.create("south");
|
||||
public static final Property<String> WEST_WALL = Property.create("west");
|
||||
public static final Property<String> EAST_REDSTONE = Property.create("east");
|
||||
public static final Property<String> NORTH_REDSTONE = Property.create("north");
|
||||
public static final Property<String> SOUTH_REDSTONE = Property.create("south");
|
||||
public static final Property<String> WEST_REDSTONE = Property.create("west");
|
||||
public static final Property<String> DOUBLE_BLOCK_HALF = Property.create("half");
|
||||
public static final Property<String> HALF = Property.create("half");
|
||||
public static final Property<String> RAIL_SHAPE = Property.create("shape");
|
||||
public static final Property<String> RAIL_SHAPE_STRAIGHT = Property.create("shape");
|
||||
public static final Property<Integer> AGE_1 = Property.create("age");
|
||||
public static final Property<Integer> AGE_2 = Property.create("age");
|
||||
public static final Property<Integer> AGE_3 = Property.create("age");
|
||||
public static final Property<Integer> AGE_4 = Property.create("age");
|
||||
public static final Property<Integer> AGE_5 = Property.create("age");
|
||||
public static final Property<Integer> AGE_7 = Property.create("age");
|
||||
public static final Property<Integer> AGE_15 = Property.create("age");
|
||||
public static final Property<Integer> AGE_25 = Property.create("age");
|
||||
public static final Property<Integer> BITES = Property.create("bites");
|
||||
public static final Property<Integer> CANDLES = Property.create("candles");
|
||||
public static final Property<Integer> DELAY = Property.create("delay");
|
||||
public static final Property<Integer> DISTANCE = Property.create("distance");
|
||||
public static final Property<Integer> EGGS = Property.create("eggs");
|
||||
public static final Property<Integer> HATCH = Property.create("hatch");
|
||||
public static final Property<Integer> LAYERS = Property.create("layers");
|
||||
public static final Property<Integer> LEVEL_CAULDRON = Property.create("level");
|
||||
public static final Property<Integer> LEVEL_COMPOSTER = Property.create("level");
|
||||
public static final Property<Integer> LEVEL_FLOWING = Property.create("level");
|
||||
public static final Property<Integer> LEVEL_HONEY = Property.create("honey_level");
|
||||
public static final Property<Integer> LEVEL = Property.create("level");
|
||||
public static final Property<Integer> MOISTURE = Property.create("moisture");
|
||||
public static final Property<Integer> NOTE = Property.create("note");
|
||||
public static final Property<Integer> PICKLES = Property.create("pickles");
|
||||
public static final Property<Integer> POWER = Property.create("power");
|
||||
public static final Property<Integer> STAGE = Property.create("stage");
|
||||
public static final Property<Integer> STABILITY_DISTANCE = Property.create("distance");
|
||||
public static final Property<Integer> RESPAWN_ANCHOR_CHARGES = Property.create("charges");
|
||||
public static final Property<Integer> ROTATION_16 = Property.create("rotation");
|
||||
public static final Property<String> BED_PART = Property.create("part");
|
||||
public static final Property<ChestType> CHEST_TYPE = Property.create("type");
|
||||
public static final Property<String> MODE_COMPARATOR = Property.create("mode");
|
||||
public static final Property<String> DOOR_HINGE = Property.create("hinge");
|
||||
public static final Property<String> NOTEBLOCK_INSTRUMENT = Property.create("instrument");
|
||||
public static final Property<String> PISTON_TYPE = Property.create("type");
|
||||
public static final Property<String> SLAB_TYPE = Property.create("type");
|
||||
public static final Property<String> STAIRS_SHAPE = Property.create("shape");
|
||||
public static final Property<String> STRUCTUREBLOCK_MODE = Property.create("mode");
|
||||
public static final Property<String> BAMBOO_LEAVES = Property.create("leaves");
|
||||
public static final Property<String> TILT = Property.create("tilt");
|
||||
public static final Property<Direction> VERTICAL_DIRECTION = Property.create("vertical_direction");
|
||||
public static final Property<String> DRIPSTONE_THICKNESS = Property.create("thickness");
|
||||
public static final Property<String> SCULK_SENSOR_PHASE = Property.create("sculk_sensor_phase");
|
||||
public static final Property<Boolean> CHISELED_BOOKSHELF_SLOT_0_OCCUPIED = Property.create("slot_0_occupied");
|
||||
public static final Property<Boolean> CHISELED_BOOKSHELF_SLOT_1_OCCUPIED = Property.create("slot_1_occupied");
|
||||
public static final Property<Boolean> CHISELED_BOOKSHELF_SLOT_2_OCCUPIED = Property.create("slot_2_occupied");
|
||||
public static final Property<Boolean> CHISELED_BOOKSHELF_SLOT_3_OCCUPIED = Property.create("slot_3_occupied");
|
||||
public static final Property<Boolean> CHISELED_BOOKSHELF_SLOT_4_OCCUPIED = Property.create("slot_4_occupied");
|
||||
public static final Property<Boolean> CHISELED_BOOKSHELF_SLOT_5_OCCUPIED = Property.create("slot_5_occupied");
|
||||
public static final Property<Integer> DUSTED = Property.create("dusted");
|
||||
public static final Property<Boolean> CRACKED = Property.create("cracked");
|
||||
public static final Property<Boolean> CRAFTING = Property.create("crafting");
|
||||
public static final Property<String> TRIAL_SPAWNER_STATE = Property.create("trial_spawner_state");
|
||||
public static final Property<String> VAULT_STATE = Property.create("vault_state");
|
||||
public static final Property<Boolean> OMINOUS = Property.create("ominous");
|
||||
public static final BooleanProperty ATTACHED = BooleanProperty.create("attached");
|
||||
public static final BooleanProperty BOTTOM = BooleanProperty.create("bottom");
|
||||
public static final BooleanProperty CONDITIONAL = BooleanProperty.create("conditional");
|
||||
public static final BooleanProperty DISARMED = BooleanProperty.create("disarmed");
|
||||
public static final BooleanProperty DRAG = BooleanProperty.create("drag");
|
||||
public static final BooleanProperty ENABLED = BooleanProperty.create("enabled");
|
||||
public static final BooleanProperty EXTENDED = BooleanProperty.create("extended");
|
||||
public static final BooleanProperty EYE = BooleanProperty.create("eye");
|
||||
public static final BooleanProperty FALLING = BooleanProperty.create("falling");
|
||||
public static final BooleanProperty HANGING = BooleanProperty.create("hanging");
|
||||
public static final BooleanProperty HAS_BOTTLE_0 = BooleanProperty.create("has_bottle_0");
|
||||
public static final BooleanProperty HAS_BOTTLE_1 = BooleanProperty.create("has_bottle_1");
|
||||
public static final BooleanProperty HAS_BOTTLE_2 = BooleanProperty.create("has_bottle_2");
|
||||
public static final BooleanProperty HAS_RECORD = BooleanProperty.create("has_record");
|
||||
public static final BooleanProperty HAS_BOOK = BooleanProperty.create("has_book");
|
||||
public static final BooleanProperty INVERTED = BooleanProperty.create("inverted");
|
||||
public static final BooleanProperty IN_WALL = BooleanProperty.create("in_wall");
|
||||
public static final BooleanProperty LIT = BooleanProperty.create("lit");
|
||||
public static final BooleanProperty LOCKED = BooleanProperty.create("locked");
|
||||
public static final BooleanProperty OCCUPIED = BooleanProperty.create("occupied");
|
||||
public static final BooleanProperty OPEN = BooleanProperty.create("open");
|
||||
public static final BooleanProperty PERSISTENT = BooleanProperty.create("persistent");
|
||||
public static final BooleanProperty POWERED = BooleanProperty.create("powered");
|
||||
public static final BooleanProperty SHORT = BooleanProperty.create("short");
|
||||
public static final BooleanProperty SIGNAL_FIRE = BooleanProperty.create("signal_fire");
|
||||
public static final BooleanProperty SNOWY = BooleanProperty.create("snowy");
|
||||
public static final BooleanProperty TRIGGERED = BooleanProperty.create("triggered");
|
||||
public static final BooleanProperty UNSTABLE = BooleanProperty.create("unstable");
|
||||
public static final BooleanProperty WATERLOGGED = BooleanProperty.create("waterlogged");
|
||||
public static final BooleanProperty BERRIES = BooleanProperty.create("berries");
|
||||
public static final BooleanProperty BLOOM = BooleanProperty.create("bloom");
|
||||
public static final BooleanProperty SHRIEKING = BooleanProperty.create("shrieking");
|
||||
public static final BooleanProperty CAN_SUMMON = BooleanProperty.create("can_summon");
|
||||
public static final EnumProperty<Axis> HORIZONTAL_AXIS = EnumProperty.create("axis", Axis.X, Axis.Z);
|
||||
public static final EnumProperty<Axis> AXIS = EnumProperty.create("axis", Axis.VALUES);
|
||||
public static final BooleanProperty UP = BooleanProperty.create("up");
|
||||
public static final BooleanProperty DOWN = BooleanProperty.create("down");
|
||||
public static final BooleanProperty NORTH = BooleanProperty.create("north");
|
||||
public static final BooleanProperty EAST = BooleanProperty.create("east");
|
||||
public static final BooleanProperty SOUTH = BooleanProperty.create("south");
|
||||
public static final BooleanProperty WEST = BooleanProperty.create("west");
|
||||
public static final EnumProperty<Direction> FACING = EnumProperty.create("facing", Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN);
|
||||
public static final EnumProperty<Direction> FACING_HOPPER = EnumProperty.create("facing", Direction.DOWN, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST);
|
||||
public static final EnumProperty<Direction> HORIZONTAL_FACING = EnumProperty.create("facing", Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST);
|
||||
public static final IntegerProperty FLOWER_AMOUNT = IntegerProperty.create("flower_amount", 1, 4);
|
||||
public static final EnumProperty<FrontAndTop> ORIENTATION = EnumProperty.create("orientation", FrontAndTop.VALUES);
|
||||
public static final BasicEnumProperty ATTACH_FACE = BasicEnumProperty.create("face", "floor", "wall", "ceiling");
|
||||
public static final BasicEnumProperty BELL_ATTACHMENT = BasicEnumProperty.create("attachment", "floor", "ceiling", "single_wall", "double_wall");
|
||||
public static final BasicEnumProperty EAST_WALL = BasicEnumProperty.create("east", "none", "low", "tall");
|
||||
public static final BasicEnumProperty NORTH_WALL = BasicEnumProperty.create("north", "none", "low", "tall");
|
||||
public static final BasicEnumProperty SOUTH_WALL = BasicEnumProperty.create("south", "none", "low", "tall");
|
||||
public static final BasicEnumProperty WEST_WALL = BasicEnumProperty.create("west", "none", "low", "tall");
|
||||
public static final BasicEnumProperty EAST_REDSTONE = BasicEnumProperty.create("east", "up", "side", "none");
|
||||
public static final BasicEnumProperty NORTH_REDSTONE = BasicEnumProperty.create("north", "up", "side", "none");
|
||||
public static final BasicEnumProperty SOUTH_REDSTONE = BasicEnumProperty.create("south", "up", "side", "none");
|
||||
public static final BasicEnumProperty WEST_REDSTONE = BasicEnumProperty.create("west", "up", "side", "none");
|
||||
public static final BasicEnumProperty DOUBLE_BLOCK_HALF = BasicEnumProperty.create("half", "upper", "lower");
|
||||
public static final BasicEnumProperty HALF = BasicEnumProperty.create("half", "top", "bottom");
|
||||
public static final BasicEnumProperty RAIL_SHAPE = BasicEnumProperty.create("shape", "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south", "south_east", "south_west", "north_west", "north_east");
|
||||
public static final BasicEnumProperty RAIL_SHAPE_STRAIGHT = BasicEnumProperty.create("shape", "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south");
|
||||
public static final IntegerProperty AGE_1 = IntegerProperty.create("age", 0, 1);
|
||||
public static final IntegerProperty AGE_2 = IntegerProperty.create("age", 0, 2);
|
||||
public static final IntegerProperty AGE_3 = IntegerProperty.create("age", 0, 3);
|
||||
public static final IntegerProperty AGE_4 = IntegerProperty.create("age", 0, 4);
|
||||
public static final IntegerProperty AGE_5 = IntegerProperty.create("age", 0, 5);
|
||||
public static final IntegerProperty AGE_7 = IntegerProperty.create("age", 0, 7);
|
||||
public static final IntegerProperty AGE_15 = IntegerProperty.create("age", 0, 15);
|
||||
public static final IntegerProperty AGE_25 = IntegerProperty.create("age", 0, 25);
|
||||
public static final IntegerProperty BITES = IntegerProperty.create("bites", 0, 6);
|
||||
public static final IntegerProperty CANDLES = IntegerProperty.create("candles", 1, 4);
|
||||
public static final IntegerProperty DELAY = IntegerProperty.create("delay", 1, 4);
|
||||
public static final IntegerProperty DISTANCE = IntegerProperty.create("distance", 1, 7);
|
||||
public static final IntegerProperty EGGS = IntegerProperty.create("eggs", 1, 4);
|
||||
public static final IntegerProperty HATCH = IntegerProperty.create("hatch", 0, 2);
|
||||
public static final IntegerProperty LAYERS = IntegerProperty.create("layers", 1, 8);
|
||||
public static final IntegerProperty LEVEL_CAULDRON = IntegerProperty.create("level", 1, 3);
|
||||
public static final IntegerProperty LEVEL_COMPOSTER = IntegerProperty.create("level", 0, 8);
|
||||
public static final IntegerProperty LEVEL_FLOWING = IntegerProperty.create("level", 1, 8);
|
||||
public static final IntegerProperty LEVEL_HONEY = IntegerProperty.create("honey_level", 0, 5);
|
||||
public static final IntegerProperty LEVEL = IntegerProperty.create("level", 0, 15);
|
||||
public static final IntegerProperty MOISTURE = IntegerProperty.create("moisture", 0, 7);
|
||||
public static final IntegerProperty NOTE = IntegerProperty.create("note", 0, 24);
|
||||
public static final IntegerProperty PICKLES = IntegerProperty.create("pickles", 1, 4);
|
||||
public static final IntegerProperty POWER = IntegerProperty.create("power", 0, 15);
|
||||
public static final IntegerProperty STAGE = IntegerProperty.create("stage", 0, 1);
|
||||
public static final IntegerProperty STABILITY_DISTANCE = IntegerProperty.create("distance", 0, 7);
|
||||
public static final IntegerProperty RESPAWN_ANCHOR_CHARGES = IntegerProperty.create("charges", 0, 4);
|
||||
public static final IntegerProperty ROTATION_16 = IntegerProperty.create("rotation", 0, 15);
|
||||
public static final BasicEnumProperty BED_PART = BasicEnumProperty.create("part", "head", "foot");
|
||||
public static final EnumProperty<ChestType> CHEST_TYPE = EnumProperty.create("type", ChestType.VALUES);
|
||||
public static final BasicEnumProperty MODE_COMPARATOR = BasicEnumProperty.create("mode", "compare", "subtract");
|
||||
public static final BasicEnumProperty DOOR_HINGE = BasicEnumProperty.create("hinge", "left", "right");
|
||||
public static final BasicEnumProperty NOTEBLOCK_INSTRUMENT = BasicEnumProperty.create("instrument", "harp", "basedrum", "snare", "hat", "bass", "flute", "bell", "guitar", "chime", "xylophone", "iron_xylophone", "cow_bell", "didgeridoo", "bit", "banjo", "pling", "zombie", "skeleton", "creeper", "dragon", "wither_skeleton", "piglin", "custom_head");
|
||||
public static final BasicEnumProperty PISTON_TYPE = BasicEnumProperty.create("type", "normal", "sticky");
|
||||
public static final BasicEnumProperty SLAB_TYPE = BasicEnumProperty.create("type", "top", "bottom", "double");
|
||||
public static final BasicEnumProperty STAIRS_SHAPE = BasicEnumProperty.create("shape", "straight", "inner_left", "inner_right", "outer_left", "outer_right");
|
||||
public static final BasicEnumProperty STRUCTUREBLOCK_MODE = BasicEnumProperty.create("mode", "save", "load", "corner", "data");
|
||||
public static final BasicEnumProperty BAMBOO_LEAVES = BasicEnumProperty.create("leaves", "none", "small", "large");
|
||||
public static final BasicEnumProperty TILT = BasicEnumProperty.create("tilt", "none", "unstable", "partial", "full");
|
||||
public static final EnumProperty<Direction> VERTICAL_DIRECTION = EnumProperty.create("vertical_direction", Direction.UP, Direction.DOWN);
|
||||
public static final BasicEnumProperty DRIPSTONE_THICKNESS = BasicEnumProperty.create("thickness", "tip_merge", "tip", "frustum", "middle", "base");
|
||||
public static final BasicEnumProperty SCULK_SENSOR_PHASE = BasicEnumProperty.create("sculk_sensor_phase", "inactive", "active", "cooldown");
|
||||
public static final BooleanProperty CHISELED_BOOKSHELF_SLOT_0_OCCUPIED = BooleanProperty.create("slot_0_occupied");
|
||||
public static final BooleanProperty CHISELED_BOOKSHELF_SLOT_1_OCCUPIED = BooleanProperty.create("slot_1_occupied");
|
||||
public static final BooleanProperty CHISELED_BOOKSHELF_SLOT_2_OCCUPIED = BooleanProperty.create("slot_2_occupied");
|
||||
public static final BooleanProperty CHISELED_BOOKSHELF_SLOT_3_OCCUPIED = BooleanProperty.create("slot_3_occupied");
|
||||
public static final BooleanProperty CHISELED_BOOKSHELF_SLOT_4_OCCUPIED = BooleanProperty.create("slot_4_occupied");
|
||||
public static final BooleanProperty CHISELED_BOOKSHELF_SLOT_5_OCCUPIED = BooleanProperty.create("slot_5_occupied");
|
||||
public static final IntegerProperty DUSTED = IntegerProperty.create("dusted", 0, 3);
|
||||
public static final BooleanProperty CRACKED = BooleanProperty.create("cracked");
|
||||
public static final BooleanProperty CRAFTING = BooleanProperty.create("crafting");
|
||||
public static final BasicEnumProperty TRIAL_SPAWNER_STATE = BasicEnumProperty.create("trial_spawner_state", "inactive", "waiting_for_players", "active", "waiting_for_reward_ejection", "ejecting_reward", "cooldown");
|
||||
public static final BasicEnumProperty VAULT_STATE = BasicEnumProperty.create("vault_state", "inactive", "active", "unlocking", "ejecting");
|
||||
public static final BooleanProperty OMINOUS = BooleanProperty.create("ominous");
|
||||
}
|
||||
|
|
|
@ -25,10 +25,10 @@
|
|||
|
||||
package org.geysermc.geyser.level.block.property;
|
||||
|
||||
public class Property<T extends Comparable<T>> {
|
||||
public abstract class Property<T extends Comparable<T>> {
|
||||
private final String name;
|
||||
|
||||
public Property(String name) {
|
||||
protected Property(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
@ -36,12 +36,12 @@ public class Property<T extends Comparable<T>> {
|
|||
return name;
|
||||
}
|
||||
|
||||
public abstract int valuesCount();
|
||||
|
||||
public abstract int indexOf(T value);
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + "[" + name + "]";
|
||||
}
|
||||
|
||||
public static <T extends Comparable<T>> Property<T> create(String name) {
|
||||
return new Property<>(name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,9 +27,6 @@ package org.geysermc.geyser.level.block.type;
|
|||
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap;
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectMaps;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
|
@ -37,6 +34,8 @@ import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
|
|||
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.level.block.property.BasicEnumProperty;
|
||||
import org.geysermc.geyser.level.block.property.IntegerProperty;
|
||||
import org.geysermc.geyser.level.block.property.Property;
|
||||
import org.geysermc.geyser.level.physics.PistonBehavior;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
|
@ -67,6 +66,12 @@ public class Block {
|
|||
protected Item item = null;
|
||||
private int javaId = -1;
|
||||
|
||||
/**
|
||||
* Used for switching a given block state to different states.
|
||||
*/
|
||||
private final Property<?>[] propertyKeys;
|
||||
private final BlockState defaultState;
|
||||
|
||||
public Block(@Subst("empty") String javaIdentifier, Builder builder) {
|
||||
this.javaIdentifier = Key.key(javaIdentifier);
|
||||
this.requiresCorrectToolForDrops = builder.requiresCorrectToolForDrops;
|
||||
|
@ -74,7 +79,10 @@ public class Block {
|
|||
this.destroyTime = builder.destroyTime;
|
||||
this.pushReaction = builder.pushReaction;
|
||||
this.pickItem = builder.pickItem;
|
||||
processStates(builder.build(this));
|
||||
|
||||
BlockState firstState = builder.build(this).get(0);
|
||||
this.propertyKeys = builder.propertyKeys; // Ensure this is not null before iterating over states
|
||||
this.defaultState = setDefaultState(firstState);
|
||||
}
|
||||
|
||||
public void updateBlock(GeyserSession session, BlockState state, Vector3i position) {
|
||||
|
@ -167,9 +175,11 @@ public class Block {
|
|||
}
|
||||
|
||||
/**
|
||||
* A list of BlockStates is created pertaining to this block. Do we need any of them? If so, override this method.
|
||||
* Should only be ran on block creation. Can be overridden.
|
||||
* @param firstState the first state created from this block
|
||||
*/
|
||||
protected void processStates(List<BlockState> states) {
|
||||
protected BlockState setDefaultState(BlockState firstState) {
|
||||
return firstState;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -194,6 +204,10 @@ public class Block {
|
|||
return this.pushReaction;
|
||||
}
|
||||
|
||||
public BlockState defaultBlockState() {
|
||||
return this.defaultState;
|
||||
}
|
||||
|
||||
public int javaId() {
|
||||
return javaId;
|
||||
}
|
||||
|
@ -213,6 +227,10 @@ public class Block {
|
|||
'}';
|
||||
}
|
||||
|
||||
Property<?>[] propertyKeys() {
|
||||
return propertyKeys;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
@ -225,11 +243,14 @@ public class Block {
|
|||
private float destroyTime;
|
||||
private Supplier<Item> pickItem;
|
||||
|
||||
// We'll use this field after building
|
||||
private Property<?>[] propertyKeys;
|
||||
|
||||
/**
|
||||
* For states that we're just tracking for mirroring Java states.
|
||||
*/
|
||||
public Builder enumState(Property<String> property, String... values) {
|
||||
states.put(property, List.of(values));
|
||||
public Builder enumState(BasicEnumProperty property) {
|
||||
states.put(property, property.values());
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -244,7 +265,9 @@ public class Block {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder intState(Property<Integer> property, int low, int high) {
|
||||
public Builder intState(IntegerProperty property) {
|
||||
int low = property.low();
|
||||
int high = property.high();
|
||||
IntList list = new IntArrayList();
|
||||
// There is a state for every number between the low and high.
|
||||
for (int i = low; i <= high; i++) {
|
||||
|
@ -283,17 +306,18 @@ public class Block {
|
|||
if (states.isEmpty()) {
|
||||
BlockState state = new BlockState(block, BlockRegistries.BLOCK_STATES.get().size());
|
||||
BlockRegistries.BLOCK_STATES.get().add(state);
|
||||
propertyKeys = null;
|
||||
return List.of(state);
|
||||
} else if (states.size() == 1) {
|
||||
// We can optimize because we don't need to worry about combinations
|
||||
Map.Entry<Property<?>, List<Comparable<?>>> property = this.states.entrySet().stream().findFirst().orElseThrow();
|
||||
List<BlockState> states = new ArrayList<>(property.getValue().size());
|
||||
property.getValue().forEach(value -> {
|
||||
Reference2ObjectMap<Property<?>, Comparable<?>> propertyMap = Reference2ObjectMaps.singleton(property.getKey(), value);
|
||||
BlockState state = new BlockState(block, BlockRegistries.BLOCK_STATES.get().size(), propertyMap);
|
||||
BlockState state = new BlockState(block, BlockRegistries.BLOCK_STATES.get().size(), new Comparable[] {value});
|
||||
BlockRegistries.BLOCK_STATES.get().add(state);
|
||||
states.add(state);
|
||||
});
|
||||
this.propertyKeys = new Property[]{property.getKey()};
|
||||
return states;
|
||||
} else {
|
||||
// Think of this stream as another list containing, at the start, one empty list.
|
||||
|
@ -327,11 +351,11 @@ public class Block {
|
|||
Property<?>[] keys = this.states.keySet().toArray(new Property<?>[0]);
|
||||
result.forEach(properties -> {
|
||||
Comparable<?>[] values = properties.toArray(new Comparable<?>[0]);
|
||||
Reference2ObjectMap<Property<?>, Comparable<?>> propertyMap = new Reference2ObjectArrayMap<>(keys, values);
|
||||
BlockState state = new BlockState(block, BlockRegistries.BLOCK_STATES.get().size(), propertyMap);
|
||||
BlockState state = new BlockState(block, BlockRegistries.BLOCK_STATES.get().size(), values);
|
||||
BlockRegistries.BLOCK_STATES.get().add(state);
|
||||
states.add(state);
|
||||
});
|
||||
this.propertyKeys = keys;
|
||||
return states;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.level.block.type;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectMaps;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.geyser.level.block.property.Property;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
|
||||
|
@ -35,13 +34,18 @@ import java.util.Locale;
|
|||
public final class BlockState {
|
||||
private final Block block;
|
||||
private final int javaId;
|
||||
private final Reference2ObjectMap<Property<?>, Comparable<?>> states;
|
||||
/**
|
||||
* The values of each property of this block state. These should be treated as keys to {@link Block#propertyKeys()}
|
||||
* Of note - the comparable part probably doesn't do anything because we occasionally use strings in place of enums.
|
||||
* Will be null if there's only one block state for a block.
|
||||
*/
|
||||
private final Comparable<?>[] states;
|
||||
|
||||
public BlockState(Block block, int javaId) {
|
||||
this(block, javaId, Reference2ObjectMaps.emptyMap());
|
||||
this(block, javaId, null);
|
||||
}
|
||||
|
||||
BlockState(Block block, int javaId, Reference2ObjectMap<Property<?>, Comparable<?>> states) {
|
||||
BlockState(Block block, int javaId, Comparable<?>[] states) {
|
||||
this.block = block;
|
||||
this.javaId = javaId;
|
||||
this.states = states;
|
||||
|
@ -49,23 +53,97 @@ public final class BlockState {
|
|||
|
||||
public <T extends Comparable<T>> T getValue(Property<T> property) {
|
||||
//noinspection unchecked
|
||||
return (T) states.get(property);
|
||||
return (T) get(property);
|
||||
}
|
||||
|
||||
public boolean getValue(Property<Boolean> property, boolean def) {
|
||||
var value = states.get(property);
|
||||
var value = get(property);
|
||||
if (value == null) {
|
||||
return def;
|
||||
}
|
||||
return (Boolean) value;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Comparable<?> get(Property<?> property) {
|
||||
Property<?>[] keys = this.block.propertyKeys();
|
||||
if (keys == null) {
|
||||
return null;
|
||||
}
|
||||
// We're copying the behavior Reference2ObjectArrayMap uses
|
||||
for (int i = keys.length; i-- != 0;) {
|
||||
if (keys[i] == property) {
|
||||
return this.states[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link BlockState} instance with the given value.
|
||||
*/
|
||||
public <T extends Comparable<T>> BlockState withValue(Property<T> property, T value) {
|
||||
Property<?>[] keys = this.block.propertyKeys();
|
||||
if (keys == null) {
|
||||
throw new IllegalStateException(this + " does not have any different states!");
|
||||
}
|
||||
|
||||
T currentValue = getValue(property);
|
||||
if (currentValue == null) {
|
||||
throw new IllegalArgumentException("This BlockState does not have the property " + property);
|
||||
}
|
||||
if (currentValue.equals(value)) {
|
||||
// No action required. This block state is the state we're looking for.
|
||||
return this;
|
||||
}
|
||||
|
||||
// Diff is how much we will have to traverse as a sort of offset
|
||||
|
||||
// Block states are calculated in a predictable structure:
|
||||
// minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=true,west=none]
|
||||
// minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=true,west=low]
|
||||
// minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=true,west=tall]
|
||||
// minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none]
|
||||
// minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=low]
|
||||
// minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=tall]
|
||||
// minecraft:cobblestone_wall[east=none,north=none,south=none,up=false,waterlogged=true,west=none]
|
||||
|
||||
// The last value goes through all its iterations, then the next state goes through all its iterations.
|
||||
// West goes none -> low -> tall, then waterlogged is toggled as west cycles again.
|
||||
// Then when waterlogged goes through all its properties, up is toggled, and west goes through again
|
||||
// If we want to find the "up" property in order, then we need to find how many iterations each property
|
||||
// after it goes in. West goes for 3, waterlogged goes for 2. Adding those together, we find that we need to
|
||||
// add five to get to the next toggle of the up property
|
||||
int diff = 0;
|
||||
for (int i = keys.length - 1; i >= 0; i--) {
|
||||
if (keys[i] != property) {
|
||||
diff += keys[i].valuesCount();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// How many times do we have to jump by diff? This depends on how far away each value is from each other.
|
||||
// piston_head[facing=north] might be right next to piston_head[facing=south], which just one diff'd hop.
|
||||
// But piston_head[facing=west] is further away, requiring more hops.
|
||||
int thatOffset = property.indexOf(value);
|
||||
int thisOffset = property.indexOf(currentValue);
|
||||
if (diff == 0) {
|
||||
// This can happen if the property is at the tail end of the block and there are no other properties to look through
|
||||
// If we have minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=true,west=none]
|
||||
// And want minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=true,west=low]
|
||||
// The above for loop will always stop at the first break because the last property has already been found
|
||||
diff = 1;
|
||||
}
|
||||
return BlockState.of(this.javaId + ((thatOffset - thisOffset) * diff));
|
||||
}
|
||||
|
||||
public Block block() {
|
||||
return block;
|
||||
return this.block;
|
||||
}
|
||||
|
||||
public int javaId() {
|
||||
return javaId;
|
||||
return this.javaId;
|
||||
}
|
||||
|
||||
public boolean is(Block block) {
|
||||
|
@ -74,7 +152,7 @@ public final class BlockState {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (this.states.isEmpty()) {
|
||||
if (this.states == null) {
|
||||
return this.block.javaIdentifier().toString();
|
||||
}
|
||||
return this.block.javaIdentifier().toString() + "[" + paramsToString() + "]";
|
||||
|
@ -82,14 +160,15 @@ public final class BlockState {
|
|||
|
||||
private String paramsToString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
var it = this.states.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
var entry = it.next();
|
||||
builder.append(entry.getKey().name())
|
||||
.append("=")
|
||||
.append(entry.getValue().toString().toLowerCase(Locale.ROOT)); // lowercase covers enums
|
||||
if (it.hasNext()) {
|
||||
builder.append(",");
|
||||
Property<?>[] propertyKeys = this.block.propertyKeys();
|
||||
if (propertyKeys != null) {
|
||||
for (int i = 0; i < propertyKeys.length; i++) {
|
||||
builder.append(propertyKeys[i].name())
|
||||
.append("=")
|
||||
.append(this.states[i].toString().toLowerCase(Locale.ROOT)); // lowercase covers enums
|
||||
if (i < propertyKeys.length - 1) {
|
||||
builder.append(",");
|
||||
}
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
|
|
|
@ -28,29 +28,14 @@ package org.geysermc.geyser.level.block.type;
|
|||
import org.geysermc.geyser.level.block.property.Properties;
|
||||
import org.geysermc.geyser.level.physics.Direction;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class FurnaceBlock extends Block {
|
||||
private static BlockState LIT;
|
||||
private static BlockState UNLIT;
|
||||
|
||||
public FurnaceBlock(String javaIdentifier, Builder builder) {
|
||||
super(javaIdentifier, builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processStates(List<BlockState> states) {
|
||||
LIT = states.stream()
|
||||
.filter(state -> state.getValue(Properties.HORIZONTAL_FACING) == Direction.NORTH
|
||||
&& state.getValue(Properties.LIT))
|
||||
.findFirst().orElseThrow();
|
||||
UNLIT = states.stream()
|
||||
.filter(state -> state.getValue(Properties.HORIZONTAL_FACING) == Direction.NORTH
|
||||
&& !state.getValue(Properties.LIT))
|
||||
.findFirst().orElseThrow();
|
||||
}
|
||||
|
||||
public static BlockState state(boolean lit) {
|
||||
return lit ? LIT : UNLIT;
|
||||
protected BlockState setDefaultState(BlockState firstState) {
|
||||
// Both furnace minecart states look north.
|
||||
return firstState.withValue(Properties.HORIZONTAL_FACING, Direction.NORTH);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,21 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.level.block.type;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class HoneyBlock extends Block {
|
||||
private static BlockState STATE;
|
||||
|
||||
public HoneyBlock(String javaIdentifier, Builder builder) {
|
||||
super(javaIdentifier, builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processStates(List<BlockState> states) {
|
||||
STATE = states.get(0);
|
||||
}
|
||||
|
||||
public static BlockState state() {
|
||||
return STATE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,21 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.level.block.type;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SpawnerBlock extends Block {
|
||||
private static BlockState STATE;
|
||||
|
||||
public SpawnerBlock(String javaIdentifier, Builder builder) {
|
||||
super(javaIdentifier, builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processStates(List<BlockState> states) {
|
||||
STATE = states.get(0);
|
||||
}
|
||||
|
||||
public static BlockState state() {
|
||||
return STATE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,17 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.level.block.type;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class WaterBlock extends Block {
|
||||
private static BlockState LEVEL_0;
|
||||
|
||||
public WaterBlock(String javaIdentifier, Builder builder) {
|
||||
super(javaIdentifier, builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processStates(List<BlockState> states) {
|
||||
super.processStates(states);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,9 @@ import org.geysermc.geyser.entity.EntityDefinitions;
|
|||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.level.block.property.Properties;
|
||||
import org.geysermc.geyser.level.block.type.BlockState;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.PistonCache;
|
||||
import org.geysermc.geyser.translator.collision.BlockCollision;
|
||||
|
@ -405,7 +408,8 @@ public class CollisionManager {
|
|||
* @return if the player is currently in a water block
|
||||
*/
|
||||
public boolean isPlayerInWater() {
|
||||
return session.getGeyser().getWorldManager().getBlockAt(session, session.getPlayerEntity().getPosition().toInt()) == BlockStateValues.JAVA_WATER_ID;
|
||||
BlockState state = session.getGeyser().getWorldManager().blockAt(session, session.getPlayerEntity().getPosition().toInt());
|
||||
return state.is(Blocks.WATER) && state.getValue(Properties.LEVEL) == 0;
|
||||
}
|
||||
|
||||
public boolean isWaterInEyes() {
|
||||
|
|
|
@ -50,7 +50,6 @@ import org.geysermc.geyser.api.block.custom.CustomBlockData;
|
|||
import org.geysermc.geyser.api.block.custom.CustomBlockState;
|
||||
import org.geysermc.geyser.api.block.custom.nonvanilla.JavaBlockState;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.level.block.property.Properties;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
|
@ -433,25 +432,13 @@ public final class BlockRegistryPopulator {
|
|||
}
|
||||
|
||||
int javaRuntimeId = -1;
|
||||
int waterRuntimeId = -1;
|
||||
for (BlockState javaBlockState : BlockRegistries.BLOCK_STATES.get()) {
|
||||
javaRuntimeId++;
|
||||
String javaId = javaBlockState.toString().intern();
|
||||
|
||||
BlockStateValues.storeBlockStateValues(javaId, javaRuntimeId);
|
||||
|
||||
BlockRegistries.JAVA_IDENTIFIER_TO_ID.register(javaId, javaRuntimeId);
|
||||
|
||||
if ("minecraft:water[level=0]".equals(javaId)) {
|
||||
waterRuntimeId = javaRuntimeId;
|
||||
}
|
||||
}
|
||||
|
||||
if (waterRuntimeId == -1) {
|
||||
throw new AssertionError("Unable to find Java water in palette");
|
||||
}
|
||||
BlockStateValues.JAVA_WATER_ID = waterRuntimeId;
|
||||
|
||||
if (!BlockRegistries.NON_VANILLA_BLOCK_STATE_OVERRIDES.get().isEmpty()) {
|
||||
IntSet usedNonVanillaRuntimeIDs = new IntOpenHashSet();
|
||||
|
||||
|
|
|
@ -90,6 +90,10 @@ public class BlockMappings implements DefinitionRegistry<GeyserBedrockBlock> {
|
|||
return this.getBedrockBlock(javaState.javaId());
|
||||
}
|
||||
|
||||
public GeyserBedrockBlock getVanillaBedrockBlock(BlockState javaState) {
|
||||
return getVanillaBedrockBlock(javaState.javaId());
|
||||
}
|
||||
|
||||
public GeyserBedrockBlock getVanillaBedrockBlock(int javaState) {
|
||||
if (javaState < 0 || javaState >= this.javaToVanillaBedrockBlocks.length) {
|
||||
return bedrockAir;
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.geysermc.geyser.inventory.holder.BlockInventoryHolder;
|
|||
import org.geysermc.geyser.inventory.holder.InventoryHolder;
|
||||
import org.geysermc.geyser.inventory.updater.InventoryUpdater;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
import org.geysermc.geyser.level.block.type.BlockState;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
||||
/**
|
||||
|
@ -40,17 +41,25 @@ public abstract class AbstractBlockInventoryTranslator extends BaseInventoryTran
|
|||
private final InventoryHolder holder;
|
||||
private final InventoryUpdater updater;
|
||||
|
||||
/**
|
||||
* @param javaBlock a Java block that is used as a temporary block
|
||||
*/
|
||||
public AbstractBlockInventoryTranslator(int size, Block javaBlock, ContainerType containerType, InventoryUpdater updater,
|
||||
Block... additionalValidBlocks) {
|
||||
this(size, javaBlock.defaultBlockState(), containerType, updater, additionalValidBlocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param size the amount of slots that the inventory adds alongside the base inventory slots
|
||||
* @param javaBlockIdentifier a Java block identifier that is used as a temporary block
|
||||
* @param javaBlockState a Java block state that is used as a temporary block
|
||||
* @param containerType the container type of this inventory
|
||||
* @param updater updater
|
||||
* @param additionalValidBlocks any other blocks that can safely use this inventory without a fake block
|
||||
*/
|
||||
public AbstractBlockInventoryTranslator(int size, String javaBlockIdentifier, ContainerType containerType, InventoryUpdater updater,
|
||||
public AbstractBlockInventoryTranslator(int size, BlockState javaBlockState, ContainerType containerType, InventoryUpdater updater,
|
||||
Block... additionalValidBlocks) {
|
||||
super(size);
|
||||
this.holder = new BlockInventoryHolder(javaBlockIdentifier, containerType, additionalValidBlocks);
|
||||
this.holder = new BlockInventoryHolder(javaBlockState, containerType, additionalValidBlocks);
|
||||
this.updater = updater;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ import java.util.Objects;
|
|||
|
||||
public class AnvilInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||
public AnvilInventoryTranslator() {
|
||||
super(3, "minecraft:anvil[facing=north]", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.ANVIL, AnvilInventoryUpdater.INSTANCE,
|
||||
super(3, Blocks.ANVIL, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.ANVIL, AnvilInventoryUpdater.INSTANCE,
|
||||
Blocks.CHIPPED_ANVIL, Blocks.DAMAGED_ANVIL);
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@ package org.geysermc.geyser.translator.inventory;
|
|||
|
||||
import it.unimi.dsi.fastutil.ints.IntSets;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest;
|
||||
|
@ -43,7 +42,9 @@ import org.geysermc.geyser.inventory.Inventory;
|
|||
import org.geysermc.geyser.inventory.PlayerInventory;
|
||||
import org.geysermc.geyser.inventory.holder.BlockInventoryHolder;
|
||||
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator;
|
||||
import org.geysermc.geyser.util.InventoryUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetBeaconPacket;
|
||||
|
@ -52,7 +53,7 @@ import java.util.OptionalInt;
|
|||
|
||||
public class BeaconInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||
public BeaconInventoryTranslator() {
|
||||
super(1, new BlockInventoryHolder("minecraft:beacon", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.BEACON) {
|
||||
super(1, new BlockInventoryHolder(Blocks.BEACON, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.BEACON) {
|
||||
@Override
|
||||
protected boolean checkInteractionPosition(GeyserSession session) {
|
||||
// Since we can't fall back to a virtual inventory, let's make opening one easier
|
||||
|
@ -89,12 +90,8 @@ public class BeaconInventoryTranslator extends AbstractBlockInventoryTranslator
|
|||
|
||||
// Send a block entity data packet update to the fake beacon inventory
|
||||
Vector3i position = inventory.getHolderPosition();
|
||||
NbtMapBuilder builder = NbtMap.builder()
|
||||
.putInt("x", position.getX())
|
||||
.putInt("y", position.getY())
|
||||
.putInt("z", position.getZ())
|
||||
NbtMapBuilder builder = BlockEntityTranslator.getConstantBedrockTag("Beacon", position)
|
||||
.putString("CustomName", inventory.getTitle())
|
||||
.putString("id", "Beacon")
|
||||
.putInt("primary", beaconContainer.getPrimaryId())
|
||||
.putInt("secondary", beaconContainer.getSecondaryId());
|
||||
|
||||
|
|
|
@ -32,11 +32,16 @@ import org.cloudburstmc.protocol.bedrock.packet.ContainerSetDataPacket;
|
|||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.inventory.Inventory;
|
||||
import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.level.block.property.Properties;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
||||
public class BrewingInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||
public BrewingInventoryTranslator() {
|
||||
super(5, "minecraft:brewing_stand[has_bottle_0=false,has_bottle_1=false,has_bottle_2=false]", ContainerType.BREWING_STAND, ContainerInventoryUpdater.INSTANCE);
|
||||
super(5, Blocks.BREWING_STAND.defaultBlockState()
|
||||
.withValue(Properties.HAS_BOTTLE_0, false)
|
||||
.withValue(Properties.HAS_BOTTLE_1, false)
|
||||
.withValue(Properties.HAS_BOTTLE_2, false), ContainerType.BREWING_STAND, ContainerInventoryUpdater.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -30,12 +30,13 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemSt
|
|||
import org.geysermc.geyser.inventory.*;
|
||||
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType;
|
||||
|
||||
public class CartographyInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||
public CartographyInventoryTranslator() {
|
||||
super(3, "minecraft:cartography_table", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.CARTOGRAPHY, UIInventoryUpdater.INSTANCE);
|
||||
super(3, Blocks.CARTOGRAPHY_TABLE, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.CARTOGRAPHY, UIInventoryUpdater.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
|||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
|
||||
import org.geysermc.geyser.inventory.*;
|
||||
import org.geysermc.geyser.inventory.updater.CrafterInventoryUpdater;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.BlockEntityUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType;
|
||||
|
@ -53,7 +54,7 @@ public class CrafterInventoryTranslator extends AbstractBlockInventoryTranslator
|
|||
private static final int TRIGGERED = 1; // triggered value
|
||||
|
||||
public CrafterInventoryTranslator() {
|
||||
super(10, "minecraft:crafter", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.CRAFTER, CrafterInventoryUpdater.INSTANCE);
|
||||
super(10, Blocks.CRAFTER, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.CRAFTER, CrafterInventoryUpdater.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -31,10 +31,11 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemSt
|
|||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.inventory.SlotType;
|
||||
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
|
||||
public class CraftingInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||
public CraftingInventoryTranslator() {
|
||||
super(10, "minecraft:crafting_table", ContainerType.WORKBENCH, UIInventoryUpdater.INSTANCE);
|
||||
super(10, Blocks.CRAFTING_TABLE, ContainerType.WORKBENCH, UIInventoryUpdater.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.cloudburstmc.protocol.bedrock.packet.PlayerEnchantOptionsPacket;
|
|||
import org.geysermc.geyser.inventory.*;
|
||||
import org.geysermc.geyser.inventory.item.Enchantment;
|
||||
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket;
|
||||
|
@ -47,7 +48,7 @@ import java.util.Locale;
|
|||
|
||||
public class EnchantingInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||
public EnchantingInventoryTranslator() {
|
||||
super(2, "minecraft:enchanting_table", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.ENCHANTMENT, UIInventoryUpdater.INSTANCE);
|
||||
super(2, Blocks.ENCHANTING_TABLE, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.ENCHANTMENT, UIInventoryUpdater.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -41,7 +41,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType;
|
|||
*/
|
||||
public class Generic3X3InventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||
public Generic3X3InventoryTranslator() {
|
||||
super(9, "minecraft:dispenser[facing=north,triggered=false]", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.DISPENSER, ContainerInventoryUpdater.INSTANCE,
|
||||
super(9, Blocks.DISPENSER, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.DISPENSER, ContainerInventoryUpdater.INSTANCE,
|
||||
Blocks.DROPPER);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,10 +30,11 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
|||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
|
||||
public class GrindstoneInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||
public GrindstoneInventoryTranslator() {
|
||||
super(3, "minecraft:grindstone[face=floor,facing=north]", ContainerType.GRINDSTONE, UIInventoryUpdater.INSTANCE);
|
||||
super(3, Blocks.GRINDSTONE, ContainerType.GRINDSTONE, UIInventoryUpdater.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -29,13 +29,14 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
|||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
|
||||
/**
|
||||
* Implemented on top of any block that does not have special properties implemented
|
||||
*/
|
||||
public class HopperInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||
public HopperInventoryTranslator() {
|
||||
super(5, "minecraft:hopper[enabled=false,facing=down]", ContainerType.HOPPER, ContainerInventoryUpdater.INSTANCE);
|
||||
super(5, Blocks.HOPPER, ContainerType.HOPPER, ContainerInventoryUpdater.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.geysermc.erosion.util.LecternUtils;
|
|||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.inventory.*;
|
||||
import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.network.GameProtocol;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.BlockEntityUtils;
|
||||
|
@ -56,7 +57,7 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator
|
|||
private boolean initialized = false;
|
||||
|
||||
public LecternInventoryTranslator() {
|
||||
super(1, "minecraft:lectern[facing=north,has_book=true,powered=true]", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.LECTERN , ContainerInventoryUpdater.INSTANCE);
|
||||
super(1, Blocks.LECTERN, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.LECTERN , ContainerInventoryUpdater.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.geysermc.geyser.inventory.SlotType;
|
|||
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
|
||||
import org.geysermc.geyser.item.type.BannerItem;
|
||||
import org.geysermc.geyser.item.type.DyeItem;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
|
||||
|
@ -101,7 +102,7 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator {
|
|||
}
|
||||
|
||||
public LoomInventoryTranslator() {
|
||||
super(4, "minecraft:loom[facing=north]", ContainerType.LOOM, UIInventoryUpdater.INSTANCE);
|
||||
super(4, Blocks.LOOM, ContainerType.LOOM, UIInventoryUpdater.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket;
|
|||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.inventory.Inventory;
|
||||
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InventoryUtils;
|
||||
|
||||
|
@ -53,7 +54,7 @@ public class OldSmithingTableTranslator extends AbstractBlockInventoryTranslator
|
|||
private static final IntFunction<ItemData> UPGRADE_TEMPLATE = InventoryUtils.getUpgradeTemplate();
|
||||
|
||||
private OldSmithingTableTranslator() {
|
||||
super(3, "minecraft:smithing_table", ContainerType.SMITHING_TABLE, UIInventoryUpdater.INSTANCE);
|
||||
super(3, Blocks.SMITHING_TABLE, ContainerType.SMITHING_TABLE, UIInventoryUpdater.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -35,7 +35,10 @@ import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
|||
import org.geysermc.geyser.inventory.Inventory;
|
||||
import org.geysermc.geyser.inventory.holder.BlockInventoryHolder;
|
||||
import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.level.block.property.Properties;
|
||||
import org.geysermc.geyser.level.block.type.BlockState;
|
||||
import org.geysermc.geyser.level.physics.Direction;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator;
|
||||
|
@ -43,12 +46,13 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType
|
|||
|
||||
public class ShulkerInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||
public ShulkerInventoryTranslator() {
|
||||
super(27, new BlockInventoryHolder("minecraft:shulker_box[facing=north]", ContainerType.CONTAINER) {
|
||||
// Ensure that the shulker box default state won't be trying to open in a state facing the player
|
||||
super(27, new BlockInventoryHolder(Blocks.SHULKER_BOX.defaultBlockState().withValue(Properties.FACING, Direction.NORTH), ContainerType.CONTAINER) {
|
||||
private final BlockEntityTranslator shulkerBoxTranslator = Registries.BLOCK_ENTITIES.get(BlockEntityType.SHULKER_BOX);
|
||||
|
||||
@Override
|
||||
protected boolean isValidBlock(String[] javaBlockString) {
|
||||
return javaBlockString[0].contains("shulker_box");
|
||||
protected boolean isValidBlock(BlockState blockState) {
|
||||
return blockState.block().javaIdentifier().value().contains("shulker_box"); // TODO ew
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -30,10 +30,11 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
|||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
|
||||
public class SmithingInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||
public SmithingInventoryTranslator() {
|
||||
super(4, "minecraft:smithing_table", ContainerType.SMITHING_TABLE, UIInventoryUpdater.INSTANCE);
|
||||
super(4, Blocks.SMITHING_TABLE, ContainerType.SMITHING_TABLE, UIInventoryUpdater.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemS
|
|||
import org.geysermc.geyser.inventory.*;
|
||||
import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData;
|
||||
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
|
@ -42,7 +43,7 @@ import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.S
|
|||
|
||||
public class StonecutterInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||
public StonecutterInventoryTranslator() {
|
||||
super(2, "minecraft:stonecutter[facing=north]", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.STONECUTTER, UIInventoryUpdater.INSTANCE);
|
||||
super(2, Blocks.STONECUTTER, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.STONECUTTER, UIInventoryUpdater.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.geysermc.geyser.level.block.Blocks;
|
|||
import org.geysermc.geyser.level.block.property.ChestType;
|
||||
import org.geysermc.geyser.level.block.property.Properties;
|
||||
import org.geysermc.geyser.level.block.type.BlockState;
|
||||
import org.geysermc.geyser.level.physics.Direction;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator;
|
||||
|
@ -51,7 +52,10 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator {
|
|||
|
||||
public DoubleChestInventoryTranslator(int size) {
|
||||
super(size, 54);
|
||||
this.defaultJavaBlockState = BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getInt("minecraft:chest[facing=north,type=single,waterlogged=false]");
|
||||
this.defaultJavaBlockState = Blocks.CHEST.defaultBlockState()
|
||||
.withValue(Properties.HORIZONTAL_FACING, Direction.NORTH)
|
||||
.withValue(Properties.CHEST_TYPE, ChestType.SINGLE)
|
||||
.javaId();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -96,11 +100,7 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator {
|
|||
blockPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY);
|
||||
session.sendUpstreamPacket(blockPacket);
|
||||
|
||||
NbtMap tag = NbtMap.builder()
|
||||
.putString("id", "Chest")
|
||||
.putInt("x", position.getX())
|
||||
.putInt("y", position.getY())
|
||||
.putInt("z", position.getZ())
|
||||
NbtMap tag = BlockEntityTranslator.getConstantBedrockTag("Chest", position)
|
||||
.putInt("pairx", pairPosition.getX())
|
||||
.putInt("pairz", pairPosition.getZ())
|
||||
.putString("CustomName", inventory.getTitle()).build();
|
||||
|
|
|
@ -30,6 +30,9 @@ import org.geysermc.geyser.inventory.Inventory;
|
|||
import org.geysermc.geyser.inventory.holder.BlockInventoryHolder;
|
||||
import org.geysermc.geyser.inventory.holder.InventoryHolder;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.level.block.property.ChestType;
|
||||
import org.geysermc.geyser.level.block.property.Properties;
|
||||
import org.geysermc.geyser.level.block.type.BlockState;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
||||
public class SingleChestInventoryTranslator extends ChestInventoryTranslator {
|
||||
|
@ -38,17 +41,17 @@ public class SingleChestInventoryTranslator extends ChestInventoryTranslator {
|
|||
// TODO add barrel???
|
||||
public SingleChestInventoryTranslator(int size) {
|
||||
super(size, 27);
|
||||
this.holder = new BlockInventoryHolder("minecraft:chest[facing=north,type=single,waterlogged=false]", ContainerType.CONTAINER,
|
||||
this.holder = new BlockInventoryHolder(Blocks.CHEST.defaultBlockState().withValue(Properties.CHEST_TYPE, ChestType.SINGLE), ContainerType.CONTAINER,
|
||||
Blocks.ENDER_CHEST, Blocks.TRAPPED_CHEST) {
|
||||
@Override
|
||||
protected boolean isValidBlock(String[] javaBlockString) {
|
||||
if (javaBlockString[0].equals("minecraft:ender_chest")) {
|
||||
protected boolean isValidBlock(BlockState blockState) {
|
||||
if (blockState.is(Blocks.ENDER_CHEST)) {
|
||||
// Can't have double ender chests
|
||||
return true;
|
||||
}
|
||||
|
||||
// Add provision to ensure this isn't a double chest
|
||||
return super.isValidBlock(javaBlockString) && (javaBlockString.length > 1 && javaBlockString[1].contains("type=single"));
|
||||
return super.isValidBlock(blockState) && blockState.getValue(Properties.CHEST_TYPE) == ChestType.SINGLE;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -32,12 +32,14 @@ import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
|||
import org.geysermc.geyser.inventory.Inventory;
|
||||
import org.geysermc.geyser.inventory.SlotType;
|
||||
import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater;
|
||||
import org.geysermc.geyser.level.block.property.Properties;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.inventory.AbstractBlockInventoryTranslator;
|
||||
|
||||
public abstract class AbstractFurnaceInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||
AbstractFurnaceInventoryTranslator(String javaBlockIdentifier, ContainerType containerType) {
|
||||
super(3, javaBlockIdentifier, containerType, ContainerInventoryUpdater.INSTANCE);
|
||||
AbstractFurnaceInventoryTranslator(Block javaBlock, ContainerType containerType) {
|
||||
super(3, javaBlock.defaultBlockState().withValue(Properties.LIT, false), containerType, ContainerInventoryUpdater.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -28,10 +28,11 @@ package org.geysermc.geyser.translator.inventory.furnace;
|
|||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
|
||||
public class BlastFurnaceInventoryTranslator extends AbstractFurnaceInventoryTranslator {
|
||||
public BlastFurnaceInventoryTranslator() {
|
||||
super("minecraft:blast_furnace[facing=north,lit=false]", ContainerType.BLAST_FURNACE);
|
||||
super(Blocks.BLAST_FURNACE, ContainerType.BLAST_FURNACE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -28,10 +28,11 @@ package org.geysermc.geyser.translator.inventory.furnace;
|
|||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
|
||||
public class FurnaceInventoryTranslator extends AbstractFurnaceInventoryTranslator {
|
||||
public FurnaceInventoryTranslator() {
|
||||
super("minecraft:furnace[facing=north,lit=false]", ContainerType.FURNACE);
|
||||
super(Blocks.FURNACE, ContainerType.FURNACE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -28,10 +28,11 @@ package org.geysermc.geyser.translator.inventory.furnace;
|
|||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
|
||||
public class SmokerInventoryTranslator extends AbstractFurnaceInventoryTranslator {
|
||||
public SmokerInventoryTranslator() {
|
||||
super("minecraft:smoker[facing=north,lit=false]", ContainerType.SMOKER);
|
||||
super(Blocks.SMOKER, ContainerType.SMOKER);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -26,22 +26,24 @@
|
|||
package org.geysermc.geyser.translator.level.block.entity;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntArrays;
|
||||
import it.unimi.dsi.fastutil.objects.*;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
import org.geysermc.geyser.level.block.type.BlockState;
|
||||
import org.geysermc.geyser.level.block.type.HoneyBlock;
|
||||
import org.geysermc.geyser.level.block.type.PistonBlock;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMaps;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import lombok.Getter;
|
||||
import org.cloudburstmc.math.vector.Vector3d;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.geyser.api.util.PlatformType;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.level.block.property.Properties;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
import org.geysermc.geyser.level.block.type.BlockState;
|
||||
import org.geysermc.geyser.level.block.type.PistonBlock;
|
||||
import org.geysermc.geyser.level.physics.Axis;
|
||||
import org.geysermc.geyser.level.physics.BoundingBox;
|
||||
import org.geysermc.geyser.level.physics.CollisionManager;
|
||||
|
@ -53,6 +55,7 @@ import org.geysermc.geyser.translator.collision.BlockCollision;
|
|||
import org.geysermc.geyser.util.BlockEntityUtils;
|
||||
import org.geysermc.geyser.util.BlockUtils;
|
||||
import org.geysermc.geyser.util.ChunkUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
|
@ -99,7 +102,7 @@ public class PistonBlockEntity {
|
|||
|
||||
static {
|
||||
// Create a ~1 x ~0.5 x ~1 bounding box above the honey block
|
||||
BlockCollision blockCollision = BlockRegistries.COLLISIONS.get(HoneyBlock.state().javaId());
|
||||
BlockCollision blockCollision = BlockRegistries.COLLISIONS.get(Blocks.HONEY_BLOCK.defaultBlockState().javaId());
|
||||
if (blockCollision == null) {
|
||||
throw new RuntimeException("Failed to find honey block collision");
|
||||
}
|
||||
|
@ -224,10 +227,10 @@ public class PistonBlockEntity {
|
|||
|
||||
private void removePistonHead() {
|
||||
Vector3i blockInFront = position.add(orientation.getUnitVector());
|
||||
int blockId = session.getGeyser().getWorldManager().getBlockAt(session, blockInFront);
|
||||
if (BlockStateValues.isPistonHead(blockId)) {
|
||||
BlockState state = session.getGeyser().getWorldManager().blockAt(session, blockInFront);
|
||||
if (state.is(Blocks.PISTON_HEAD)) {
|
||||
ChunkUtils.updateBlock(session, Block.JAVA_AIR_ID, blockInFront);
|
||||
} else if ((session.getGeyser().getPlatformType() == PlatformType.SPIGOT || session.getErosionHandler().isActive()) && blockId == Block.JAVA_AIR_ID) {
|
||||
} else if ((session.getGeyser().getPlatformType() == PlatformType.SPIGOT || session.getErosionHandler().isActive()) && state.is(Blocks.AIR)) {
|
||||
// Spigot removes the piston head from the cache, but we need to send the block update ourselves
|
||||
ChunkUtils.updateBlock(session, Block.JAVA_AIR_ID, blockInFront);
|
||||
}
|
||||
|
@ -353,7 +356,9 @@ public class PistonBlockEntity {
|
|||
playerBoundingBox.setSizeZ(playerBoundingBox.getSizeZ() - shrink.getZ());
|
||||
|
||||
// Resolve collision with the piston head
|
||||
BlockState pistonHeadId = BlockState.of(BlockStateValues.getPistonHead(orientation));
|
||||
BlockState pistonHeadId = Blocks.PISTON_HEAD.defaultBlockState()
|
||||
.withValue(Properties.SHORT, false)
|
||||
.withValue(Properties.FACING, orientation);
|
||||
pushPlayerBlock(pistonHeadId, getPistonHeadPos().toDouble(), blockMovement, playerBoundingBox);
|
||||
|
||||
// Resolve collision with any attached moving blocks, but skip slime blocks
|
||||
|
@ -562,9 +567,11 @@ public class PistonBlockEntity {
|
|||
|
||||
private BlockState getAttachedBlockId(Vector3i blockPos) {
|
||||
if (blockPos.equals(getPistonHeadPos())) {
|
||||
return BlockState.of(BlockStateValues.getPistonHead(orientation));
|
||||
return Blocks.PISTON_HEAD.defaultBlockState()
|
||||
.withValue(Properties.SHORT, false)
|
||||
.withValue(Properties.FACING, orientation);
|
||||
} else {
|
||||
return attachedBlocks.getOrDefault(blockPos, BlockState.of(Block.JAVA_AIR_ID)); //FIXME
|
||||
return attachedBlocks.getOrDefault(blockPos, Blocks.AIR.defaultBlockState());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -633,7 +640,9 @@ public class PistonBlockEntity {
|
|||
if (action == PistonValueType.PUSHING) {
|
||||
Vector3i pistonHeadPos = getPistonHeadPos().add(movement);
|
||||
if (!SOLID_BOUNDING_BOX.checkIntersection(pistonHeadPos.toDouble(), session.getCollisionManager().getPlayerBoundingBox())) {
|
||||
ChunkUtils.updateBlock(session, BlockStateValues.getPistonHead(orientation), pistonHeadPos);
|
||||
ChunkUtils.updateBlock(session, Blocks.PISTON_HEAD.defaultBlockState()
|
||||
.withValue(Properties.SHORT, false)
|
||||
.withValue(Properties.FACING, orientation), pistonHeadPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,8 +56,8 @@ import org.geysermc.geyser.item.type.BlockItem;
|
|||
import org.geysermc.geyser.item.type.BoatItem;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.item.type.SpawnEggItem;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.level.block.property.Properties;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
import org.geysermc.geyser.level.block.type.BlockState;
|
||||
import org.geysermc.geyser.level.block.type.CauldronBlock;
|
||||
|
@ -295,10 +295,10 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
|||
*/
|
||||
|
||||
if (packet.getItemInHand() != null && session.getItemMappings().getMapping(packet.getItemInHand()).getJavaItem() instanceof SpawnEggItem) {
|
||||
int blockState = session.getGeyser().getWorldManager().getBlockAt(session, packet.getBlockPosition());
|
||||
if (blockState == BlockStateValues.JAVA_WATER_ID) {
|
||||
BlockState blockState = session.getGeyser().getWorldManager().blockAt(session, packet.getBlockPosition());
|
||||
if (blockState.is(Blocks.WATER) && blockState.getValue(Properties.LEVEL) == 0) {
|
||||
// Otherwise causes multiple mobs to spawn - just send a use item packet
|
||||
useItem(session, packet, blockState);
|
||||
useItem(session, packet, blockState.javaId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.translator.protocol.java;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.command.CommandNode;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.command.CommandParser;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.command.properties.ResourceProperties;
|
||||
|
@ -54,12 +55,16 @@ import org.geysermc.geyser.translator.protocol.Translator;
|
|||
import org.geysermc.geyser.util.EntityUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@SuppressWarnings("removal") // We know. This is our doing.
|
||||
@Translator(packet = ClientboundCommandsPacket.class)
|
||||
public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommandsPacket> {
|
||||
|
||||
private static final String[] ALL_BLOCK_NAMES = BlockRegistries.JAVA_BLOCKS.get().stream().map(block -> block.javaIdentifier().toString()).toArray(String[]::new);
|
||||
/**
|
||||
* Wait until the registries load before getting all the block names.
|
||||
*/
|
||||
private static final Supplier<String[]> ALL_BLOCK_NAMES = Suppliers.memoize(() -> BlockRegistries.JAVA_BLOCKS.get().stream().map(block -> block.javaIdentifier().toString()).toArray(String[]::new));
|
||||
private static final String[] ALL_EFFECT_IDENTIFIERS = EntityUtils.getAllEffectIdentifiers();
|
||||
private static final String[] ATTRIBUTES = AttributeType.Builtin.BUILTIN.values().stream().map(AttributeType::getIdentifier).toList().toArray(new String[0]);
|
||||
private static final String[] ENUM_BOOLEAN = {"true", "false"};
|
||||
|
@ -247,7 +252,7 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
|
|||
case RESOURCE_LOCATION, FUNCTION -> CommandParam.FILE_PATH;
|
||||
case BOOL -> ENUM_BOOLEAN;
|
||||
case OPERATION -> CommandParam.OPERATOR; // ">=", "==", etc
|
||||
case BLOCK_STATE -> ALL_BLOCK_NAMES;
|
||||
case BLOCK_STATE -> ALL_BLOCK_NAMES.get();
|
||||
case ITEM_STACK -> context.getItemNames();
|
||||
case COLOR -> VALID_COLORS;
|
||||
case SCOREBOARD_SLOT -> VALID_SCOREBOARD_SLOTS;
|
||||
|
|
|
@ -65,7 +65,6 @@ fastutil-int-byte-maps = { group = "com.nukkitx.fastutil", name = "fastutil-int-
|
|||
fastutil-int-boolean-maps = { group = "com.nukkitx.fastutil", name = "fastutil-int-boolean-maps", version.ref = "fastutil" }
|
||||
fastutil-object-int-maps = { group = "com.nukkitx.fastutil", name = "fastutil-object-int-maps", version.ref = "fastutil" }
|
||||
fastutil-object-object-maps = { group = "com.nukkitx.fastutil", name = "fastutil-object-object-maps", version.ref = "fastutil" }
|
||||
fastutil-reference-object-maps = { group = "com.nukkitx.fastutil", name = "fastutil-reference-object-maps", version.ref = "fastutil" }
|
||||
|
||||
adventure-text-serializer-gson = { group = "net.kyori", name = "adventure-text-serializer-gson", version.ref = "adventure" } # Remove when we remove our Adventure bump
|
||||
adventure-text-serializer-legacy = { group = "net.kyori", name = "adventure-text-serializer-legacy", version.ref = "adventure" }
|
||||
|
@ -143,7 +142,7 @@ blossom = { id = "net.kyori.blossom", version.ref = "blossom" }
|
|||
|
||||
[bundles]
|
||||
jackson = [ "jackson-annotations", "jackson-core", "jackson-dataformat-yaml" ]
|
||||
fastutil = [ "fastutil-int-int-maps", "fastutil-int-long-maps", "fastutil-int-byte-maps", "fastutil-int-boolean-maps", "fastutil-object-int-maps", "fastutil-object-object-maps", "fastutil-reference-object-maps" ]
|
||||
fastutil = [ "fastutil-int-int-maps", "fastutil-int-long-maps", "fastutil-int-byte-maps", "fastutil-int-boolean-maps", "fastutil-object-int-maps", "fastutil-object-object-maps" ]
|
||||
adventure = [ "adventure-text-serializer-gson", "adventure-text-serializer-legacy", "adventure-text-serializer-plain" ]
|
||||
log4j = [ "log4j-api", "log4j-core", "log4j-slf4j2-impl" ]
|
||||
jline = [ "jline-terminal", "jline-terminal-jna", "jline-reader" ]
|
||||
|
|
Loading…
Reference in a new issue