Merge pull request 'Add Wind Charge limit and region constraint' (#484) from Jaki/SteamWar:main into main

Reviewed-on: SteamWar/SteamWar#484
Reviewed-by: YoyoNow <4+yoyonow@noreply.localhost>
This commit is contained in:
2026-10-31 23:27:31 +01:00
8 changed files with 97 additions and 9 deletions
@@ -515,6 +515,20 @@ public final class GameModeConfig<M, W> {
*/
public final boolean WindchargesDestroyWater;
/**
* Allows Wind Charges to leave the Region.
*
* @implSpec {@code true} by default
*/
public final boolean WindchargesCanLeaveRegion;
/**
* Limits the amount of Wind Charges in each extended region. -1 is no limit
*
* @implSpec {@code -1} by default
*/
public final int WindchargeLimit;
private ArenaConfig(YMLWrapper<M, W> loader, SchematicConfig.SizeConfig Size, List<Integer> EnterStages) {
loaded = loader.canLoad();
WaterDepth = loader.getInt("WaterDepth", 0);
@@ -535,6 +549,8 @@ public final class GameModeConfig<M, W> {
WindchargesCanCrossMiddle = loader.getBoolean("WindchargesCanCrossMiddle", false);
WindchargesInteractWithBlocks = loader.getBoolean("WindchargesInteractWithBlocks", true);
WindchargesDestroyWater = loader.getBoolean("WindchargesDestroyWater", false);
WindchargesCanLeaveRegion = loader.getBoolean("WindchargesCanLeaveRegion", true);
WindchargeLimit = loader.getInt("WindchargeLimit", -1);
}
@ToString
@@ -68,6 +68,10 @@ Arena:
WindchargesCanCrossMiddle: false # defaults to false if missing
# Allows Wind Charge interaction with Blocks.
WindchargesInteractWithBlocks: false # defaults to false if missing
# Allows Wind Charges to leave the extended region.
WindchargesCanLeaveRegion: true # defaults to true
# Limits the amount of Wind Charges in each extended region. -1 is no limit
WindchargeLimit: -1 # defaults to -1
Schematic:
# The size of the schematics
@@ -21,8 +21,8 @@ package de.steamwar.fightsystem;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.core.Core;
import de.steamwar.core.WorldIdentifier;
import de.steamwar.core.worldedit.SteamEdit;
import de.steamwar.core.worldedit.WorldEditRendererCUIEditor;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.listener.ClickAnalyzer;
@@ -79,6 +79,11 @@ public class FightSystem extends JavaPlugin {
Core.setServerName("Replay");
}
String arenaMap = System.getProperty("arenaMap");
if (arenaMap != null) {
WorldIdentifier.set("arena/" + Core.getVersion() + "/" + arenaMap);
}
message = new Message("de.steamwar.fightsystem.FightSystem", FightSystem.class.getClassLoader());
spigotLinker = new SpigotLinker(this, message) {
@@ -22,31 +22,71 @@ package de.steamwar.fightsystem.listener;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentTask;
import de.steamwar.fightsystem.utils.Region;
import de.steamwar.linkage.Linked;
import net.minecraft.world.entity.projectile.windcharge.WindCharge;
import org.bukkit.Location;
@Linked
public class WindchargeStopper {
public WindchargeStopper() {
new StateDependentTask(!Config.GameModeConfig.Arena.WindchargesCanCrossMiddle, FightState.Running, this::run, 1, 1);
canCrossMiddle = Config.GameModeConfig.Arena.WindchargesCanCrossMiddle;
canLeaveRegion = Config.GameModeConfig.Arena.WindchargesCanLeaveRegion;
limit = Config.GameModeConfig.Arena.WindchargeLimit;
boolean enabled = limit >= 0 || !canCrossMiddle || !canLeaveRegion;
new StateDependentTask(enabled, FightState.Running, this::run, 1, 1);
}
private static final int middleLine = Config.SpecSpawn.getBlockZ();
private static final Class<?> windChargeClass = WindCharge.class;
private final boolean canCrossMiddle;
private final boolean canLeaveRegion;
private final int limit;
private int blueCount;
private int redCount;
private void run() {
redCount = 0;
blueCount = 0;
Recording.iterateOverEntities(windChargeClass::isInstance, entity -> {
Location nextlocation = entity.getLocation().add(entity.getVelocity());
Location location = entity.getLocation();
Location nextlocation = location.clone().add(entity.getVelocity());
boolean passedMiddle = nextlocation.getBlockZ() >= middleLine && location.getBlockZ() <= middleLine ||
nextlocation.getBlockZ() <= middleLine && location.getBlockZ() >= middleLine;
if (!canCrossMiddle) {
boolean passedMiddle = nextlocation.getBlockZ() >= middleLine && location.getBlockZ() <= middleLine ||
nextlocation.getBlockZ() <= middleLine && location.getBlockZ() >= middleLine;
if (passedMiddle) {
entity.remove();
return;
}
}
if (passedMiddle) {
entity.remove();
Region region = Config.BlueExtendRegion.inRegion(location) ? Config.BlueExtendRegion
: Config.RedExtendRegion.inRegion(location) ? Config.RedExtendRegion
: null;
if (!canLeaveRegion) {
if (region == null) {
entity.remove();
return;
}
if (!region.inRegion(nextlocation)) {
entity.remove();
return;
}
}
if (limit >= 0 && region != null) {
if (region == Config.BlueExtendRegion) {
if (++blueCount > limit) entity.remove();
} else {
if (++redCount > limit) entity.remove();
}
}
});
}
@@ -19,6 +19,8 @@
package de.steamwar.misslewars;
import de.steamwar.core.Core;
import de.steamwar.core.WorldIdentifier;
import de.steamwar.linkage.AbstractLinker;
import de.steamwar.linkage.SpigotLinker;
import de.steamwar.misslewars.items.CustomItem;
@@ -56,6 +58,11 @@ public class MissileWars extends JavaPlugin {
redTeam = new MWTeam(Config.TeamRedColor, Config.RedSpawn, Config.TeamRedName, Config.RedPortalZ);
blueTeam = new MWTeam(Config.TeamBlueColor, Config.BlueSpawn, Config.TeamBlueName, Config.BluePortalZ);
String arenaMap = System.getProperty("arenaMap");
if (arenaMap != null) {
WorldIdentifier.set("arena/" + Core.getVersion() + "/" + arenaMap);
}
SpigotLinker spigotLinker = new SpigotLinker(this, null) {
@Override
protected void linkObject(Object any) {
@@ -19,6 +19,8 @@
package de.steamwar.tntleague
import de.steamwar.core.Core
import de.steamwar.core.WorldIdentifier
import de.steamwar.message.Message
import de.steamwar.tntleague.command.*
import de.steamwar.tntleague.events.GlobalListener
@@ -43,6 +45,11 @@ class TNTLeague : JavaPlugin() {
logger.info("TNTLeague enabled")
val arenaMap = System.getProperty("arenaMap")
if (arenaMap != null) {
WorldIdentifier.set("arena/" + Core.getVersion() + "/" + arenaMap)
}
ReadyCommand.register()
InviteCommand.register()
AcceptCommand.register()
@@ -20,6 +20,8 @@
package de.steamwar.towerrun;
import de.steamwar.command.SWCommand;
import de.steamwar.core.Core;
import de.steamwar.core.WorldIdentifier;
import de.steamwar.linkage.AbstractLinker;
import de.steamwar.linkage.LinkedInstance;
import de.steamwar.linkage.SpigotLinker;
@@ -56,6 +58,11 @@ public class TowerRun extends JavaPlugin {
towerGenerator = new TowerGenerator(WorldConfig.TOWER_GENERATOR_CONFIG);
}
String arenaMap = System.getProperty("arenaMap");
if (arenaMap != null) {
WorldIdentifier.set("arena/" + Core.getVersion() + "/" + arenaMap);
}
SpigotLinker spigotLinker = new SpigotLinker(this, message) {
@Override
protected void linkObject(Object any) {
@@ -64,6 +71,7 @@ public class TowerRun extends JavaPlugin {
}
}
};
try {
spigotLinker.link();
} catch (AbstractLinker.LinkException e) {
@@ -91,6 +91,7 @@ public class ServerStarter {
gameMode = mode.configFile.getName().replace(".yml", "");
directory = new File(SERVER_PATH, mode.Server.Folder);
arguments.put("config", mode.configFile.getName());
arguments.put("arenaMap", map);
tempWorld(SERVER_PATH + mode.Server.Folder + "/arenas/" + map);
startCondition = () -> {
if (playersToSend.stream().anyMatch(player -> Subserver.isArena(Subserver.getSubserver(player)))) {