mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-27 11:38:03 +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.MinecraftServer;
|
||||||
import fr.themode.minestom.command.CommandManager;
|
import fr.themode.minestom.command.CommandManager;
|
||||||
import fr.themode.minestom.instance.block.BlockManager;
|
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.ItemStack;
|
||||||
import fr.themode.minestom.item.Material;
|
import fr.themode.minestom.item.Material;
|
||||||
import fr.themode.minestom.net.packet.server.play.DeclareRecipesPacket;
|
import fr.themode.minestom.net.packet.server.play.DeclareRecipesPacket;
|
||||||
@ -23,6 +24,8 @@ public class Main {
|
|||||||
blockManager.registerCustomBlock(new StoneBlock());
|
blockManager.registerCustomBlock(new StoneBlock());
|
||||||
blockManager.registerCustomBlock(new UpdatableBlockDemo());
|
blockManager.registerCustomBlock(new UpdatableBlockDemo());
|
||||||
|
|
||||||
|
blockManager.registerBlockPlacementRule(new RedstonePlacementRule());
|
||||||
|
|
||||||
CommandManager commandManager = MinecraftServer.getCommandManager();
|
CommandManager commandManager = MinecraftServer.getCommandManager();
|
||||||
commandManager.register(new HealthCommand());
|
commandManager.register(new HealthCommand());
|
||||||
commandManager.register(new SimpleCommand());
|
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) {
|
private void setBlock(int index, short blockId, short customId, Data data, UpdateConsumer updateConsumer) {
|
||||||
|
|
||||||
if (blockId != 0
|
if (blockId != 0
|
||||||
|| (blockId == 0 && customId != 0 && updateConsumer != null)) { // Allow custom air block for update purpose, refused if no update consumer has been found
|
|| (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);
|
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.BlockBatch;
|
||||||
import fr.themode.minestom.instance.batch.ChunkBatch;
|
import fr.themode.minestom.instance.batch.ChunkBatch;
|
||||||
import fr.themode.minestom.instance.block.CustomBlock;
|
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.PacketWriterUtils;
|
||||||
import fr.themode.minestom.net.packet.server.play.BlockChangePacket;
|
import fr.themode.minestom.net.packet.server.play.BlockChangePacket;
|
||||||
import fr.themode.minestom.net.packet.server.play.ParticlePacket;
|
import fr.themode.minestom.net.packet.server.play.ParticlePacket;
|
||||||
@ -52,8 +53,14 @@ public class InstanceContainer extends Instance {
|
|||||||
|
|
||||||
callBlockDestroy(chunk, index, x, y, z);
|
callBlockDestroy(chunk, index, x, y, z);
|
||||||
|
|
||||||
|
BlockPosition blockPosition = new BlockPosition(x, y, z);
|
||||||
|
|
||||||
|
blockId = executeBlockPlacementRule(blockId, blockPosition);
|
||||||
|
|
||||||
chunk.UNSAFE_setBlock(index, blockId, data);
|
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
|
// 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);
|
sendBlockChange(chunk, x, y, z, blockId);
|
||||||
}
|
}
|
||||||
@ -70,12 +77,18 @@ public class InstanceContainer extends Instance {
|
|||||||
|
|
||||||
callBlockDestroy(chunk, index, x, y, z);
|
callBlockDestroy(chunk, index, x, y, z);
|
||||||
|
|
||||||
|
BlockPosition blockPosition = new BlockPosition(x, y, z);
|
||||||
|
|
||||||
|
blockId = executeBlockPlacementRule(blockId, blockPosition);
|
||||||
|
|
||||||
chunk.UNSAFE_setCustomBlock(index, blockId, data);
|
chunk.UNSAFE_setCustomBlock(index, blockId, data);
|
||||||
short id = BLOCK_MANAGER.getBlock(blockId).getType();
|
|
||||||
|
executeNeighboursBlockPlacementRule(blockId, blockPosition);
|
||||||
|
|
||||||
callBlockPlace(chunk, index, x, y, z);
|
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
|
// 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);
|
sendBlockChange(chunk, x, y, z, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,6 +123,38 @@ public class InstanceContainer extends Instance {
|
|||||||
actualBlock.onPlace(this, new BlockPosition(x, y, z), previousData);
|
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
|
@Override
|
||||||
public void breakBlock(Player player, BlockPosition blockPosition) {
|
public void breakBlock(Player player, BlockPosition blockPosition) {
|
||||||
Chunk chunk = getChunkAt(blockPosition);
|
Chunk chunk = getChunkAt(blockPosition);
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package fr.themode.minestom.instance.block;
|
package fr.themode.minestom.instance.block;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -688,6 +690,12 @@ public enum Block {
|
|||||||
HONEY_BLOCK,
|
HONEY_BLOCK,
|
||||||
HONEYCOMB_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 short blockId;
|
||||||
private List<BlockAlternative> blockAlternatives = new ArrayList<>();
|
private List<BlockAlternative> blockAlternatives = new ArrayList<>();
|
||||||
|
|
||||||
@ -697,6 +705,7 @@ public enum Block {
|
|||||||
|
|
||||||
public void addBlockAlternative(short id, String... properties) {
|
public void addBlockAlternative(short id, String... properties) {
|
||||||
this.blockAlternatives.add(new BlockAlternative(id, properties));
|
this.blockAlternatives.add(new BlockAlternative(id, properties));
|
||||||
|
blocksMap.put(id, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public short withProperties(String... properties) {
|
public short withProperties(String... properties) {
|
||||||
@ -705,8 +714,8 @@ public enum Block {
|
|||||||
return blockAlternative.id;
|
return blockAlternative.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// No id found
|
// No id found, return default
|
||||||
return 0;
|
return blockId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getBlockId() {
|
public short getBlockId() {
|
||||||
@ -734,5 +743,13 @@ public enum Block {
|
|||||||
public String[] getProperties() {
|
public String[] getProperties() {
|
||||||
return properties;
|
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);
|
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) {
|
public CustomBlock getBlock(String identifier) {
|
||||||
return blocksId.get(identifier);
|
return blocksId.get(identifier);
|
||||||
}
|
}
|
||||||
|
@ -12,9 +12,7 @@ public abstract class BlockPlacementRule {
|
|||||||
this.block = block;
|
this.block = block;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void onPlace(Instance instance, BlockPosition blockPosition);
|
public abstract short blockRefresh(Instance instance, BlockPosition blockPosition);
|
||||||
|
|
||||||
public abstract void onNeighborPlace(Instance instance, int offsetX, int offsetY, int offsetZ);
|
|
||||||
|
|
||||||
public Block getBlock() {
|
public Block getBlock() {
|
||||||
return block;
|
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) {
|
for (RegistryBlock.BlockState blockState : registryBlock.states) {
|
||||||
short id = blockState.id;
|
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);
|
block.addBlockAlternative(id, properties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user