diff --git a/CommonCore/SQL/src/de/steamwar/sql/GameModeConfig.java b/CommonCore/SQL/src/de/steamwar/sql/GameModeConfig.java index 17bfccb5a..82d07ef56 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/GameModeConfig.java +++ b/CommonCore/SQL/src/de/steamwar/sql/GameModeConfig.java @@ -509,6 +509,20 @@ public final class GameModeConfig { */ 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 loader, SchematicConfig.SizeConfig Size, List EnterStages) { loaded = loader.canLoad(); WaterDepth = loader.getInt("WaterDepth", 0); @@ -529,6 +543,8 @@ public final class GameModeConfig { 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 diff --git a/FightSystem/FightSystem_Core/src/config.yml b/FightSystem/FightSystem_Core/src/config.yml index dbaf3c336..756f4c2a6 100644 --- a/FightSystem/FightSystem_Core/src/config.yml +++ b/FightSystem/FightSystem_Core/src/config.yml @@ -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 diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/WindchargeStopper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/WindchargeStopper.java index a750a1b90..d81cd7a9f 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/WindchargeStopper.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/WindchargeStopper.java @@ -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(); + } } }); }