diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java
index d137de1..b449484 100644
--- a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java
+++ b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java
@@ -108,6 +108,7 @@ public class FightSystem extends JavaPlugin {
new WinconditionBlacklistPercent();
new WinconditionWhitelistPercent();
new WinconditionPoints();
+ new WinconditionPointsAirShip();
new WinconditionTimeout();
new WinconditionTimeTechKO();
new EventTeamOffWincondition();
diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties
index f7ade17..ae4ae52 100644
--- a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties
+++ b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties
@@ -194,6 +194,7 @@ BAR_RUNNING3={1} {3} {5} {7} {9} {0} {6} {8} {10} {4} {2}
BAR_TIE={1} §7Draw {0} {2}
BAR_WIN={1} §7Victory {3} {0} {2}
BAR_POINTS={0} §8Points
+BAR_POINTS_OF={0}§8/§7{1} §8Points
BAR_PERCENT={0}§8%
BAR_CANNONS={0} §8Cannons
BAR_WATER={0} §8Water
diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties
index dd2c67f..166ddc8 100644
--- a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties
+++ b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties
@@ -179,6 +179,7 @@ BAR_PRE_RUNNING={1} {3} §7Kampfbeginn in {0} {4} {2}
BAR_TIE={1} §7Unentschieden {0} {2}
BAR_WIN={1} §7Sieg {3} {0} {2}
BAR_POINTS={0} §8Punkte
+BAR_POINTS_OF={0}§8/§7{1} §8Punkte
BAR_PERCENT={0}§8%
BAR_CANNONS={0} §8Kanonen
BAR_WATER={0} §8Wasser
diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/PercentWincondition.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/PercentWincondition.java
index a188528..40b227f 100644
--- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/PercentWincondition.java
+++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/PercentWincondition.java
@@ -85,6 +85,10 @@ public class PercentWincondition extends Wincondition implements PrintableWincon
return teamMap.get(team).totalBlocks;
}
+ protected int getCurrentBlocks(FightTeam team) {
+ return teamMap.get(team).currentBlocks;
+ }
+
private class TeamPercent implements Listener {
private final FightTeam team;
diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPointsAirShip.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPointsAirShip.java
new file mode 100644
index 0000000..978b898
--- /dev/null
+++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPointsAirShip.java
@@ -0,0 +1,153 @@
+/*
+ * 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.fight.Fight;
+import de.steamwar.fightsystem.fight.FightTeam;
+import de.steamwar.fightsystem.states.FightState;
+import de.steamwar.fightsystem.states.StateDependentListener;
+import de.steamwar.fightsystem.states.StateDependentTask;
+import de.steamwar.fightsystem.utils.Message;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.entity.PlayerDeathEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class WinconditionPointsAirShip extends PercentWincondition implements Listener {
+
+ private double[] as = new double[] {
+ 0.5,
+ 0.6,
+ 0.68,
+ 0.74,
+ 0.8
+ };
+
+ private double[] es = new double[] {
+ 0.25,
+ 0.3,
+ 0.34,
+ 0.37,
+ 0.4
+ };
+
+ private final Map teamMap = new HashMap<>();
+
+ public WinconditionPointsAirShip(){
+ super("Points", Winconditions.POINTS_AIRSHIP);
+
+ checkWin = team -> {
+ if (teamMap.get(team).getPoints() > TeamPoints.WIN_POINTS) {
+ end();
+ }
+ };
+ postEnable = this::pointInit;
+
+ Fight.teams().forEach(team -> teamMap.put(team, new TeamPoints(team)));
+
+ new StateDependentListener(Winconditions.POINTS_AIRSHIP, FightState.Ingame, this);
+ new StateDependentTask(Winconditions.POINTS_AIRSHIP, FightState.Running, this::running, 20, 20);
+
+ }
+
+ private void end() {
+ comparisonWin(team -> teamMap.get(team).getPoints(), "WIN_POINTS", "WIN_POINTS_EQUAL");
+ }
+
+ private void running() {
+ AtomicBoolean possibleEnd = new AtomicBoolean(false);
+ Fight.teams().forEach(team -> {
+ teamMap.get(team).points += 1;
+ possibleEnd.compareAndSet(false, teamMap.get(team).getPoints() >= TeamPoints.WIN_POINTS);
+ });
+ if(possibleEnd.get())
+ end();
+ }
+
+ @EventHandler
+ public void handlePlayerDeath(PlayerDeathEvent event) {
+ handleDeath(event.getEntity().getPlayer());
+ }
+
+ @EventHandler
+ public void handlePlayerQuit(PlayerQuitEvent event) {
+ handleDeath(event.getPlayer());
+ }
+
+ private void handleDeath(Player player){
+ FightTeam team = isTarget(player);
+ if(team == null)
+ return;
+
+ TeamPoints enemy = teamMap.get(Fight.getOpposite(team));
+ enemy.points += 200.0 / team.getPlayerCount();
+
+ if (enemy.getPoints() >= TeamPoints.WIN_POINTS)
+ end();
+ }
+
+ 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_OF", team.getPrefix() + (int) Math.round(teamMap.get(team).getPoints()), TeamPoints.WIN_POINTS);
+ }
+
+ private class TeamPoints {
+ protected static final double WIN_POINTS = 1200;
+
+ private final FightTeam team;
+ private double pointGetPerXBlocksBroken;
+ private double points;
+
+ TeamPoints(FightTeam team){
+ this.team = team;
+ }
+
+ private void setup(int enemyBlocks){
+ points = 0;
+
+ int factorIndex = Math.min(Math.max(team.getPlayerCount(), Fight.getOpposite(team).getPlayerCount()), as.length);
+ double a = as[factorIndex];
+ double e = es[factorIndex];
+ double volume = team.getSchemRegion().volume();
+
+ double needed = enemyBlocks * (a - (a * enemyBlocks) / volume + (e * enemyBlocks) / volume);
+ pointGetPerXBlocksBroken = needed / WIN_POINTS;
+ }
+
+ public double getPoints(){
+ FightTeam fightTeam = Fight.getOpposite(team);
+ return points + (getPercentWincondition().getTotalBlocks(fightTeam) - getPercentWincondition().getCurrentBlocks(fightTeam)) / pointGetPerXBlocksBroken;
+ }
+ }
+}
diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java
index 6c228ce..9d7ae2a 100644
--- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java
+++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java
@@ -31,6 +31,7 @@ public enum Winconditions {
WHITELIST_PERCENT,
RELATIVE_PERCENT,
POINTS,
+ POINTS_AIRSHIP,
TIME_TECH_KO,
WATER_TECH_KO,