diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/Config.java b/FightSystem_Core/src/de/steamwar/fightsystem/Config.java index 8f09b06..c5d69f7 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/Config.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/Config.java @@ -26,6 +26,7 @@ import de.steamwar.sql.EventFight; import de.steamwar.sql.Team; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.World; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; @@ -97,7 +98,7 @@ public class Config { //win condition parameters public static final int TimeoutTime; public static final double PercentWin; - public static final List IgnoredBlocks; + public static final Set PercentBlocks; //default kits public static final String MemberDefault; @@ -188,7 +189,7 @@ public class Config { TimeoutTime = config.getInt("WinConditionParams.TimeoutTime"); PercentWin = config.getDouble("WinConditionParams.PercentWin"); - IgnoredBlocks = Collections.unmodifiableList(config.getStringList("WinConditionParams.IgnoredBlocks")); + PercentBlocks = config.getStringList("WinConditionParams.IgnoredBlocks").stream().map(Material::valueOf).collect(Collectors.toSet()); EnterStages = Collections.unmodifiableList(config.getIntegerList("EnterStages")); diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java index 28ab5e5..ee08281 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java @@ -97,7 +97,8 @@ public class FightSystem extends JavaPlugin { new WinconditionPumpkinTechKO(); new WinconditionWaterTechKO(); new WinconditionPercentSystem(); - new WinconditionRelativePercent(); + new WinconditionBlacklistPercent(); + new WinconditionWhitelistPercent(); new WinconditionPoints(); new WinconditionTimeout(); new WinconditionHeartRatioTimeout(); diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/states/OneShotStateDependent.java b/FightSystem_Core/src/de/steamwar/fightsystem/states/OneShotStateDependent.java index 564415b..f5e87ff 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/states/OneShotStateDependent.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/states/OneShotStateDependent.java @@ -20,6 +20,8 @@ package de.steamwar.fightsystem.states; import de.steamwar.fightsystem.ArenaMode; +import de.steamwar.fightsystem.Config; +import de.steamwar.fightsystem.winconditions.Winconditions; import java.util.Set; @@ -33,6 +35,12 @@ public class OneShotStateDependent extends StateDependent{ register(); } + public OneShotStateDependent(Winconditions wincondition, Set states, Runnable runnable) { + super(Config.ActiveWinconditions.contains(wincondition), states); + this.runnable = runnable; + register(); + } + @Override public void enable() { runnable.run(); diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/PercentWincondition.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/PercentWincondition.java index eacac0b..c47c2a9 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/PercentWincondition.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/PercentWincondition.java @@ -19,8 +19,116 @@ package de.steamwar.fightsystem.winconditions; +import de.steamwar.fightsystem.Config; +import de.steamwar.fightsystem.fight.Fight; import de.steamwar.fightsystem.fight.FightTeam; +import de.steamwar.fightsystem.states.FightState; +import de.steamwar.fightsystem.states.OneShotStateDependent; +import de.steamwar.fightsystem.states.StateDependentListener; +import de.steamwar.fightsystem.utils.Message; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityExplodeEvent; -public interface PercentWincondition { - double getPercent(FightTeam team); +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BooleanSupplier; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.function.ToIntFunction; + +public class PercentWincondition extends Wincondition implements PrintableWincondition { + + private static final World world = Bukkit.getWorlds().get(0); + + private final Map teamMap = new HashMap<>(); + + protected BooleanSupplier explosionFilter = () -> !Config.EnterStages.isEmpty() && Config.EnterStages.get(0) >= Wincondition.getTimeOverCountdown().getTimeLeft(); + protected Predicate testBlock = type -> !Config.PercentBlocks.contains(type); + protected ToIntFunction totalBlockCalc = team -> { + AtomicInteger blocks = new AtomicInteger(); + team.getSchemRegion().forEach((x, y, z) -> { + if (testBlock.test(world.getBlockAt(x, y, z).getType())) { + blocks.getAndIncrement(); + } + }); + return blocks.get(); + }; + protected Consumer checkWin = team -> { + if (getPercent(team) >= Config.PercentWin) { + win(Fight.getOpposite(team), "WIN_PERCENT", team.getColoredName()); + } + }; + protected Consumer postEnable = team -> {}; + + public PercentWincondition(String windescription, Winconditions wincondition) { + super(windescription); + + if (Config.ActiveWinconditions.contains(wincondition)) { + printableWinconditions.add(this); + percentWincondition = this; + } + + new TeamPercent(Fight.getBlueTeam(), wincondition); + new TeamPercent(Fight.getRedTeam(), wincondition); + } + + public Message getDisplay(FightTeam team) { + return new Message("BAR_PERCENT", team.getPrefix() + (Math.round(100.0 * getPercent(team)) / 100.0)); + } + + public double getPercent(FightTeam team) { + return teamMap.get(team).getPercent(); + } + + protected int getTotalBlocks(FightTeam team) { + return teamMap.get(team).totalBlocks; + } + + private class TeamPercent implements Listener { + private final FightTeam team; + + private int totalBlocks = 0; + private int currentBlocks = 0; + + private TeamPercent(FightTeam team, Winconditions wincondition) { + this.team = team; + + new OneShotStateDependent(wincondition, FightState.Running, this::enable); + new StateDependentListener(wincondition, FightState.Running, this).register(); + teamMap.put(team, this); + } + + @EventHandler + public void onEntityExplode(EntityExplodeEvent event) { + if (explosionFilter.getAsBoolean() || !team.getExtendRegion().inRegion(event.getEntity().getLocation())) { + return; + } + + event.blockList().forEach(block -> { + if (testBlock.test(block.getType())) { + currentBlocks--; + } + }); + + checkWin.accept(team); + } + + private void enable() { + totalBlocks = totalBlockCalc.applyAsInt(team); + currentBlocks = totalBlocks; + postEnable.accept(team); + } + + private double getPercent() { + if (currentBlocks >= totalBlocks) { + return 0; + } + return (totalBlocks - currentBlocks) * 100 / (double) totalBlocks; + } + } } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionBlacklistPercent.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionBlacklistPercent.java new file mode 100644 index 0000000..a823079 --- /dev/null +++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionBlacklistPercent.java @@ -0,0 +1,27 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2020 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.fightsystem.winconditions; + +public class WinconditionBlacklistPercent extends PercentWincondition { + + public WinconditionBlacklistPercent(){ + super("RelativePercent", Winconditions.RELATIVE_PERCENT); + } +} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercentSystem.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercentSystem.java index 2f73c42..6be7476 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercentSystem.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercentSystem.java @@ -19,81 +19,12 @@ package de.steamwar.fightsystem.winconditions; -import de.steamwar.fightsystem.Config; -import de.steamwar.fightsystem.fight.Fight; -import de.steamwar.fightsystem.fight.FightTeam; -import de.steamwar.fightsystem.states.FightState; -import de.steamwar.fightsystem.states.StateDependentListener; -import de.steamwar.fightsystem.utils.Message; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityExplodeEvent; - -import java.util.HashMap; -import java.util.Map; - -public class WinconditionPercentSystem extends Wincondition implements Listener, PrintableWincondition, PercentWincondition { - - private final Map teamMap = new HashMap<>(); +public class WinconditionPercentSystem extends PercentWincondition { public WinconditionPercentSystem() { - super("Percent"); - teamMap.put(Fight.getBlueTeam(), new TeamPercent(Fight.getBlueTeam())); - teamMap.put(Fight.getRedTeam(), new TeamPercent(Fight.getRedTeam())); + super("Percent", Winconditions.PERCENT_SYSTEM); - new StateDependentListener(Winconditions.PERCENT_SYSTEM, FightState.Running, this){ - @Override - public void enable() { - super.enable(); - teamMap.forEach((team, percent) -> { - percent.destroyedBlocks = 0; - percent.percent = 0; - }); - } - }; - if(Config.ActiveWinconditions.contains(Winconditions.PERCENT_SYSTEM)){ - printableWinconditions.add(this); - percentWincondition = this; - } - } - - @EventHandler - public void handleEntityExplode(EntityExplodeEvent event) { - teamMap.values().forEach(teamPercent -> teamPercent.check(event)); - } - - @Override - public Message getDisplay(FightTeam team) { - return new Message("BAR_PERCENT", team.getPrefix() + (Math.round(100.0 * getPercent(team)) / 100.0)); - } - - @Override - public double getPercent(FightTeam team) { - return teamMap.get(team).percent; - } - - private class TeamPercent { - - private final FightTeam team; - private final int volume; - private double percent; - private int destroyedBlocks; - - private TeamPercent(FightTeam team) { - this.team = team; - this.volume = team.getSchemRegion().volume(); - } - - private void check(EntityExplodeEvent event) { - if(!team.getExtendRegion().inRegion(event.getEntity().getLocation())){ - return; - } - - destroyedBlocks += event.blockList().size(); - percent = (double)destroyedBlocks * 100 / volume; - if(percent >= Config.PercentWin) { - win(Fight.getOpposite(team), "WIN_PERCENT", team.getColoredName()); - } - } + totalBlockCalc = team -> team.getSchemRegion().volume(); + explosionFilter = () -> false; } } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPoints.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPoints.java index b988530..10bf4cf 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPoints.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPoints.java @@ -24,7 +24,6 @@ import de.steamwar.fightsystem.countdown.TimeOverCountdown; import de.steamwar.fightsystem.fight.Fight; import de.steamwar.fightsystem.fight.FightTeam; import de.steamwar.fightsystem.states.FightState; -import de.steamwar.fightsystem.states.StateDependent; import de.steamwar.fightsystem.states.StateDependentCountdown; import de.steamwar.fightsystem.states.StateDependentListener; import de.steamwar.fightsystem.utils.Message; @@ -37,35 +36,27 @@ import org.bukkit.event.player.PlayerQuitEvent; import java.util.HashMap; import java.util.Map; -public class WinconditionPoints extends Wincondition implements PrintableWincondition, Listener { +public class WinconditionPoints extends PercentWincondition implements Listener { private final Map teamMap = new HashMap<>(); public WinconditionPoints(){ - super("Points"); + super("Points", Winconditions.POINTS); + + checkWin = team -> {}; + postEnable = this::pointInit; teamMap.put(Fight.getBlueTeam(), new TeamPoints(Fight.getBlueTeam())); teamMap.put(Fight.getRedTeam(), new TeamPoints(Fight.getRedTeam())); new StateDependentListener(Winconditions.POINTS, FightState.Ingame, this); - new StateDependent(Winconditions.POINTS, FightState.Ingame){ - @Override - public void enable() { - teamMap.values().forEach(TeamPoints::enable); - } - @Override - public void disable() { - teamMap.values().forEach(TeamPoints::disable); - } - }.register(); if(Config.ActiveWinconditions.contains(Winconditions.POINTS)){ timeOverCountdown = new StateDependentCountdown(Winconditions.POINTS, FightState.Running, new TimeOverCountdown(this::timeOver)); - printableWinconditions.add(this); } } - protected void timeOver() { + private void timeOver() { int redPoints = teamMap.get(Fight.getRedTeam()).getPoints(); int bluePoints = teamMap.get(Fight.getBlueTeam()).getPoints(); @@ -104,6 +95,15 @@ public class WinconditionPoints extends Wincondition implements PrintableWincond } + private void pointInit(FightTeam team) { + TeamPoints opponent = teamMap.get(Fight.getOpposite(team)); + if(getTotalBlocks(team) == 0) + return; + + teamMap.get(team).setup(getTotalBlocks(Fight.getOpposite(team))); + opponent.setup(getTotalBlocks(team)); + } + @Override public Message getDisplay(FightTeam team) { return new Message("BAR_POINTS", team.getPrefix() + teamMap.get(team).getPoints()); @@ -113,26 +113,19 @@ public class WinconditionPoints extends Wincondition implements PrintableWincond private static final int MAX_POINTS = 2000; private final FightTeam team; - private final WinconditionRelativePercent.TeamPercent percent; - private double factor; private int points; TeamPoints(FightTeam team){ this.team = team; - this.percent = new WinconditionRelativePercent.TeamPercent(team); } - public void enable() { - this.points = 0; - percent.enable(); - int ownBlocks = percent.getBlockCount(); - int enemyBlocks = teamMap.get(Fight.getOpposite(team)).percent.getBlockCount(); - - if(enemyBlocks < ownBlocks) { + private void setup(int enemyBlocks){ + points = 0; + if(enemyBlocks < getTotalBlocks(team)) { this.factor = 100; //Original mit 20 (20% = 0.2 ergeben 2000 Punkte } else { - double f = 100.0 * ownBlocks / enemyBlocks; + double f = 100.0 * getTotalBlocks(team) / enemyBlocks; if(f > 100) f = 100; @@ -143,12 +136,8 @@ public class WinconditionPoints extends Wincondition implements PrintableWincond } } - public void disable(){ - percent.disable(); - } - public int getPoints(){ - int damagePoints = (int)(teamMap.get(Fight.getOpposite(team)).percent.getPercent() * factor); + int damagePoints = (int)(getPercent(Fight.getOpposite(team)) * factor); if(damagePoints > MAX_POINTS) damagePoints = MAX_POINTS; return points + damagePoints; diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionRelativePercent.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionRelativePercent.java deleted file mode 100644 index 064e444..0000000 --- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionRelativePercent.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - This file is a part of the SteamWar software. - - Copyright (C) 2020 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.fightsystem.winconditions; - -import de.steamwar.fightsystem.Config; -import de.steamwar.fightsystem.FightSystem; -import de.steamwar.fightsystem.fight.Fight; -import de.steamwar.fightsystem.fight.FightTeam; -import de.steamwar.fightsystem.states.FightState; -import de.steamwar.fightsystem.states.StateDependent; -import de.steamwar.fightsystem.utils.Message; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.scheduler.BukkitTask; - -import java.util.*; - -public class WinconditionRelativePercent extends Wincondition implements PrintableWincondition, PercentWincondition { - - private static final World world = Bukkit.getWorlds().get(0); - private static final Set ignoredBlocks; - - static{ - Set ignored = new HashSet<>(); - for(String s : Config.IgnoredBlocks) - ignored.add(Material.valueOf(s)); - ignoredBlocks = Collections.unmodifiableSet(ignored); - } - - private final Map teamMap = new HashMap<>(); - - public WinconditionRelativePercent(){ - super("RelativePercent"); - teamMap.put(Fight.getBlueTeam(), new TeamPercent(Fight.getBlueTeam())); - teamMap.put(Fight.getRedTeam(), new TeamPercent(Fight.getRedTeam())); - - if(Config.ActiveWinconditions.contains(Winconditions.RELATIVE_PERCENT)){ - printableWinconditions.add(this); - percentWincondition = this; - } - } - - @Override - public double getPercent(FightTeam team) { - return teamMap.get(team).getPercent(); - } - - @Override - public Message getDisplay(FightTeam team) { - return new Message("BAR_PERCENT", team.getPrefix() + (Math.round(100.0 * getPercent(team)) / 100.0)); - } - - public static class TeamPercent extends StateDependent { - private final FightTeam team; - - private int blockCount; - private BukkitTask task; - private int currentBlocks; - - public TeamPercent(FightTeam team){ - super(Winconditions.RELATIVE_PERCENT, FightState.Running); - this.team = team; - this.currentBlocks = 1; - register(); - } - - @Override - public void enable(){ - blockCount = currentBlocks(); - task = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), this::check, 400, 400); - } - - @Override - public void disable(){ - task.cancel(); - } - - private void check(){ - currentBlocks(); - - if(!Config.ActiveWinconditions.contains(Winconditions.RELATIVE_PERCENT)) - return; - - if(getPercent() >= Config.PercentWin){ - FightSystem.setSpectateState(Fight.getOpposite(team), "RelativePercent", "WIN_PERCENT", team.getColoredName()); - } - } - - public double getPercent(){ - if(currentBlocks > blockCount) - return 0; - return (blockCount - currentBlocks) * 100 / (double) blockCount; - } - - public int getBlockCount(){ - return blockCount; - } - - private int currentBlocks(){ - // Entern active - if(!Config.EnterStages.isEmpty() && Config.EnterStages.get(0) >= Wincondition.getTimeOverCountdown().getTimeLeft()) - return currentBlocks; - - currentBlocks = 0; - team.getSchemRegion().forEach((x, y, z) -> { - if(!ignoredBlocks.contains(world.getBlockAt(x,y,z).getType())) - currentBlocks++; - }); - return currentBlocks; - } - } -} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionWhitelistPercent.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionWhitelistPercent.java new file mode 100644 index 0000000..6607173 --- /dev/null +++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionWhitelistPercent.java @@ -0,0 +1,31 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2021 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.fightsystem.winconditions; + +import de.steamwar.fightsystem.Config; + +public class WinconditionWhitelistPercent extends PercentWincondition { + + public WinconditionWhitelistPercent() { + super("WhitelistPercent", Winconditions.WHITELIST_PERCENT); + + testBlock = Config.PercentBlocks::contains; + } +} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java index ed55771..2d9c5f6 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java @@ -28,6 +28,7 @@ public enum Winconditions { CAPTAIN_DEAD, PERCENT_SYSTEM, + WHITELIST_PERCENT, RELATIVE_PERCENT, POINTS,