From 39927bbcaec3525180bdb7c40272013c3941ca86 Mon Sep 17 00:00:00 2001 From: Patbox <39821509+Patbox@users.noreply.github.com> Date: Thu, 23 Dec 2021 12:00:21 +0100 Subject: [PATCH] [2.0.0-beta.2] Stability fixes - Added `universal_graves:breaking_time` and `universal_graves:protection_time` - Visual Graves now use their own hologram/sign text - Changing protection time to 0 disables it (it was it's own option before) - Graves now have static id instead of being position based - Fixed compatibility with Immersive Portals - Fixed few bugs --- build.gradle | 2 +- gradle.properties | 2 +- .../java/eu/pb4/graves/GraveNetworking.java | 6 +- src/main/java/eu/pb4/graves/GravesMod.java | 3 +- .../eu/pb4/graves/client/GravesModClient.java | 9 ++- .../java/eu/pb4/graves/config/Config.java | 4 + .../eu/pb4/graves/config/data/ConfigData.java | 21 ++++- .../graves/config/data/old/ConfigDataV1.java | 1 - src/main/java/eu/pb4/graves/grave/Grave.java | 80 ++++++++++++------- .../eu/pb4/graves/grave/GraveManager.java | 58 ++++++++++++-- .../pb4/graves/registry/GraveBlockEntity.java | 50 ++++++++---- .../pb4/graves/registry/GraveGameRules.java | 35 ++++++++ .../pb4/graves/registry/VisualGraveBlock.java | 4 +- .../registry/VisualGraveBlockEntity.java | 6 +- .../graves/registry/VisualGraveBlockItem.java | 4 +- src/main/java/eu/pb4/graves/ui/GraveGui.java | 6 +- .../data/universal_graves/lang/en_us.json | 5 +- 17 files changed, 226 insertions(+), 70 deletions(-) create mode 100644 src/main/java/eu/pb4/graves/registry/GraveGameRules.java diff --git a/build.gradle b/build.gradle index f4c409c..09f09de 100644 --- a/build.gradle +++ b/build.gradle @@ -56,7 +56,7 @@ dependencies { modImplementation include("eu.pb4:sgui:1.0.0-rc6+1.18-pre5") modImplementation include("eu.pb4:hologram-api:0.2.1+1.18-pre5") modImplementation include("eu.pb4:placeholder-api:1.1.3+1.17.1") - modImplementation include("eu.pb4:polymer:0.2.0-beta.12+1.18.1") + modImplementation include("eu.pb4:polymer:0.2.0-beta.13+1.18.1") modImplementation include("fr.catcore:server-translations-api:1.4.8+1.18-pre1") modImplementation include("me.lucko:fabric-permissions-api:0.1-SNAPSHOT") diff --git a/gradle.properties b/gradle.properties index 376c1ac..92d2829 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ org.gradle.jvmargs=-Xmx1G fabric_version=0.44.0+1.18 # Mod Properties - mod_version = 2.0.0-beta.1+1.18 + mod_version = 2.0.0-beta.2+1.18 maven_group = eu.pb4 archives_base_name = graves diff --git a/src/main/java/eu/pb4/graves/GraveNetworking.java b/src/main/java/eu/pb4/graves/GraveNetworking.java index 0c77c2d..7c76d17 100644 --- a/src/main/java/eu/pb4/graves/GraveNetworking.java +++ b/src/main/java/eu/pb4/graves/GraveNetworking.java @@ -98,10 +98,8 @@ public static NetworkingGrave readGrave(int version, PacketByteBuf buf) { } public static void initialize() { - - // A bug in polymer networking api... I will fix that later but for now it will do - ServerPackets.register("custom/" + CLIENT_HELLO.getNamespace() + "/" + CLIENT_HELLO.getPath(), 0); - ServerPackets.register("custom/" + CLIENT_GRAVE.getNamespace() + "/" + CLIENT_GRAVE.getPath(), 0); + PolymerPacketUtils.registerServerPacket(CLIENT_HELLO, 0); + PolymerPacketUtils.registerServerPacket(CLIENT_GRAVE, 0); PolymerSyncUtils.ON_SYNC_CUSTOM.register(((handler, full) -> { sendConfig(handler); diff --git a/src/main/java/eu/pb4/graves/GravesMod.java b/src/main/java/eu/pb4/graves/GravesMod.java index a193eb2..e3ad36a 100644 --- a/src/main/java/eu/pb4/graves/GravesMod.java +++ b/src/main/java/eu/pb4/graves/GravesMod.java @@ -48,6 +48,7 @@ public void onInitialize() { PolymerBlockUtils.registerBlockEntity(VisualGraveBlockEntity.BLOCK_ENTITY_TYPE); GraveNetworking.initialize(); + new GraveGameRules(); GravesApi.registerInventoryMask(new Identifier("vanilla"), VanillaInventoryMask.INSTANCE); @@ -69,7 +70,7 @@ public void onInitialize() { ServerWorldEvents.LOAD.register(((server, world) -> { if (world == server.getOverworld()) { GraveManager.INSTANCE = (GraveManager) world.getPersistentStateManager() - .getOrCreate(GraveManager::fromNbt, GraveManager::new, "universal-graves"); + .getOrCreate((nbt) -> GraveManager.fromNbt(nbt, server), GraveManager::new, "universal-graves"); } })); diff --git a/src/main/java/eu/pb4/graves/client/GravesModClient.java b/src/main/java/eu/pb4/graves/client/GravesModClient.java index cd188a9..89801cd 100644 --- a/src/main/java/eu/pb4/graves/client/GravesModClient.java +++ b/src/main/java/eu/pb4/graves/client/GravesModClient.java @@ -7,16 +7,21 @@ import eu.pb4.graves.registry.GraveBlockEntity; import eu.pb4.graves.other.GravesLookType; import eu.pb4.polymer.api.client.PolymerClientUtils; +import fr.catcore.server.translations.api.ServerTranslations; import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; import net.fabricmc.fabric.api.client.model.*; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; import net.fabricmc.fabric.api.client.rendering.v1.BlockEntityRendererRegistry; import net.fabricmc.fabric.api.networking.v1.PacketSender; +import net.fabricmc.fabric.api.resource.ResourceManagerHelper; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.render.block.entity.BlockEntityRenderer; import net.minecraft.network.PacketByteBuf; +import net.minecraft.resource.ReloadableResourceManager; import net.minecraft.resource.ResourceManager; +import net.minecraft.resource.ResourceType; import net.minecraft.util.Identifier; import java.util.function.Consumer; @@ -34,8 +39,8 @@ public void onInitializeClient() { (ctx) -> (BlockEntityRenderer) (Object) new GraveRenderer(ctx)); - PolymerClientUtils.registerPacket(GraveNetworking.CLIENT_HELLO, this::handleHelloPacket, 0); - PolymerClientUtils.registerPacket(GraveNetworking.CLIENT_GRAVE, this::handleGravePacket, 0); + PolymerClientUtils.registerPacketHandler(GraveNetworking.CLIENT_HELLO, this::handleHelloPacket, 0); + PolymerClientUtils.registerPacketHandler(GraveNetworking.CLIENT_GRAVE, this::handleGravePacket, 0); ClientPlayConnectionEvents.JOIN.register(this::onConnect); diff --git a/src/main/java/eu/pb4/graves/config/Config.java b/src/main/java/eu/pb4/graves/config/Config.java index 06baaaa..aad6edf 100644 --- a/src/main/java/eu/pb4/graves/config/Config.java +++ b/src/main/java/eu/pb4/graves/config/Config.java @@ -32,9 +32,11 @@ public final class Config { public final Text[] hologramProtectedText; public final Text[] hologramText; + public final Text[] hologramVisualText; public final Text[] signProtectedText; public final Text[] signText; + public final Text[] signVisualText; public final Text graveTitle; @@ -78,8 +80,10 @@ public Config(ConfigData data) { this.xpCalc = GravesXPCalculation.byName(configData.xpStorageType); this.hologramProtectedText = parse(data.hologramProtectedText); this.hologramText = parse(data.hologramText); + this.hologramVisualText = parse(data.hologramVisualText); this.signProtectedText = parse(data.customStyleSignProtectedText); this.signText = parse(data.customStyleSignText); + this.signVisualText = parse(data.customStyleSignVisualText); this.graveTitle = TextParser.parse(data.graveTitle); this.canClientSide = data.allowClientSideStyle && this.style.allowClient; diff --git a/src/main/java/eu/pb4/graves/config/data/ConfigData.java b/src/main/java/eu/pb4/graves/config/data/ConfigData.java index 52e9b03..6666b4f 100644 --- a/src/main/java/eu/pb4/graves/config/data/ConfigData.java +++ b/src/main/java/eu/pb4/graves/config/data/ConfigData.java @@ -31,9 +31,10 @@ public class ConfigData extends VersionedConfigData implements Cloneable { public List customStyleSignProtectedText = getDefaultProtectedSign(); + public List customStyleSignVisualText = getDefaultVisualSign(); + public int customStyleUpdateRate = 20; - public boolean isProtected = true; public int protectionTime = 900; public int breakingTime = 1800; public boolean keepBlockAfterBreaking = true; @@ -62,6 +63,7 @@ public class ConfigData extends VersionedConfigData implements Cloneable { public double hologramOffset = 1.2; public List hologramProtectedText = getDefaultProtectedHologram(); public List hologramText = getDefaultHologram(); + public List hologramVisualText = getDefaultVisualHologram(); public String guiTitle = ""; public List guiProtectedText = getDefaultProtectedGui(); @@ -108,6 +110,15 @@ private static List getDefaultProtectedHologram() { return list; } + private static List getDefaultVisualHologram() { + List list = new ArrayList<>(); + + list.add("${player}'>"); + list.add("${death_cause}"); + + return list; + } + private static List getDefaultHologram() { List list = new ArrayList<>(); @@ -156,6 +167,14 @@ private static List getDefaultProtectedSign() { return list; } + private List getDefaultVisualSign() { + List list = new ArrayList<>(); + + list.add("${player}"); + + return list; + } + private static List getDefaultSign() { List list = new ArrayList<>(); diff --git a/src/main/java/eu/pb4/graves/config/data/old/ConfigDataV1.java b/src/main/java/eu/pb4/graves/config/data/old/ConfigDataV1.java index 20efcda..73fc6fb 100644 --- a/src/main/java/eu/pb4/graves/config/data/old/ConfigDataV1.java +++ b/src/main/java/eu/pb4/graves/config/data/old/ConfigDataV1.java @@ -122,7 +122,6 @@ public ConfigData update() { config.graveStyle = this.graveType; config.presetHeadUnlockedTexture = this.unlockedTexture; config.presetHeadLockedTexture = this.lockedTexture; - config.isProtected = this.isProtected; config.protectionTime = this.shouldProtectionExpire ? this.protectionTime : -1; config.breakingTime = this.shouldBreak ? this.breakAfter : -1; config.xpStorageType = this.storeExperience ? this.xpStorageType : GravesXPCalculation.DROP.name; diff --git a/src/main/java/eu/pb4/graves/grave/Grave.java b/src/main/java/eu/pb4/graves/grave/Grave.java index 04e7429..1625ed2 100644 --- a/src/main/java/eu/pb4/graves/grave/Grave.java +++ b/src/main/java/eu/pb4/graves/grave/Grave.java @@ -47,6 +47,7 @@ public final class Grave { protected Location location; protected GraveType type; protected boolean isRemoved; + protected long id = -1; protected boolean utilProtectionChangeMessage; protected boolean isProtectionEnabled; @@ -67,7 +68,7 @@ public Grave() { this.visualData = VisualGraveData.DEFAULT; } - public Grave(GameProfile profile, BlockPos position, Identifier world, GraveType type, long creationTime, long gameCreationTime, int xp, Text deathCause, Collection allowedUUIDs, Collection itemStacks, boolean isProtectionEnabled) { + public Grave(long id, GameProfile profile, BlockPos position, Identifier world, GraveType type, long creationTime, long gameCreationTime, int xp, Text deathCause, Collection allowedUUIDs, Collection itemStacks, boolean isProtectionEnabled) { this.gameProfile = profile; this.creationTime = creationTime; this.gameCreationTime = gameCreationTime; @@ -79,17 +80,19 @@ public Grave(GameProfile profile, BlockPos position, Identifier world, GraveType this.items = DefaultedList.copyOf(PositionedItemStack.EMPTY, itemStacks.toArray(new PositionedItemStack[0])); this.utilProtectionChangeMessage = !this.isProtected(); this.isProtectionEnabled = isProtectionEnabled; + this.id = id; this.updateDisplay(); } public static final Grave createBlock(GameProfile profile, Identifier world, BlockPos position, int xp, Text deathCause, Collection allowedUUIDs, Collection itemStacks) { - return new Grave(profile, position, world, GraveType.BLOCK, System.currentTimeMillis() / 1000, GraveManager.INSTANCE.getCurrentGameTime(), xp, deathCause, allowedUUIDs, itemStacks, true); + return new Grave(GraveManager.INSTANCE.requestId(),profile, position, world, GraveType.BLOCK, System.currentTimeMillis() / 1000, GraveManager.INSTANCE.getCurrentGameTime(), xp, deathCause, allowedUUIDs, itemStacks, true); } public NbtCompound writeNbt(NbtCompound nbt) { if (this.gameProfile != null) { nbt.put("GameProfile", NbtHelper.writeGameProfile(new NbtCompound(), this.gameProfile)); } + nbt.putLong("Id", this.id); nbt.putInt("XP", this.xp); nbt.putLong("CreationTime", this.creationTime); nbt.putInt("ItemCount", this.itemCount); @@ -116,6 +119,12 @@ public NbtCompound writeNbt(NbtCompound nbt) { public void readNbt(NbtCompound nbt) { try { + if (nbt.contains("Id", NbtElement.LONG_TYPE)) { + this.id = nbt.getLong("Id"); + } else { + this.id = GraveManager.INSTANCE.requestId(); + } + this.gameProfile = NbtHelper.toGameProfile(nbt.getCompound("GameProfile")); this.xp = nbt.getInt("XP"); this.creationTime = nbt.getLong("CreationTime"); @@ -161,13 +170,13 @@ public VisualGraveData toVisualGraveData() { public Map getPlaceholders(MinecraftServer server) { Config config = ConfigManager.getConfig(); - long protectionTime = config.configData.protectionTime > -1 ? getTimeLeft(config.configData.protectionTime, config.configData.useRealTime) : Long.MAX_VALUE; - long breakTime = config.configData.breakingTime > -1 ? getTimeLeft(config.configData.breakingTime, config.configData.useRealTime) : Long.MAX_VALUE; + long protectionTime = GraveManager.INSTANCE.getProtectionTime() > -1 ? getTimeLeft(GraveManager.INSTANCE.getProtectionTime(), config.configData.useRealTime) : Long.MAX_VALUE; + long breakTime = GraveManager.INSTANCE.getBreakingTime() > -1 ? getTimeLeft(GraveManager.INSTANCE.getBreakingTime(), config.configData.useRealTime) : Long.MAX_VALUE; Map values = new HashMap<>(); values.put("player", new LiteralText(this.gameProfile != null ? this.gameProfile.getName() : "")); - values.put("protection_time", new LiteralText("" + (config.configData.protectionTime > -1 ? config.getFormattedTime(protectionTime) : config.configData.infinityText))); - values.put("break_time", new LiteralText("" + (config.configData.breakingTime > -1 ? config.getFormattedTime(breakTime) : config.configData.infinityText))); + values.put("protection_time", new LiteralText("" + (GraveManager.INSTANCE.getProtectionTime() > -1 ? config.getFormattedTime(protectionTime) : config.configData.infinityText))); + values.put("break_time", new LiteralText("" + (GraveManager.INSTANCE.getBreakingTime() > -1 ? config.getFormattedTime(breakTime) : config.configData.infinityText))); values.put("xp", new LiteralText("" + this.xp)); values.put("item_count", new LiteralText("" + this.itemCount)); values.put("position", new LiteralText("" + this.location.blockPos().toShortString())); @@ -177,10 +186,10 @@ public Map getPlaceholders(MinecraftServer server) { } public boolean shouldNaturallyBreak() { - Config config = ConfigManager.getConfig(); + var time = GraveManager.INSTANCE.getBreakingTime(); - if (config.configData.breakingTime > -1) { - long breakTime = getTimeLeft(config.configData.breakingTime, config.configData.useRealTime); + if (time > -1) { + long breakTime = getTimeLeft(time, ConfigManager.getConfig().configData.useRealTime); return breakTime <= 0; } else { @@ -193,14 +202,14 @@ public boolean isProtected() { } public boolean isTimeProtected() { - Config config = ConfigManager.getConfig(); + var time = GraveManager.INSTANCE.getProtectionTime(); - if (config.configData.protectionTime > -1 && config.configData.isProtected) { - long protectionTime = getTimeLeft(config.configData.protectionTime, config.configData.useRealTime); + if (time > -1 && GraveManager.INSTANCE.isProtectionEnabled()) { + long protectionTime = getTimeLeft(time, ConfigManager.getConfig().configData.useRealTime); return protectionTime > 0; } else { - return config.configData.isProtected; + return GraveManager.INSTANCE.isProtectionEnabled(); } } @@ -242,6 +251,14 @@ public Location getLocation() { return this.location; } + public void setLocation(Identifier identifier, BlockPos pos) { + setLocation(new Location(identifier, pos)); + } + + public void setLocation(Location location) { + this.location = location; + } + public List getItems() { return this.items; } @@ -374,22 +391,27 @@ public boolean isEmpty() { } public void quickEquip(ServerPlayerEntity player) { - if (this.canTakeFrom(player)) { - for (var item : this.items) { - if (!item.isEmpty() && item.inventoryMask() != null) { - item.inventoryMask().moveToPlayerExactly(player, item.stack(), item.slot(), item.optionalData()); + try { + + if (this.canTakeFrom(player)) { + for (var item : this.items) { + if (!item.isEmpty() && item.inventoryMask() != null) { + item.inventoryMask().moveToPlayerExactly(player, item.stack(), item.slot(), item.optionalData()); + } } - } - for (var item : this.items) { - if (!item.isEmpty()) { - if (item.inventoryMask() != null) { - item.inventoryMask().moveToPlayerClosest(player, item.stack(), item.slot(), item.optionalData()); - } else { - VanillaInventoryMask.INSTANCE.moveToPlayerClosest(player, item.stack(), -1, null); + for (var item : this.items) { + if (!item.isEmpty()) { + if (item.inventoryMask() != null) { + item.inventoryMask().moveToPlayerClosest(player, item.stack(), item.slot(), item.optionalData()); + } else { + VanillaInventoryMask.INSTANCE.moveToPlayerClosest(player, item.stack(), -1, null); + } } } + this.updateSelf(player.getServer()); } - this.updateSelf(player.getServer()); + } catch (Exception e) { + e.printStackTrace(); } } @@ -406,11 +428,15 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Grave graveInfo = (Grave) o; - return Objects.equals(this.location, graveInfo.location); + return Objects.equals(this.id, graveInfo.id); } @Override public int hashCode() { - return this.location.hashCode(); + return Objects.hashCode(this.id); + } + + public long getId() { + return this.id; } } diff --git a/src/main/java/eu/pb4/graves/grave/GraveManager.java b/src/main/java/eu/pb4/graves/grave/GraveManager.java index a4c5226..1ac5636 100644 --- a/src/main/java/eu/pb4/graves/grave/GraveManager.java +++ b/src/main/java/eu/pb4/graves/grave/GraveManager.java @@ -1,6 +1,10 @@ package eu.pb4.graves.grave; import eu.pb4.graves.other.Location; +import eu.pb4.graves.registry.GraveGameRules; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtElement; import net.minecraft.nbt.NbtList; @@ -17,13 +21,22 @@ public class GraveManager extends PersistentState { private HashMap> byUuid = new HashMap<>(); private HashMap byLocation = new HashMap<>(); + private Long2ObjectMap byId = new Long2ObjectOpenHashMap<>(); private HashSet graves = new HashSet<>(); private long ticker; private long currentGameTime; + private long currentGraveId = 0; + private int protectionTime; + private int breakingTime; public void add(Grave grave) { + if (grave.id == -1) { + grave.id = this.requestId(); + } + this.byUuid.computeIfAbsent(grave.gameProfile.getId(), (v) -> new HashSet<>()).add(grave); this.byLocation.put(grave.location, grave); + this.byId.put(grave.id, grave); this.graves.add(grave); this.markDirty(); } @@ -32,6 +45,7 @@ public void remove(Grave info) { if (this.graves.remove(info)) { var graveInfoList = this.byUuid.get(info.gameProfile.getId()); this.byLocation.remove(info.location); + this.byId.remove(info.id); if (graveInfoList != null) { graveInfoList.remove(info); if (graveInfoList.isEmpty()) { @@ -54,24 +68,25 @@ public NbtCompound writeNbt(NbtCompound nbt) { nbt.put("Graves", list); nbt.putInt("Version", 2); nbt.putLong("CurrentGameTime", this.currentGameTime); + nbt.putLong("CurrentGrave", this.currentGraveId); return nbt; } - public static PersistentState fromNbt(NbtCompound nbt) { + public static PersistentState fromNbt(NbtCompound nbt, MinecraftServer server) { GraveManager manager = new GraveManager(); + manager.protectionTime = GraveGameRules.getProtectionTime(server); + manager.breakingTime = GraveGameRules.getBreakingTime(server); GraveManager.INSTANCE = manager; manager.currentGameTime = nbt.getLong("CurrentGameTime"); + manager.currentGraveId = nbt.getLong("CurrentGrave"); NbtList graves = nbt.getList("Graves", NbtElement.COMPOUND_TYPE); for (NbtElement graveNbt : graves) { Grave graveInfo = new Grave(); graveInfo.readNbt((NbtCompound) graveNbt); - - if (!graveInfo.shouldNaturallyBreak()) { - manager.add(graveInfo); - } + manager.add(graveInfo); } return manager; } @@ -86,6 +101,10 @@ public Collection getByUuid(UUID uuid) { return Collections.emptyList(); } + public Grave getId(long id) { + return this.byId.get(id); + } + public Grave getByLocation(Location location) { return this.byLocation.get(location); } @@ -104,12 +123,19 @@ public Collection getAll() { public void tick(MinecraftServer server) { this.ticker++; - if (this.ticker >= 20) { this.ticker = 0; this.currentGameTime++; - for (var grave : this.graves) { - grave.tick(server); + + this.protectionTime = GraveGameRules.getProtectionTime(server); + this.breakingTime = GraveGameRules.getBreakingTime(server); + + try { + for (var grave : this.graves.toArray(new Grave[0])) { + grave.tick(server); + } + } catch (Exception e) { + e.printStackTrace(); } } } @@ -117,4 +143,20 @@ public void tick(MinecraftServer server) { public long getCurrentGameTime() { return this.currentGameTime; } + + public long requestId() { + return this.currentGraveId++; + } + + public int getProtectionTime() { + return this.protectionTime; + } + + public boolean isProtectionEnabled() { + return this.protectionTime != 0; + } + + public int getBreakingTime() { + return this.breakingTime; + } } diff --git a/src/main/java/eu/pb4/graves/registry/GraveBlockEntity.java b/src/main/java/eu/pb4/graves/registry/GraveBlockEntity.java index 0b4f2ba..c5601b4 100644 --- a/src/main/java/eu/pb4/graves/registry/GraveBlockEntity.java +++ b/src/main/java/eu/pb4/graves/registry/GraveBlockEntity.java @@ -41,6 +41,7 @@ public class GraveBlockEntity extends AbstractGraveBlockEntity { private Grave data = null; private int dataRetrieveTries = 0; private VisualGraveData visualData = VisualGraveData.DEFAULT; + private long graveId = -1; public GraveBlockEntity(BlockPos pos, BlockState state) { super(BLOCK_ENTITY_TYPE, pos, state); @@ -51,6 +52,7 @@ public void setGrave(Grave grave, BlockState oldBlockState) { this.replacedBlockState = oldBlockState; this.visualData = grave.toVisualGraveData(); GraveManager.INSTANCE.add(grave); + this.graveId = grave.getId(); this.markDirty(); } @@ -59,6 +61,9 @@ protected void writeNbt(NbtCompound nbt) { super.writeNbt(nbt); nbt.put("BlockState", NbtHelper.fromBlockState(this.replacedBlockState)); nbt.put("VisualData", this.getClientData().toNbt()); + if (this.data != null) { + nbt.putLong("GraveId", this.graveId); + } } @@ -66,8 +71,8 @@ protected void writeNbt(NbtCompound nbt) { public void readNbt(NbtCompound nbt) { super.readNbt(nbt); try { - // Legacy grave handling if (nbt.contains("GraveInfo", NbtElement.COMPOUND_TYPE)) { + // Legacy grave handling this.data = new Grave(); this.data.readNbt(nbt.getCompound("GraveInfo")); @@ -77,13 +82,15 @@ public void readNbt(NbtCompound nbt) { this.data.getItems().add(new PositionedItemStack(ItemStack.fromNbt((NbtCompound) compound), -1, VanillaInventoryMask.INSTANCE, null)); } GraveManager.INSTANCE.add(this.data); - } else { - this.data = GraveManager.INSTANCE.getByLocation(new Location(this.world.getRegistryKey().getValue(), this.pos)); + } else if (nbt.contains("GraveId", NbtElement.LONG_TYPE)) { + this.graveId = nbt.getLong("GraveId"); + } + + if (this.data == null) { + this.fetchGraveData(); } - if (this.data != null) { - this.visualData = data.toVisualGraveData(); - } else { + if (this.visualData == null) { this.visualData = VisualGraveData.fromNbt(nbt.getCompound("VisualData")); } @@ -93,6 +100,20 @@ public void readNbt(NbtCompound nbt) { } } + protected void fetchGraveData() { + this.data = GraveManager.INSTANCE.getId(this.graveId); + + if (this.data == null) { + // Beta.1 grave handling + this.data = GraveManager.INSTANCE.getByLocation(new Location(this.world.getRegistryKey().getValue(), this.pos)); + } + + if (this.data != null) { + this.visualData = this.data.toVisualGraveData(); + this.updateForAllPlayers(); + } + } + protected void updateForAllPlayers() { assert this.world != null; @@ -132,17 +153,14 @@ public static void tick(World world, BlockPos pos, Block } if (self.data == null) { - self.data = GraveManager.INSTANCE.getByLocation(world, pos); + self.fetchGraveData(); + self.dataRetrieveTries++; - if (self.data == null) { - self.dataRetrieveTries++; - - if (self.dataRetrieveTries > 10) { - self.breakBlock(); - } - - return; + if (self.dataRetrieveTries > 10) { + self.breakBlock(); } + + return; } if (self.data.isRemoved()) { @@ -183,7 +201,7 @@ public static void tick(World world, BlockPos pos, Block self.hologram = new WorldHologram((ServerWorld) world, new Vec3d(pos.getX(), pos.getY(), pos.getZ()).add(0.5, config.configData.hologramOffset, 0.5)) { @Override public boolean canAddPlayer(ServerPlayerEntity player) { - return !config.configData.hologramDisplayIfOnClient ? !GraveNetworking.canReceive(player.networkHandler) : true; + return config.configData.hologramDisplayIfOnClient || !GraveNetworking.canReceive(player.networkHandler); } }; self.hologram.show(); diff --git a/src/main/java/eu/pb4/graves/registry/GraveGameRules.java b/src/main/java/eu/pb4/graves/registry/GraveGameRules.java new file mode 100644 index 0000000..3c4a97f --- /dev/null +++ b/src/main/java/eu/pb4/graves/registry/GraveGameRules.java @@ -0,0 +1,35 @@ +package eu.pb4.graves.registry; + +import eu.pb4.graves.config.ConfigManager; +import net.fabricmc.fabric.api.gamerule.v1.GameRuleFactory; +import net.fabricmc.fabric.api.gamerule.v1.GameRuleRegistry; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.GameRules; + +public class GraveGameRules { + public static final GameRules.Key PROTECTION_TIME = + GameRuleRegistry.register("universal_graves:protection_time", GameRules.Category.PLAYER, GameRuleFactory.createIntRule(-2, -2)); + public static final GameRules.Key BREAKING_TIME = + GameRuleRegistry.register("universal_graves:breaking_time", GameRules.Category.PLAYER, GameRuleFactory.createIntRule(-2, -2)); + + + public static final int getProtectionTime(MinecraftServer server) { + var rule = server.getOverworld().getGameRules().get(PROTECTION_TIME).get(); + + if (rule == -2) { + return ConfigManager.getConfig().configData.protectionTime; + } else { + return rule; + } + } + + public static final int getBreakingTime(MinecraftServer server) { + var rule = server.getOverworld().getGameRules().get(BREAKING_TIME).get(); + + if (rule == -2) { + return ConfigManager.getConfig().configData.breakingTime; + } else { + return rule; + } + } +} diff --git a/src/main/java/eu/pb4/graves/registry/VisualGraveBlock.java b/src/main/java/eu/pb4/graves/registry/VisualGraveBlock.java index 64300d1..b6dc1a3 100644 --- a/src/main/java/eu/pb4/graves/registry/VisualGraveBlock.java +++ b/src/main/java/eu/pb4/graves/registry/VisualGraveBlock.java @@ -91,8 +91,8 @@ public void onPolymerBlockSend(ServerPlayerEntity player, BlockPos.Mutable pos, var blockEntity = player.world.getBlockEntity(pos); boolean locked = state.get(IS_LOCKED); - if (blockEntity instanceof VisualGraveBlockEntity grave && !GraveNetworking.sendGrave(player.networkHandler, pos, locked, grave.getGrave(), grave.getGrave().getPlaceholders(player.server), grave.getTextOverrides())) { - ConfigManager.getConfig().style.converter.sendNbt(player, state, pos.toImmutable(), state.get(Properties.ROTATION), state.get(IS_LOCKED), grave.getGrave(), null, grave.getTextOverrides()); + if (blockEntity instanceof VisualGraveBlockEntity grave && !GraveNetworking.sendGrave(player.networkHandler, pos, locked, grave.getGrave(), grave.getGrave().getPlaceholders(player.server), grave.getSignText())) { + ConfigManager.getConfig().style.converter.sendNbt(player, state, pos.toImmutable(), state.get(Properties.ROTATION), state.get(IS_LOCKED), grave.getGrave(), null, grave.getSignText()); } } diff --git a/src/main/java/eu/pb4/graves/registry/VisualGraveBlockEntity.java b/src/main/java/eu/pb4/graves/registry/VisualGraveBlockEntity.java index ec60d24..64f7326 100644 --- a/src/main/java/eu/pb4/graves/registry/VisualGraveBlockEntity.java +++ b/src/main/java/eu/pb4/graves/registry/VisualGraveBlockEntity.java @@ -143,7 +143,7 @@ public boolean canAddPlayer(ServerPlayerEntity player) { } } } else { - for (Text text : config.hologramText) { + for (Text text : config.hologramVisualText) { if (!text.equals(LiteralText.EMPTY)) { texts.add(PlaceholderAPI.parsePredefinedText(text, PlaceholderAPI.PREDEFINED_PLACEHOLDER_PATTERN, placeholders)); } else { @@ -188,6 +188,10 @@ public VisualGraveData getClientData() { return this.visualData; } + public Text[] getSignText() { + return this.textOverrides != null ? this.textOverrides : ConfigManager.getConfig().signVisualText; + } + public Text[] getTextOverrides() { return this.textOverrides; } diff --git a/src/main/java/eu/pb4/graves/registry/VisualGraveBlockItem.java b/src/main/java/eu/pb4/graves/registry/VisualGraveBlockItem.java index cdb385f..b298db0 100644 --- a/src/main/java/eu/pb4/graves/registry/VisualGraveBlockItem.java +++ b/src/main/java/eu/pb4/graves/registry/VisualGraveBlockItem.java @@ -22,9 +22,9 @@ public Item getPolymerItem(ItemStack itemStack, @Nullable ServerPlayerEntity pla @Override public ItemStack getPolymerItemStack(ItemStack itemStack, @Nullable ServerPlayerEntity player) { - if (player != null && GraveNetworking.canReceive(player.networkHandler)) { + /*if (player != null && GraveNetworking.canReceive(player.networkHandler)) { return itemStack; - } + }*/ return PolymerItem.super.getPolymerItemStack(itemStack, player); } diff --git a/src/main/java/eu/pb4/graves/ui/GraveGui.java b/src/main/java/eu/pb4/graves/ui/GraveGui.java index ecde1d0..fd279e4 100644 --- a/src/main/java/eu/pb4/graves/ui/GraveGui.java +++ b/src/main/java/eu/pb4/graves/ui/GraveGui.java @@ -30,10 +30,12 @@ public GraveGui(ServerPlayerEntity player, Grave grave, boolean canTake) { return; } - this.addSlotRedirect(new OutputSlot(inventory, x, 0, 0, canTake)); + if (!inventory.getStack(x).isEmpty()) { + this.addSlotRedirect(new OutputSlot(inventory, x, 0, 0, canTake)); + } } - for (; x < this.getSize(); x++) { + while (this.getFirstEmptySlot() != -1) { this.addSlot(emptyPane); } } diff --git a/src/main/resources/data/universal_graves/lang/en_us.json b/src/main/resources/data/universal_graves/lang/en_us.json index 05657f4..67cc885 100644 --- a/src/main/resources/data/universal_graves/lang/en_us.json +++ b/src/main/resources/data/universal_graves/lang/en_us.json @@ -24,5 +24,8 @@ "item.universal_graves.grave_compass": "Grave Compass", "block.universal_graves.grave": "Grave", - "block.universal_graves.visual_grave": "Gravestone" + "block.universal_graves.visual_grave": "Gravestone", + + "gamerule.universal_graves:protection_time": "Time of grave's protection against other players", + "gamerule.universal_graves:breaking_time": "Grave expiration time" } \ No newline at end of file