diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/Config.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/Config.java index 3ecfa070..d7ce5f9e 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/Config.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/Config.java @@ -108,6 +108,7 @@ public class Config { public static final boolean PercentEntern; public static final boolean PercentBlocksWhitelist; public static final Set PercentBlocks; + public static final int TechKoTime; //default kits public static final String MemberDefault; @@ -209,6 +210,7 @@ public class Config { PercentEntern = config.getBoolean("WinConditionParams.PercentEntern", true); PercentBlocksWhitelist = config.getBoolean("WinConditionParams.BlocksWhitelist", false); PercentBlocks = Collections.unmodifiableSet(config.getStringList("WinConditionParams.Blocks").stream().map(Material::valueOf).collect(Collectors.toSet())); + TechKoTime = config.getInt("WinConditionParams.TechKoTime", 90); EnterStages = Collections.unmodifiableList(config.getIntegerList("EnterStages")); AllowMissiles = config.getBoolean("Arena.AllowMissiles", !EnterStages.isEmpty()); diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties index 455e0444..22babff0 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties @@ -191,6 +191,7 @@ BAR_POINTS_OF={0}§8/§7{1} §8Points BAR_PERCENT={0}§8% BAR_CANNONS={0} §8Cannons BAR_WATER={0} §8Water +BAR_SECONDS={0}§8s # Winconditions diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java index 1f205122..afd357e8 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java @@ -19,20 +19,15 @@ package de.steamwar.fightsystem.fight; -import com.comphenix.tinyprotocol.TinyProtocol; -import com.mojang.authlib.GameProfile; import de.steamwar.core.Core; -import de.steamwar.core.ProtocolWrapper; import de.steamwar.fightsystem.ArenaMode; import de.steamwar.fightsystem.Config; -import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.record.GlobalRecorder; +import de.steamwar.fightsystem.utils.RandomSeed; import lombok.Getter; import org.bukkit.Bukkit; -import org.bukkit.GameMode; import org.bukkit.Sound; import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; import java.util.Collection; import java.util.HashSet; @@ -40,6 +35,8 @@ import java.util.HashSet; public class Fight { private Fight(){} + @Getter + private static final RandomSeed randomSeed = new RandomSeed(); @Getter private static final FightTeam redTeam = new FightTeam(Config.TeamRedName, Config.TeamRedColor, Config.TeamRedSpawn, Config.RedPasteRegion, Config.RedExtendRegion, Config.RedRotate, false, Config.RedLeader); @Getter diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightSchematic.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightSchematic.java index d566c022..0fe45c73 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightSchematic.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightSchematic.java @@ -31,6 +31,7 @@ import de.steamwar.fightsystem.states.StateDependent; import de.steamwar.fightsystem.utils.ColorConverter; import de.steamwar.fightsystem.utils.Region; import de.steamwar.fightsystem.utils.WorldeditWrapper; +import de.steamwar.fightsystem.winconditions.Winconditions; import de.steamwar.sql.SchematicData; import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SchematicType; @@ -141,6 +142,11 @@ public class FightSchematic extends StateDependent { team.teleportToSpawn(); + boolean rotate = this.rotate; + if (Config.ActiveWinconditions.contains(Winconditions.RANDOM_ROTATE)) { + rotate = Fight.getRandomSeed().getRandom(schematic).nextBoolean(); + } + Vector dims = WorldeditWrapper.impl.getDimensions(clipboard); WorldeditWrapper.impl.pasteClipboard( clipboard, diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java index 47efc09d..84906a7b 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java @@ -20,7 +20,6 @@ package de.steamwar.fightsystem.record; import com.sk89q.worldedit.extent.clipboard.Clipboard; -import de.steamwar.core.Core; import de.steamwar.core.TrickyTrialsWrapper; import de.steamwar.core.WorldEditWrapper; import de.steamwar.entity.REntity; @@ -153,6 +152,7 @@ public class PacketProcessor implements Listener { packetDecoder[0xc6] = this::winMessage; packetDecoder[0xc7] = this::bossBarMessage; packetDecoder[0xef] = source::readUTF; + packetDecoder[0xfd] = this::randomSeed; packetDecoder[0xff] = this::tick; execSync(FightWorld::forceLoad); @@ -638,6 +638,14 @@ public class PacketProcessor implements Listener { execSync(() -> entities.get(entityId).setOnFire(perma)); } + private void randomSeed() throws IOException { + long seed = source.readLong(); + + execSync(() -> { + Fight.getRandomSeed().setSeed(seed); + }); + } + private void tick(){ execSync(entityServer::tick); diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/Recorder.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/Recorder.java index 73821e6f..c6b899ef 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/Recorder.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/Recorder.java @@ -133,6 +133,7 @@ public interface Recorder { * WinPacket (0xc6) + byte team + Message subtitle * BossBarPacket (0xc7) + double leftBlueProgress, leftRedProgress + Message leftBlueText, leftRedText * + * RandomSeed (0xfd) + long seed * CommentPacket (0xfe) + String comment * TickPacket (0xff) * @@ -310,6 +311,10 @@ public interface Recorder { write(0xc6, bTeam, new Message(subtitle, params)); } + default void seed(long seed) { + write(0xfd, seed); + } + default void tick(){ write(0xff); } @@ -339,6 +344,8 @@ public interface Recorder { stream.writeShort((Short)o); else if(o instanceof Integer) stream.writeInt((Integer)o); + else if(o instanceof Long) + stream.writeLong((Long)o); else if(o instanceof Float) stream.writeFloat((Float)o); else if(o instanceof Double) diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/RandomSeed.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/RandomSeed.java new file mode 100644 index 00000000..94db59dd --- /dev/null +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/RandomSeed.java @@ -0,0 +1,45 @@ +/* + * 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.utils; + +import de.steamwar.fightsystem.ArenaMode; +import de.steamwar.fightsystem.record.GlobalRecorder; +import de.steamwar.fightsystem.states.FightState; +import de.steamwar.fightsystem.states.OneShotStateDependent; +import lombok.Setter; + +import java.util.Random; + +public class RandomSeed { + + @Setter + private long seed; + + public RandomSeed() { + new OneShotStateDependent(ArenaMode.AntiReplay, FightState.PreSchemSetup, () -> { + this.seed = System.nanoTime(); + GlobalRecorder.getInstance().seed(seed); + }); + } + + public Random getRandom(int derivation) { + return new Random(seed ^ new Random(derivation).nextLong()); + } +} diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionTimeTechKO.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionTimeTechKO.java index f1177afa..df6e92ae 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionTimeTechKO.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionTimeTechKO.java @@ -20,6 +20,7 @@ package de.steamwar.fightsystem.winconditions; import de.steamwar.core.TrickyTrialsWrapper; +import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.countdown.Countdown; import de.steamwar.fightsystem.fight.Fight; import de.steamwar.fightsystem.fight.FightTeam; @@ -30,7 +31,6 @@ import de.steamwar.fightsystem.states.StateDependentTask; import de.steamwar.fightsystem.utils.Message; import de.steamwar.fightsystem.utils.SWSound; import org.bukkit.Location; -import org.bukkit.entity.EntityType; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityExplodeEvent; @@ -41,8 +41,7 @@ import java.util.Map; public class WinconditionTimeTechKO extends Wincondition implements Listener { - private static final int TECH_KO_TIME_IN_S = 90; - private static final int TECH_KO_HALF_TIME = TECH_KO_TIME_IN_S/2; + private static final int TECH_KO_HALF_TIME = Config.TechKoTime/2; private final Map spawnLocations = new HashMap<>(); private final Map countdowns = new HashMap<>(); @@ -51,9 +50,9 @@ public class WinconditionTimeTechKO extends Wincondition implements Listener { public WinconditionTimeTechKO(){ super("TechKO"); - new StateDependentListener(Winconditions.TIME_TECH_KO, FightState.Running, this); - new StateDependentTask(Winconditions.TIME_TECH_KO, FightState.Running, this::run, 20, 20); - new StateDependent(Winconditions.TIME_TECH_KO, FightState.Running) { + new StateDependentListener(Winconditions.TIMED_DAMAGE_TECH_KO, FightState.Running, this); + new StateDependentTask(Winconditions.TIMED_DAMAGE_TECH_KO, FightState.Running, this::run, 20, 20); + new StateDependent(Winconditions.TIMED_DAMAGE_TECH_KO, FightState.Running) { @Override public void enable() { Fight.teams().forEach(team -> currentTime.put(team, TECH_KO_HALF_TIME)); diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionTimedDamageTechKO.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionTimedDamageTechKO.java new file mode 100644 index 00000000..c561400c --- /dev/null +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionTimedDamageTechKO.java @@ -0,0 +1,115 @@ +/* + * 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.core.TrickyTrialsWrapper; +import de.steamwar.fightsystem.Config; +import de.steamwar.fightsystem.countdown.Countdown; +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.StateDependentListener; +import de.steamwar.fightsystem.utils.Message; +import de.steamwar.fightsystem.utils.SWSound; +import org.bukkit.Location; +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 WinconditionTimedDamageTechKO extends Wincondition implements PrintableWincondition, Listener { + + private final Map countdowns = new HashMap<>(); + + public WinconditionTimedDamageTechKO() { + super("TechKO"); + + new StateDependentListener(Winconditions.TIMED_DAMAGE_TECH_KO, FightState.Running, this); + new StateDependent(Winconditions.TIMED_DAMAGE_TECH_KO, FightState.Running) { + @Override + public void enable() { + Fight.teams().forEach(team -> { + TechKOCountdown countdown = new TechKOCountdown(team, Config.TechKoTime); + countdowns.put(team, countdown); + countdown.enable(); + }); + } + + @Override + public void disable() { + countdowns.values().forEach(Countdown::disable); + countdowns.clear(); + } + }.register(); + } + + @Override + public Message getDisplay(FightTeam team) { + return new Message("BAR_SECONDS", team.getPrefix() + countdowns.get(team).getTimeLeft()); + } + + @EventHandler + public void onExplode(EntityExplodeEvent e) { + if (e.getEntityType() != TrickyTrialsWrapper.impl.getTntEntityType()) + return; + + Location location = e.getLocation(); + TechKOCountdown countdown = null; + FightTeam fightTeam = null; + for (FightTeam team : Fight.teams()) { + FightTeam current = Fight.getOpposite(team); + if (current.getExtendRegion().inRegion(location)) { + fightTeam = current; + countdown = countdowns.get(team); + break; + } + } + if (fightTeam == null) { + return; + } + + FightTeam finalFightTeam = fightTeam; + TechKOCountdown finalCountdown = countdown; + e.blockList().forEach(block -> { + if (block.isEmpty()) return; + if (finalFightTeam.getExtendRegion().inRegion(block)) { + finalCountdown.disable(); + finalCountdown.enable(); + } + }); + } + + private class TechKOCountdown extends Countdown { + private final FightTeam team; + + public TechKOCountdown(FightTeam team, int countdownTime) { + super(countdownTime, new Message("TECHKO_COUNTDOWN", team.getColoredName()), SWSound.BLOCK_NOTE_PLING, false); + this.team = team; + } + + @Override + public void countdownFinished() { + win(Fight.getOpposite(team), "WIN_TECHKO", team.getColoredName()); + } + } +} diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java index 2aaecae6..81b75173 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java @@ -31,7 +31,8 @@ public enum Winconditions { POINTS, POINTS_AIRSHIP, - TIME_TECH_KO, + DAMAGE_TECH_KO, + TIMED_DAMAGE_TECH_KO, WATER_TECH_KO, PUMPKIN_TECH_KO, @@ -41,4 +42,5 @@ public enum Winconditions { PERSISTENT_DAMAGE, TNT_DISTRIBUTION, NO_GRAVITY, + RANDOM_ROTATE, }