mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-04 23:47:59 +01:00
Added CampfireHandler demo
This commit is contained in:
parent
54b6868b2e
commit
d6a2a5b316
@ -60,7 +60,7 @@ public class DynamicChunk extends Chunk {
|
||||
public void setBlock(int x, int y, int z, @NotNull Block block) {
|
||||
final short blockStateId = block.getStateId();
|
||||
final BlockHandler handler = block.getHandler();
|
||||
final NBTCompound nbt = null; // TODO
|
||||
final NBTCompound nbt = block.getNbt(); // TODO
|
||||
final boolean updatable = false; // TODO
|
||||
{
|
||||
// Update pathfinder
|
||||
|
@ -36,6 +36,8 @@ public interface Block extends ProtocolObject, TagReadable, BlockConstants {
|
||||
|
||||
@NotNull String getProperty(@NotNull String property);
|
||||
|
||||
@Nullable NBTCompound getNbt();
|
||||
|
||||
@Nullable BlockHandler getHandler();
|
||||
|
||||
@NotNull Block getDefaultBlock();
|
||||
|
@ -3,10 +3,14 @@ package net.minestom.server.instance.block;
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.tag.Tag;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
import net.minestom.server.utils.NamespaceID;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* Interface used to provide block behavior. Set with {@link Block#withHandler(BlockHandler)}.
|
||||
* <p>
|
||||
@ -51,6 +55,14 @@ public interface BlockHandler {
|
||||
default void handleContact(@NotNull Instance instance, @NotNull BlockPosition position, @NotNull Entity touching) {
|
||||
}
|
||||
|
||||
default @NotNull Collection<Tag<?>> getBlockEntityTags() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
default byte getBlockEntityAction() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id of this handler.
|
||||
* <p>
|
||||
|
@ -132,6 +132,11 @@ class BlockImpl implements Block {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable NBTCompound getNbt() {
|
||||
return compound != null ? compound.deepClone() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Block getDefaultBlock() {
|
||||
return original;
|
||||
|
@ -9,6 +9,7 @@ import net.minestom.server.instance.Section;
|
||||
import net.minestom.server.instance.block.BlockHandler;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.tag.Tag;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
import net.minestom.server.utils.Utils;
|
||||
import net.minestom.server.utils.binary.BinaryReader;
|
||||
@ -23,10 +24,7 @@ import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ChunkDataPacket implements ServerPacket, CacheablePacket {
|
||||
@ -130,25 +128,35 @@ public class ChunkDataPacket implements ServerPacket, CacheablePacket {
|
||||
if (handlerMap == null || handlerMap.isEmpty()) {
|
||||
writer.writeVarInt(0);
|
||||
} else {
|
||||
writer.writeVarInt(handlerMap.size());
|
||||
|
||||
List<NBTCompound> compounds = new ArrayList<>();
|
||||
for (var entry : handlerMap.entrySet()) {
|
||||
final int index = entry.getKey();
|
||||
final BlockHandler handler = entry.getValue();
|
||||
final BlockPosition blockPosition = ChunkUtils.getBlockPosition(index, chunkX, chunkZ);
|
||||
final var blockEntityTags = handler.getBlockEntityTags();
|
||||
if (blockEntityTags.isEmpty())
|
||||
continue;
|
||||
final var blockNbt = Objects.requireNonNullElseGet(nbtMap.get(index), NBTCompound::new);
|
||||
final var resultNbt = new NBTCompound();
|
||||
|
||||
NBTCompound nbt;
|
||||
if (nbtMap != null) {
|
||||
nbt = Objects.requireNonNullElseGet(nbtMap.get(index), NBTCompound::new);
|
||||
} else {
|
||||
nbt = new NBTCompound();
|
||||
for (Tag<?> tag : blockEntityTags) {
|
||||
final var value = tag.read(blockNbt);
|
||||
if (value != null) {
|
||||
// Tag is present and valid
|
||||
tag.writeUnsafe(resultNbt, value);
|
||||
}
|
||||
}
|
||||
|
||||
if (resultNbt.getSize() > 0) {
|
||||
final BlockPosition blockPosition = ChunkUtils.getBlockPosition(index, chunkX, chunkZ);
|
||||
resultNbt.setString("id", handler.getNamespaceId().asString())
|
||||
.setInt("x", blockPosition.getX())
|
||||
.setInt("y", blockPosition.getY())
|
||||
.setInt("z", blockPosition.getZ());
|
||||
compounds.add(resultNbt);
|
||||
}
|
||||
nbt.setString("id", handler.getNamespaceId().asString())
|
||||
.setInt("x", blockPosition.getX())
|
||||
.setInt("y", blockPosition.getY())
|
||||
.setInt("z", blockPosition.getZ());
|
||||
writer.writeNBT("", nbt);
|
||||
}
|
||||
writer.writeVarInt(compounds.size());
|
||||
compounds.forEach(nbtCompound -> writer.writeNBT("", nbtCompound));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,6 +101,10 @@ public class Tag<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeUnsafe(@NotNull NBTCompound nbtCompound, @Nullable Object value) {
|
||||
write(nbtCompound, (T) value);
|
||||
}
|
||||
|
||||
public static @NotNull Tag<Byte> Byte(@NotNull String key) {
|
||||
return new Tag<>(key,
|
||||
nbtCompound -> nbtCompound.getByte(key),
|
||||
@ -178,20 +182,7 @@ public class Tag<T> {
|
||||
|
||||
public static <T> @NotNull Tag<T> Custom(@NotNull String key, @NotNull TagSerializer<T> serializer) {
|
||||
return new Tag<>(key,
|
||||
nbtCompound -> {
|
||||
final var compound = nbtCompound.getCompound(key);
|
||||
if (compound == null) {
|
||||
return null;
|
||||
}
|
||||
return serializer.read(TagReadable.fromCompound(compound));
|
||||
},
|
||||
(nbtCompound, value) -> {
|
||||
var compound = nbtCompound.getCompound(key);
|
||||
if (compound == null) {
|
||||
compound = new NBTCompound();
|
||||
nbtCompound.set(key, compound);
|
||||
}
|
||||
serializer.write(TagWritable.fromCompound(compound), value);
|
||||
});
|
||||
nbtCompound -> serializer.read(TagReadable.fromCompound(nbtCompound)),
|
||||
(nbtCompound, value) -> serializer.write(TagWritable.fromCompound(nbtCompound), value));
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package demo;
|
||||
|
||||
import demo.block.CampfireHandler;
|
||||
import demo.generator.ChunkGeneratorDemo;
|
||||
import demo.generator.NoiseTestGenerator;
|
||||
import net.kyori.adventure.text.Component;
|
||||
@ -37,10 +38,7 @@ import net.minestom.server.utils.Vector;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.world.DimensionType;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@ -58,6 +56,10 @@ public class PlayerInit {
|
||||
instanceContainer.enableAutoChunkLoad(true);
|
||||
instanceContainer.setChunkGenerator(chunkGeneratorDemo);
|
||||
|
||||
instanceContainer.setBlock(0, 45, 3, Block.CAMPFIRE
|
||||
.withHandler(new CampfireHandler())
|
||||
.withTag(CampfireHandler.ITEMS, List.of(ItemStack.of(Material.DIAMOND, 1))));
|
||||
|
||||
inventory = new Inventory(InventoryType.CHEST_1_ROW, Component.text("Test inventory"));
|
||||
/*inventory.addInventoryCondition((p, slot, clickType, inventoryConditionResult) -> {
|
||||
p.sendMessage("click type inventory: " + clickType);
|
||||
@ -204,13 +206,6 @@ public class PlayerInit {
|
||||
int x = Math.abs(ThreadLocalRandom.current().nextInt()) % 500 - 250;
|
||||
int z = Math.abs(ThreadLocalRandom.current().nextInt()) % 500 - 250;
|
||||
player.setRespawnPoint(new Position(0, 42f, 0));
|
||||
|
||||
player.getInventory().addInventoryCondition((p, slot, clickType, inventoryConditionResult) -> {
|
||||
if (slot == -999)
|
||||
return;
|
||||
//ItemStack itemStack = p.getInventory().getItemStack(slot);
|
||||
//System.out.println("test " + itemStack.getIdentifier() + " " + itemStack.getData());
|
||||
});
|
||||
});
|
||||
|
||||
globalEventHandler.addEventCallback(PlayerSpawnEvent.class, event -> {
|
||||
|
84
src/test/java/demo/block/CampfireHandler.java
Normal file
84
src/test/java/demo/block/CampfireHandler.java
Normal file
@ -0,0 +1,84 @@
|
||||
package demo.block;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.instance.block.BlockHandler;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.Material;
|
||||
import net.minestom.server.registry.Registries;
|
||||
import net.minestom.server.tag.Tag;
|
||||
import net.minestom.server.tag.TagReadable;
|
||||
import net.minestom.server.tag.TagSerializer;
|
||||
import net.minestom.server.tag.TagWritable;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
import net.minestom.server.utils.NamespaceID;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTList;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTTypes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class CampfireHandler implements BlockHandler {
|
||||
|
||||
public static final Tag<List<ItemStack>> ITEMS = Tag.Custom("Items", new TagSerializer<>() {
|
||||
|
||||
private final Tag<NBT> internal = Tag.NBT("Items");
|
||||
|
||||
@Override
|
||||
public @Nullable List<ItemStack> read(@NotNull TagReadable reader) {
|
||||
NBTList<NBTCompound> item = (NBTList<NBTCompound>) reader.getTag(internal);
|
||||
List<ItemStack> result = new ArrayList<>();
|
||||
assert item != null;
|
||||
item.forEach(nbtCompound -> {
|
||||
int amount = nbtCompound.getAsByte("Count");
|
||||
String id = nbtCompound.getString("id");
|
||||
Material material = Registries.getMaterial(id);
|
||||
result.add(ItemStack.of(material, amount));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull TagWritable writer, @NotNull List<ItemStack> value) {
|
||||
NBTList<NBTCompound> items = new NBTList<>(NBTTypes.TAG_Compound);
|
||||
for (var item : value) {
|
||||
NBTCompound compound = new NBTCompound()
|
||||
.setByte("Count", (byte) item.getAmount())
|
||||
.setByte("Slot", (byte) 1)
|
||||
.setString("id", item.getMaterial().getNamespaceID().asString());
|
||||
items.add(compound);
|
||||
}
|
||||
writer.setTag(internal, items);
|
||||
}
|
||||
});
|
||||
|
||||
@Override
|
||||
public void onPlace(@NotNull Instance instance, @NotNull BlockPosition blockPosition) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy(@NotNull Instance instance, @NotNull BlockPosition blockPosition) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInteract(@NotNull Player player, Player.@NotNull Hand hand, @NotNull BlockPosition blockPosition) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Tag<?>> getBlockEntityTags() {
|
||||
return List.of(ITEMS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull NamespaceID getNamespaceId() {
|
||||
return NamespaceID.from("minestom:test");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user