feat: implemented item prefabs

This commit is contained in:
Andrey Terentev 2024-10-31 01:55:55 +07:00
parent c8c0868f56
commit 9f34bea77a
3 changed files with 122 additions and 0 deletions

View File

@ -3,6 +3,7 @@ package ru.dragonestia.msb3.api;
import lombok.Getter;
import lombok.extern.log4j.Log4j2;
import net.minestom.server.MinecraftServer;
import ru.dragonestia.msb3.api.item.ItemPrefabManager;
import ru.dragonestia.msb3.api.resource.ResourcePackManager;
import java.net.InetSocketAddress;
@ -26,9 +27,11 @@ public class ServerBootstrap {
};
@Getter private static ServerBootstrap instance;
@Getter private static boolean started = false;
private final MinecraftServer server;
@Getter private final ResourcePackManager resourcePackManager;
@Getter private final ItemPrefabManager itemPrefabManager;
public ServerBootstrap() {
instance = this;
@ -40,11 +43,13 @@ public class ServerBootstrap {
MinecraftServer.setBrandName("Dragonestia");
resourcePackManager = new ResourcePackManager();
itemPrefabManager = new ItemPrefabManager();
init();
}
public void start(String address, int port) {
started = true;
server.start(new InetSocketAddress(address, port));
}

View File

@ -0,0 +1,33 @@
package ru.dragonestia.msb3.api.item;
import lombok.extern.log4j.Log4j2;
import ru.dragonestia.msb3.api.ServerBootstrap;
import ru.dragonestia.msb3.api.item.prefab.ItemPrefab;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@Log4j2
public final class ItemPrefabManager {
private final Map<String, ItemPrefab> prefabs = new HashMap<>();
public ItemPrefabManager() {}
public synchronized void register(ItemPrefab prefab) {
if (ServerBootstrap.isStarted()) {
throw new IllegalStateException("Server is already started");
}
if (prefabs.containsKey(prefab.getIdentifier())) {
throw new IllegalArgumentException("Prefab already registered: " + prefab.getIdentifier());
}
prefabs.put(prefab.getIdentifier(), prefab);
}
public Optional<ItemPrefab> getPrefab(String identifier) {
return Optional.ofNullable(prefabs.get(identifier));
}
}

View File

@ -0,0 +1,84 @@
package ru.dragonestia.msb3.api.item.prefab;
import net.kyori.adventure.nbt.BinaryTag;
import net.minestom.server.item.ItemStack;
import net.minestom.server.tag.Tag;
import ru.dragonestia.msb3.api.ServerBootstrap;
import java.util.Optional;
import java.util.function.Supplier;
public class ItemPrefab {
private static final Tag<String> TAG_IDENTIFIER = Tag.String("msb3_prefab_id");
private static final Tag<BinaryTag> TAG_DATA = Tag.NBT("msb3_prefab_data");
private final String identifier;
protected final Supplier<ItemStack> factory;
public ItemPrefab(String identifier, Supplier<ItemStack> factory) {
this.identifier = identifier;
this.factory = factory;
}
public static Optional<ItemPrefab> of(String identifier) {
return ServerBootstrap.getInstance().getItemPrefabManager().getPrefab(identifier);
}
public static Optional<ItemPrefab> of(ItemStack item) {
if (item == null || item.hasTag(TAG_IDENTIFIER)) return Optional.empty();
return ServerBootstrap.getInstance().getItemPrefabManager().getPrefab(item.getTag(TAG_IDENTIFIER));
}
public final String getIdentifier() {
return identifier;
}
public final boolean isOwn(ItemStack item) {
return item.hasTag(TAG_IDENTIFIER) && identifier.equals(item.getTag(TAG_IDENTIFIER));
}
public final ItemStack create(int amount, BinaryTag data) {
var builder = factory.get().builder()
.amount(amount)
.set(TAG_IDENTIFIER, identifier);
if (data != null) builder.set(TAG_DATA, data);
return builder.build();
}
public final ItemStack create(int amount) {
return create(amount, null);
}
public final ItemStack create() {
return create(1);
}
public final BinaryTag extractData(ItemStack item) {
if (item.hasTag(TAG_DATA)) return item.getTag(TAG_DATA);
return null;
}
public static SerializedPrefab serialize(ItemStack item) {
if (item == null || item.isAir()) return null;
var prefabOpt = of(item);
if (prefabOpt.isEmpty()) return null;
var prefab = prefabOpt.get();
return new SerializedPrefab(prefab.getIdentifier(), item.amount());
}
public record SerializedPrefab(String id, int amount) {
public ItemStack deserialize(SerializedPrefab serialized) {
var prefabOpt = of(serialized.id);
if (prefabOpt.isEmpty()) return null;
var prefab = prefabOpt.get();
return prefab.create(serialized.amount);
}
}
}