Add Projectile Stopper

This commit is contained in:
2026-11-01 11:17:42 +01:00
parent 110833db39
commit e9a7908e26
9 changed files with 215 additions and 30 deletions
@@ -52,8 +52,9 @@ FLAG_ITEMS = Items
FLAG_NO_GRAVITY = No Gravity
FLAG_TESTBLOCK = Testblock
FLAG_CHANGED = Changed
FLAG_WINDCHARGE = Windcharge
FLAG_WINDCHARGE_INTERACT = Windcharge interaction
FLAG_WATER_DESTROY = Water Destroy
FLAG_PROJECTILE_STOPPER = Projectile Stopper
FLAG_WATER_DESTROY_ALLOW = §coff
FLAG_WATER_DESTROY_DENY = §aon
FLAG_FIRE_ALLOW = §con
@@ -93,9 +94,10 @@ FLAG_TESTBLOCK_NORTH = §eNorth
FLAG_TESTBLOCK_SOUTH = §eSouth
FLAG_CHANGED_NO_CHANGE = §cNo
FLAG_CHANGED_HAS_CHANGE = §aYes
FLAG_WINDCHARGE_ALLOW = §aon
FLAG_WINDCHARGE_DENY = §coff
FLAG_WINDCHARGE_NO_INTERACT = §7no §8windcharge interact
FLAG_WINDCHARGE_INTERACT_ALLOW = §aon
FLAG_WINDCHARGE_INTERACT_DENY = §coff
FLAG_PROJECTILE_STOPPER_ENABLED = §aon
FLAG_PROJECTILE_STOPPER_DISABLED = §coff
# Region
REGION_TYPE_NORMAL = Normal
REGION_TYPE_BUILD = Build area
@@ -831,7 +833,12 @@ REGION_TNT_OFF = §cTNT-Damage deactivated
REGION_TNT_TB = §aTNT-Damage activated outside the building area
REGION_TNT_BUILD_DESTROY = §cAn explosion would have destroyed blocks in the building area
REGION_TNT_TB_DESTROY = §cAn explosion would have destroyed blocks in the testblock area
REGION_WINDCHARGE_HELP = §8/§ewindcharge §8[§7Mode§8] §8- §7Set WindCharge behaviour to a given mode
REGION_WINDCHARGE_INTERACT_HELP = §8/§ewindcharge §8- §7Toggle the Windcharge interaction
REGION_WINDCHARGE_INTERACT_ON = §aWindcharge interaction on
REGION_WINDCHARGE_INTERACT_OFF = §cWindcharge interaction off
REGION_PROJECTILE_STOPPER_HELP = §8/§eprojectilestopper §8- §7Toggle the Projectile stopper
REGION_PROJECTILE_STOPPER_ON = §aProjectile stopper enabled
REGION_PROJECTILE_STOPPER_OFF = §cProjectile stopper disabled
AFK_KICK_MESSAGE = §cNothing happened on this server for 15 minutes.
AFK_WARNING_MESSAGE = §cThis server will stop in one minute if you remain inactive
@@ -55,6 +55,8 @@ FLAG_FREEZE_INACTIVE = §caus
FLAG_PROTECT_ACTIVE = §aan
FLAG_PROTECT_INACTIVE = §caus
FLAG_WATER_DESTROY = Wasserschaden
FLAG_PROJECTILE_STOPPER = Projektiel stopper
FLAG_WINDCHARGE_INTERACT = Windkugel interaktion
FLAG_WATER_DESTROY_ALLOW = §cerlaubt
FLAG_WATER_DESTROY_DENY = §aaus
FLAG_TNT_ALLOW = §aan
@@ -81,6 +83,10 @@ FLAG_COLOR_BROWN = §eBraun
FLAG_COLOR_GREEN = §2Grün
FLAG_COLOR_RED = §cRot
FLAG_COLOR_BLACK = §0Schwarz
FLAG_WINDCHARGE_INTERACT_ALLOW = §aan
FLAG_WINDCHARGE_INTERACT_DENY = §caus
FLAG_PROJECTILE_STOPPER_ENABLED = §aan
FLAG_PROJECTILE_STOPPER_DISABLED = §caus
# Region
REGION_TYPE_NORMAL = Normal
REGION_TYPE_BUILD = Baubereich
@@ -765,6 +771,12 @@ REGION_TNT_OFF = §cTNT-Schaden deaktiviert
REGION_TNT_TB = §aTNT-Schaden außerhalb Baurahmen aktiviert
REGION_TNT_BUILD_DESTROY = §cEine Explosion hätte Blöcke im Baubereich zerstört
REGION_TNT_TB_DESTROY = §cEine Explosion hätte Blöcke im Testblockbereich zerstört
REGION_WINDCHARGE_INTERACT_HELP = §8/§ewindcharge §8- §7Windkugel interaktion umschalten
REGION_WINDCHARGE_INTERACT_ON = §aWindkugel interaktion on
REGION_WINDCHARGE_INTERACT_OFF = §cWindkugel interaktion off
REGION_PROJECTILE_STOPPER_HELP = §8/§eprojectilestopper §8- §7
REGION_PROJECTILE_STOPPER_ON = §aProjektiel stopper an
REGION_PROJECTILE_STOPPER_OFF = §cProjektiel stopper aus
AFK_KICK_MESSAGE = §cAuf diesem Server ist seit 15 Minuten nichts passiert.
AFK_WARNING_MESSAGE = §cDieser Server wird bei weiterer Inaktivität in einer Minute gestoppt
SKIN_HELP = §8/§eskin §8[§7Kuerzel§8] §8[§7Creator§8|§epublic§8] §8[§7Name...§8] §8- §7Erstellt die Skin Schematics. 'public' als Creator nutzen für keinen Creator, danach die nachricht an YoyoNow kopieren (mit Click kopieren)
@@ -1,23 +0,0 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.region;
public class ProjectieleStopperListener {
}
@@ -0,0 +1,48 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.region;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.RegionUtils;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.region.flags.ProjectileStopperMode;
import de.steamwar.command.AbstractSWCommand;
import de.steamwar.command.SWCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.Player;
@Linked
public class ProjectileStopperCommand extends SWCommand {
public ProjectileStopperCommand() {
super("projectilestopper");
}
@AbstractSWCommand.Register(description = "REGION_PROJECTILE_STOPPER_HELP")
public void toggleCommand(@AbstractSWCommand.Validator Player p) {
Region region = Region.getRegion(p.getLocation());
if (region.getRegionData().get(Flag.PROJECTILE_STOPPER).get() == ProjectileStopperMode.ENABLED) {
region.getRegionData().set(Flag.PROJECTILE_STOPPER, ProjectileStopperMode.DISABLED);
RegionUtils.actionBar(region, "REGION_PROJECTILE_STOPPER_OFF");
} else {
region.getRegionData().set(Flag.PROJECTILE_STOPPER, ProjectileStopperMode.ENABLED);
RegionUtils.actionBar(region, "REGION_PROJECTILE_STOPPER_ON");
}
}
}
@@ -0,0 +1,87 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.region;
import com.destroystokyo.paper.event.server.ServerTickEndEvent;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.region.flags.ProjectileStopperMode;
import de.steamwar.bausystem.utils.ScoreboardElement;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntitySpawnEvent;
import java.util.*;
@Linked
public class ProjectileStopperListener implements Listener, ScoreboardElement {
private Map<Region, Set<Entity>> projektileList = new HashMap<>();
@EventHandler
public void onTick(ServerTickEndEvent event) {
List<Entity> entitiesToAdd = new ArrayList<>();
projektileList.forEach((region, entities) -> {
entities.removeIf(entity -> {
if (region != Region.getRegion(entity.getLocation())) {
if (region.getRegionData().get(Flag.PROJECTILE_STOPPER).getWithDefault() == ProjectileStopperMode.ENABLED) {
entity.remove();
} else {
entitiesToAdd.add(entity);
}
return true;
}
return false;
});
});
entitiesToAdd.forEach(this::addEntity);
}
@EventHandler
public void onEntitySpawn(EntitySpawnEvent event) {
if (event.getEntityType() != EntityType.WIND_CHARGE && event.getEntityType() != EntityType.ARROW && event.getEntityType() != EntityType.SMALL_FIREBALL) return;
addEntity(event.getEntity());
}
private void addEntity(Entity entity) {
Region region = Region.getRegion(entity.getLocation());
projektileList.computeIfAbsent(region, key -> new HashSet<>()).add(entity);
}
@Override
public ScoreboardGroup getGroup() {
return ScoreboardGroup.REGION;
}
@Override
public int order() {
return 2;
}
@Override
public String get(Region region, Player p) {
if (region.getRegionData().get(Flag.PROJECTILE_STOPPER).is(ProjectileStopperMode.ENABLED)) return null;
return "§e" + BauSystem.MESSAGE.parse(Flag.PROJECTILE_STOPPER.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getRegionData().get(Flag.PROJECTILE_STOPPER).getWithDefault().getChatValue(), p);
}
}
@@ -45,6 +45,7 @@ public final class Flag<T extends Enum<T> & Flag.Value<T>> implements EnumDispla
public static final Flag<ChangedMode> CHANGED = new Flag<>("CHANGED", "FLAG_CHANGED", ChangedMode.class, ChangedMode.NO_CHANGE);
public static final Flag<WaterDestroyMode> WATER_DESTROY = new Flag<>("WATER_DESTROY", "FLAG_WATER_DESTROY", WaterDestroyMode.class, WaterDestroyMode.ALLOW);
public static final Flag<WindChargeInteractMode> WIND_CHARGE_INTERACT = new Flag<>("WINDCHARGE_INTERACT", "FLAG_WINDCHARGE_INTERACT", WindChargeInteractMode.class, WindChargeInteractMode.ALLOW);
public static final Flag<ProjectileStopperMode> PROJECTILE_STOPPER = new Flag<>("PROJECTILE_STOPPER", "FLAG_PROJECTILE_STOPPER", ProjectileStopperMode.class, ProjectileStopperMode.ENABLED);
private String name;
private int ordinal;
@@ -0,0 +1,52 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.region.flags;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum ProjectileStopperMode implements Flag.Value<ProjectileStopperMode> {
ENABLED("FLAG_PROJECTILE_STOPPER_ENABLED"),
DISABLED("FLAG_PROJECTILE_STOPPER_DISABLED");
private static WindChargeInteractMode[] values;
private final String chatValue;
@Override
public ProjectileStopperMode[] getValues() {
return ProjectileStopperMode.values();
}
@Override
public ProjectileStopperMode getValue() {
return this;
}
@Override
public ProjectileStopperMode getValueOf(final String name) {
try {
return ProjectileStopperMode.valueOf(name.toUpperCase());
} catch (IllegalArgumentException e) {
return ProjectileStopperMode.ENABLED;
}
}
}
@@ -37,6 +37,7 @@ public class FixedGlobalRegionData extends RegionData {
flagMap.put(Flag.COLOR, ColorMode.YELLOW);
flagMap.put(Flag.PROTECT, ProtectMode.INACTIVE);
flagMap.put(Flag.WIND_CHARGE_INTERACT, WindChargeInteractMode.ALLOW);
flagMap.put(Flag.PROJECTILE_STOPPER, ProjectileStopperMode.ENABLED);
}
@Override
@@ -47,7 +48,7 @@ public class FixedGlobalRegionData extends RegionData {
if (flag.oneOf(Flag.ITEMS)) {
return RegionFlagPolicy.WRITABLE;
}
if (flag.oneOf(Flag.TNT, Flag.FIRE, Flag.FREEZE)) {
if (flag.oneOf(Flag.TNT, Flag.FIRE, Flag.FREEZE, Flag.PROJECTILE_STOPPER, Flag.WIND_CHARGE_INTERACT )) {
return RegionFlagPolicy.WRITABLE;
}
return RegionFlagPolicy.NOT_APPLICABLE;
@@ -33,7 +33,7 @@ public class FixedRegionData extends RegionData {
@Override
public @NonNull <T extends Enum<T> & Flag.Value<T>> RegionFlagPolicy has(@NonNull Flag<T> flag) {
if (flag.oneOf(Flag.COLOR, Flag.TNT, Flag.FIRE, Flag.FREEZE, Flag.PROTECT, Flag.NO_GRAVITY, Flag.CHANGED, Flag.WATER_DESTROY, Flag.WIND_CHARGE_INTERACT)) {
if (flag.oneOf(Flag.COLOR, Flag.TNT, Flag.FIRE, Flag.FREEZE, Flag.PROTECT, Flag.NO_GRAVITY, Flag.CHANGED, Flag.WATER_DESTROY, Flag.WIND_CHARGE_INTERACT, Flag.PROJECTILE_STOPPER)) {
return RegionFlagPolicy.WRITABLE;
}
if (flag.oneOf(Flag.ITEMS)) {