mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-06 16:37:38 +01:00
hollow-cube/block-handler-in-chunk-setblock
(cherry picked from commit 54e839e58a
)
This commit is contained in:
parent
f31b74a386
commit
37f6877b0a
@ -5,6 +5,7 @@ import net.kyori.adventure.text.format.NamedTextColor;
|
|||||||
import net.kyori.adventure.text.format.Style;
|
import net.kyori.adventure.text.format.Style;
|
||||||
import net.kyori.adventure.text.format.TextColor;
|
import net.kyori.adventure.text.format.TextColor;
|
||||||
import net.kyori.adventure.text.format.TextDecoration;
|
import net.kyori.adventure.text.format.TextDecoration;
|
||||||
|
import net.minestom.demo.block.TestBlockHandler;
|
||||||
import net.minestom.demo.commands.*;
|
import net.minestom.demo.commands.*;
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.command.CommandManager;
|
import net.minestom.server.command.CommandManager;
|
||||||
@ -27,6 +28,7 @@ public class Main {
|
|||||||
MinecraftServer minecraftServer = MinecraftServer.init();
|
MinecraftServer minecraftServer = MinecraftServer.init();
|
||||||
|
|
||||||
BlockManager blockManager = MinecraftServer.getBlockManager();
|
BlockManager blockManager = MinecraftServer.getBlockManager();
|
||||||
|
blockManager.registerHandler(TestBlockHandler.INSTANCE.getNamespaceId(), () -> TestBlockHandler.INSTANCE);
|
||||||
|
|
||||||
CommandManager commandManager = MinecraftServer.getCommandManager();
|
CommandManager commandManager = MinecraftServer.getCommandManager();
|
||||||
commandManager.register(new TestCommand());
|
commandManager.register(new TestCommand());
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
package net.minestom.demo.block;
|
||||||
|
|
||||||
|
import net.minestom.server.instance.block.BlockHandler;
|
||||||
|
import net.minestom.server.utils.NamespaceID;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class TestBlockHandler implements BlockHandler {
|
||||||
|
public static final BlockHandler INSTANCE = new TestBlockHandler();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull NamespaceID getNamespaceId() {
|
||||||
|
return NamespaceID.from("minestom", "test");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPlace(@NotNull Placement placement) {
|
||||||
|
System.out.println(placement);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy(@NotNull Destroy destroy) {
|
||||||
|
System.out.println(destroy);
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,11 @@
|
|||||||
package net.minestom.demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
|
import net.minestom.demo.block.TestBlockHandler;
|
||||||
import net.minestom.server.command.builder.Command;
|
import net.minestom.server.command.builder.Command;
|
||||||
import net.minestom.server.command.builder.arguments.minecraft.ArgumentBlockState;
|
import net.minestom.server.command.builder.arguments.minecraft.ArgumentBlockState;
|
||||||
import net.minestom.server.command.builder.arguments.relative.ArgumentRelativeBlockPosition;
|
import net.minestom.server.command.builder.arguments.relative.ArgumentRelativeBlockPosition;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
|
||||||
import static net.minestom.server.command.builder.arguments.ArgumentType.BlockState;
|
import static net.minestom.server.command.builder.arguments.ArgumentType.BlockState;
|
||||||
import static net.minestom.server.command.builder.arguments.ArgumentType.RelativeBlockPosition;
|
import static net.minestom.server.command.builder.arguments.ArgumentType.RelativeBlockPosition;
|
||||||
@ -17,7 +19,12 @@ public class SetBlockCommand extends Command {
|
|||||||
|
|
||||||
addSyntax((sender, context) -> {
|
addSyntax((sender, context) -> {
|
||||||
final Player player = (Player) sender;
|
final Player player = (Player) sender;
|
||||||
player.getInstance().setBlock(context.get(position).from(player), context.get(block));
|
|
||||||
|
Block blockToPlace = context.get(block);
|
||||||
|
if (blockToPlace.stateId() == Block.GOLD_BLOCK.stateId())
|
||||||
|
blockToPlace = blockToPlace.withHandler(TestBlockHandler.INSTANCE);
|
||||||
|
|
||||||
|
player.getInstance().setBlock(context.get(position).from(player), blockToPlace);
|
||||||
}, position, block);
|
}, position, block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import net.minestom.server.coordinate.Vec;
|
|||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.entity.pathfinding.PFColumnarSpace;
|
import net.minestom.server.entity.pathfinding.PFColumnarSpace;
|
||||||
import net.minestom.server.instance.block.Block;
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.block.BlockHandler;
|
||||||
import net.minestom.server.network.packet.server.play.ChunkDataPacket;
|
import net.minestom.server.network.packet.server.play.ChunkDataPacket;
|
||||||
import net.minestom.server.snapshot.Snapshotable;
|
import net.minestom.server.snapshot.Snapshotable;
|
||||||
import net.minestom.server.tag.TagHandler;
|
import net.minestom.server.tag.TagHandler;
|
||||||
@ -15,6 +16,7 @@ import net.minestom.server.utils.chunk.ChunkSupplier;
|
|||||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||||
import net.minestom.server.world.biomes.Biome;
|
import net.minestom.server.world.biomes.Biome;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -85,7 +87,13 @@ public abstract class Chunk implements Block.Getter, Block.Setter, Biome.Getter,
|
|||||||
* @param block the block to place
|
* @param block the block to place
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public abstract void setBlock(int x, int y, int z, @NotNull Block block);
|
public void setBlock(int x, int y, int z, @NotNull Block block) {
|
||||||
|
setBlock(x, y, z, block, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void setBlock(int x, int y, int z, @NotNull Block block,
|
||||||
|
@Nullable BlockHandler.Placement placement,
|
||||||
|
@Nullable BlockHandler.Destroy destroy);
|
||||||
|
|
||||||
public abstract @NotNull List<Section> getSections();
|
public abstract @NotNull List<Section> getSections();
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import com.extollit.gaming.ai.path.model.ColumnarOcclusionFieldList;
|
|||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.coordinate.Point;
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.coordinate.Vec;
|
||||||
import net.minestom.server.entity.Entity;
|
import net.minestom.server.entity.Entity;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.entity.pathfinding.PFBlock;
|
import net.minestom.server.entity.pathfinding.PFBlock;
|
||||||
@ -56,7 +57,9 @@ public class DynamicChunk extends Chunk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBlock(int x, int y, int z, @NotNull Block block) {
|
public void setBlock(int x, int y, int z, @NotNull Block block,
|
||||||
|
@Nullable BlockHandler.Placement placement,
|
||||||
|
@Nullable BlockHandler.Destroy destroy) {
|
||||||
assertLock();
|
assertLock();
|
||||||
this.lastChange = System.currentTimeMillis();
|
this.lastChange = System.currentTimeMillis();
|
||||||
this.chunkCache.invalidate();
|
this.chunkCache.invalidate();
|
||||||
@ -68,16 +71,21 @@ public class DynamicChunk extends Chunk {
|
|||||||
columnarOcclusionFieldList.onBlockChanged(x, y, z, blockDescription, 0);
|
columnarOcclusionFieldList.onBlockChanged(x, y, z, blockDescription, 0);
|
||||||
}
|
}
|
||||||
Section section = getSectionAt(y);
|
Section section = getSectionAt(y);
|
||||||
section.blockPalette()
|
section.blockPalette().set(
|
||||||
.set(toSectionRelativeCoordinate(x), toSectionRelativeCoordinate(y), toSectionRelativeCoordinate(z), block.stateId());
|
toSectionRelativeCoordinate(x),
|
||||||
|
toSectionRelativeCoordinate(y),
|
||||||
|
toSectionRelativeCoordinate(z),
|
||||||
|
block.stateId()
|
||||||
|
);
|
||||||
|
|
||||||
final int index = ChunkUtils.getBlockIndex(x, y, z);
|
final int index = ChunkUtils.getBlockIndex(x, y, z);
|
||||||
// Handler
|
// Handler
|
||||||
final BlockHandler handler = block.handler();
|
final BlockHandler handler = block.handler();
|
||||||
|
final Block lastCachedBlock;
|
||||||
if (handler != null || block.hasNbt() || block.registry().isBlockEntity()) {
|
if (handler != null || block.hasNbt() || block.registry().isBlockEntity()) {
|
||||||
this.entries.put(index, block);
|
lastCachedBlock = this.entries.put(index, block);
|
||||||
} else {
|
} else {
|
||||||
this.entries.remove(index);
|
lastCachedBlock = this.entries.remove(index);
|
||||||
}
|
}
|
||||||
// Block tick
|
// Block tick
|
||||||
if (handler != null && handler.isTickable()) {
|
if (handler != null && handler.isTickable()) {
|
||||||
@ -85,6 +93,21 @@ public class DynamicChunk extends Chunk {
|
|||||||
} else {
|
} else {
|
||||||
this.tickableMap.remove(index);
|
this.tickableMap.remove(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update block handlers
|
||||||
|
var blockPosition = new Vec(x, y, z);
|
||||||
|
if (lastCachedBlock != null && lastCachedBlock.handler() != null) {
|
||||||
|
// Previous destroy
|
||||||
|
lastCachedBlock.handler().onDestroy(Objects.requireNonNullElseGet(destroy,
|
||||||
|
() -> new BlockHandler.Destroy(lastCachedBlock, instance, blockPosition)));
|
||||||
|
}
|
||||||
|
if (handler != null) {
|
||||||
|
// New placement
|
||||||
|
final Block finalBlock = block;
|
||||||
|
handler.onPlace(Objects.requireNonNullElseGet(placement,
|
||||||
|
() -> new BlockHandler.Placement(finalBlock, instance, blockPosition)));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -125,9 +125,6 @@ public class InstanceContainer extends Instance {
|
|||||||
}
|
}
|
||||||
this.currentlyChangingBlocks.put(blockPosition, block);
|
this.currentlyChangingBlocks.put(blockPosition, block);
|
||||||
|
|
||||||
final Block previousBlock = chunk.getBlock(blockPosition);
|
|
||||||
final BlockHandler previousHandler = previousBlock.handler();
|
|
||||||
|
|
||||||
// Change id based on neighbors
|
// Change id based on neighbors
|
||||||
final BlockPlacementRule blockPlacementRule = MinecraftServer.getBlockManager().getBlockPlacementRule(block);
|
final BlockPlacementRule blockPlacementRule = MinecraftServer.getBlockManager().getBlockPlacementRule(block);
|
||||||
if (blockPlacementRule != null) {
|
if (blockPlacementRule != null) {
|
||||||
@ -135,7 +132,7 @@ public class InstanceContainer extends Instance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the block
|
// Set the block
|
||||||
chunk.setBlock(x, y, z, block);
|
chunk.setBlock(x, y, z, block, placement, destroy);
|
||||||
|
|
||||||
// Refresh neighbors since a new block has been placed
|
// Refresh neighbors since a new block has been placed
|
||||||
executeNeighboursBlockPlacementRule(blockPosition);
|
executeNeighboursBlockPlacementRule(blockPosition);
|
||||||
@ -149,19 +146,6 @@ public class InstanceContainer extends Instance {
|
|||||||
chunk.sendPacketToViewers(new BlockEntityDataPacket(blockPosition, registry.blockEntityId(), data));
|
chunk.sendPacketToViewers(new BlockEntityDataPacket(blockPosition, registry.blockEntityId(), data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (previousHandler != null) {
|
|
||||||
// Previous destroy
|
|
||||||
previousHandler.onDestroy(Objects.requireNonNullElseGet(destroy,
|
|
||||||
() -> new BlockHandler.Destroy(previousBlock, this, blockPosition)));
|
|
||||||
}
|
|
||||||
final BlockHandler handler = block.handler();
|
|
||||||
if (handler != null) {
|
|
||||||
// New placement
|
|
||||||
final Block finalBlock = block;
|
|
||||||
handler.onPlace(Objects.requireNonNullElseGet(placement,
|
|
||||||
() -> new BlockHandler.Placement(finalBlock, this, blockPosition)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import net.minestom.server.coordinate.Point;
|
|||||||
import net.minestom.server.coordinate.Vec;
|
import net.minestom.server.coordinate.Vec;
|
||||||
import net.minestom.server.instance.block.Block;
|
import net.minestom.server.instance.block.Block;
|
||||||
import net.minestom.server.instance.block.BlockFace;
|
import net.minestom.server.instance.block.BlockFace;
|
||||||
|
import net.minestom.server.instance.block.BlockHandler;
|
||||||
import net.minestom.server.instance.light.Light;
|
import net.minestom.server.instance.light.Light;
|
||||||
import net.minestom.server.network.packet.server.CachedPacket;
|
import net.minestom.server.network.packet.server.CachedPacket;
|
||||||
import net.minestom.server.network.packet.server.play.data.LightData;
|
import net.minestom.server.network.packet.server.play.data.LightData;
|
||||||
@ -17,6 +18,7 @@ import net.minestom.server.timer.TaskSchedule;
|
|||||||
import net.minestom.server.utils.NamespaceID;
|
import net.minestom.server.utils.NamespaceID;
|
||||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
@ -101,8 +103,10 @@ public class LightingChunk extends DynamicChunk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBlock(int x, int y, int z, @NotNull Block block) {
|
public void setBlock(int x, int y, int z, @NotNull Block block,
|
||||||
super.setBlock(x, y, z, block);
|
@Nullable BlockHandler.Placement placement,
|
||||||
|
@Nullable BlockHandler.Destroy destroy) {
|
||||||
|
super.setBlock(x, y, z, block, placement, destroy);
|
||||||
this.heightmap = null;
|
this.heightmap = null;
|
||||||
|
|
||||||
// Invalidate neighbor chunks, since they can be updated by this block change
|
// Invalidate neighbor chunks, since they can be updated by this block change
|
||||||
|
Loading…
Reference in New Issue
Block a user