diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/Config.java b/FightSystem_Core/src/de/steamwar/fightsystem/Config.java index 8f09b06..72f436b 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; @@ -33,7 +34,12 @@ import org.bukkit.util.Vector; import java.io.File; import java.util.*; +import java.util.function.BiConsumer; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.function.Supplier; import java.util.logging.Level; +import java.util.stream.Collector; import java.util.stream.Collectors; public class Config { @@ -97,7 +103,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 Blocks; //default kits public static final String MemberDefault; @@ -188,7 +194,7 @@ public class Config { TimeoutTime = config.getInt("WinConditionParams.TimeoutTime"); PercentWin = config.getDouble("WinConditionParams.PercentWin"); - IgnoredBlocks = Collections.unmodifiableList(config.getStringList("WinConditionParams.IgnoredBlocks")); + Blocks = Collections.unmodifiableSet(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 12c713d..58a1296 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java @@ -94,6 +94,7 @@ public class FightSystem extends JavaPlugin { new WinconditionWaterTechKO(); new WinconditionPercentSystem(); new WinconditionRelativePercent(); + new WinconditionRelativeWhitelistPercent(); 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..988e287 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; @@ -27,6 +29,12 @@ public class OneShotStateDependent extends StateDependent{ private final Runnable runnable; + public OneShotStateDependent(Winconditions wincondition, Set states, Runnable runnable) { + super(Config.ActiveWinconditions.contains(wincondition), states); + this.runnable = runnable; + register(); + } + public OneShotStateDependent(Set mode, Set states, Runnable runnable) { super(mode, states); this.runnable = runnable; diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/PercentWincondition.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/PercentWincondition.java index eacac0b..6a603d8 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/PercentWincondition.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/PercentWincondition.java @@ -19,8 +19,109 @@ 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.OneShotStateDependent; +import de.steamwar.fightsystem.states.StateDependentListener; +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; + +public abstract class PercentWincondition extends Wincondition implements PrintableWincondition { + + private static final World world = Bukkit.getWorlds().get(0); + + protected final Map teamMap = new HashMap<>(); + + protected PercentWincondition(String windescription, Winconditions winconditions) { + super(windescription); + + if (Config.ActiveWinconditions.contains(winconditions)) { + printableWinconditions.add(this); + percentWincondition = this; + } + } + + public String getDisplay(FightTeam team) { + return team.getPrefix() + "Schaden: " + (Math.round(100.0 * getPercent(team)) / 100.0) + "%"; + } + + public double getPercent(FightTeam team) { + return teamMap.get(team).getPercent(); + } + + protected class TeamPercent implements Listener { + protected final FightTeam fightTeam; + + protected int totalBlocks = 0; + private int currentBlocks = 0; + + protected TeamPercent(FightTeam fightTeam, Winconditions wincondition) { + this.fightTeam = fightTeam; + + new OneShotStateDependent(wincondition, FightState.Running, this::enable); + new StateDependentListener(wincondition, FightState.Running, this).register(); + teamMap.put(fightTeam, this); + } + + @EventHandler + public void onEntityExplode(EntityExplodeEvent event) { + if (checkEntern() || !fightTeam.getExtendRegion().inRegion(event.getEntity().getLocation())) { + return; + } + + event.blockList().forEach(block -> { + if (test(block.getType())) { + currentBlocks--; + } + }); + + checkWin(); + } + + protected void enable(){ + countTotal(); + currentBlocks = totalBlocks; + } + + protected void countTotal(){ + totalBlocks = 0; + fightTeam.getSchemRegion().forEach((x, y, z) -> { + if (test(world.getBlockAt(x, y, z).getType())) { + totalBlocks++; + } + }); + } + + protected boolean checkEntern(){ + return !Config.EnterStages.isEmpty() && Config.EnterStages.get(0) >= Wincondition.getTimeOverCountdown().getTimeLeft(); + } + + protected boolean test(Material type){ + return !Config.Blocks.contains(type); + } + + protected void checkWin(){ + if (getPercent() >= Config.PercentWin) { + Bukkit.broadcastMessage(FightSystem.PREFIX + "§cTeam " + fightTeam.getColoredName() + " §chat zu viel Schaden erlitten!"); + win(Fight.getOpposite(fightTeam)); + } + } + + protected double getPercent() { + if (currentBlocks >= totalBlocks) { + return 0; + } + return (totalBlocks - currentBlocks) * 100 / (double) totalBlocks; + } + } } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercentSystem.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercentSystem.java index 7a2f730..1285a61 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercentSystem.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercentSystem.java @@ -19,82 +19,28 @@ 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.StateDependentListener; -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); + create(Fight.getBlueTeam()); + create(Fight.getRedTeam()); + } - new StateDependentListener(Winconditions.PERCENT_SYSTEM, FightState.Running, this){ + private void create(FightTeam fightTeam) { + new TeamPercent(fightTeam, Winconditions.PERCENT_SYSTEM){ @Override - public void enable() { - super.enable(); - teamMap.forEach((team, percent) -> { - percent.destroyedBlocks = 0; - percent.percent = 0; - }); + protected boolean checkEntern() { + return false; + } + + @Override + protected void countTotal() { + totalBlocks = fightTeam.getSchemRegion().volume(); } }; - 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 String getDisplay(FightTeam team) { - return team.getPrefix() + "Schaden: " + (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) { - FightSystem.broadcast("§cTeam " + team.getColoredName() + " §chat zu viel Schaden erlitten!"); - win(Fight.getOpposite(team)); - } - } } } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPoints.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPoints.java index 52ac282..e3e5ff3 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPoints.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPoints.java @@ -25,7 +25,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 org.bukkit.entity.Player; @@ -37,31 +36,18 @@ 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); 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); } } @@ -113,30 +99,38 @@ public class WinconditionPoints extends Wincondition implements PrintableWincond return team.getPrefix() + "Punkte: " + teamMap.get(team).getPoints(); } - private class TeamPoints { + private class TeamPoints extends TeamPercent { 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); + super(team, Winconditions.POINTS); } - public void enable() { - this.points = 0; - percent.enable(); - int ownBlocks = percent.getBlockCount(); - int enemyBlocks = teamMap.get(Fight.getOpposite(team)).percent.getBlockCount(); + @Override + protected void checkWin() { + //ignored + } - if(enemyBlocks < ownBlocks) { + @Override + protected void enable() { + super.enable(); + TeamPoints opponent = teamMap.get(Fight.getOpposite(fightTeam)); + if(opponent.totalBlocks == 0) + return; + + setup(opponent.totalBlocks); + opponent.setup(totalBlocks); + } + + private void setup(int enemyBlocks){ + points = 0; + if(enemyBlocks < totalBlocks) { this.factor = 100; //Original mit 20 (20% = 0.2 ergeben 2000 Punkte } else { - double f = 100.0 * ownBlocks / enemyBlocks; + double f = 100.0 * totalBlocks / enemyBlocks; if(f > 100) f = 100; @@ -147,12 +141,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)(teamMap.get(Fight.getOpposite(fightTeam)).getPercent() * 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 index fd2b511..c042646 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionRelativePercent.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionRelativePercent.java @@ -19,112 +19,18 @@ 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 org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.scheduler.BukkitTask; -import java.util.*; +public class WinconditionRelativePercent extends PercentWincondition { -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); + public WinconditionRelativePercent() { + super("RelativePercent", Winconditions.RELATIVE_PERCENT); + create(Fight.getBlueTeam()); + create(Fight.getRedTeam()); } - 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 String getDisplay(FightTeam team) { - return team.getPrefix() + "Schaden: " + (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.broadcast("§cTeam " + team.getColoredName() + " §chat zu viel Schaden erlitten!"); - FightSystem.setSpectateState(Fight.getOpposite(team), "RelativePercent"); - } - } - - 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; - } + private void create(FightTeam fightTeam) { + new TeamPercent(fightTeam, Winconditions.RELATIVE_PERCENT); } } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java index ed55771..3fef015 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, + RELATIVE_WHITELIST_PERCENT, RELATIVE_PERCENT, POINTS, diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/winconditions/WinconditionRelativeWhitelistPercent.java b/FightSystem_Main/src/de/steamwar/fightsystem/winconditions/WinconditionRelativeWhitelistPercent.java new file mode 100644 index 0000000..b64df9c --- /dev/null +++ b/FightSystem_Main/src/de/steamwar/fightsystem/winconditions/WinconditionRelativeWhitelistPercent.java @@ -0,0 +1,44 @@ +/* + 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.fight.Fight; +import de.steamwar.fightsystem.fight.FightTeam; +import org.bukkit.Material; +import org.bukkit.event.Listener; + +public class WinconditionRelativeWhitelistPercent extends PercentWincondition implements Listener { + + public WinconditionRelativeWhitelistPercent() { + super("RelativeWhitelistPercent", Winconditions.RELATIVE_WHITELIST_PERCENT); + create(Fight.getBlueTeam()); + create(Fight.getRedTeam()); + } + + private void create(FightTeam fightTeam) { + new PercentWincondition.TeamPercent(fightTeam, Winconditions.RELATIVE_WHITELIST_PERCENT){ + @Override + protected boolean test(Material type) { + return Config.Blocks.contains(type); + } + }; + } +}