Added CampfireHandler demo

This commit is contained in:
TheMode 2021-06-12 19:17:50 +02:00
parent 54b6868b2e
commit d6a2a5b316
8 changed files with 141 additions and 44 deletions

View File

@ -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

View File

@ -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();

View File

@ -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>

View File

@ -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;

View File

@ -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));
}
}

View File

@ -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));
}
}

View File

@ -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 -> {

View 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");
}
}