mirror of
https://github.com/Minestom/Minestom.git
synced 2024-11-20 01:25:27 +01:00
hollow-cube/block-handler-in-chunk-setblock
(cherry picked from commit 54e839e58a
)
This commit is contained in:
parent
36b84fd85b
commit
7cbf3c62b6
@ -5,6 +5,7 @@ import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.Style;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
import net.minestom.demo.block.TestBlockHandler;
|
||||
import net.minestom.demo.commands.*;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.command.CommandManager;
|
||||
@ -27,6 +28,7 @@ public class Main {
|
||||
MinecraftServer minecraftServer = MinecraftServer.init();
|
||||
|
||||
BlockManager blockManager = MinecraftServer.getBlockManager();
|
||||
blockManager.registerHandler(TestBlockHandler.INSTANCE.getNamespaceId(), () -> TestBlockHandler.INSTANCE);
|
||||
|
||||
CommandManager commandManager = MinecraftServer.getCommandManager();
|
||||
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;
|
||||
|
||||
import net.minestom.demo.block.TestBlockHandler;
|
||||
import net.minestom.server.command.builder.Command;
|
||||
import net.minestom.server.command.builder.arguments.minecraft.ArgumentBlockState;
|
||||
import net.minestom.server.command.builder.arguments.relative.ArgumentRelativeBlockPosition;
|
||||
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.RelativeBlockPosition;
|
||||
@ -17,7 +19,12 @@ public class SetBlockCommand extends Command {
|
||||
|
||||
addSyntax((sender, context) -> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import net.minestom.server.coordinate.Vec;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.entity.pathfinding.PFColumnarSpace;
|
||||
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.snapshot.Snapshotable;
|
||||
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.world.biomes.Biome;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
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
|
||||
*/
|
||||
@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();
|
||||
|
||||
|
@ -4,6 +4,7 @@ import com.extollit.gaming.ai.path.model.ColumnarOcclusionFieldList;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.coordinate.Point;
|
||||
import net.minestom.server.coordinate.Vec;
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.entity.pathfinding.PFBlock;
|
||||
@ -56,7 +57,9 @@ public class DynamicChunk extends Chunk {
|
||||
}
|
||||
|
||||
@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();
|
||||
this.lastChange = System.currentTimeMillis();
|
||||
this.chunkCache.invalidate();
|
||||
@ -68,16 +71,21 @@ public class DynamicChunk extends Chunk {
|
||||
columnarOcclusionFieldList.onBlockChanged(x, y, z, blockDescription, 0);
|
||||
}
|
||||
Section section = getSectionAt(y);
|
||||
section.blockPalette()
|
||||
.set(toSectionRelativeCoordinate(x), toSectionRelativeCoordinate(y), toSectionRelativeCoordinate(z), block.stateId());
|
||||
section.blockPalette().set(
|
||||
toSectionRelativeCoordinate(x),
|
||||
toSectionRelativeCoordinate(y),
|
||||
toSectionRelativeCoordinate(z),
|
||||
block.stateId()
|
||||
);
|
||||
|
||||
final int index = ChunkUtils.getBlockIndex(x, y, z);
|
||||
// Handler
|
||||
final BlockHandler handler = block.handler();
|
||||
final Block lastCachedBlock;
|
||||
if (handler != null || block.hasNbt() || block.registry().isBlockEntity()) {
|
||||
this.entries.put(index, block);
|
||||
lastCachedBlock = this.entries.put(index, block);
|
||||
} else {
|
||||
this.entries.remove(index);
|
||||
lastCachedBlock = this.entries.remove(index);
|
||||
}
|
||||
// Block tick
|
||||
if (handler != null && handler.isTickable()) {
|
||||
@ -85,6 +93,21 @@ public class DynamicChunk extends Chunk {
|
||||
} else {
|
||||
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
|
||||
|
@ -125,9 +125,6 @@ public class InstanceContainer extends Instance {
|
||||
}
|
||||
this.currentlyChangingBlocks.put(blockPosition, block);
|
||||
|
||||
final Block previousBlock = chunk.getBlock(blockPosition);
|
||||
final BlockHandler previousHandler = previousBlock.handler();
|
||||
|
||||
// Change id based on neighbors
|
||||
final BlockPlacementRule blockPlacementRule = MinecraftServer.getBlockManager().getBlockPlacementRule(block);
|
||||
if (blockPlacementRule != null) {
|
||||
@ -135,7 +132,7 @@ public class InstanceContainer extends Instance {
|
||||
}
|
||||
|
||||
// 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
|
||||
executeNeighboursBlockPlacementRule(blockPosition);
|
||||
@ -149,19 +146,6 @@ public class InstanceContainer extends Instance {
|
||||
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.instance.block.Block;
|
||||
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.network.packet.server.CachedPacket;
|
||||
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.chunk.ChunkUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
@ -101,8 +103,10 @@ public class LightingChunk extends DynamicChunk {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, @NotNull Block block) {
|
||||
super.setBlock(x, y, z, block);
|
||||
public void setBlock(int x, int y, int z, @NotNull Block block,
|
||||
@Nullable BlockHandler.Placement placement,
|
||||
@Nullable BlockHandler.Destroy destroy) {
|
||||
super.setBlock(x, y, z, block, placement, destroy);
|
||||
this.heightmap = null;
|
||||
|
||||
// Invalidate neighbor chunks, since they can be updated by this block change
|
||||
|
Loading…
Reference in New Issue
Block a user