diff --git a/shared/src/main/java/net/blay09/mods/waystones/api/WaystoneRemoveReceivedEvent.java b/shared/src/main/java/net/blay09/mods/waystones/api/WaystoneRemoveReceivedEvent.java new file mode 100644 index 00000000..0d0fd753 --- /dev/null +++ b/shared/src/main/java/net/blay09/mods/waystones/api/WaystoneRemoveReceivedEvent.java @@ -0,0 +1,36 @@ +package net.blay09.mods.waystones.api; + +import net.blay09.mods.balm.api.event.BalmEvent; +import net.minecraft.resources.ResourceLocation; + +import java.util.UUID; + +/** + * This event is fired on the client side when the client has been notified of a waystone being removed. + */ +public class WaystoneRemoveReceivedEvent extends BalmEvent { + private final ResourceLocation waystoneType; + private final UUID waystoneId; + private final boolean wasDestroyed; + + public WaystoneRemoveReceivedEvent(ResourceLocation waystoneType, UUID waystoneId, boolean wasDestroyed) { + this.waystoneType = waystoneType; + this.waystoneId = waystoneId; + this.wasDestroyed = wasDestroyed; + } + + public ResourceLocation getWaystoneType() { + return waystoneType; + } + + public UUID getWaystoneId() { + return waystoneId; + } + + /** + * @return true if the waystone was destroyed, i.e. it is not just being moved with silk touch + */ + public boolean wasDestroyed() { + return wasDestroyed; + } +} diff --git a/shared/src/main/java/net/blay09/mods/waystones/block/WaystoneBlockBase.java b/shared/src/main/java/net/blay09/mods/waystones/block/WaystoneBlockBase.java index 8ba3c00b..42cd1fc4 100644 --- a/shared/src/main/java/net/blay09/mods/waystones/block/WaystoneBlockBase.java +++ b/shared/src/main/java/net/blay09/mods/waystones/block/WaystoneBlockBase.java @@ -246,12 +246,14 @@ protected InteractionResult handleActivation(Level world, BlockPos pos, Player p @Override public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) { if (!state.is(newState.getBlock())) { - BlockEntity blockEntity = world.getBlockEntity(pos); - if (blockEntity instanceof WaystoneBlockEntityBase && (!canSilkTouch() || !((WaystoneBlockEntityBase) blockEntity).isSilkTouched())) { - IWaystone waystone = ((WaystoneBlockEntityBase) blockEntity).getWaystone(); + final var blockEntity = world.getBlockEntity(pos); + final var waystone = ((WaystoneBlockEntityBase) blockEntity).getWaystone(); + final var wasNotSilkTouched = blockEntity instanceof WaystoneBlockEntityBase && (!canSilkTouch() || !((WaystoneBlockEntityBase) blockEntity).isSilkTouched()); + if (wasNotSilkTouched) { WaystoneManager.get(world.getServer()).removeWaystone(waystone); PlayerWaystoneManager.removeKnownWaystone(world.getServer(), waystone); } + WaystoneSyncManager.sendWaystoneRemovalToAll(world.getServer(), waystone, wasNotSilkTouched); } super.onRemove(state, world, pos, newState, isMoving); diff --git a/shared/src/main/java/net/blay09/mods/waystones/block/entity/WaystoneBlockEntityBase.java b/shared/src/main/java/net/blay09/mods/waystones/block/entity/WaystoneBlockEntityBase.java index 15db5d97..2308cc14 100644 --- a/shared/src/main/java/net/blay09/mods/waystones/block/entity/WaystoneBlockEntityBase.java +++ b/shared/src/main/java/net/blay09/mods/waystones/block/entity/WaystoneBlockEntityBase.java @@ -146,6 +146,7 @@ public void uninitializeWaystone() { if (waystone.isValid()) { WaystoneManager.get(level.getServer()).removeWaystone(waystone); PlayerWaystoneManager.removeKnownWaystone(level.getServer(), waystone); + WaystoneSyncManager.sendWaystoneRemovalToAll(level.getServer(), waystone, true); } waystone = InvalidWaystone.INSTANCE; diff --git a/shared/src/main/java/net/blay09/mods/waystones/compat/JourneyMapIntegration.java b/shared/src/main/java/net/blay09/mods/waystones/compat/JourneyMapIntegration.java index 7bed0350..d15b21fc 100644 --- a/shared/src/main/java/net/blay09/mods/waystones/compat/JourneyMapIntegration.java +++ b/shared/src/main/java/net/blay09/mods/waystones/compat/JourneyMapIntegration.java @@ -8,10 +8,7 @@ import journeymap.client.api.event.ClientEvent; import net.blay09.mods.balm.api.Balm; import net.blay09.mods.waystones.Waystones; -import net.blay09.mods.waystones.api.IWaystone; -import net.blay09.mods.waystones.api.WaystoneTypes; -import net.blay09.mods.waystones.api.WaystoneUpdateReceivedEvent; -import net.blay09.mods.waystones.api.WaystonesListReceivedEvent; +import net.blay09.mods.waystones.api.*; import net.blay09.mods.waystones.config.WaystonesConfig; import net.blay09.mods.waystones.config.WaystonesConfigData; import net.minecraft.client.resources.language.I18n; @@ -36,6 +33,7 @@ public JourneyMapIntegration() { instance = this; Balm.getEvents().onEvent(WaystonesListReceivedEvent.class, this::onWaystonesListReceived); Balm.getEvents().onEvent(WaystoneUpdateReceivedEvent.class, this::onWaystoneUpdateReceived); + Balm.getEvents().onEvent(WaystoneRemoveReceivedEvent.class, this::onWaystoneRemoveReceived); } @Override @@ -96,6 +94,12 @@ public void onWaystoneUpdateReceived(WaystoneUpdateReceivedEvent event) { } } + public void onWaystoneRemoveReceived(WaystoneRemoveReceivedEvent event) { + if (shouldManageWaypoints() && isSupportedWaystoneType(event.getWaystoneType())) { + runWhenJourneyMapIsReady(() -> removeWaypoint(event.getWaystoneType(), event.getWaystoneId())); + } + } + private void runWhenJourneyMapIsReady(Runnable runnable) { if (journeyMapReady) { runnable.run(); @@ -120,6 +124,14 @@ private void updateAllWaypoints(ResourceLocation waystoneType, List w } } + private void removeWaypoint(ResourceLocation waystoneType, UUID waystoneId) { + final var prefixedId = getPrefixedWaystoneId(waystoneType, waystoneId); + final var waypoint = api.getWaypoint(Waystones.MOD_ID, prefixedId); + if (waypoint != null) { + api.remove(waypoint); + } + } + private void updateWaypoint(IWaystone waystone) { try { final var prefixedId = getPrefixedWaystoneId(waystone); @@ -153,7 +165,10 @@ private static WaypointGroup getWaystoneGroup(IWaystone waystone) { } private String getPrefixedWaystoneId(IWaystone waystone) { - return waystone.getWaystoneType().getPath() + ":" + waystone.getWaystoneUid().toString(); + return getPrefixedWaystoneId(waystone.getWaystoneType(), waystone.getWaystoneUid()); } + private String getPrefixedWaystoneId(ResourceLocation waystoneType, UUID waystoneId) { + return waystoneType.getPath() + ":" + waystoneId.toString(); + } } diff --git a/shared/src/main/java/net/blay09/mods/waystones/core/WaystoneSyncManager.java b/shared/src/main/java/net/blay09/mods/waystones/core/WaystoneSyncManager.java index 157ff6ff..c814254d 100644 --- a/shared/src/main/java/net/blay09/mods/waystones/core/WaystoneSyncManager.java +++ b/shared/src/main/java/net/blay09/mods/waystones/core/WaystoneSyncManager.java @@ -6,6 +6,7 @@ import net.blay09.mods.waystones.network.message.KnownWaystonesMessage; import net.blay09.mods.waystones.network.message.PlayerWaystoneCooldownsMessage; import net.blay09.mods.waystones.network.message.UpdateWaystoneMessage; +import net.blay09.mods.waystones.network.message.WaystoneRemovedMessage; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; @@ -29,6 +30,17 @@ public static void sendWaystoneUpdateToAll(@Nullable MinecraftServer server, IWa } } + public static void sendWaystoneRemovalToAll(@Nullable MinecraftServer server, IWaystone waystone, boolean wasDestroyed) { + if (server == null) { + return; + } + + List players = server.getPlayerList().getPlayers(); + for (ServerPlayer player : players) { + sendWaystoneRemoval(player, waystone, wasDestroyed); + } + } + public static void sendActivatedWaystones(Player player) { List waystones = PlayerWaystoneManager.getWaystones(player); Balm.getNetworking().sendTo(player, new KnownWaystonesMessage(WaystoneTypes.WAYSTONE, waystones)); @@ -46,6 +58,13 @@ public static void sendWaystoneUpdate(Player player, IWaystone waystone) { } } + public static void sendWaystoneRemoval(Player player, IWaystone waystone, boolean wasDestroyed) { + // If this is a waystone, only send an update if the player has activated it already + if (!waystone.getWaystoneType().equals(WaystoneTypes.WAYSTONE) || PlayerWaystoneManager.isWaystoneActivated(player, waystone)) { + Balm.getNetworking().sendTo(player, new WaystoneRemovedMessage(waystone.getWaystoneType(), waystone.getWaystoneUid(), wasDestroyed)); + } + } + public static void sendWaystoneCooldowns(Player player) { long inventoryButtonCooldownUntil = PlayerWaystoneManager.getInventoryButtonCooldownUntil(player); long warpStoneCooldownUntil = PlayerWaystoneManager.getWarpStoneCooldownUntil(player); diff --git a/shared/src/main/java/net/blay09/mods/waystones/network/ModNetworking.java b/shared/src/main/java/net/blay09/mods/waystones/network/ModNetworking.java index 4cae6e51..7e90858d 100644 --- a/shared/src/main/java/net/blay09/mods/waystones/network/ModNetworking.java +++ b/shared/src/main/java/net/blay09/mods/waystones/network/ModNetworking.java @@ -19,6 +19,7 @@ public static void initialize(BalmNetworking networking) { networking.registerServerboundPacket(id("request_edit_waystone"), RequestEditWaystoneMessage.class, RequestEditWaystoneMessage::encode, RequestEditWaystoneMessage::decode, RequestEditWaystoneMessage::handle); networking.registerClientboundPacket(id("waystone_update"), UpdateWaystoneMessage.class, UpdateWaystoneMessage::encode, UpdateWaystoneMessage::decode, UpdateWaystoneMessage::handle); + networking.registerClientboundPacket(id("waystone_removed"), WaystoneRemovedMessage.class, WaystoneRemovedMessage::encode, WaystoneRemovedMessage::decode, WaystoneRemovedMessage::handle); networking.registerClientboundPacket(id("known_waystones"), KnownWaystonesMessage.class, KnownWaystonesMessage::encode, KnownWaystonesMessage::decode, KnownWaystonesMessage::handle); networking.registerClientboundPacket(id("teleport_effect"), TeleportEffectMessage.class, TeleportEffectMessage::encode, TeleportEffectMessage::decode, TeleportEffectMessage::handle); networking.registerClientboundPacket(id("waystone_cooldown"), PlayerWaystoneCooldownsMessage.class, PlayerWaystoneCooldownsMessage::encode, PlayerWaystoneCooldownsMessage::decode, PlayerWaystoneCooldownsMessage::handle); diff --git a/shared/src/main/java/net/blay09/mods/waystones/network/message/RemoveWaystoneMessage.java b/shared/src/main/java/net/blay09/mods/waystones/network/message/RemoveWaystoneMessage.java index 0609951e..f4481bf7 100644 --- a/shared/src/main/java/net/blay09/mods/waystones/network/message/RemoveWaystoneMessage.java +++ b/shared/src/main/java/net/blay09/mods/waystones/network/message/RemoveWaystoneMessage.java @@ -2,10 +2,7 @@ import net.blay09.mods.waystones.api.IWaystone; import net.blay09.mods.waystones.block.WaystoneBlock; -import net.blay09.mods.waystones.core.PlayerWaystoneManager; -import net.blay09.mods.waystones.core.Waystone; -import net.blay09.mods.waystones.core.WaystoneManager; -import net.blay09.mods.waystones.core.WaystoneProxy; +import net.blay09.mods.waystones.core.*; import net.minecraft.core.BlockPos; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; @@ -50,6 +47,7 @@ public static void handle(ServerPlayer player, RemoveWaystoneMessage message) { if (targetWorld == null || !(state.getBlock() instanceof WaystoneBlock)) { WaystoneManager.get(player.server).removeWaystone(backingWaystone); PlayerWaystoneManager.removeKnownWaystone(player.server, backingWaystone); + WaystoneSyncManager.sendWaystoneRemovalToAll(player.server, backingWaystone, true); } } } diff --git a/shared/src/main/java/net/blay09/mods/waystones/network/message/WaystoneRemovedMessage.java b/shared/src/main/java/net/blay09/mods/waystones/network/message/WaystoneRemovedMessage.java new file mode 100644 index 00000000..26ce86c5 --- /dev/null +++ b/shared/src/main/java/net/blay09/mods/waystones/network/message/WaystoneRemovedMessage.java @@ -0,0 +1,36 @@ +package net.blay09.mods.waystones.network.message; + +import net.blay09.mods.balm.api.Balm; +import net.blay09.mods.waystones.api.WaystoneRemoveReceivedEvent; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; + +import java.util.UUID; + +public class WaystoneRemovedMessage { + + private final ResourceLocation waystoneType; + private final UUID waystoneId; + private final boolean wasDestroyed; + + public WaystoneRemovedMessage(ResourceLocation waystoneType, UUID waystoneId, boolean wasDestroyed) { + this.waystoneType = waystoneType; + this.waystoneId = waystoneId; + this.wasDestroyed = wasDestroyed; + } + + public static void encode(WaystoneRemovedMessage message, FriendlyByteBuf buf) { + buf.writeResourceLocation(message.waystoneType); + buf.writeUUID(message.waystoneId); + buf.writeBoolean(message.wasDestroyed); + } + + public static WaystoneRemovedMessage decode(FriendlyByteBuf buf) { + return new WaystoneRemovedMessage(buf.readResourceLocation(), buf.readUUID(), buf.readBoolean()); + } + + public static void handle(Player player, WaystoneRemovedMessage message) { + Balm.getEvents().fireEvent(new WaystoneRemoveReceivedEvent(message.waystoneType, message.waystoneId, message.wasDestroyed)); + } +}