Fix mobs, double chat

This commit is contained in:
NotAlexNoyle committed 2026-05-25 00:54:31 -04:00
1 parent 7ce35dfc42
commit 25295f5430
8 files changed
+188 -6

No files matched your search

BIN
View File
Binary file not shown.
@@ -0,0 +1,16 @@
package uk.hotten.herobrine.chat;
import org.bukkit.entity.Player;
import uk.hotten.herobrine.lobby.GameLobby;
/**
* Delivery boundary for game-lobby chat. A future Chat-OG adapter can route
* through a world/channel API while retaining TheHerobrine's lobby isolation
* and game-specific formatting.
*/
public interface LobbyChatDelivery {
void send(GameLobby lobby, Player sender, String rawMessage, String formattedMessage);
}
@@ -0,0 +1,17 @@
package uk.hotten.herobrine.chat;
import org.bukkit.entity.Player;
import uk.hotten.herobrine.lobby.GameLobby;
import uk.hotten.herobrine.utils.Message;
public class LocalLobbyChatDelivery implements LobbyChatDelivery {
@Override
public void send(GameLobby lobby, Player sender, String rawMessage, String formattedMessage) {
Message.broadcast(lobby, formattedMessage);
}
}
@@ -47,6 +47,8 @@ import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
import org.bukkit.Location;
import uk.hotten.herobrine.HerobrinePluginOG;
import uk.hotten.herobrine.chat.LocalLobbyChatDelivery;
import uk.hotten.herobrine.chat.LobbyChatDelivery;
import uk.hotten.herobrine.compat.IllegalStackCompat;
import uk.hotten.herobrine.kit.KitGui;
import uk.hotten.herobrine.lobby.GameLobby;
@@ -65,13 +67,21 @@ public class GMListener implements Listener {
private GameManager gameManager;
private GameLobby gameLobby;
private LobbyChatDelivery lobbyChatDelivery;
private ArrayList<Player> kitCooldown = new ArrayList<>();
private Set<UUID> returningToMainOnLogin = ConcurrentHashMap.newKeySet();
public GMListener(GameManager gm, GameLobby gl) {
this(gm, gl, new LocalLobbyChatDelivery());
}
public GMListener(GameManager gm, GameLobby gl, LobbyChatDelivery lobbyChatDelivery) {
this.gameManager = gm;
this.gameLobby = gl;
this.lobbyChatDelivery = lobbyChatDelivery;
}
@@ -655,6 +665,13 @@ public class GMListener implements Listener {
}
if (gameManager.isPvpProtected()) {
event.setCancelled(true);
return;
}
// Allows arrow damage
if (event.getEntity() instanceof Player && event.getDamager() instanceof Arrow) { // If the damaged is a player
@@ -948,40 +965,47 @@ public class GMListener implements Listener {
}
@EventHandler
@EventHandler(priority = EventPriority.LOWEST)
public void onChat(AsyncChatEvent event) {
if (!event.getPlayer().getWorld().getName().startsWith(gameLobby.getLobbyId()))
return;
// This lobby owns delivery for now; Chat-OG's normal-priority listener
// observes cancellation and does not also broadcast globally.
event.setCancelled(true);
StatManager sm = gameLobby.getStatManager();
Player player = event.getPlayer();
GameRank rank = sm.getGameRank(player.getUniqueId());
int points = sm.getPoints().get(player.getUniqueId());
String rawMessage = PlainTextComponentSerializer.plainText().serialize(event.message());
String endMessage = "&9" + PlainTextComponentSerializer.plainText().serialize(player.displayName()) + "&8 » &r"
+ PlainTextComponentSerializer.plainText().serialize(event.message());
+ rawMessage;
String formattedMessage = null;
if (gameManager.getGameState() == GameState.WAITING || gameManager.getGameState() == GameState.STARTING) {
Message.broadcast(gameLobby, "&e" + points + "&8 ▏ " + rank.getDisplay() + " " + endMessage);
formattedMessage = "&e" + points + "&8 ▏ " + rank.getDisplay() + " " + endMessage;
} else if (gameManager.getGameState() == GameState.LIVE || gameManager.getGameState() == GameState.ENDING) {
if (gameManager.isHerobrine(player) || gameManager.isSurvivor(player)) {
Message.broadcast(gameLobby, rank.getDisplay() + " " + endMessage);
formattedMessage = rank.getDisplay() + " " + endMessage;
} else {
Message.broadcast(gameLobby, "&e" + points + "&8 ▍ &4DEAD &8▏ " + endMessage);
formattedMessage = "&e" + points + "&8 ▍ &4DEAD &8▏ " + endMessage;
}
}
if (formattedMessage != null)
lobbyChatDelivery.send(gameLobby, player, rawMessage, formattedMessage);
}
}
@@ -21,6 +21,7 @@ import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.inventory.ItemStack;
@@ -150,6 +151,10 @@ public class GameManager {
public boolean timerPaused = false;
private BukkitTask waitingRunnable;
private NarrationRunnable narrationRunnable;
private BukkitTask pvpProtectionTask;
@Getter
private volatile boolean pvpProtected;
@Getter
private Kit[] kits;
@@ -312,6 +317,7 @@ public class GameManager {
public void startWaiting(boolean cleanGameWorld) {
cancelPvpProtection();
setGameState(GameState.WAITING);
deadSurvivors.clear();
if (waitingRunnable != null)
@@ -530,6 +536,7 @@ public class GameManager {
try {
setGameState(GameState.LIVE);
startPvpProtection();
narrationRunnable = new NarrationRunnable(this);
narrationRunnable.runTaskTimerAsynchronously(plugin, 0, 10); // has to run before the shardstate updates
setShardState(ShardState.WAITING);
@@ -821,6 +828,7 @@ public class GameManager {
public void end(WinType type) {
cancelPvpProtection();
setGameState(GameState.ENDING);
setShardState(ShardState.INACTIVE);
voidKits();
@@ -885,6 +893,74 @@ public class GameManager {
}
private void startPvpProtection() {
cancelPvpProtection();
final World roundWorld = worldManager.getGameWorld();
if (roundWorld == null)
return;
final int seconds = Math.max(0, plugin.getConfig().getInt("pvpProtectionSeconds", 30));
if (seconds == 0) {
roundWorld.setPVP(true);
return;
}
pvpProtected = true;
roundWorld.setPVP(false);
pvpProtectionTask = new BukkitRunnable() {
private int remaining = seconds;
@Override
public void run() {
if (gameState != GameState.LIVE && gameState != GameState.STARTING) {
pvpProtected = false;
pvpProtectionTask = null;
cancel();
return;
}
if (remaining == 0) {
pvpProtected = false;
roundWorld.setPVP(true);
PlayerUtil.broadcastActionbar(gameLobby, "&aPvP is now enabled!");
pvpProtectionTask = null;
cancel();
return;
}
String time = Message.formatTime(remaining);
PlayerUtil.broadcastActionbar(gameLobby, "&cPvP is disabled &7- &eEnables in &c" + time);
remaining--;
}
}.runTaskTimer(plugin, 0, 20);
}
private void cancelPvpProtection() {
if (pvpProtectionTask != null) {
pvpProtectionTask.cancel();
pvpProtectionTask = null;
}
pvpProtected = false;
}
public void endCheck() {
if (gameState != GameState.LIVE)
@@ -28,6 +28,9 @@ public class NarrationRunnable extends BukkitRunnable {
}
if (gm.isPvpProtected())
return;
if (gm.getShardCount() == 0 && gm.getShardState() == ShardState.WAITING && !gm.isShardPreviousDestroyed()) // I
// dunno
// i
@@ -16,9 +16,14 @@ import org.bukkit.Difficulty;
import org.bukkit.GameRule;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Animals;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Monster;
import org.bukkit.entity.Player;
import org.bukkit.entity.Wolf;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.EntitiesLoadEvent;
import org.bukkit.plugin.java.JavaPlugin;
import com.bergerkiller.bukkit.mw.WorldConfig;
@@ -590,6 +595,10 @@ public class WorldManager implements Listener {
}
gameWorld = world;
// MyWorlds' animal/monster filter also rejects custom creature spawns used
// by game abilities. Use the vanilla rule to stop ambient arena spawning.
world.setGameRule(GameRule.DO_MOB_SPAWNING, false);
logRemovedArenaCreatures(removeAmbientArenaCreatures(world.getEntities()));
Console.info(gameLobby, "Game world '" + worldName + "' loaded with void chunk-generator override.");
// Share inventory between this lobby's hub and game world so the player
@@ -672,7 +681,7 @@ public class WorldManager implements Listener {
}
case SHARD_SPAWN -> {
shardSpawns.add(dLoc);
shardSpawns.add(dLoc.clone().add(0.5, 0, 0.5));
shardCountDp++;
}
@@ -837,6 +846,42 @@ public class WorldManager implements Listener {
}
@EventHandler
public void removeLoadedArenaCreatures(EntitiesLoadEvent event) {
if (gameWorld == null || event.getWorld() != gameWorld)
return;
logRemovedArenaCreatures(removeAmbientArenaCreatures(event.getEntities()));
}
private int removeAmbientArenaCreatures(Iterable<? extends Entity> entities) {
int removed = 0;
for (Entity entity : entities) {
if (!(entity instanceof Monster) && !(entity instanceof Animals))
continue;
if (entity instanceof Wolf wolf && wolf.isTamed())
continue;
entity.remove();
removed++;
}
return removed;
}
private void logRemovedArenaCreatures(int count) {
if (count > 0)
Console.info(gameLobby, "Removed " + count + " ambient creature(s) loaded into the arena.");
}
@EventHandler
public void gameStart(GameStateUpdateEvent event) {
+1
View File
@@ -2,6 +2,7 @@ networkName: ^{BRAND_NAME} # Name of your network
networkWeb: true-og.net # Website of your network
gamePrefix: "DEFAULT" # PLEASE PUT IN SPEECH MARKS! Set as "DEFAULT" for classic Hive Java, else it will be your own.
mapBase: "maps" # Folder where the map base and maps folder is.
pvpProtectionSeconds: 30 # Seconds after a round starts before arena player combat is enabled.
lockClassicKits: true # Do you want to lock classic kits such as Archer and Scout behind their permission?
lockUnlockableKits: true # Do you want to lock unlockable kits such as Mage and Sorcerer behind their permission?