diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStone.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStone.java index e34dce68..70270bac 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStone.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStone.java @@ -21,10 +21,7 @@ package de.steamwar.bausystem.features.design.endstone; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.region.Region; -import de.steamwar.entity.REntity; -import de.steamwar.entity.REntityAction; -import de.steamwar.entity.REntityServer; -import de.steamwar.entity.RFallingBlockEntity; +import de.steamwar.entity.*; import net.md_5.bungee.api.ChatMessageType; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -60,15 +57,15 @@ public class DesignEndStone { .filter(material -> material.getBlastResistance() > region.getGameModeConfig().Schematic.MaxDesignBlastResistance) .collect(Collectors.toSet()); calculateFromBottom = region.getGameModeConfig().Arena.NoFloor; + } - entityServer.setCallback((player, rEntity, entityAction) -> { - if (entityAction != REntityAction.ATTACK) return; - Location location = new Location(WORLD, rEntity.getX(), rEntity.getY(), rEntity.getZ()); - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { - location.getBlock().breakNaturally(); - calc(); - }, 1); - }); + private void interact(Player player, RInteraction entity, REntityAction action) { + if (action != REntityAction.ATTACK) return; + Location location = new Location(WORLD, entity.getX(), entity.getY(), entity.getZ()); + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + location.getBlock().breakNaturally(); + calc(); + }, 1); } public void calc() { @@ -111,12 +108,15 @@ public class DesignEndStone { Material material = WORLD.getBlockAt(cx, cy, cz).getType(); if (material != Material.WATER && material != Material.LAVA && limited.contains(material)) { - Location location = new Location(WORLD, cx + 0.5, cy, cz + 0.5); + Location location = new Location(WORLD, cx, cy, cz); if (!locations.add(location)) break; - RFallingBlockEntity entity = new RFallingBlockEntity(entityServer, location, Material.RED_STAINED_GLASS); - entity.setNoGravity(true); + RBlockDisplay entity = new RBlockDisplay(entityServer, location); + entity.setBlock(Material.RED_STAINED_GLASS.createBlockData()); entity.setGlowing(true); entities.add(entity); + RInteraction interaction = new RInteraction(entityServer, location); + interaction.setCallback(this::interact); + entities.add(interaction); break; } else if (!material.isAir() && material != Material.WATER && material != Material.LAVA) { break; diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/Detonator.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/Detonator.java index 51d5e4e5..86932f2e 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/Detonator.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/Detonator.java @@ -26,8 +26,9 @@ import de.steamwar.bausystem.features.autostart.AutostartListener; import de.steamwar.bausystem.features.detonator.storage.DetonatorStorage; import de.steamwar.bausystem.features.detonator.storage.ItemStorage; import de.steamwar.core.SWPlayer; +import de.steamwar.entity.RBlockDisplay; import de.steamwar.entity.REntityServer; -import de.steamwar.entity.RFallingBlockEntity; +import de.steamwar.entity.RInteraction; import lombok.Getter; import lombok.Setter; import lombok.experimental.UtilityClass; @@ -58,10 +59,6 @@ public class Detonator { @Override public void onMount(SWPlayer player) { entities.addPlayer(player.getPlayer()); - entities.setCallback((player1, entity, action) -> { - Vector vector = new Vector(entity.getX(), entity.getY(), entity.getZ()); - DetonatorListener.addLocationToDetonator(vector.toLocation(player.getWorld()).getBlock().getLocation(), player1); - }); } @Override @@ -70,8 +67,6 @@ public class Detonator { } } - private static final Vector HALF = new Vector(0.5, 0, 0.5); - public static boolean isDetonator(ItemStack itemStack) { return ItemStorage.isDetonator(itemStack); } @@ -79,8 +74,14 @@ public class Detonator { public static void showDetonator(Player p, List locs) { DetonatorComponent detonatorComponent = SWPlayer.of(p).getComponentOrDefault(DetonatorComponent.class, DetonatorComponent::new); locs.forEach(location -> { - RFallingBlockEntity entity = new RFallingBlockEntity(detonatorComponent.entities, location.clone().add(HALF), Material.RED_STAINED_GLASS); - entity.setNoGravity(true); + RBlockDisplay blockDisplay = new RBlockDisplay(detonatorComponent.entities, location); + blockDisplay.setBlock(Material.RED_STAINED_GLASS.createBlockData()); + + RInteraction interaction = new RInteraction(detonatorComponent.entities, location); + interaction.setCallback((player, entity, action) -> { + Vector vector = new Vector(entity.getX(), entity.getY(), entity.getZ()); + DetonatorListener.addLocationToDetonator(vector.toLocation(player.getWorld()).getBlock().getLocation(), player); + }); }); } diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerVisualizer.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerVisualizer.java index 9efd6dc2..6b1f189e 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerVisualizer.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerVisualizer.java @@ -24,9 +24,9 @@ import de.steamwar.bausystem.region.Point; import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar; import de.steamwar.bausystem.utils.bossbar.BossBarService; +import de.steamwar.entity.RBlockDisplay; import de.steamwar.entity.REntity; import de.steamwar.entity.REntityServer; -import de.steamwar.entity.RFallingBlockEntity; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.World; @@ -290,8 +290,8 @@ public class KillcheckerVisualizer { } rEntities.get(point).die(); } - RFallingBlockEntity entity = new RFallingBlockEntity(outlinePoints.contains(point) ? outline : inner, point.toLocation(WORLD, 0.5, 0, 0.5), MATERIALS[Math.min(count - 1, MATERIALS.length) - 1]); - entity.setNoGravity(true); + RBlockDisplay entity = new RBlockDisplay(outlinePoints.contains(point) ? outline : inner, point.toLocation(WORLD, 0.5, 0, 0.5)); + entity.setBlock(MATERIALS[Math.min(count - 1, MATERIALS.length) - 1].createBlockData()); rEntities.put(point, entity); if (outlinePoints.contains(point)) outlinePointsCache.add(point); killCount.put(point, count); diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/ViewFlag.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/ViewFlag.java index c061bfe5..3938d88e 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/ViewFlag.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/ViewFlag.java @@ -20,8 +20,8 @@ package de.steamwar.bausystem.features.tracer.rendering; import de.steamwar.bausystem.features.tracer.TNTPoint; +import de.steamwar.entity.RBlockDisplay; import de.steamwar.entity.REntityServer; -import de.steamwar.entity.RFallingBlockEntity; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.util.Vector; @@ -129,8 +129,8 @@ public abstract class ViewFlag { Location yLocation = previous.getLocation().clone().add(0, delta.getY(), 0); if (yLocation.distanceSquared(representative.getLocation()) >= 1.0 / 256.0 && yLocation.distanceSquared(previous.getLocation()) >= 1.0 / 256.0) { - RFallingBlockEntity y = new RFallingBlockEntity(server, yLocation, Material.WHITE_STAINED_GLASS); - y.setNoGravity(true); + RBlockDisplay y = new RBlockDisplay(server, yLocation); + y.setBlock(Material.WHITE_STAINED_GLASS.createBlockData()); } Location secoundLocation; @@ -141,8 +141,8 @@ public abstract class ViewFlag { } if (secoundLocation.distanceSquared(representative.getLocation()) >= 1.0 / 256.0 && secoundLocation.distanceSquared(previous.getLocation()) >= 1.0 / 256.0) { - RFallingBlockEntity second = new RFallingBlockEntity(server, secoundLocation, Material.WHITE_STAINED_GLASS); - second.setNoGravity(true); + RBlockDisplay second = new RBlockDisplay(server, secoundLocation); + second.setBlock(Material.WHITE_STAINED_GLASS.createBlockData()); } } } diff --git a/LobbySystem/src/de/steamwar/lobby/boatrace/BoatRace.java b/LobbySystem/src/de/steamwar/lobby/boatrace/BoatRace.java index ea8575b9..11aa3023 100644 --- a/LobbySystem/src/de/steamwar/lobby/boatrace/BoatRace.java +++ b/LobbySystem/src/de/steamwar/lobby/boatrace/BoatRace.java @@ -22,6 +22,7 @@ package de.steamwar.lobby.boatrace; import de.steamwar.entity.REntity; import de.steamwar.entity.REntityAction; import de.steamwar.entity.REntityServer; +import de.steamwar.entity.RInteraction; import de.steamwar.lobby.LobbySystem; import de.steamwar.lobby.util.LeaderboardManager; import de.steamwar.sql.SteamwarUser; @@ -59,11 +60,12 @@ public class BoatRace implements EventListener, Listener { static { boatNpcServer = new REntityServer(); - REntity starter = new REntity(boatNpcServer, EntityType.VILLAGER, BoatRacePositions.NPC); - boatNpcServer.setCallback((player, rEntity, entityAction) -> { - if (rEntity != starter) return; - Bukkit.getWorlds().get(0).getEntities().stream().filter(entity -> entity.getType() == EntityType.END_CRYSTAL).forEach(Entity::remove); - if (entityAction == REntityAction.INTERACT && !oneNotStarted) { + new REntity(boatNpcServer, EntityType.VILLAGER, BoatRacePositions.NPC); + RInteraction interaction = new RInteraction(boatNpcServer, BoatRacePositions.NPC.clone().subtract(0.5, 0, 0.5)); + interaction.setInteractionHeight(1.95f); + interaction.setCallback((player, entity, action) -> { + Bukkit.getWorlds().get(0).getEntities().stream().filter(e -> e.getType() == EntityType.END_CRYSTAL).forEach(Entity::remove); + if (action == REntityAction.INTERACT && !oneNotStarted) { oneNotStarted = true; new BoatRace(player); } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RArmorStand.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RArmorStand.java index c2fb90c2..746a080e 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RArmorStand.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RArmorStand.java @@ -20,6 +20,7 @@ package de.steamwar.entity; import lombok.Getter; +import lombok.Setter; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import org.bukkit.Location; @@ -27,13 +28,16 @@ import org.bukkit.entity.EntityType; import java.util.function.Consumer; -public class RArmorStand extends REntity { +@Getter +public class RArmorStand extends REntity implements RInteractableEntity { private static final EntityDataAccessor sizeWatcher = new EntityDataAccessor<>(15, EntityDataSerializers.BYTE); - @Getter private final Size size; + @Setter + private REntityActionListener callback = null; + public RArmorStand(REntityServer server, Location location, Size size) { super(server, EntityType.ARMOR_STAND, location, 0); this.size = size; diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java index d980d439..7a48f553 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java @@ -21,7 +21,6 @@ package de.steamwar.entity; import com.comphenix.tinyprotocol.TinyProtocol; import de.steamwar.core.Core; -import lombok.Setter; import net.minecraft.network.protocol.game.ServerboundInteractPacket; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -52,8 +51,6 @@ public class REntityServer implements Listener { private final HashMap lastLocation = new HashMap<>(); private final HashMap viewDistance = new HashMap<>(); - @Setter - private REntityActionListener callback = null; private final Set playersThatClicked = Collections.synchronizedSet(new HashSet<>()); private final BiFunction filter = (player, packet) -> { @@ -66,11 +63,8 @@ public class REntityServer implements Listener { REntityAction action = packet.isAttack() ? REntityAction.ATTACK : REntityAction.INTERACT; Bukkit.getScheduler().runTask(Core.getInstance(), () -> { playersThatClicked.remove(player); - if (entity instanceof RInteraction interaction && interaction.callback != null) { - interaction.callback.onAction(player, interaction, action); - } - if (callback != null) { - callback.onAction(player, entity, action); + if (entity instanceof RInteractableEntity interactable && interactable.getCallback() != null) { + interactable.getCallback().onAction(player, entity, action); } }); return null; diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RFallingBlockEntity.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RFallingBlockEntity.java index 07356085..e1ab5cba 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RFallingBlockEntity.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RFallingBlockEntity.java @@ -20,16 +20,21 @@ package de.steamwar.entity; import de.steamwar.techhider.BlockIds; +import lombok.AccessLevel; import lombok.Getter; +import lombok.Setter; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.EntityType; @Getter -public class RFallingBlockEntity extends REntity { +public class RFallingBlockEntity extends REntity implements RInteractableEntity { private final Material material; + @Setter + private REntityActionListener callback = null; + public RFallingBlockEntity(REntityServer server, Location location, Material material) { super(server, EntityType.FALLING_BLOCK, location, BlockIds.impl.materialToId(material)); this.material = material; diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RInteractableEntity.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RInteractableEntity.java new file mode 100644 index 00000000..f5c75def --- /dev/null +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RInteractableEntity.java @@ -0,0 +1,34 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2026 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.entity; + +import org.bukkit.entity.Player; + +import java.util.function.BiConsumer; + +public interface RInteractableEntity { + REntityActionListener getCallback(); + + void setCallback(REntityActionListener callback); + + default void setCallback(BiConsumer callback) { + setCallback((player, interaction, entityAction) -> callback.accept(player, entityAction)); + } +} diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RInteraction.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RInteraction.java index b43d02ca..58514280 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RInteraction.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RInteraction.java @@ -20,11 +20,10 @@ package de.steamwar.entity; import de.steamwar.core.BountifulWrapper; -import lombok.AccessLevel; import lombok.Getter; +import lombok.Setter; import org.bukkit.Location; import org.bukkit.entity.EntityType; -import org.bukkit.entity.Player; import java.util.ArrayList; import java.util.List; @@ -35,12 +34,12 @@ import java.util.function.Consumer; * !! This class cannot be used in Versions lower than or equal to 1.19.4 !! */ @Getter -public class RInteraction extends REntity { +public class RInteraction extends REntity implements RInteractableEntity { protected final Consumer updatePacketSink = o -> server.updateEntity(this, o); - @Getter(AccessLevel.PRIVATE) - protected REntityActionListener callback = null; + @Setter + private REntityActionListener callback = null; private float interactionWidth = 1.0f; private float interactionHeight = 1.0f; @@ -114,12 +113,4 @@ public class RInteraction extends REntity { dataSink.accept(responsiveWatcher, responsive); } } - - public void setCallback(REntityActionListener callback) { - this.callback = callback; - } - - public void setCallback(BiConsumer callback) { - this.callback = (player, interaction, entityAction) -> callback.accept(player, entityAction); - } } \ No newline at end of file diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RPlayer.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RPlayer.java index cd0bd3b4..daa9a648 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RPlayer.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RPlayer.java @@ -27,6 +27,7 @@ import de.steamwar.network.CoreNetworkHandler; import de.steamwar.network.NetworkSender; import de.steamwar.network.packets.common.PlayerSkinRequestPacket; import lombok.Getter; +import lombok.Setter; import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; import net.minecraft.world.phys.Vec3; import org.bukkit.GameMode; @@ -39,7 +40,7 @@ import java.util.Map; import java.util.UUID; import java.util.function.Consumer; -public class RPlayer extends REntity { +public class RPlayer extends REntity implements RInteractableEntity { private static final Object skinPartsDataWatcher = BountifulWrapper.impl.getDataWatcherObject(17, Byte.class); @@ -48,6 +49,10 @@ public class RPlayer extends REntity { @Getter private final String name; + @Setter + @Getter + private REntityActionListener callback = null; + public RPlayer(REntityServer server, UUID uuid, String name, Location location) { super(server, EntityType.PLAYER, UUID.nameUUIDFromBytes(uuid.toString().getBytes(StandardCharsets.UTF_8)), location, 0); this.actualUUID = uuid;