|
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
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<FightTeam, TeamPoints> 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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|