2021-03-12 15:43:32 +01:00
|
|
|
/*
|
|
|
|
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/>.
|
|
|
|
*/
|
|
|
|
|
2021-03-10 22:45:17 +01:00
|
|
|
package de.steamwar.fightsystem.winconditions;
|
|
|
|
|
2021-10-28 16:03:16 +02:00
|
|
|
import de.steamwar.fightsystem.Config;
|
|
|
|
import de.steamwar.fightsystem.fight.Fight;
|
2021-03-10 22:45:17 +01:00
|
|
|
import de.steamwar.fightsystem.fight.FightTeam;
|
2021-10-28 16:03:16 +02:00
|
|
|
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.Material;
|
2022-02-06 19:42:37 +01:00
|
|
|
import org.bukkit.entity.EntityType;
|
2021-10-28 16:03:16 +02:00
|
|
|
import org.bukkit.event.EventHandler;
|
|
|
|
import org.bukkit.event.Listener;
|
|
|
|
import org.bukkit.event.entity.EntityExplodeEvent;
|
2021-03-10 22:45:17 +01:00
|
|
|
|
2021-10-28 16:03:16 +02:00
|
|
|
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 final Map<FightTeam, TeamPercent> teamMap = new HashMap<>();
|
|
|
|
|
|
|
|
protected BooleanSupplier explosionFilter = () -> !Config.EnterStages.isEmpty() && Config.EnterStages.get(0) >= Wincondition.getTimeOverCountdown().getTimeLeft();
|
|
|
|
protected Predicate<Material> testBlock = type -> !Config.PercentBlocks.contains(type);
|
|
|
|
protected ToIntFunction<FightTeam> totalBlockCalc = team -> {
|
|
|
|
AtomicInteger blocks = new AtomicInteger();
|
|
|
|
team.getSchemRegion().forEach((x, y, z) -> {
|
2022-04-09 16:14:03 +02:00
|
|
|
if (testBlock.test(Config.world.getBlockAt(x, y, z).getType())) {
|
2021-10-28 16:03:16 +02:00
|
|
|
blocks.getAndIncrement();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return blocks.get();
|
|
|
|
};
|
|
|
|
protected Consumer<FightTeam> checkWin = team -> {
|
|
|
|
if (getPercent(team) >= Config.PercentWin) {
|
|
|
|
win(Fight.getOpposite(team), "WIN_PERCENT", team.getColoredName());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
protected Consumer<FightTeam> postEnable = team -> {};
|
|
|
|
|
|
|
|
public PercentWincondition(String windescription, Winconditions wincondition) {
|
|
|
|
super(windescription);
|
|
|
|
|
|
|
|
if (Config.ActiveWinconditions.contains(wincondition)) {
|
|
|
|
printableWinconditions.add(this);
|
|
|
|
percentWincondition = this;
|
|
|
|
}
|
|
|
|
|
2022-04-09 16:14:03 +02:00
|
|
|
Fight.teams().forEach(team -> new TeamPercent(team, wincondition));
|
2021-10-28 16:03:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
2022-02-10 18:34:37 +01:00
|
|
|
if (event.getEntityType() == EntityType.FIREBALL || explosionFilter.getAsBoolean() || !team.getExtendRegion().inRegion(event.getEntity().getLocation())) {
|
|
|
|
return;
|
|
|
|
}
|
2021-10-28 16:03:16 +02:00
|
|
|
|
2022-02-10 18:34:37 +01:00
|
|
|
event.blockList().forEach(block -> {
|
|
|
|
if (testBlock.test(block.getType())) {
|
|
|
|
currentBlocks--;
|
|
|
|
}
|
|
|
|
});
|
2022-02-06 19:42:37 +01:00
|
|
|
|
2022-02-10 18:34:37 +01:00
|
|
|
checkWin.accept(team);
|
2021-10-28 16:03:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2021-03-10 22:45:17 +01:00
|
|
|
}
|