mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-26 19:18:12 +01:00
Added redstone placement
This commit is contained in:
parent
a8f48aafe9
commit
126d778221
@ -7,6 +7,7 @@ import fr.themode.demo.commands.SimpleCommand;
|
||||
import fr.themode.minestom.MinecraftServer;
|
||||
import fr.themode.minestom.command.CommandManager;
|
||||
import fr.themode.minestom.instance.block.BlockManager;
|
||||
import fr.themode.minestom.instance.block.rule.vanilla.RedstonePlacementRule;
|
||||
import fr.themode.minestom.item.ItemStack;
|
||||
import fr.themode.minestom.item.Material;
|
||||
import fr.themode.minestom.net.packet.server.play.DeclareRecipesPacket;
|
||||
@ -23,6 +24,8 @@ public class Main {
|
||||
blockManager.registerCustomBlock(new StoneBlock());
|
||||
blockManager.registerCustomBlock(new UpdatableBlockDemo());
|
||||
|
||||
blockManager.registerBlockPlacementRule(new RedstonePlacementRule());
|
||||
|
||||
CommandManager commandManager = MinecraftServer.getCommandManager();
|
||||
commandManager.register(new HealthCommand());
|
||||
commandManager.register(new SimpleCommand());
|
||||
|
@ -90,7 +90,6 @@ public class Chunk implements Viewable {
|
||||
}
|
||||
|
||||
private void setBlock(int index, short blockId, short customId, Data data, UpdateConsumer updateConsumer) {
|
||||
|
||||
if (blockId != 0
|
||||
|| (blockId == 0 && customId != 0 && updateConsumer != null)) { // Allow custom air block for update purpose, refused if no update consumer has been found
|
||||
refreshBlockValue(index, blockId, customId);
|
||||
|
@ -7,6 +7,7 @@ import fr.themode.minestom.event.PlayerBlockBreakEvent;
|
||||
import fr.themode.minestom.instance.batch.BlockBatch;
|
||||
import fr.themode.minestom.instance.batch.ChunkBatch;
|
||||
import fr.themode.minestom.instance.block.CustomBlock;
|
||||
import fr.themode.minestom.instance.block.rule.BlockPlacementRule;
|
||||
import fr.themode.minestom.net.PacketWriterUtils;
|
||||
import fr.themode.minestom.net.packet.server.play.BlockChangePacket;
|
||||
import fr.themode.minestom.net.packet.server.play.ParticlePacket;
|
||||
@ -52,8 +53,14 @@ public class InstanceContainer extends Instance {
|
||||
|
||||
callBlockDestroy(chunk, index, x, y, z);
|
||||
|
||||
BlockPosition blockPosition = new BlockPosition(x, y, z);
|
||||
|
||||
blockId = executeBlockPlacementRule(blockId, blockPosition);
|
||||
|
||||
chunk.UNSAFE_setBlock(index, blockId, data);
|
||||
|
||||
executeNeighboursBlockPlacementRule(blockId, blockPosition);
|
||||
|
||||
// TODO instead of sending a block change packet each time, cache changed blocks and flush them every tick with a MultiBlockChangePacket
|
||||
sendBlockChange(chunk, x, y, z, blockId);
|
||||
}
|
||||
@ -70,12 +77,18 @@ public class InstanceContainer extends Instance {
|
||||
|
||||
callBlockDestroy(chunk, index, x, y, z);
|
||||
|
||||
BlockPosition blockPosition = new BlockPosition(x, y, z);
|
||||
|
||||
blockId = executeBlockPlacementRule(blockId, blockPosition);
|
||||
|
||||
chunk.UNSAFE_setCustomBlock(index, blockId, data);
|
||||
short id = BLOCK_MANAGER.getBlock(blockId).getType();
|
||||
|
||||
executeNeighboursBlockPlacementRule(blockId, blockPosition);
|
||||
|
||||
callBlockPlace(chunk, index, x, y, z);
|
||||
|
||||
// TODO instead of sending a block change packet each time, cache changed blocks and flush them every tick with a MultiBlockChangePacket
|
||||
short id = BLOCK_MANAGER.getBlock(blockId).getType();
|
||||
sendBlockChange(chunk, x, y, z, id);
|
||||
}
|
||||
}
|
||||
@ -110,6 +123,38 @@ public class InstanceContainer extends Instance {
|
||||
actualBlock.onPlace(this, new BlockPosition(x, y, z), previousData);
|
||||
}
|
||||
|
||||
private short executeBlockPlacementRule(short blockId, BlockPosition blockPosition) {
|
||||
|
||||
BlockPlacementRule blockPlacementRule = BLOCK_MANAGER.getBlockPlacementRule(blockId);
|
||||
if (blockPlacementRule != null) {
|
||||
return blockPlacementRule.blockRefresh(this, blockPosition);
|
||||
}
|
||||
return blockId;
|
||||
}
|
||||
|
||||
private void executeNeighboursBlockPlacementRule(short blockId, BlockPosition blockPosition) {
|
||||
for (int offsetX = -1; offsetX < 2; offsetX++) {
|
||||
for (int offsetY = -1; offsetY < 2; offsetY++) {
|
||||
for (int offsetZ = -1; offsetZ < 2; offsetZ++) {
|
||||
if (offsetX == 0 && offsetY == 0 && offsetZ == 0)
|
||||
continue;
|
||||
int neighborX = blockPosition.getX() + offsetX;
|
||||
int neighborY = blockPosition.getY() + offsetY;
|
||||
int neighborZ = blockPosition.getZ() + offsetZ;
|
||||
short neighborId = getBlockId(neighborX, neighborY, neighborZ);
|
||||
BlockPlacementRule neighborBlockPlacementRule = BLOCK_MANAGER.getBlockPlacementRule(neighborId);
|
||||
if (neighborBlockPlacementRule != null) {
|
||||
short newNeighborId = neighborBlockPlacementRule.blockRefresh(this,
|
||||
new BlockPosition(neighborX, neighborY, neighborZ));
|
||||
if (neighborId != newNeighborId) {
|
||||
refreshBlockId(neighborX, neighborY, neighborZ, newNeighborId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void breakBlock(Player player, BlockPosition blockPosition) {
|
||||
Chunk chunk = getChunkAt(blockPosition);
|
||||
|
@ -1,5 +1,7 @@
|
||||
package fr.themode.minestom.instance.block;
|
||||
|
||||
import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@ -688,6 +690,12 @@ public enum Block {
|
||||
HONEY_BLOCK,
|
||||
HONEYCOMB_BLOCK;
|
||||
|
||||
private static Short2ObjectOpenHashMap<Block> blocksMap = new Short2ObjectOpenHashMap<>();
|
||||
|
||||
public static Block getBlockFromId(short blockId) {
|
||||
return blocksMap.getOrDefault(blockId, AIR);
|
||||
}
|
||||
|
||||
private short blockId;
|
||||
private List<BlockAlternative> blockAlternatives = new ArrayList<>();
|
||||
|
||||
@ -697,6 +705,7 @@ public enum Block {
|
||||
|
||||
public void addBlockAlternative(short id, String... properties) {
|
||||
this.blockAlternatives.add(new BlockAlternative(id, properties));
|
||||
blocksMap.put(id, this);
|
||||
}
|
||||
|
||||
public short withProperties(String... properties) {
|
||||
@ -705,8 +714,8 @@ public enum Block {
|
||||
return blockAlternative.id;
|
||||
}
|
||||
}
|
||||
// No id found
|
||||
return 0;
|
||||
// No id found, return default
|
||||
return blockId;
|
||||
}
|
||||
|
||||
public short getBlockId() {
|
||||
@ -734,5 +743,13 @@ public enum Block {
|
||||
public String[] getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BlockAlternative{" +
|
||||
"id=" + id +
|
||||
", properties=" + Arrays.toString(properties) +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,11 @@ public class BlockManager {
|
||||
this.placementRules.put(blockPlacementRule.getBlock(), blockPlacementRule);
|
||||
}
|
||||
|
||||
public BlockPlacementRule getBlockPlacementRule(short blockId) {
|
||||
Block block = Block.getBlockFromId(blockId);
|
||||
return this.placementRules.get(block);
|
||||
}
|
||||
|
||||
public CustomBlock getBlock(String identifier) {
|
||||
return blocksId.get(identifier);
|
||||
}
|
||||
|
@ -12,9 +12,7 @@ public abstract class BlockPlacementRule {
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
public abstract void onPlace(Instance instance, BlockPosition blockPosition);
|
||||
|
||||
public abstract void onNeighborPlace(Instance instance, int offsetX, int offsetY, int offsetZ);
|
||||
public abstract short blockRefresh(Instance instance, BlockPosition blockPosition);
|
||||
|
||||
public Block getBlock() {
|
||||
return block;
|
||||
|
@ -0,0 +1,68 @@
|
||||
package fr.themode.minestom.instance.block.rule.vanilla;
|
||||
|
||||
import fr.themode.minestom.instance.Instance;
|
||||
import fr.themode.minestom.instance.block.Block;
|
||||
import fr.themode.minestom.instance.block.rule.BlockPlacementRule;
|
||||
import fr.themode.minestom.utils.BlockPosition;
|
||||
|
||||
public class RedstonePlacementRule extends BlockPlacementRule {
|
||||
|
||||
|
||||
public RedstonePlacementRule() {
|
||||
super(Block.REDSTONE_WIRE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public short blockRefresh(Instance instance, BlockPosition blockPosition) {
|
||||
int x = blockPosition.getX();
|
||||
int y = blockPosition.getY();
|
||||
int z = blockPosition.getZ();
|
||||
|
||||
String east = "none";
|
||||
String north = "none";
|
||||
String power = "0";
|
||||
String south = "none";
|
||||
String west = "none";
|
||||
|
||||
if (isRedstone(instance, x + 1, y + 1, z)) {
|
||||
east = "up";
|
||||
} else if (isRedstone(instance, x + 1, y, z)) {
|
||||
east = "side";
|
||||
} else if (isRedstone(instance, x + 1, y - 1, z)) {
|
||||
east = "side";
|
||||
}
|
||||
|
||||
if (isRedstone(instance, x - 1, y + 1, z)) {
|
||||
west = "up";
|
||||
} else if (isRedstone(instance, x - 1, y, z)) {
|
||||
west = "side";
|
||||
} else if (isRedstone(instance, x - 1, y - 1, z)) {
|
||||
west = "side";
|
||||
}
|
||||
|
||||
if (isRedstone(instance, x, y + 1, z + 1)) {
|
||||
south = "up";
|
||||
} else if (isRedstone(instance, x, y, z + 1)) {
|
||||
south = "side";
|
||||
} else if (isRedstone(instance, x, y - 1, z + 1)) {
|
||||
south = "side";
|
||||
}
|
||||
|
||||
if (isRedstone(instance, x, y + 1, z - 1)) {
|
||||
north = "up";
|
||||
} else if (isRedstone(instance, x, y, z - 1)) {
|
||||
north = "side";
|
||||
} else if (isRedstone(instance, x, y - 1, z - 1)) {
|
||||
north = "side";
|
||||
}
|
||||
|
||||
|
||||
return Block.REDSTONE_WIRE.withProperties(east, north, power, south, west);
|
||||
}
|
||||
|
||||
private boolean isRedstone(Instance instance, int x, int y, int z) {
|
||||
short blockId = instance.getBlockId(x, y, z);
|
||||
return Block.getBlockFromId(blockId) == Block.REDSTONE_WIRE;
|
||||
}
|
||||
|
||||
}
|
@ -45,7 +45,7 @@ public class RegistryMain {
|
||||
|
||||
for (RegistryBlock.BlockState blockState : registryBlock.states) {
|
||||
short id = blockState.id;
|
||||
String[] properties = blockState.propertiesValues.toArray(new String[registryBlock.states.size()]);
|
||||
String[] properties = blockState.propertiesValues.toArray(new String[blockState.propertiesValues.size()]);
|
||||
block.addBlockAlternative(id, properties);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user