diff --git a/FightSystem_14/src/de/steamwar/fightsystem/utils/BlockIdWrapper14.java b/FightSystem_14/src/de/steamwar/fightsystem/utils/BlockIdWrapper14.java index 916bfb6..934d9b6 100644 --- a/FightSystem_14/src/de/steamwar/fightsystem/utils/BlockIdWrapper14.java +++ b/FightSystem_14/src/de/steamwar/fightsystem/utils/BlockIdWrapper14.java @@ -21,6 +21,7 @@ package de.steamwar.fightsystem.utils; import com.comphenix.tinyprotocol.Reflection; import de.steamwar.core.Core; +import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; @@ -56,4 +57,11 @@ public class BlockIdWrapper14 implements BlockIdWrapper { getTypeAndData.invoke(nworld, pos, blockData, 1042); flagDirty.invoke(getChunkProvider.invoke(nworld), pos); } + + private static final Reflection.MethodInvoker getMaterialByBlock = Reflection.getTypedMethod(Reflection.getClass("{obc}.util.CraftMagicNumbers"), "getMaterial", Material.class, block); + private static final Reflection.MethodInvoker getBlockByBlockData = Reflection.getTypedMethod(iBlockData, null, block); + @Override + public Material idToMaterial(int blockState) { + return (Material)getMaterialByBlock.invoke(null, getBlockByBlockData.invoke(getByCombinedId.invoke(null, blockState))); + } } diff --git a/FightSystem_8/src/de/steamwar/fightsystem/utils/BlockIdWrapper8.java b/FightSystem_8/src/de/steamwar/fightsystem/utils/BlockIdWrapper8.java index aedd2e8..cbf186a 100644 --- a/FightSystem_8/src/de/steamwar/fightsystem/utils/BlockIdWrapper8.java +++ b/FightSystem_8/src/de/steamwar/fightsystem/utils/BlockIdWrapper8.java @@ -19,6 +19,7 @@ package de.steamwar.fightsystem.utils; +import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; @@ -37,4 +38,13 @@ public class BlockIdWrapper8 implements BlockIdWrapper { world.getBlockAt(x, y, z).setTypeIdAndData(blockState >> 4, (byte)(blockState & 0b1111), false); } + + @Override + @SuppressWarnings("deprecation") + public Material idToMaterial(int blockState) { + if((blockState >> 4) > 256) // Illegal blockstate / corrupted replay + blockState = 0; + + return Material.getMaterial(blockState >> 4); + } } diff --git a/FightSystem_Core/src/config.yml b/FightSystem_Core/src/config.yml index e2fffe4..ca3645d 100644 --- a/FightSystem_Core/src/config.yml +++ b/FightSystem_Core/src/config.yml @@ -61,10 +61,14 @@ Schematic: z: 0 # The schematic type that can be chosen in this arena Type: Normal # defaults to Normal if missing + # The schematic types that are also allowed to be chosen in this arena + SubTypes: [] # defaults to empty List # Shortcut of the schematic type Shortcut: "" # defaults to "" if missing # Spigot (1.8) material for GUIs Material: STONE_BUTTON # defaults to STONE_BUTTON if missing + # Manual check of schematic necessary + ManualCheck: true # defaults to true if missing # If the schematics should be rotated during pasting Rotate: true # defaults to true if missing # If the schematics should be pasted aligned to the borders instead of centered @@ -110,8 +114,6 @@ WinConditions: # defaults to none if missing # - CAPTAIN_DEAD # - PERCENT_SYSTEM - # - WHITELIST_PERCENT - # - RELATIVE_PERCENT # - POINTS # - POINTS_AIRSHIP @@ -121,12 +123,18 @@ WinConditions: # defaults to none if missing # - HELLS_BELLS # - METEOR + # - PERSISTENT_DAMAGE + # - TNT_DISTRIBUTION WinConditionParams: # The time of any of the timeout win conditions in seconds TimeoutTime: 1200 # defaults to 1200 if missing # The percentage when any of the percent win conditions limits or triggers a win PercentWin: 7.0 # defaults to 7.0 if missing + # Does the percentage still change after the start of the enter phase + PercentEntern: true # defaults to true if missing + # Is Blocks a whitelist (true) or blacklist (false) + BlocksWhitelist: false # defaults to false if missing # Special Blocks (Valid spigot material values) used by the percent win conditions Blocks: [] # defaults to none if missing diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/Config.java b/FightSystem_Core/src/de/steamwar/fightsystem/Config.java index 9b8bf6d..b1030f7 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/Config.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/Config.java @@ -83,6 +83,7 @@ public class Config { public static final boolean OnlyPublicSchematics; public static final boolean IgnorePublicOnly; public static final de.steamwar.sql.SchematicType SchematicType; + public static final List SubTypes; public static final boolean RedRotate; public static final boolean BlueRotate; public static final boolean PasteAligned; @@ -106,6 +107,8 @@ public class Config { //win condition parameters public static final int TimeoutTime; public static final double PercentWin; + public static final boolean PercentEntern; + public static final boolean PercentBlocksWhitelist; public static final Set PercentBlocks; //default kits @@ -117,7 +120,7 @@ public class Config { //tech hider parameter public static final boolean TechhiderActive; - public static final Set HiddenBlocks; + public static final Set HiddenBlocks; public static final Set HiddenBlockEntities; public static final String ObfuscateWith; @@ -181,6 +184,7 @@ public class Config { int schemsizeZ = config.getInt("Schematic.Size.z"); RanksEnabled = !config.getStringList("Ranks").isEmpty(); SchematicType = de.steamwar.sql.SchematicType.fromDB(Objects.requireNonNull(config.getString("Schematic.Type", "normal"))); + SubTypes = config.getStringList("Schematic.SubTypes").stream().map(de.steamwar.sql.SchematicType::fromDB).collect(Collectors.toList()); IgnorePublicOnly = config.getBoolean("Schematic.IgnorePublicOnly", false); boolean rotate = config.getBoolean("Schematic.Rotate", true); PasteAligned = config.getBoolean("Schematic.PasteAligned", false); @@ -195,6 +199,8 @@ public class Config { TimeoutTime = config.getInt("WinConditionParams.TimeoutTime", 1200); PercentWin = config.getDouble("WinConditionParams.PercentWin", 7.0); + 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())); EnterStages = Collections.unmodifiableList(config.getIntegerList("EnterStages")); @@ -208,7 +214,7 @@ public class Config { TechhiderActive = config.getBoolean("Techhider.Active", false); ObfuscateWith = config.getString("Techhider.ObfuscateWith", "end_stone").toUpperCase(); - HiddenBlocks = Collections.unmodifiableSet(new HashSet<>(config.getStringList("Techhider.HiddenBlocks"))); + HiddenBlocks = config.getStringList("Techhider.HiddenBlocks").stream().map(String::toUpperCase).map(Material::getMaterial).collect(Collectors.toSet()); HiddenBlockEntities = Collections.unmodifiableSet(new HashSet<>(config.getStringList("Techhider.HiddenBlockEntities"))); if(schemsizeX < 0){ diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java index bead0f8..875c926 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java @@ -27,6 +27,8 @@ import de.steamwar.fightsystem.commands.*; import de.steamwar.fightsystem.countdown.*; import de.steamwar.fightsystem.event.HellsBells; import de.steamwar.fightsystem.event.Meteor; +import de.steamwar.fightsystem.event.PersistentDamage; +import de.steamwar.fightsystem.event.TNTDistributor; import de.steamwar.fightsystem.fight.Fight; import de.steamwar.fightsystem.fight.FightTeam; import de.steamwar.fightsystem.fight.FightWorld; @@ -54,6 +56,7 @@ public class FightSystem extends JavaPlugin { private FightTeam lastWinner; private String lastWinreason; private TechHiderWrapper techHider; + private HullHider hullHider; @Override public void onLoad() { @@ -108,6 +111,7 @@ public class FightSystem extends JavaPlugin { new EnterHandler(); techHider = new TechHiderWrapper(); + hullHider = new HullHider(); new FightWorld(); new FightUI(); new FightStatistics(); @@ -117,9 +121,7 @@ public class FightSystem extends JavaPlugin { new WinconditionCaptainDead(); new WinconditionBlocks(Winconditions.WATER_TECH_KO, "WaterTechKO", "BAR_WATER", FlatteningWrapper.impl::isWater); new WinconditionBlocks(Winconditions.PUMPKIN_TECH_KO, "PumpkinTechKO", "BAR_CANNONS", block -> block.getType() == WinconditionBlocks.PUMPKIN_LANTERN); - new WinconditionPercentSystem(); - new WinconditionBlacklistPercent(); - new WinconditionWhitelistPercent(); + new WinconditionPercent(Winconditions.PERCENT_SYSTEM, "Percent"); new WinconditionPoints(); new WinconditionPointsAirShip(); new WinconditionTimeout(); @@ -130,6 +132,8 @@ public class FightSystem extends JavaPlugin { new HellsBells(); new Meteor(); + new PersistentDamage(); + new TNTDistributor(); new WinconditionAmongUs(); new NoPlayersOnlineCountdown(); @@ -153,6 +157,7 @@ public class FightSystem extends JavaPlugin { new LockschemCommand(); new StateCommand(); new SkipCommand(); + new TPSWarpCommand(); new UnrankCommand(); new WinCommand(); @@ -164,7 +169,15 @@ public class FightSystem extends JavaPlugin { if(Config.mode == ArenaMode.EVENT) { FightState.setFightState(FightState.PRE_SCHEM_SETUP); }else if(Config.mode == ArenaMode.CHECK){ - Fight.getBlueTeam().setSchem(SchematicNode.getSchematicNode(Config.CheckSchemID)); + SchematicNode checkSchematicNode = SchematicNode.getSchematicNode(Config.CheckSchemID); + Fight.getBlueTeam().setSchem(checkSchematicNode); + + if (checkSchematicNode.getName().endsWith("-prepared")) { + SchematicNode unpreparedSchematicNode = SchematicNode.getSchematicNode(checkSchematicNode.getOwner(), checkSchematicNode.getName().substring(0, checkSchematicNode.getName().length() - 9), checkSchematicNode.getParent()); + if (unpreparedSchematicNode != null) { + Fight.getRedTeam().setSchem(unpreparedSchematicNode); + } + } }else if(Config.mode == ArenaMode.PREPARE) { Fight.getUnrotated().setSchem(SchematicNode.getSchematicNode(Config.PrepareSchemID)); } @@ -217,6 +230,10 @@ public class FightSystem extends JavaPlugin { return plugin.techHider; } + public static HullHider getHullHider() { + return plugin.hullHider; + } + public static void shutdown() { //Staggered kick to prevent lobby overloading if(Bukkit.getOnlinePlayers().isEmpty()){ diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties index c60b91b..3c220d6 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties +++ b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties @@ -51,6 +51,9 @@ INFO_RANKED=§7Ranked§8: §e{0} INFO_LEADER=§7Leader {0}§8: {1} INFO_SCHEMATIC=§7Schematic {0}§8: §e{1} §7from {2}, Rank: {3} +TPSWARP_HELP=§8/§7tpswarp §8[§eticks per second§8] +TPSWARP_SET=§7TPS set to §e{0} + # GUI STATE_TITLE=Fight state @@ -75,6 +78,7 @@ KITSEARCH_TITLE=Search for kit SCHEM_NO_ENEMY=§cNo schematic selection without an opponent SCHEM_TITLE={0} selection SCHEM_PUBLIC=§ePublic {0} +SCHEM_UNCHECKED=§eUnchecked {0} SCHEM_PRIVATE=§ePrivate {0} SCHEM_NO_PRIVATE=§7No private {0} present SCHEM_PRIVATE_FORBIDDEN=§7No private {0} allowed @@ -99,6 +103,7 @@ SPECTATE_COUNTDOWN=until the arena is reset # Fight SCHEMATIC_UNLOADABLE=§cUnable to load schematic SCHEMATIC_CHOSEN=§7{0} §e{1} §7chosen +SCHEMATIC_UNCHECKED=§7Team {0} §7has chosen an §eunchecked §7schematic§8! TEAM_READY=§aTeam ready TEAM_NOT_READY=§c§mTeam ready SKIP_READY=§aSkipping to next event diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties index 415652c..06b07d1 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties +++ b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties @@ -45,6 +45,9 @@ REMOVE_HELP=§8/§eremove §8[§eSpieler§8] NOT_FIGHTLEADER=§cDu bist nicht Kampfleiter WIN_HELP=§8/§7win §8[§eTeam §8oder §etie§8] +TPSWARP_HELP=§8/§7tpswarp §8[§eTicks pro Sekunde§8] +TPSWARP_SET=§7TPS auf §e{0} §7gesetzt + # GUI STATE_TITLE=Kampfstatus @@ -69,6 +72,7 @@ KITSEARCH_TITLE=Nach Kit suchen SCHEM_NO_ENEMY=§cKeine Schematicwahl ohne Gegner SCHEM_TITLE={0}-Auswahl SCHEM_PUBLIC=§eÖffentliches {0} +SCHEM_UNCHECKED=§eUngeprüftes {0} SCHEM_PRIVATE=§ePrivates {0} SCHEM_NO_PRIVATE=§7Kein privates {0} vorhanden SCHEM_PRIVATE_FORBIDDEN=§7Kein privates {0} erlaubt @@ -93,6 +97,7 @@ SPECTATE_COUNTDOWN=bis die Arena zurückgesetzt wird # Fight SCHEMATIC_UNLOADABLE=§cSchematic konnte nicht geladen werden SCHEMATIC_CHOSEN=§7{0} §e{1} §7gewählt +SCHEMATIC_UNCHECKED=§7Team {0} §7hat eine §eungeprüfte §7Schematic gewählt§8! TEAM_READY=§aTeam bereit TEAM_NOT_READY=§c§mTeam bereit SKIP_READY=§aBeschleunigung zum nächsten Event diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java b/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java index cb63550..438bd1a 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java @@ -19,6 +19,7 @@ package de.steamwar.fightsystem.commands; +import de.steamwar.fightsystem.ArenaMode; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.fight.*; @@ -29,6 +30,7 @@ import de.steamwar.inventory.*; import de.steamwar.message.Message; import de.steamwar.sql.PersonalKit; import de.steamwar.sql.SchematicNode; +import de.steamwar.sql.SchematicType; import de.steamwar.sql.SteamwarUser; import net.md_5.bungee.api.ChatMessageType; import org.bukkit.Bukkit; @@ -167,27 +169,47 @@ public class GUI { return; } - SWInventory inv = new SWInventory(p, 9, msg.parse("SCHEM_TITLE", p, Config.GameName)); - inv.setItem(8, Material.REDSTONE, msg.parse("SCHEM_PUBLIC", p, Config.GameName), (ClickType click) -> { - p.closeInventory(); - schemDialog(p, true); - }); - if(Fight.getMaxRank() == 0){ - inv.setItem(0, SWItem.getDye(8), (byte)8, msg.parse("SCHEM_PRIVATE_FORBIDDEN", p, Config.GameName), (ClickType click)->{}); - }else if(SchematicNode.getAllAccessibleSchematicsOfType(SteamwarUser.get(p.getUniqueId()).getId(), Config.SchematicType.toDB()).isEmpty() && !Config.test()){ - inv.setItem(0, SWItem.getDye(8), (byte)8, msg.parse("SCHEM_NO_PRIVATE", p, Config.GameName), (ClickType click)->{}); - }else{ - inv.setItem(0, SWItem.getMaterial("CAULDRON_ITEM"), msg.parse("SCHEM_PRIVATE", p, Config.GameName), (ClickType click) -> { - p.closeInventory(); - schemDialog(p, false); - }); + int invSize = (Config.SubTypes.size() + 1) * 9; + SWInventory inv = new SWInventory(p, invSize, msg.parse("SCHEM_TITLE", p, Config.GameName)); + setupSchemTypeRow(p, inv, Config.SchematicType, 0); + for (int i = 0; i < Config.SubTypes.size(); i++) { + setupSchemTypeRow(p, inv, Config.SubTypes.get(i), i + 1); } inv.setCallback(-999, (ClickType click) -> p.closeInventory()); inv.open(); } - private static void schemDialog(Player p, boolean publicSchems){ - SchematicSelector selector = new SchematicSelector(p, Config.test()?SchematicSelector.selectSchematic():SchematicSelector.selectSchematicTypeWithRank(Config.SchematicType, Fight.getMaxRank()), node -> { + private static void setupSchemTypeRow(Player p, SWInventory inv, SchematicType type, int row) { + inv.setItem(row * 9 + 8, Material.REDSTONE, msg.parse("SCHEM_PUBLIC", p, type.name()), (ClickType click) -> { + p.closeInventory(); + schemDialog(p, type, true, false); + }); + + if (Fight.publicOnly()) { + inv.setItem(row * 9, SWItem.getDye(8), (byte)8, msg.parse("SCHEM_PRIVATE_FORBIDDEN", p, type.name()), (ClickType click)->{}); + return; + } + + if (type.checkType() != null && type.checkType() != type && ArenaMode.AntiEvent.contains(Config.mode) && !SchematicNode.getAllAccessibleSchematicsOfType(SteamwarUser.get(p.getUniqueId()).getId(), type.checkType().toDB()).isEmpty()) { + inv.setItem(row * 9 + 4, Material.ANVIL, msg.parse("SCHEM_UNCHECKED", p, type.name()), (ClickType click) -> { + p.closeInventory(); + schemDialog(p, type, false, true); + }); + } + + if (SchematicNode.getAllAccessibleSchematicsOfType(SteamwarUser.get(p.getUniqueId()).getId(), type.toDB()).isEmpty() && !Config.test()) { + inv.setItem(row * 9, SWItem.getDye(8), (byte)8, msg.parse("SCHEM_NO_PRIVATE", p, type.name()), (ClickType click)->{}); + return; + } + + inv.setItem(row * 9, SWItem.getMaterial("CAULDRON_ITEM"), msg.parse("SCHEM_PRIVATE", p, type.name()), (ClickType click) -> { + p.closeInventory(); + schemDialog(p, type, false, false); + }); + } + + private static void schemDialog(Player p, SchematicType type, boolean publicSchems, boolean unchecked){ + SchematicSelector selector = new SchematicSelector(p, Config.test() ? SchematicSelector.selectSchematic() : SchematicSelector.selectSchematicType(unchecked ? type.checkType() : type), node -> { FightTeam fightTeam = Fight.getPlayerTeam(p); if(fightTeam == null) return; diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/commands/LockschemCommand.java b/FightSystem_Core/src/de/steamwar/fightsystem/commands/LockschemCommand.java index 9f9bd62..9ea0c13 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/commands/LockschemCommand.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/commands/LockschemCommand.java @@ -35,7 +35,7 @@ import org.bukkit.entity.Player; public class LockschemCommand implements CommandExecutor { public LockschemCommand() { - new StateDependentCommand(ArenaMode.AntiReplay, FightState.All, "lockschem", this); + new StateDependentCommand(ArenaMode.All, FightState.Schem, "lockschem", this); } @Override diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/commands/TPSWarpCommand.java b/FightSystem_Core/src/de/steamwar/fightsystem/commands/TPSWarpCommand.java new file mode 100644 index 0000000..27927f7 --- /dev/null +++ b/FightSystem_Core/src/de/steamwar/fightsystem/commands/TPSWarpCommand.java @@ -0,0 +1,52 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 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.commands; + +import de.steamwar.core.TPSWarpUtils; +import de.steamwar.fightsystem.ArenaMode; +import de.steamwar.fightsystem.FightSystem; +import de.steamwar.fightsystem.states.FightState; +import de.steamwar.fightsystem.states.StateDependentCommand; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class TPSWarpCommand implements CommandExecutor { + + public TPSWarpCommand() { + new StateDependentCommand(ArenaMode.Prepare, FightState.PostSchemSetup, "tpswarp", this); + new StateDependentCommand(ArenaMode.Prepare, FightState.PostSchemSetup, "tpslimit", this); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + double tps; + try { + tps = Double.parseDouble(args[0]); + } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) { + FightSystem.getMessage().send("TPSWARP_HELP", sender); + return false; + } + + TPSWarpUtils.warp(tps); + FightSystem.getMessage().broadcastActionbar("TPSWARP_SET", tps); + return false; + } +} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/countdown/EnternCountdown.java b/FightSystem_Core/src/de/steamwar/fightsystem/countdown/EnternCountdown.java index 7517be6..157c296 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/countdown/EnternCountdown.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/countdown/EnternCountdown.java @@ -25,17 +25,15 @@ import de.steamwar.fightsystem.fight.FightPlayer; import de.steamwar.fightsystem.utils.Message; import de.steamwar.fightsystem.utils.SWSound; import de.steamwar.techhider.ProtocolUtils; -import de.steamwar.fightsystem.winconditions.Wincondition; import net.md_5.bungee.api.ChatMessageType; import java.util.List; public class EnternCountdown extends Countdown { - private static int calcTime(FightPlayer fp) { + private static int calcTime(FightPlayer fp, Countdown countdown) { int time = Config.EnterStages.get(fp.getKit().getEnterStage()); - Countdown countdown = Wincondition.getTimeOverCountdown(); if(countdown != null) { time -= Config.TimeoutTime - countdown.getTimeLeft(); @@ -49,8 +47,8 @@ public class EnternCountdown extends Countdown { private final FightPlayer fightPlayer; private List chunkPos; - public EnternCountdown(FightPlayer fp) { - super(calcTime(fp), new Message("ENTERN_COUNTDOWN"), SWSound.BLOCK_NOTE_PLING, false); + public EnternCountdown(FightPlayer fp, Countdown countdown) { + super(calcTime(fp, countdown), new Message("ENTERN_COUNTDOWN"), SWSound.BLOCK_NOTE_PLING, false); fightPlayer = fp; enable(); } @@ -58,7 +56,10 @@ public class EnternCountdown extends Countdown { @Override public void countdownFinished() { FightSystem.getMessage().sendPrefixless("ENTERN_ALLOWED", fightPlayer.getEntity(), ChatMessageType.ACTION_BAR); - fightPlayer.ifPlayer(player -> FightSystem.getTechHider().reloadChunks(player, chunkPos, false)); + fightPlayer.ifPlayer(player -> { + FightSystem.getHullHider().updatePlayer(player); + FightSystem.getTechHider().reloadChunks(player, chunkPos, false); + }); } @Override diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/event/PersistentDamage.java b/FightSystem_Core/src/de/steamwar/fightsystem/event/PersistentDamage.java new file mode 100644 index 0000000..543eff9 --- /dev/null +++ b/FightSystem_Core/src/de/steamwar/fightsystem/event/PersistentDamage.java @@ -0,0 +1,49 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 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.event; + +import com.sk89q.worldedit.WorldEditException; +import de.steamwar.fightsystem.ArenaMode; +import de.steamwar.fightsystem.Config; +import de.steamwar.fightsystem.FightSystem; +import de.steamwar.fightsystem.fight.Fight; +import de.steamwar.fightsystem.states.FightState; +import de.steamwar.fightsystem.states.OneShotStateDependent; +import de.steamwar.fightsystem.utils.WorldeditWrapper; +import de.steamwar.fightsystem.winconditions.Winconditions; +import de.steamwar.sql.SchematicNode; + +import java.util.logging.Level; + +public class PersistentDamage { + + public PersistentDamage() { + if(!ArenaMode.SeriousFight.contains(Config.mode)) + return; + + new OneShotStateDependent(Winconditions.PERSISTENT_DAMAGE, FightState.Spectate, () -> Fight.teams().forEach(team -> { + try{ + WorldeditWrapper.impl.saveSchem(SchematicNode.getSchematicNode(team.getSchematic()), team.getExtendRegion(), team.getSchemRegion().getMinY()); + }catch(WorldEditException e){ + FightSystem.getPlugin().getLogger().log(Level.SEVERE, "Could not persist schematic state", e); + } + })); + } +} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/event/TNTDistributor.java b/FightSystem_Core/src/de/steamwar/fightsystem/event/TNTDistributor.java new file mode 100644 index 0000000..8982bb3 --- /dev/null +++ b/FightSystem_Core/src/de/steamwar/fightsystem/event/TNTDistributor.java @@ -0,0 +1,39 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 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.event; + +import de.steamwar.fightsystem.fight.Fight; +import de.steamwar.fightsystem.states.FightState; +import de.steamwar.fightsystem.states.StateDependentTask; +import de.steamwar.fightsystem.winconditions.Winconditions; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +public class TNTDistributor { + + public TNTDistributor() { + new StateDependentTask(Winconditions.TNT_DISTRIBUTION, FightState.Running, () -> Fight.teams().forEach(team -> team.getPlayers().forEach(fp -> { + if(!fp.isLiving()) + return; + + fp.ifPlayer(player -> player.getInventory().addItem(new ItemStack(Material.TNT, 20))); + })), 300, 300); + } +} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java b/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java index f7011d0..e8966ab 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java @@ -139,21 +139,16 @@ public class Fight { TinyProtocol.instance.sendPacket(player, ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.GAMEMODE, new GameProfile(player.getUniqueId(), player.getName()), enable ? GameMode.CREATIVE : GameMode.SPECTATOR)); } - public static int getMaxRank(){ - /* MaxRank of 0 is Pubonly*/ - if(Config.OnlyPublicSchematics){ - return 0; + public static boolean publicOnly() { + if (Config.OnlyPublicSchematics) { + return true; } - - if(Config.IgnorePublicOnly || ArenaMode.RankedEvent.contains(Config.mode)){ - return 1000; + if (Config.IgnorePublicOnly || ArenaMode.RankedEvent.contains(Config.mode)) { + return false; } - - - if(redTeam.getLeader() == null || blueTeam.getLeader() == null){ - return 1000; + if (redTeam.getLeader() == null || blueTeam.getLeader() == null) { + return false; } - - return Math.min(redTeam.getSchemRank(), blueTeam.getSchemRank()); + return redTeam.isPublicsOnly() || blueTeam.isPublicsOnly(); } } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightPlayer.java b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightPlayer.java index 2ea6f58..e6740a8 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightPlayer.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightPlayer.java @@ -21,6 +21,7 @@ package de.steamwar.fightsystem.fight; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.ai.AI; +import de.steamwar.fightsystem.countdown.Countdown; import de.steamwar.fightsystem.countdown.EnternCountdown; import de.steamwar.sql.PersonalKit; import de.steamwar.sql.SteamwarUser; @@ -65,9 +66,9 @@ public class FightPlayer { ifAI(AI::stop); } - public void startEnternCountdown() { + public void startEnternCountdown(Countdown countdown) { if(Config.EnterStages.size() > kit.getEnterStage() && kit.getEnterStage() >= 0) - enternCountdown = new EnternCountdown(this); + enternCountdown = new EnternCountdown(this, countdown); } public void stopEnternCountdown(){ diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightSchematic.java b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightSchematic.java index 0ffff16..93e6e5f 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightSchematic.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightSchematic.java @@ -33,6 +33,7 @@ import de.steamwar.fightsystem.utils.Region; import de.steamwar.fightsystem.utils.WorldeditWrapper; import de.steamwar.sql.SchematicData; import de.steamwar.sql.SchematicNode; +import de.steamwar.sql.SchematicType; import org.bukkit.Bukkit; import org.bukkit.DyeColor; import org.bukkit.Location; @@ -100,8 +101,17 @@ public class FightSchematic extends StateDependent { if(clipboard == null){ List publics = SchematicNode.getAllSchematicsOfType(0, Config.SchematicType.toDB()); - if(publics.isEmpty()) - return; + if(publics.isEmpty()) { + for (SchematicType type : Config.SubTypes) { + publics = SchematicNode.getAllSchematicsOfType(0, type.toDB()); + if (!publics.isEmpty()) { + break; + } + } + if (publics.isEmpty()) { + return; + } + } setSchematic(publics.get(new Random().nextInt(publics.size()))); } @@ -138,6 +148,7 @@ public class FightSchematic extends StateDependent { ).add(new Vector(rotate ? 1 : 0, 0, rotate ? 1 : 0)), new AffineTransform().rotateY(rotate ? 180 : 0) ); + FightSystem.getHullHider().initialize(team); Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), freezer::disable, 3); Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), team::teleportToSpawn, 40); @@ -187,7 +198,7 @@ public class FightSchematic extends StateDependent { } length -= 1; - AffineTransform aT = new AffineTransform().rotateY(rotate ? 180 : 0); + AffineTransform aT = new AffineTransform().rotateY(((team == Fight.getRedTeam()) == (Config.BlueToRedZ > 0)) ? 180 : 0); Location base = new Location(Config.world, region.centerX(), team.getExtendRegion().getMaxY(), region.centerZ()); for(int i = 0; i < characters.length; i++){ WorldeditWrapper.impl.pasteClipboard(characters[i], base, new Vector(offsets[i] - length/2, 0, -region.getSizeZ()/2), aT); diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java index 74092af..7aad62d 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java @@ -33,6 +33,7 @@ import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.OneShotStateDependent; import de.steamwar.fightsystem.states.StateDependent; import de.steamwar.fightsystem.utils.*; +import de.steamwar.fightsystem.winconditions.Wincondition; import de.steamwar.fightsystem.winconditions.Winconditions; import de.steamwar.inventory.SWItem; import de.steamwar.sql.SchematicNode; @@ -90,7 +91,7 @@ public class FightTeam { private UUID designatedLeader; private FightPlayer leader; - private int schemRank; + private boolean publicsOnly; private final Map players = new HashMap<>(); @@ -113,7 +114,7 @@ public class FightTeam { this.spawn = spawn; this.schemRegion = schemRegion; this.extendRegion = extendRegion; - this.schemRank = 0; + this.publicsOnly = false; this.ready = false; this.skip = false; this.blue = blue; @@ -161,8 +162,8 @@ public class FightTeam { return isLeaderless() && (designatedLeader == null || designatedLeader.equals(p.getUniqueId())); } - public int getSchemRank() { - return schemRank; + public boolean isPublicsOnly() { + return publicsOnly; } public void teleportToSpawn(){ @@ -274,6 +275,7 @@ public class FightTeam { BountifulWrapper.impl.setAttackSpeed(player); player.setFoodLevel(20); player.getInventory().clear(); + FightSystem.getHullHider().updatePlayer(player); if(FightState.Spectate.contains(FightState.getFightState())) { Fight.setPlayerGamemode(player, GameMode.SPECTATOR); @@ -284,7 +286,7 @@ public class FightTeam { }); if(FightState.Running.contains(FightState.getFightState())) - fightPlayer.startEnternCountdown(); + fightPlayer.startEnternCountdown(Wincondition.getTimeOverCountdown()); GlobalRecorder.getInstance().playerJoins(entity, user); fightPlayer.ifPlayer(player -> FightSystem.getTechHider().reloadChunks(player, chunksToReload, false)); @@ -317,6 +319,7 @@ public class FightTeam { player.getInventory().clear(); if(player.isOnline()){ + FightSystem.getHullHider().updatePlayer(player); FightSystem.getTechHider().reloadChunks(player, chunksToReload, true); if(ArenaMode.VariableTeams.contains(Config.mode)) @@ -357,11 +360,7 @@ public class FightTeam { if(!silent) FightUI.addSubtitle("UI_LEADER_JOINS", prefix, leader.getEntity().getName()); - Optional maxRank = SchematicNode.getAllAccessibleSchematicsOfType(leader.getUser().getId(), Config.SchematicType.toDB()).stream().map(SchematicNode::getRank).max(Integer::compare); - if(Config.RanksEnabled) - schemRank = maxRank.orElse(1); - else - schemRank = maxRank.isPresent() ? 1 : 0; + publicsOnly = SchematicNode.getAllAccessibleSchematicsOfType(leader.getUser().getId(), Config.SchematicType.toDB()).isEmpty(); if(!Config.PersonalKits) leader.setKit(Kit.getKitByName(Config.LeaderDefault)); @@ -393,6 +392,11 @@ public class FightTeam { } public void pasteSchem(SchematicNode schematic){ + if(schematic.getSchemtype().check()) { + FightStatistics.unrank(); + FightSystem.getMessage().broadcast("SCHEMATIC_UNCHECKED", getColoredName()); + } + setSchem(schematic); testPasteAction(); } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/ArrowStopper.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/ArrowStopper.java index e7b4d01..3fd7f7d 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/listener/ArrowStopper.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/listener/ArrowStopper.java @@ -85,7 +85,7 @@ public class ArrowStopper { } private boolean checkBlock(Block block) { - return Config.HiddenBlocks.contains(block.getType().name().toLowerCase()); + return Config.HiddenBlocks.contains(block.getType()); } private boolean invalidEntity(Projectile entity) { diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java index e56d472..a0eabba 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java @@ -37,7 +37,6 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockDispenseEvent; import org.bukkit.event.block.BlockFromToEvent; import org.bukkit.event.entity.EntityExplodeEvent; @@ -153,14 +152,6 @@ public class Permanent implements Listener { e.setCancelled(true); } - @SuppressWarnings("deprecation") - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onBlockBreak(BlockBreakEvent e) { - Block block = e.getBlock(); - for(ItemStack stack : block.getDrops(e.getPlayer().getItemInHand())) - Config.world.dropItemNaturally(block.getLocation(), stack); - } - @EventHandler public void onDropPickup(PlayerPickupItemEvent e) { if(!(Config.ArenaRegion.inRegion(e.getItem().getLocation()))) diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java b/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java index d7c31fd..cb1dddb 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java @@ -88,7 +88,7 @@ public class PacketProcessor implements Listener { private final PacketSource source; private final BukkitTask task; private final LinkedList syncList = new LinkedList<>(); - private final Set hiddenBlockIds = Config.HiddenBlocks.stream().map(String::toUpperCase).map(Material::getMaterial).flatMap(m -> BlockIds.impl.materialToAllIds(m).stream()).collect(Collectors.toSet()); + private final Set hiddenBlockIds = Config.HiddenBlocks.stream().flatMap(m -> BlockIds.impl.materialToAllIds(m).stream()).collect(Collectors.toSet()); private final int obfuscateWith = BlockIds.impl.materialToId(Material.getMaterial(Config.ObfuscateWith.toUpperCase())); private final FreezeWorld freezer = new FreezeWorld(); private final REntityServer entityServer = new REntityServer(); @@ -165,6 +165,11 @@ public class PacketProcessor implements Listener { entityServer.addPlayer(player); } + private void addREntity(int entityId, REntity entity) { + entities.put(entityId, entity); + FightSystem.getHullHider().updateREntity(entity); + } + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onPlayerJoin(PlayerJoinEvent e) { entityServer.addPlayer(e.getPlayer()); @@ -235,7 +240,7 @@ public class PacketProcessor implements Listener { execSync(() -> { SteamwarUser user = SteamwarUser.get(userId); - entities.put(entityId, new RPlayer(entityServer, user.getUUID(), user.getUserName(), Config.SpecSpawn)); + addREntity(entityId, new RPlayer(entityServer, user.getUUID(), user.getUserName(), Config.SpecSpawn)); team.addEntry(user.getUserName()); }); } @@ -257,8 +262,10 @@ public class PacketProcessor implements Listener { execSync(() -> { REntity entity = entities.get(entityId); - if(entity != null) + if(entity != null) { entity.move(locX, locY, locZ, pitch, yaw, headYaw); + FightSystem.getHullHider().updateREntity(entity); + } }); } @@ -267,8 +274,10 @@ public class PacketProcessor implements Listener { execSync(() -> { REntity entity = entities.remove(entityId); - if(entity != null) + if(entity != null) { + FightSystem.getHullHider().despawnREntity(entity); entity.die(); + } }); } @@ -289,7 +298,7 @@ public class PacketProcessor implements Listener { private void tntSpawn() throws IOException { int entityId = source.readInt(); - execSync(() -> entities.put(entityId, new REntity(entityServer, EntityType.PRIMED_TNT, Config.SpecSpawn))); + execSync(() -> addREntity(entityId, new REntity(entityServer, EntityType.PRIMED_TNT, Config.SpecSpawn))); } private void entityVelocity() throws IOException { @@ -344,13 +353,13 @@ public class PacketProcessor implements Listener { private void arrowSpawn() throws IOException { int entityId = source.readInt(); - execSync(() -> entities.put(entityId, new REntity(entityServer, EntityType.ARROW, Config.SpecSpawn))); + execSync(() -> addREntity(entityId, new REntity(entityServer, EntityType.ARROW, Config.SpecSpawn))); } private void fireballSpawn() throws IOException { int entityId = source.readInt(); - execSync(() -> entities.put(entityId, new REntity(entityServer, EntityType.FIREBALL, Config.SpecSpawn))); + execSync(() -> addREntity(entityId, new REntity(entityServer, EntityType.FIREBALL, Config.SpecSpawn))); } private void send(ChatMessageType type) throws IOException { @@ -437,7 +446,10 @@ public class PacketProcessor implements Listener { if(!Config.ArenaRegion.in2dRegion(x, z)) return; //Outside of the arena - execSync(() -> BlockIdWrapper.impl.setBlock(Config.world, x, y, z, TechHiderWrapper.ENABLED && hiddenBlockIds.contains(blockState) ? obfuscateWith : blockState)); + execSync(() -> { + BlockIdWrapper.impl.setBlock(Config.world, x, y, z, TechHiderWrapper.ENABLED && hiddenBlockIds.contains(blockState) ? obfuscateWith : blockState); + FightSystem.getHullHider().blockUpdate(Config.world.getBlockAt(x, y, z), BlockIdWrapper.impl.idToMaterial(blockState)); + }); } private void particle() throws IOException { @@ -578,6 +590,7 @@ public class PacketProcessor implements Listener { private void endReplay() { HandlerList.unregisterAll(this); entityServer.close(); + entities.values().forEach(FightSystem.getHullHider()::despawnREntity); entities.clear(); freezer.disable(); diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/BlockIdWrapper.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/BlockIdWrapper.java index 6cda218..399e63d 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/BlockIdWrapper.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/BlockIdWrapper.java @@ -21,12 +21,14 @@ package de.steamwar.fightsystem.utils; import de.steamwar.core.VersionDependent; import de.steamwar.fightsystem.FightSystem; +import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; public interface BlockIdWrapper { BlockIdWrapper impl = VersionDependent.getVersionImpl(FightSystem.getPlugin()); + Material idToMaterial(int blockState); int blockToId(Block block); void setBlock(World world, int x, int y, int z, int blockState); } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/EnterHandler.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/EnterHandler.java index ee5aa79..042efba 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/EnterHandler.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/EnterHandler.java @@ -51,7 +51,7 @@ public class EnterHandler implements IStateDependent { private void registerTeam(FightTeam team){ for(FightPlayer fp : team.getPlayers()){ - fp.startEnternCountdown(); + fp.startEnternCountdown(null); } } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/FightStatistics.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/FightStatistics.java index 7467e0e..df12a82 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/FightStatistics.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/FightStatistics.java @@ -98,12 +98,12 @@ public class FightStatistics { Integer redSchem; try { blueSchem = SchematicNode.getSchematicNode(Fight.getBlueTeam().getSchematic()).getId(); - } catch (SecurityException e) { + } catch (NullPointerException e) { blueSchem = null; } try { redSchem = SchematicNode.getSchematicNode(Fight.getRedTeam().getSchematic()).getId(); - } catch (SecurityException e) { + } catch (NullPointerException e) { redSchem = null; } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java new file mode 100644 index 0000000..57cfa29 --- /dev/null +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java @@ -0,0 +1,348 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 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.entity.REntity; +import de.steamwar.fightsystem.Config; +import de.steamwar.fightsystem.FightSystem; +import de.steamwar.fightsystem.fight.FightTeam; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import java.util.*; +import java.util.function.BiConsumer; +import java.util.logging.Level; + +public class Hull { + + private static boolean isOccluding(Material material) { + return material.isOccluding() || Config.HiddenBlocks.contains(material); + } + + private final Region region; + private final boolean groundVisible; + + private final BitSet occluding; + private final BitSet visibility; + private final Map> blockVisibility = new HashMap<>(); + + private final Set players = new HashSet<>(); + private final Set entities = new HashSet<>(); + private final Set rentities = new HashSet<>(); + + public Hull(FightTeam team) { + this.region = team.getSchemRegion(); + this.groundVisible = region.getMinY() != Config.PlayerRegion.getMinY(); + this.occluding = new BitSet(region.volume()); + this.visibility = new BitSet(region.volume()); + + IntVector[] directions; + if (groundVisible) { + directions = new IntVector[]{ + new IntVector(1, 0, 0), + new IntVector(-1, 0, 0), + new IntVector(0, 1, 0), + new IntVector(0, -1, 0), + new IntVector(0, 0, 1), + new IntVector(0, 0, -1) + }; + } else { + directions = new IntVector[]{ + new IntVector(1, 0, 0), + new IntVector(-1, 0, 0), + new IntVector(0, -1, 0), + new IntVector(0, 0, 1), + new IntVector(0, 0, -1) + }; + } + + // Generate quadrants for each direction + for (IntVector direction : directions) { + Map map = new HashMap<>(); + for (int z = (direction.z == 0 ? -1 : 0); z <= 1; z += 2) { + for (int y = (direction.y == 0 ? -1 : 0); y <= 1; y += 2) { + for (int x = (direction.x == 0 ? -1 : 0); x <= 1; x += 2) { + map.put(new IntVector(x, y, z), new BitSet(region.volume())); + } + } + } + blockVisibility.put(direction, map); + } + } + + @SuppressWarnings("deprecation") + public void addPlayer(Player player) { + if(players.add(player)) { + for(Entity entity : entities) + player.hideEntity(FightSystem.getPlugin(), entity); + } + } + + @SuppressWarnings("deprecation") + public void removePlayer(Player player, boolean activeRemoval) { + if(players.remove(player) && activeRemoval) { + for(Entity entity : entities) + player.showEntity(FightSystem.getPlugin(), entity); + } + } + + public void checkEntity(Entity entity) { + Location location = entity.getLocation(); + if(region.inRegion(location) && !visibility.get(new IntVector(location).toId(region))) { //TODO more precise + if(entities.add(entity)) { + for(Player player : players) + player.hideEntity(FightSystem.getPlugin(), entity); + } + } else { + if(entities.remove(entity)) { + for(Player player : players) + player.showEntity(FightSystem.getPlugin(), entity); + } + } + } + + public void removeEntity(Entity entity) { + entities.remove(entity); + } + + public void checkREntity(REntity entity) { + Location location = new Location(Config.world, entity.getX(), entity.getY(), entity.getZ()); + if(region.inRegion(location) && !visibility.get(new IntVector(location).toId(region))) { //TODO more precise + if(rentities.add(entity)) + entity.hide(true); + } else { + if(rentities.remove(entity)) + entity.hide(false); + } + } + + public void removeREntity(REntity entity) { + rentities.remove(entity); + } + + public void initialize() { + visibility.clear(); + occluding.clear(); + for (Map direction : blockVisibility.values()) { + for (BitSet set : direction.values()) + set.clear(); + } + + long start = System.currentTimeMillis(); + region.forEach((x, y, z) -> { + IntVector block = new IntVector(x, y, z); + if (isOccluding(Config.world.getBlockAt(x, y, z).getType())) + occluding.set(block.toId(region)); + }); + forEachBorder((root, direction) -> { + for (Map.Entry quadrant : blockVisibility.get(direction).entrySet()) { + checkBlock(new NullList<>(), root, direction, quadrant.getKey(), quadrant.getValue()); + } + }); + FightSystem.getPlugin().getLogger().log(Level.INFO, () -> "[HullHider] initialisation finished: " + (System.currentTimeMillis() - start) + " ms, visible blocks: " + visibility.cardinality()); + } + + @SuppressWarnings("deprecation") + public void updateBlockVisibility(Block b, Material changedType) { + IntVector root = new IntVector(b.getX(), b.getY(), b.getZ()); + if (root.notInRegion(region)) + return; + + int id = root.toId(region); + if (!occluding.get(id) || isOccluding(changedType)) + return; + + List uncovered = new ArrayList<>(); + occluding.clear(id); + for (Map.Entry> direction : blockVisibility.entrySet()) { + for (Map.Entry quadrant : direction.getValue().entrySet()) { + if (quadrant.getValue().get(id)) { + quadrant.getValue().clear(id); + checkBlock(uncovered, root, direction.getKey(), quadrant.getKey(), quadrant.getValue()); + } + } + } + + if(uncovered.isEmpty()) + return; + + Set uncoveredSet = new HashSet<>(uncovered); + Iterator it = entities.iterator(); + while(it.hasNext()) { + Entity entity = it.next(); + if(uncoveredSet.contains(new IntVector(entity.getLocation()))) { //TODO more precise + it.remove(); + for(Player player : players) + player.showEntity(FightSystem.getPlugin(), entity); + } + } + + Iterator rit = rentities.iterator(); + while(rit.hasNext()) { + REntity entity = rit.next(); + if(uncoveredSet.contains(new IntVector(new Location(Config.world, entity.getX(), entity.getY(), entity.getZ())))) { //TODO more precise + it.remove(); + entity.hide(false); + } + } + } + + private void forEachBorder(BiConsumer f) { + for (int x = region.getMinX(); x < region.getMaxX(); x++) { + for (int z = region.getMinZ(); z < region.getMaxZ(); z++) { + if (groundVisible) + f.accept(new IntVector(x, region.getMinY(), z), new IntVector(0, 1, 0)); + f.accept(new IntVector(x, region.getMaxY() - 1, z), new IntVector(0, -1, 0)); + } + } + + for (int x = region.getMinX(); x < region.getMaxX(); x++) { + for (int y = region.getMinY(); y < region.getMaxY(); y++) { + f.accept(new IntVector(x, y, region.getMinZ()), new IntVector(0, 0, 1)); + f.accept(new IntVector(x, y, region.getMaxZ() - 1), new IntVector(0, 0, -1)); + } + } + + for (int z = region.getMinZ(); z < region.getMaxZ(); z++) { + for (int y = region.getMinY(); y < region.getMaxY(); y++) { + f.accept(new IntVector(region.getMinX(), y, z), new IntVector(1, 0, 0)); + f.accept(new IntVector(region.getMaxX() - 1, y, z), new IntVector(-1, 0, 0)); + } + } + } + + private void checkBlock(List uncovered, IntVector block, IntVector direction, IntVector quadrant, BitSet quadVisibility) { + if (block.notInRegion(region)) + return; + + int id = block.toId(region); + if (quadVisibility.get(id)) + return; + + quadVisibility.set(id); + if (!visibility.get(id)) { + visibility.set(id); + uncovered.add(block); + } + + if (occluding.get(id)) + return; + + IntVector neighbour = block.add(direction); + checkBlock(uncovered, neighbour, direction, quadrant, quadVisibility); + boolean neigbourTransparent = boundedNonOccluding(neighbour); + boolean diagonalReachable = false; + if (direction.x == 0 && (neigbourTransparent || boundedNonOccluding(block.add(quadrant.x, 0, 0)))) { + checkBlock(uncovered, neighbour.add(quadrant.x, 0, 0), direction, quadrant, quadVisibility); + diagonalReachable = boundedNonOccluding(neighbour.add(quadrant.x, 0, 0)); + } + + if (direction.y == 0 && (neigbourTransparent || boundedNonOccluding(block.add(0, quadrant.y, 0)))) { + checkBlock(uncovered, neighbour.add(0, quadrant.y, 0), direction, quadrant, quadVisibility); + diagonalReachable = diagonalReachable || boundedNonOccluding(neighbour.add(0, quadrant.y, 0)); + } + + if (direction.z == 0 && (neigbourTransparent || boundedNonOccluding(block.add(0, 0, quadrant.z)))) { + checkBlock(uncovered, neighbour.add(0, 0, quadrant.z), direction, quadrant, quadVisibility); + diagonalReachable = diagonalReachable || boundedNonOccluding(neighbour.add(0, 0, quadrant.z)); + } + + if (diagonalReachable) + checkBlock(uncovered, neighbour.add(quadrant), direction, quadrant, quadVisibility); + } + + private boolean boundedNonOccluding(IntVector block) { + return !(block.notInRegion(region) || occluding.get(block.toId(region))); + } + + + private static class IntVector { + private final int x; + private final int y; + private final int z; + + public IntVector(int x, int y, int z) { + this.x = x; + this.y = y; + this.z = z; + } + + public IntVector(Location location) { + this.x = location.getBlockX(); + this.y = location.getBlockY(); + this.z = location.getBlockZ(); + } + + public boolean notInRegion(Region region) { + return !region.inRegion(x, y, z); + } + + public int toId(Region region) { + return ((y - region.getMinY()) * region.getSizeZ() + (z - region.getMinZ())) * region.getSizeX() + (x - region.getMinX()); + } + + public IntVector add(int x, int y, int z) { + return new IntVector(this.x + x, this.y + y, this.z + z); + } + + public IntVector add(IntVector v) { + return add(v.x, v.y, v.z); + } + + @Override + public int hashCode() { + return y << 24 ^ x << 12 ^ z; + } + + @Override + public boolean equals(Object o) { + if(o == null || this.getClass() != o.getClass()) + return false; + + IntVector v = (IntVector) o; + return x == v.x && y == v.y && z == v.z; + } + + @Override + public String toString() { + return x + "," + y + "," + z; + } + } + + private static class NullList extends AbstractList { + @Override + public void add(int index, E element) { + // Straight to /dev/null! + } + + @Override + public E get(int index) { + return null; + } + + @Override + public int size() { + return 0; + } + } +} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHider.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHider.java new file mode 100644 index 0000000..1d95eef --- /dev/null +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHider.java @@ -0,0 +1,147 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2022 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.core.Core; +import de.steamwar.entity.REntity; +import de.steamwar.fightsystem.fight.Fight; +import de.steamwar.fightsystem.fight.FightPlayer; +import de.steamwar.fightsystem.fight.FightTeam; +import de.steamwar.fightsystem.listener.Recording; +import de.steamwar.fightsystem.states.FightState; +import de.steamwar.fightsystem.states.StateDependent; +import de.steamwar.fightsystem.states.StateDependentListener; +import de.steamwar.fightsystem.states.StateDependentTask; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntitySpawnEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +public class HullHider implements Listener { + + private static final boolean ENABLED = TechHiderWrapper.ENABLED && Core.getVersion() >= 18; + private final Map hulls = new HashMap<>(); + + public HullHider() { + if(ENABLED) + Fight.teams().forEach(team -> hulls.put(team, new Hull(team))); + + new StateDependentListener(ENABLED, FightState.Schem, this); + new StateDependent(ENABLED, FightState.Schem) { + @Override + public void enable() { + Bukkit.getOnlinePlayers().forEach(HullHider.this::updatePlayer); + } + + @Override + public void disable() { + Bukkit.getOnlinePlayers().forEach(player -> removePlayer(player, true)); + } + }.register(); + new StateDependentTask(ENABLED, FightState.Schem, this::onTick, 0, 1); + } + + public void initialize(FightTeam team) { + if(!ENABLED) + return; + + hulls.get(team).initialize(); + } + + + @EventHandler(priority = EventPriority.HIGH) + public void onJoin(PlayerJoinEvent e) { + updatePlayer(e.getPlayer()); + } + + @EventHandler + public void onLeave(PlayerQuitEvent e) { + removePlayer(e.getPlayer(), false); + } + + public void updatePlayer(Player player) { + if(!ENABLED) + return; + + FightTeam team = Fight.getPlayerTeam(player); + FightPlayer fp = Fight.getFightPlayer(player); + for(Map.Entry hull : hulls.entrySet()) { + if(hull.getKey() == team || (fp != null && fp.canEntern())) { + hull.getValue().removePlayer(player, true); + } else { + hull.getValue().addPlayer(player); + } + } + } + + private void removePlayer(Player player, boolean activeRemoval) { + hulls.values().forEach(hull -> hull.removePlayer(player, activeRemoval)); + } + + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onBlockPhysic(BlockPhysicsEvent e) { + if(FlatteningWrapper.impl.doRecord(e)) + blockUpdate(e.getBlock(), e.getChangedType()); + } + + public void blockUpdate(Block block, Material changedType) { + for (Hull hull : hulls.values()) + hull.updateBlockVisibility(block, changedType); + } + + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onSpawn(EntitySpawnEvent e) { + hulls.values().forEach(hull -> hull.checkEntity(e.getEntity())); + } + + private void onTick() { + Recording.iterateOverEntities(Objects::nonNull, entity -> { + for (Hull hull : hulls.values()) + hull.checkEntity(entity); + }); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onDeath(EntityDeathEvent e) { + hulls.values().forEach(hull -> hull.removeEntity(e.getEntity())); + } + + public void updateREntity(REntity e) { + hulls.values().forEach(hull -> hull.checkREntity(e)); + } + + public void despawnREntity(REntity e) { + hulls.values().forEach(hull -> hull.removeREntity(e)); + } +} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/Region.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/Region.java index 53f52ae..1308f40 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/Region.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/Region.java @@ -114,7 +114,7 @@ public class Region { public void forEach(TriConsumer executor) { for(int x = minX; x < maxX; x++) { for(int y = minY; y < maxY; y++) { - for (int z = minZ; z <= maxZ; z++) { + for (int z = minZ; z < maxZ; z++) { executor.accept(x, y, z); } } @@ -150,13 +150,17 @@ public class Region { } public boolean in2dRegion(int x, int z) { - return minX <= x && x < maxX && minZ <= z && z <= maxZ; + return minX <= x && x < maxX && minZ <= z && z < maxZ; } public boolean inRegion(Block block){ return in2dRegion(block) && minY <= block.getY() && block.getY() < maxY; } + public boolean inRegion(int x, int y, int z) { + return in2dRegion(x, z) && minY <= y && y < maxY; + } + public interface TriConsumer{ void accept(T x, V y, U z); } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java index 5b443da..9638292 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java @@ -36,7 +36,6 @@ import org.bukkit.entity.Player; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; public class TechHiderWrapper extends StateDependent { @@ -45,7 +44,7 @@ public class TechHiderWrapper extends StateDependent { public TechHiderWrapper() { super(ENABLED, FightState.Schem); - techHider = new TechHider(this::bypass, Material.getMaterial(Config.ObfuscateWith), Config.HiddenBlocks.stream().map(String::toUpperCase).map(Material::getMaterial).collect(Collectors.toSet()), Config.HiddenBlockEntities); + techHider = new TechHider(this::bypass, Material.getMaterial(Config.ObfuscateWith), Config.HiddenBlocks, Config.HiddenBlockEntities); register(); } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Wincondition.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Wincondition.java index 8e6e283..3f0f58e 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Wincondition.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Wincondition.java @@ -34,7 +34,7 @@ import java.util.stream.Collectors; public abstract class Wincondition { - protected static PercentWincondition percentWincondition = null; + protected static WinconditionPercent percentWincondition = null; protected static StateDependentCountdown timeOverCountdown = null; protected static final List printableWinconditions = new ArrayList<>(); @@ -65,7 +65,7 @@ public abstract class Wincondition { return printableWinconditions; } - public static PercentWincondition getPercentWincondition() { + public static WinconditionPercent getPercentWincondition() { return percentWincondition; } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionBlacklistPercent.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionBlacklistPercent.java deleted file mode 100644 index a823079..0000000 --- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionBlacklistPercent.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - 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; - -public class WinconditionBlacklistPercent extends PercentWincondition { - - public WinconditionBlacklistPercent(){ - super("RelativePercent", Winconditions.RELATIVE_PERCENT); - } -} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/PercentWincondition.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercent.java similarity index 73% rename from FightSystem_Core/src/de/steamwar/fightsystem/winconditions/PercentWincondition.java rename to FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercent.java index 40b227f..37d3faf 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/PercentWincondition.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercent.java @@ -26,7 +26,6 @@ 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; import org.bukkit.entity.EntityType; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -34,27 +33,12 @@ import org.bukkit.event.entity.EntityExplodeEvent; 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 { +public class WinconditionPercent extends Wincondition implements PrintableWincondition { private final Map teamMap = new HashMap<>(); - protected BooleanSupplier explosionFilter = () -> !Config.EnterStages.isEmpty() && Config.EnterStages.get(0) >= Wincondition.getTimeOverCountdown().getTimeLeft(); - protected Predicate testBlock = type -> !Config.PercentBlocks.contains(type); - protected ToIntFunction totalBlockCalc = team -> { - AtomicInteger blocks = new AtomicInteger(); - team.getSchemRegion().forEach((x, y, z) -> { - if (testBlock.test(Config.world.getBlockAt(x, y, z).getType())) { - blocks.getAndIncrement(); - } - }); - return blocks.get(); - }; protected Consumer checkWin = team -> { if (getPercent(team) >= Config.PercentWin) { win(Fight.getOpposite(team), "WIN_PERCENT", team.getColoredName()); @@ -62,7 +46,7 @@ public class PercentWincondition extends Wincondition implements PrintableWincon }; protected Consumer postEnable = team -> {}; - public PercentWincondition(String windescription, Winconditions wincondition) { + public WinconditionPercent(Winconditions wincondition, String windescription) { super(windescription); if (Config.ActiveWinconditions.contains(wincondition)) { @@ -74,7 +58,7 @@ public class PercentWincondition extends Wincondition implements PrintableWincon } public Message getDisplay(FightTeam team) { - return new Message("BAR_PERCENT", team.getPrefix() + (Math.round(100.0 * getPercent(team)) / 100.0)); + return new Message("BAR_PERCENT", team.getPrefix() + (Math.round(10000.0 * (1.0 - getPercent(team) / Config.PercentWin)) / 100.0)); } public double getPercent(FightTeam team) { @@ -105,12 +89,16 @@ public class PercentWincondition extends Wincondition implements PrintableWincon @EventHandler public void onEntityExplode(EntityExplodeEvent event) { - if (event.getEntityType() == EntityType.FIREBALL || explosionFilter.getAsBoolean() || !team.getExtendRegion().inRegion(event.getEntity().getLocation())) { + if ( + event.getEntityType() == EntityType.FIREBALL || + !team.getExtendRegion().inRegion(event.getEntity().getLocation()) || + (!Config.PercentEntern && !Config.EnterStages.isEmpty() && Config.EnterStages.get(0) >= Wincondition.getTimeOverCountdown().getTimeLeft()) + ) { return; } event.blockList().forEach(block -> { - if (testBlock.test(block.getType())) { + if (Config.PercentBlocks.contains(block.getType()) == Config.PercentBlocksWhitelist) { currentBlocks--; } }); @@ -119,7 +107,11 @@ public class PercentWincondition extends Wincondition implements PrintableWincon } private void enable() { - totalBlocks = totalBlockCalc.applyAsInt(team); + totalBlocks = 0; + team.getSchemRegion().forEach((x, y, z) -> { + if (Config.PercentBlocks.contains(Config.world.getBlockAt(x, y, z).getType()) == Config.PercentBlocksWhitelist) + totalBlocks++; + }); currentBlocks = totalBlocks; postEnable.accept(team); } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercentSystem.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercentSystem.java deleted file mode 100644 index 6be7476..0000000 --- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercentSystem.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - 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; - -public class WinconditionPercentSystem extends PercentWincondition { - - public WinconditionPercentSystem() { - super("Percent", Winconditions.PERCENT_SYSTEM); - - totalBlockCalc = team -> team.getSchemRegion().volume(); - explosionFilter = () -> false; - } -} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPoints.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPoints.java index 2d0396d..028e893 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPoints.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPoints.java @@ -36,12 +36,12 @@ import org.bukkit.event.player.PlayerQuitEvent; import java.util.HashMap; import java.util.Map; -public class WinconditionPoints extends PercentWincondition implements Listener { +public class WinconditionPoints extends WinconditionPercent implements Listener { private final Map teamMap = new HashMap<>(); public WinconditionPoints(){ - super("Points", Winconditions.POINTS); + super(Winconditions.POINTS, "Points"); checkWin = team -> {}; postEnable = this::pointInit; diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPointsAirShip.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPointsAirShip.java index 124ed14..4f166a6 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPointsAirShip.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPointsAirShip.java @@ -35,7 +35,7 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; -public class WinconditionPointsAirShip extends PercentWincondition implements Listener { +public class WinconditionPointsAirShip extends WinconditionPercent implements Listener { private double[] as = new double[] { 0.5, @@ -56,7 +56,7 @@ public class WinconditionPointsAirShip extends PercentWincondition implements Li private final Map teamMap = new HashMap<>(); public WinconditionPointsAirShip(){ - super("Points", Winconditions.POINTS_AIRSHIP); + super(Winconditions.POINTS_AIRSHIP, "Points"); checkWin = team -> { if (teamMap.get(team).getPoints() > TeamPoints.WIN_POINTS) { diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionWhitelistPercent.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionWhitelistPercent.java deleted file mode 100644 index 6607173..0000000 --- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionWhitelistPercent.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - This file is a part of the SteamWar software. - - Copyright (C) 2021 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; - -public class WinconditionWhitelistPercent extends PercentWincondition { - - public WinconditionWhitelistPercent() { - super("WhitelistPercent", Winconditions.WHITELIST_PERCENT); - - testBlock = Config.PercentBlocks::contains; - } -} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java index 620a247..296cf97 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java @@ -28,8 +28,6 @@ public enum Winconditions { CAPTAIN_DEAD, PERCENT_SYSTEM, - WHITELIST_PERCENT, - RELATIVE_PERCENT, POINTS, POINTS_AIRSHIP, @@ -39,5 +37,7 @@ public enum Winconditions { HELLS_BELLS, METEOR, - AMONG_US + AMONG_US, + PERSISTENT_DAMAGE, + TNT_DISTRIBUTION } diff --git a/FightSystem_Core/src/plugin.yml b/FightSystem_Core/src/plugin.yml index f0df4c2..d876395 100644 --- a/FightSystem_Core/src/plugin.yml +++ b/FightSystem_Core/src/plugin.yml @@ -26,4 +26,6 @@ commands: win: resetwg: resettb: + tpslimit: + tpswarp: unrank: \ No newline at end of file