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 ad4afc56..e34dce68 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
@@ -22,6 +22,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 net.md_5.bungee.api.ChatMessageType;
@@ -61,7 +62,7 @@ public class DesignEndStone {
calculateFromBottom = region.getGameModeConfig().Arena.NoFloor;
entityServer.setCallback((player, rEntity, entityAction) -> {
- if (entityAction != REntityServer.EntityAction.ATTACK) return;
+ if (entityAction != REntityAction.ATTACK) return;
Location location = new Location(WORLD, rEntity.getX(), rEntity.getY(), rEntity.getZ());
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
location.getBlock().breakNaturally();
diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java
index c55c5135..5179eead 100644
--- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java
+++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java
@@ -25,6 +25,7 @@ import de.steamwar.bausystem.features.tracer.rendering.TraceEntity;
import de.steamwar.bausystem.features.tracer.rendering.ViewFlag;
import de.steamwar.bausystem.region.Region;
import de.steamwar.entity.REntity;
+import de.steamwar.entity.REntityAction;
import de.steamwar.entity.REntityServer;
import lombok.Getter;
import lombok.Setter;
@@ -144,7 +145,7 @@ public class Trace {
entityServer = new REntityServer();
entityServer.addPlayer(player);
entityServer.setCallback((p, rEntity, entityAction) -> {
- if (entityAction != REntityServer.EntityAction.INTERACT) {
+ if (entityAction != REntityAction.INTERACT) {
return;
}
if (rEntity instanceof TraceEntity) {
@@ -168,7 +169,7 @@ public class Trace {
REntityServer newEntityServer = new REntityServer();
newEntityServer.addPlayer(k);
newEntityServer.setCallback((p, rEntity, entityAction) -> {
- if (entityAction != REntityServer.EntityAction.INTERACT) {
+ if (entityAction != REntityAction.INTERACT) {
return;
}
if (rEntity instanceof TraceEntity) {
diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/ArrowStopper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/ArrowStopper.java
index e6b0c64e..3bf98bda 100644
--- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/ArrowStopper.java
+++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/ArrowStopper.java
@@ -46,6 +46,7 @@ public class ArrowStopper {
private void run() {
Recording.iterateOverEntities(AbstractArrow.class::isInstance, entity -> {
Projectile arrow = (Projectile) entity;
+ if(!(arrow.getShooter() instanceof Player)) return;
if (invalidEntity(arrow)) return;
Location prevLocation = arrow.getLocation().toVector().subtract(arrow.getVelocity()).toLocation(arrow.getWorld());
diff --git a/LobbySystem/src/de/steamwar/lobby/boatrace/BoatRace.java b/LobbySystem/src/de/steamwar/lobby/boatrace/BoatRace.java
index 81d99dc2..ea8575b9 100644
--- a/LobbySystem/src/de/steamwar/lobby/boatrace/BoatRace.java
+++ b/LobbySystem/src/de/steamwar/lobby/boatrace/BoatRace.java
@@ -20,6 +20,7 @@
package de.steamwar.lobby.boatrace;
import de.steamwar.entity.REntity;
+import de.steamwar.entity.REntityAction;
import de.steamwar.entity.REntityServer;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.util.LeaderboardManager;
@@ -62,7 +63,7 @@ public class BoatRace implements EventListener, Listener {
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 == REntityServer.EntityAction.INTERACT && !oneNotStarted) {
+ if (entityAction == REntityAction.INTERACT && !oneNotStarted) {
oneNotStarted = true;
new BoatRace(player);
}
diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntityAction.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntityAction.java
new file mode 100644
index 00000000..d4046cf0
--- /dev/null
+++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntityAction.java
@@ -0,0 +1,25 @@
+/*
+ * 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;
+
+public enum REntityAction {
+ INTERACT,
+ ATTACK,
+}
diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntityActionListener.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntityActionListener.java
new file mode 100644
index 00000000..8a364642
--- /dev/null
+++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntityActionListener.java
@@ -0,0 +1,26 @@
+/*
+ * 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;
+
+public interface REntityActionListener {
+ void onAction(Player player, E entity, REntityAction action);
+}
diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java
index 051e8f9b..b6e3d2d4 100644
--- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java
+++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java
@@ -21,6 +21,7 @@ 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;
@@ -51,7 +52,8 @@ public class REntityServer implements Listener {
private final HashMap lastLocation = new HashMap<>();
private final HashMap viewDistance = new HashMap<>();
- private EntityActionListener callback = null;
+ @Setter
+ private REntityActionListener callback = null;
private final Set playersThatClicked = Collections.synchronizedSet(new HashSet<>());
private final BiFunction filter = (player, packet) -> {
@@ -62,26 +64,22 @@ public class REntityServer implements Listener {
if (playersThatClicked.contains(player)) return null;
playersThatClicked.add(player);
- EntityAction action = packet.isAttack() ? EntityAction.ATTACK : EntityAction.INTERACT;
-
+ REntityAction action = packet.isAttack() ? REntityAction.ATTACK : REntityAction.INTERACT;
Bukkit.getScheduler().runTask(Core.getInstance(), () -> {
playersThatClicked.remove(player);
- callback.onAction(player, targetEntity, action);
+ if (entity instanceof RInteraction interaction && interaction.callback != null) {
+ interaction.callback.onAction(player, interaction, action);
+ }
+ if (callback != null) {
+ callback.onAction(player, entity, action);
+ }
});
return null;
};
public REntityServer() {
Core.getInstance().getServer().getPluginManager().registerEvents(this, Core.getInstance());
- }
-
- public void setCallback(EntityActionListener callback) {
- boolean uninitialized = this.callback == null;
- this.callback = callback;
-
- if (uninitialized) {
- TinyProtocol.instance.addFilter(ServerboundInteractPacket.class, filter);
- }
+ TinyProtocol.instance.addFilter(ServerboundInteractPacket.class, filter);
}
public void addPlayer(Player player) {
@@ -295,13 +293,4 @@ public class REntityServer implements Listener {
private long chunkToId(int x, int z) {
return ((long) x << 32) + z;
}
-
- public enum EntityAction {
- INTERACT,
- ATTACK,
- }
-
- public interface EntityActionListener {
- void onAction(Player player, REntity entity, EntityAction action);
- }
}
diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RInteraction.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RInteraction.java
new file mode 100644
index 00000000..b43d02ca
--- /dev/null
+++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RInteraction.java
@@ -0,0 +1,125 @@
+/*
+ * 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 de.steamwar.core.BountifulWrapper;
+import lombok.AccessLevel;
+import lombok.Getter;
+import org.bukkit.Location;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.Player;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.BiConsumer;
+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 {
+
+ protected final Consumer