diff --git a/MissileWars/build.gradle.kts b/MissileWars/build.gradle.kts new file mode 100644 index 00000000..71351cfa --- /dev/null +++ b/MissileWars/build.gradle.kts @@ -0,0 +1,70 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 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 . + */ + +plugins { + id("java") + id("base") + id("application") + + id("com.github.johnrengelman.shadow") +} + +group = "de.steamwar" +version = "" + +tasks.compileJava { + options.encoding = "UTF-8" +} + +tasks.build { + finalizedBy(tasks.shadowJar) +} + +tasks.compileJava { + options.encoding = "UTF-8" +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 +} + +sourceSets { + main { + java { + srcDirs("src/") + } + resources { + srcDirs("src/") + exclude("**/*.java", "**/*.kt") + } + } +} + +dependencies { + compileOnly("org.projectlombok:lombok:1.18.32") + annotationProcessor("org.projectlombok:lombok:1.18.32") + + compileOnly(project(":SpigotCore")) + + compileOnly("de.steamwar:spigot:1.20") + compileOnly("de.steamwar:fastasyncworldedit:1.18") + + compileOnly("org.spigotmc:spigot-api:1.20-R0.1-SNAPSHOT") +} diff --git a/MissileWars/src/config.yml b/MissileWars/src/config.yml new file mode 100644 index 00000000..c963eef2 --- /dev/null +++ b/MissileWars/src/config.yml @@ -0,0 +1,31 @@ +WaitingTime: 600 +ItemTime: 300 +ShieldFlyTime: 100 +PlatformTime: 30 +EndTime: 200 + +# Special +Barrier: true + +Arena: + MinX: 0 + MaxX: 0 + MinY: 0 + MinZ: 0 + MaxZ: 0 + +Red: + PortalZ: -60 + SpawnX: 0 + SpawnY: 0 + SpawnZ: 0 + SpawnYaw: 0 + SpawnPitch: 0 + +Blue: + PortalZ: 60 + SpawnX: 0 + SpawnY: 0 + SpawnZ: 0 + SpawnYaw: 0 + SpawnPitch: 0 diff --git a/MissileWars/src/de/steamwar/misslewars/Config.java b/MissileWars/src/de/steamwar/misslewars/Config.java new file mode 100644 index 00000000..b50ec741 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/Config.java @@ -0,0 +1,180 @@ +/* + 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.misslewars; + +import de.steamwar.sql.Event; +import de.steamwar.sql.EventFight; +import de.steamwar.sql.Team; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.util.UUID; +import java.util.logging.Level; + +public class Config { + private Config() { + } + + public static final int ArenaMinX; + public static final int ArenaMaxX; + public static final int ArenaMinY; + public static final int ArenaMinZ; + public static final int ArenaMaxZ; + + public static final Location RedSpawn; + public static final int RedPortalZ; + public static final Location BlueSpawn; + public static final int BluePortalZ; + + public static final int WaitingTime; + public static final int PlatformTime; + public static final int ItemTime; + public static final int ShieldFlyTime; + public static final int EndTime; + + public static final double MissileChance; + + public static final boolean Barrier; + public static final boolean Space; + + // Challenge + public static UUID BlueLeader; + public static UUID RedLeader; + + private static final int EventKampfID; + + // Event + public static final EventFight EventKampf; + public static final String TeamBlueName; + public static final String TeamRedName; + public static final String TeamBlueColor; + public static final String TeamRedColor; + public static final int EventTeamBlueID; + public static final int EventTeamRedID; + public static final int MaximumTeamMembers; + + static { + File configfile = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "config.yml"); + if (!configfile.exists()) { + Bukkit.getLogger().log(Level.SEVERE, "Config fehlt!"); + Bukkit.shutdown(); + } + + FileConfiguration config = YamlConfiguration.loadConfiguration(configfile); + WaitingTime = config.getInt("WaitingTime"); + PlatformTime = config.getInt("PlatformTime"); + ItemTime = config.getInt("ItemTime"); + ShieldFlyTime = config.getInt("ShieldFlyTime"); + EndTime = config.getInt("EndTime"); + + MissileChance = config.getDouble("MissileChance"); + + ConfigurationSection arena = config.getConfigurationSection("Arena"); + assert arena != null; + ArenaMinX = arena.getInt("MinX"); + ArenaMaxX = arena.getInt("MaxX"); + ArenaMinY = arena.getInt("MinY"); + ArenaMinZ = arena.getInt("MinZ"); + ArenaMaxZ = arena.getInt("MaxZ"); + + ConfigurationSection red = config.getConfigurationSection("Red"); + assert red != null; + RedPortalZ = red.getInt("PortalZ"); + RedSpawn = new Location(Bukkit.getWorlds().get(0), red.getDouble("SpawnX"), red.getDouble("SpawnY"), red.getDouble("SpawnZ"), (float) red.getDouble("SpawnYaw"), (float) red.getDouble("SpawnPitch")); + + ConfigurationSection blue = config.getConfigurationSection("Blue"); + assert blue != null; + BluePortalZ = blue.getInt("PortalZ"); + BlueSpawn = new Location(Bukkit.getWorlds().get(0), blue.getDouble("SpawnX"), blue.getDouble("SpawnY"), blue.getDouble("SpawnZ"), (float) blue.getDouble("SpawnYaw"), (float) blue.getDouble("SpawnPitch")); + + String blueLeader = System.getProperty("blueLeader", null); + String redLeader = System.getProperty("redLeader", null); + if (blueLeader != null) + BlueLeader = UUID.fromString(blueLeader); + else + BlueLeader = null; + if (redLeader != null) + RedLeader = UUID.fromString(redLeader); + else + RedLeader = null; + + Barrier = config.getBoolean("Barrier", false); + Space = config.getBoolean("Space", false); + + EventKampfID = Integer.parseInt(System.getProperty("fightID", "0")); + if (EventKampfID >= 1) { + EventKampf = EventFight.get(EventKampfID); + if (EventKampf == null) { + Bukkit.getLogger().log(Level.SEVERE, "Failed to load EventFight"); + Bukkit.shutdown(); + } + assert EventKampf != null; + + Team team1 = Team.get(EventKampf.getTeamBlue()); + Team team2 = Team.get(EventKampf.getTeamRed()); + + if (team1 == null || team2 == null) { + Bukkit.getLogger().log(Level.SEVERE, "Failed to load Team"); + Bukkit.shutdown(); + } + assert team1 != null; + assert team2 != null; + + TeamBlueName = team1.getTeamKuerzel(); + TeamRedName = team2.getTeamKuerzel(); + TeamBlueColor = "§" + team1.getTeamColor(); + TeamRedColor = "§" + team2.getTeamColor(); + EventTeamBlueID = team1.getTeamId(); + EventTeamRedID = team2.getTeamId(); + + Event event = Event.get(EventKampf.getEventID()); + if (EventTeamBlueID == 0 && EventTeamRedID == 0) { + MaximumTeamMembers = Integer.MAX_VALUE; + } else { + MaximumTeamMembers = event.getMaximumTeamMembers(); + } + } else { + EventKampf = null; + TeamBlueName = "Blau"; + TeamRedName = "Rot"; + TeamBlueColor = "§3"; + TeamRedColor = "§c"; + EventTeamBlueID = 0; + EventTeamRedID = 0; + MaximumTeamMembers = Integer.MAX_VALUE; + } + } + + public static boolean isEvent() { + return EventKampfID >= 1; + } + + public static boolean isChallenge() { + return BlueLeader != null && RedLeader != null; + } + + public static boolean test() { + return EventKampfID == -1; + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/FightInfoPacketSender.java b/MissileWars/src/de/steamwar/misslewars/FightInfoPacketSender.java new file mode 100644 index 00000000..ca58263f --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/FightInfoPacketSender.java @@ -0,0 +1,71 @@ +/* + * + * 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.misslewars; + +import de.steamwar.network.NetworkSender; +import de.steamwar.network.packets.common.FightInfoPacket; +import de.steamwar.sql.SteamwarUser; +import org.bukkit.Bukkit; +import org.bukkit.World; + +import java.util.List; +import java.util.stream.Collectors; + +public class FightInfoPacketSender implements Runnable { + + private final World world = Bukkit.getWorlds().get(0); + + private final String serverName = Bukkit.getServer().getName(); + private final String gameMode = "missilewars"; + private final String worldName = world.getName(); + private final String blueName = Config.TeamBlueColor + Config.TeamBlueName; + private final String redName = Config.TeamRedColor + Config.TeamRedName; + private final int blueLeader = Config.BlueLeader != null ? SteamwarUser.get(Config.BlueLeader).getId() : 0; + private final int redLeader = Config.RedLeader != null ? SteamwarUser.get(Config.RedLeader).getId() : 0; + + @Override + public void run() { + if (Config.test()) { + return; + } + + int countdown; + if (FightScoreboard.getStartTime() == 0) { + countdown = 0; + } else { + countdown = (int) ((System.currentTimeMillis() - FightScoreboard.getStartTime()) / 1000); + } + + List bluePlayers = MissileWars.getBlueTeam().getPlayers().stream() + .map(player -> SteamwarUser.get(player.getUniqueId()).getId()) + .collect(Collectors.toList()); + List redPlayers = MissileWars.getRedTeam().getPlayers().stream() + .map(player -> SteamwarUser.get(player.getUniqueId()).getId()) + .collect(Collectors.toList()); + List spectatorPlayers = Bukkit.getOnlinePlayers().stream() + .map(player -> SteamwarUser.get(player.getUniqueId()).getId()) + .filter(integer -> !(bluePlayers.contains(integer) || redPlayers.contains(integer))) + .collect(Collectors.toList()); + + NetworkSender.send(new FightInfoPacket(serverName, gameMode, worldName, blueName, redName, MissileWars.getFightState().name().toLowerCase(), countdown, blueLeader, redLeader, 0, 0, bluePlayers, redPlayers, spectatorPlayers)); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/FightScoreboard.java b/MissileWars/src/de/steamwar/misslewars/FightScoreboard.java new file mode 100644 index 00000000..8b16b403 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/FightScoreboard.java @@ -0,0 +1,94 @@ +/* + 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.misslewars; + +import de.steamwar.scoreboard.SWScoreboard; +import de.steamwar.scoreboard.ScoreboardCallback; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; + +import java.text.SimpleDateFormat; +import java.util.HashMap; +import java.util.Objects; + +/** + * Modified Version of the Fight-System Scoreboard + */ +class FightScoreboard implements Listener { + + public FightScoreboard() { + Bukkit.getPluginManager().registerEvents(this, MissileWars.getPlugin()); + } + + private static final Scoreboard scoreboard = Objects.requireNonNull(Bukkit.getScoreboardManager()).getMainScoreboard(); + + private static long startTime = 0; + + public static long getStartTime() { + return startTime; + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + SWScoreboard.createScoreboard(event.getPlayer(), new ScoreboardCallback() { + @Override + public String getTitle() { + return "§eMissileWars"; + } + + @Override + public HashMap getData() { + HashMap data = new HashMap<>(); + data.put("§eSpielzeit", 5); + if (startTime == 0) { + data.put("§7??:??:??", 4); + } else { + long current_time = System.currentTimeMillis() - startTime; + data.put(String.format("§7%02d:%02d", current_time / 60000, (current_time / 1000) % 60), 4); + } + + data.put("", 3); + data.put("§eSpieler", 2); + MissileWars.getBlueTeam().teamScoreboard(data); + MissileWars.getRedTeam().teamScoreboard(data); + return data; + } + }); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + SWScoreboard.removeScoreboard(event.getPlayer()); + } + + static Scoreboard getScoreboard() { + return scoreboard; + } + + static void startTime() { + startTime = System.currentTimeMillis(); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/FightState.java b/MissileWars/src/de/steamwar/misslewars/FightState.java new file mode 100644 index 00000000..d0210605 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/FightState.java @@ -0,0 +1,26 @@ +/* + 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.misslewars; + +public enum FightState { + WAITING, // waiting for at least 2 players + FIGHTING, // no one has won + END // fight ended for some reason +} diff --git a/MissileWars/src/de/steamwar/misslewars/FightWorld.java b/MissileWars/src/de/steamwar/misslewars/FightWorld.java new file mode 100644 index 00000000..38dfab08 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/FightWorld.java @@ -0,0 +1,84 @@ +/* + * + * 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.misslewars; + +import de.steamwar.core.CraftbukkitWrapper; +import net.minecraft.world.level.chunk.Chunk; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.WorldCreator; +import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +import java.util.function.ObjIntConsumer; + +public class FightWorld { + + private static final World world = Bukkit.getWorlds().get(0); + + private static double posToChunk(int pos){ + return pos / 16.0; + } + + private static int getMinChunkX(){ + return (int) Math.floor(posToChunk(Config.ArenaMinX)); + } + + private static int getMaxChunkX(){ + return (int) Math.ceil(posToChunk(Config.ArenaMaxX)); + } + + private static int getMinChunkZ(){ + return (int) Math.floor(posToChunk(Config.ArenaMinZ)); + } + + private static int getMaxChunkZ(){ + return (int) Math.ceil(posToChunk(Config.ArenaMaxZ)); + } + + private static void forEachChunk(ObjIntConsumer executor) { + for(int x = getMinChunkX(); x <= getMaxChunkX(); x++) + for(int z = getMinChunkZ(); z <= getMaxChunkZ(); z++) + executor.accept(x, z); + } + + public static void resetWorld(){ + world.getEntities().stream().filter(entity -> entity.getType() != EntityType.PLAYER).forEach(Entity::remove); + + World backup = new WorldCreator(world.getName() + "/backup").createWorld(); + assert backup != null; + forEachChunk((x, z) -> resetChunk(world, backup, x, z)); + Bukkit.unloadWorld(backup, false); + } + + private static void resetChunk(World world, World backup, int x, int z) { + Chunk chunk = ((CraftWorld) world).getHandle().d(x, z); + Chunk backupChunk = ((CraftWorld) backup).getHandle().d(x, z); + + System.arraycopy(backupChunk.d(), 0, chunk.d(), 0, chunk.d().length); + + for(Player p : Bukkit.getOnlinePlayers()) + CraftbukkitWrapper.impl.sendChunk(p, x, z); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/MWTeam.java b/MissileWars/src/de/steamwar/misslewars/MWTeam.java new file mode 100644 index 00000000..7d4224dc --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/MWTeam.java @@ -0,0 +1,251 @@ +/* + 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.misslewars; + +import lombok.Getter; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.Damageable; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.scoreboard.Team; + +import java.util.*; + +public class MWTeam { + public static final ItemStack bow = new ItemStack(Material.BOW); + + static { + ItemMeta bowMeta = Objects.requireNonNull(bow.getItemMeta()); + bowMeta.addEnchant(Enchantment.ARROW_FIRE, 1, true); + bowMeta.addEnchant(Enchantment.ARROW_KNOCKBACK, 1, true); + bowMeta.addEnchant(Enchantment.KNOCKBACK, 1, true); + bowMeta.addEnchant(Enchantment.DAMAGE_ALL, 2, true); + bowMeta.setUnbreakable(true); + bow.setItemMeta(bowMeta); + } + + private final String color; + private final String teamName; + private final Team sbteam; //scoreboard-Team + @Getter + private final Location spawn; + @Getter + private final int portalZ; + + @Getter + private final LinkedList players = new LinkedList<>(); + private final Set openInvitations = new HashSet<>(); + + MWTeam(String color, Location spawn, String teamName, int portalZ) { + this.teamName = teamName; + this.color = color; + this.spawn = spawn; + this.portalZ = portalZ; + if (FightScoreboard.getScoreboard().getTeam(teamName) == null) + sbteam = FightScoreboard.getScoreboard().registerNewTeam(teamName); + else + sbteam = FightScoreboard.getScoreboard().getTeam(teamName); + assert sbteam != null; + sbteam.setAllowFriendlyFire(false); + sbteam.setColor(ChatColor.getByChar(color.charAt(1))); + } + + public void countdown(int timeDelay, int offset) { + if (players.isEmpty()) { + return; + } + + int i = 0; + for (Player p : players) { + int time = timeDelay * (i + 1) - offset; + i++; + + p.setExp(time / (float) Config.ItemTime); + p.setLevel(0); + } + } + + private int getUsesOfItem(ItemStack itemStack) { + ItemMeta itemMeta = itemStack.getItemMeta(); + if (itemMeta instanceof Damageable) { + Damageable damageable = (Damageable) itemMeta; + return itemStack.getType().getMaxDurability() - damageable.getDamage(); + } + return 1_000_000; + } + + private boolean hasUses(ItemStack itemStack) { + switch (itemStack.getType()) { + case WOODEN_AXE: + case STONE_AXE: + case IRON_AXE: + case GOLDEN_AXE: + case DIAMOND_AXE: + case NETHERITE_AXE: + // return true; + case WOODEN_SHOVEL: + case STONE_SHOVEL: + case IRON_SHOVEL: + case GOLDEN_SHOVEL: + case DIAMOND_SHOVEL: + case NETHERITE_SHOVEL: + // return true; + case WOODEN_PICKAXE: + case STONE_PICKAXE: + case IRON_PICKAXE: + case GOLDEN_PICKAXE: + case DIAMOND_PICKAXE: + case NETHERITE_PICKAXE: + return true; + default: + return false; + } + } + + public void givePlayerItem(ItemStack item) { + if (players.isEmpty()) { + return; + } + Player p = players.removeFirst(); + players.addLast(p); + + Inventory inventory = p.getInventory(); + for (int i = 0; i <= 35; i++) { // 35 is the last normal inventory slot + ItemStack itemStack = inventory.getItem(i); + if (itemStack == null) continue; + if (itemStack.isSimilar(item) && itemStack.getAmount() + item.getAmount() <= item.getMaxStackSize()) { + itemStack.setAmount(itemStack.getAmount() + item.getAmount()); + inventory.setItem(i, itemStack); + return; + } + if (hasUses(itemStack) && hasUses(item) && getUsesOfItem(itemStack) + getUsesOfItem(item) <= itemStack.getType().getMaxDurability()) { + int uses = getUsesOfItem(itemStack) + getUsesOfItem(item); + ItemMeta itemMeta = itemStack.getItemMeta(); + Damageable damageable = (Damageable) itemMeta; + damageable.setDamage(itemStack.getType().getMaxDurability() - uses); + itemStack.setItemMeta(damageable); + inventory.setItem(i, itemStack); + return; + } + } + + for (int i = 0; i <= 35; i++) { // 35 is the last normal inventory slot + ItemStack itemStack = inventory.getItem(i); + if (itemStack == null || itemStack.getType().equals(Material.AIR)) { + inventory.setItem(i, item); + return; + } + } + } + + public void teamScoreboard(HashMap data) { + players.forEach(player -> { + data.put(getColorCode() + player.getName(), 1); + }); + } + + public int size() { + return players.size(); + } + + public void join(Player p) { + players.add(p); + p.teleport(spawn); + p.setGameMode(GameMode.SURVIVAL); + p.getInventory().setItem(0, bow); + sbteam.addPlayer(p); + p.setDisplayName(color + p.getName()); + if (MissileWars.getFightState() == FightState.WAITING && !enemy().players.isEmpty()) + MissileWars.startRound(); + } + + public void leave(Player p) { + if (!players.contains(p)) return; + + players.remove(p); + for (ItemStack stack : p.getInventory().getContents()) { + if (stack == null) continue; + if (stack.getType() == Material.AIR) continue; + if (stack.isSimilar(bow)) continue; + givePlayerItem(stack); + } + + p.getInventory().clear(); + + p.setDisplayName("§7" + p.getName()); + sbteam.removePlayer(p); + if (players.isEmpty() && MissileWars.getFightState() == FightState.FIGHTING) + MissileWars.end(WinReasons.NO_ENEMY, enemy()); + } + + public void reset() { + openInvitations.clear(); + + List tempPlayer = new ArrayList<>(players); + players.clear(); + tempPlayer.forEach(player -> player.getInventory().clear()); + tempPlayer.forEach(player -> player.setHealth(20.0)); + tempPlayer.forEach(this::join); + } + + public void invitePlayer(Player p) { + if (enemy().openInvitations.contains(p)) return; + openInvitations.add(p); + } + + public void acceptInvite(Player p) { + removeInvitations(p); + join(p); + } + + private MWTeam enemy() { + if (this == MissileWars.getRedTeam()) + return MissileWars.getBlueTeam(); + + return MissileWars.getRedTeam(); + } + + public String getColorCode() { + return color; + } + + public boolean hasPlayer(Player p) { + return players.contains(p); + } + + public boolean hasInvite(Player p) { + return openInvitations.contains(p); + } + + public String getColoredName() { + return color + teamName; + } + + public static void removeInvitations(Player p) { + MissileWars.getRedTeam().openInvitations.remove(p); + MissileWars.getBlueTeam().openInvitations.remove(p); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/MissileWars.java b/MissileWars/src/de/steamwar/misslewars/MissileWars.java new file mode 100644 index 00000000..2dab0597 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/MissileWars.java @@ -0,0 +1,217 @@ +/* + 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.misslewars; + +import de.steamwar.misslewars.commands.AcceptCommand; +import de.steamwar.misslewars.commands.DeclineCommand; +import de.steamwar.misslewars.commands.InviteCommand; +import de.steamwar.misslewars.commands.SpectateCommand; +import de.steamwar.misslewars.countdowns.EndCountdown; +import de.steamwar.misslewars.countdowns.ItemCountdown; +import de.steamwar.misslewars.countdowns.WaitingCountdown; +import de.steamwar.misslewars.items.CustomItem; +import de.steamwar.misslewars.items.Missile; +import de.steamwar.misslewars.listener.*; +import de.steamwar.misslewars.listener.special.BarrierListener; +import de.steamwar.misslewars.listener.special.SpaceListener; +import de.steamwar.misslewars.slowmo.SlowMoRunner; +import de.steamwar.network.NetworkSender; +import de.steamwar.network.packets.common.FightEndsPacket; +import de.steamwar.sql.SteamwarUser; +import org.bukkit.*; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +public class MissileWars extends JavaPlugin { + private static MissileWars plugin; + private static MWTeam redTeam; //red has South side -> spawns missles towards north + private static MWTeam blueTeam; + private static FightState fightState; + + /** + * create teams, ect + */ + @Override + public void onLoad() { + plugin = this; + fightState = FightState.WAITING; + } + + @Override + public void onEnable() { + redTeam = new MWTeam(Config.TeamRedColor, Config.RedSpawn, Config.TeamRedName, Config.RedPortalZ); + blueTeam = new MWTeam(Config.TeamBlueColor, Config.BlueSpawn, Config.TeamBlueName, Config.BluePortalZ); + new BreakListener(); + new DeathListener(); + new ItemListener(); + new ArenaListener(); + new ConnectionListener(); + new JoinListener(); + new EndListener(); + new PortalDestructListener(); + new WaitingListener(); + new FightListener(); + new ChatListener(); + new SpectateCommand(); + + // Invitation Commands + new InviteCommand(); + new AcceptCommand(); + new DeclineCommand(); + + new WaitingCountdown(); + new ItemCountdown(); + new EndCountdown(); + + new FightScoreboard(); + Missile.init(); + CustomItem.init(); + + StateDependent.setupState(fightState); + + new BarrierListener(); + new SpaceListener(); + + Bukkit.getScheduler().runTaskTimer(this, new FightInfoPacketSender(), 20, 20); + + Bukkit.getWorlds().forEach(world -> { + world.setGameRule(GameRule.KEEP_INVENTORY, true); + world.setGameRule(GameRule.MOB_GRIEFING, true); + world.setGameRule(GameRule.DO_TILE_DROPS, false); + }); + + // TODO: Enable Item Dropping, and the own team can pick them up! Add config value for that? + } + + public static void waiting() { + if (fightState == FightState.END) { + fightState = FightState.WAITING; + StateDependent.setupState(fightState); + + SlowMoRunner.resetSlowMoTime(); + + Set uuidList = Bukkit.getOnlinePlayers().stream().map(Entity::getUniqueId).collect(Collectors.toSet()); + if (!uuidList.contains(Config.RedLeader) || !uuidList.contains(Config.BlueLeader)) { + Config.RedLeader = null; + Config.BlueLeader = null; + } + + redTeam.reset(); + blueTeam.reset(); + } + } + + /** + * call to change fightstate from WAITING to INGAME + */ + static void startRound() { + if (fightState != FightState.WAITING) // anti dual-call + return; + fightState = FightState.FIGHTING; + StateDependent.setupState(fightState); + } + + /** + * Fight beenden + * @param reason Grund fürs ende + * @param winner Gewinner (oder null) + */ + public static void end(WinReasons reason, MWTeam winner) { + if (fightState == FightState.END) //verhindern dass es mehrfach gecallt wird + return; + fightState = FightState.END; + StateDependent.setupState(fightState); + + for(Player player : Bukkit.getOnlinePlayers()) { + player.playSound(player.getLocation(), Sound.ENTITY_ENDER_DRAGON_DEATH, 100f, 1f); + player.setGameMode(GameMode.SPECTATOR); + } + + byte ergebnis = winner == blueTeam ? (byte) 1 : (byte) 2; + if (Config.isEvent()) { + Config.EventKampf.setErgebnis(ergebnis); + } + if (Config.isEvent() || Config.isChallenge()) { + FightEndsPacket packet = FightEndsPacket.builder() + .gameMode("MissileWars") + .duration((int)((System.currentTimeMillis() - FightScoreboard.getStartTime()) / 1000)) + .win(ergebnis) + .bluePlayers(blueTeam.getPlayers().stream().map(Player::getUniqueId).map(SteamwarUser::get).map(SteamwarUser::getId).collect(Collectors.toList())) + .redPlayers(redTeam.getPlayers().stream().map(Player::getUniqueId).map(SteamwarUser::get).map(SteamwarUser::getId).collect(Collectors.toList())) + .blueSchem(-1) + .redSchem(-1) + .build(); + NetworkSender.send(packet); + } + + switch (reason) { + case PORTAL_DESTROYED: + Bukkit.getServer().broadcastMessage(winner.getColoredName() + ChatColor.RESET + " §7hat das gegnerische Portal zerstört"); + break; + case NO_ENEMY: + default: + Bukkit.getServer().broadcastMessage("§7Team " + winner.getColoredName() + ChatColor.RESET + " §7hat aufgrund fehlenden Gegners gewonnen"); + break; + } + } + + public static MissileWars getPlugin() { + return plugin; + } + + public static FightState getFightState() { + return fightState; + } + + public static MWTeam getRedTeam() { + return redTeam; + } + + public static MWTeam getBlueTeam() { + return blueTeam; + } + + public static MWTeam getTeam(Player p) { + if(blueTeam.hasPlayer(p)) + return blueTeam; + if(redTeam.hasPlayer(p)) + return redTeam; + return null; + } + + public static MWTeam getInvitation(Player p) { + if(blueTeam.hasInvite(p)) + return blueTeam; + if(redTeam.hasInvite(p)) + return redTeam; + return null; + } + + public static void leave(Player p) { + MissileWars.getBlueTeam().leave(p); + MissileWars.getRedTeam().leave(p); + } + +} diff --git a/MissileWars/src/de/steamwar/misslewars/SpawnPlatformCreator.java b/MissileWars/src/de/steamwar/misslewars/SpawnPlatformCreator.java new file mode 100644 index 00000000..b9c222a1 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/SpawnPlatformCreator.java @@ -0,0 +1,83 @@ +/* + 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.misslewars; + +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitTask; + +public class SpawnPlatformCreator { + + private final Player player; + private final Location spawn; + private final BukkitTask task; + + private Block currentBlock; + private int ticks; + + public SpawnPlatformCreator(Player player){ + this.player = player; + MWTeam team = MissileWars.getTeam(player); + if(team == null) + this.spawn = Config.BlueSpawn; + else + this.spawn = team.getSpawn(); + ticks = Config.PlatformTime; + currentBlock = null; + task = Bukkit.getScheduler().runTaskTimer(MissileWars.getPlugin(), this::createPlatform, 0, 1); + } + + private void createPlatform(){ + Location playerLoc = player.getLocation(); + playerLoc.setY(spawn.getY() - 1); + + if(currentBlock == null || !currentBlock.getLocation().equals(playerLoc)){ + if(currentBlock != null){ + if(currentBlock.getType() == Material.OBSIDIAN) + currentBlock.setType(Material.AIR); + currentBlock = null; + } + + Block newBlock = playerLoc.getBlock(); + if(newBlock.getType() == Material.AIR){ + newBlock.setType(Material.OBSIDIAN); + currentBlock = newBlock; + } + } + + if(currentBlock != null && player.getLocation().getY() - 1 < currentBlock.getY()) + player.teleport(playerLoc.add(0, 1, 0)); + + player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("Spawnplattform§8: §c§l" + String.format("%.2f", ticks / 20f) + "§8s")); + + if(ticks == 0){ + if(currentBlock != null && currentBlock.getType() == Material.OBSIDIAN) + currentBlock.setType(Material.AIR); + + task.cancel(); + } + ticks--; + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/StateDependent.java b/MissileWars/src/de/steamwar/misslewars/StateDependent.java new file mode 100644 index 00000000..155d824d --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/StateDependent.java @@ -0,0 +1,54 @@ +/* + 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.misslewars; + +import java.util.HashSet; +import java.util.Set; + +public abstract class StateDependent { + private static Set listeners = new HashSet<>(); + + private final Set active; + private boolean running; + + public StateDependent(final Set active){ + this.active = active; + running = false; + listeners.add(this); + } + + public abstract void enable(); + public abstract void disable(); + + static void setupState(FightState state){ + if (state == FightState.FIGHTING) { + FightScoreboard.startTime(); + } + for(StateDependent listener : listeners){ + if(listener.running && !listener.active.contains(state)){ + listener.disable(); + listener.running = false; + }else if(!listener.running && listener.active.contains(state)){ + listener.enable(); + listener.running = true; + } + } + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/WinReasons.java b/MissileWars/src/de/steamwar/misslewars/WinReasons.java new file mode 100644 index 00000000..ef52a173 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/WinReasons.java @@ -0,0 +1,25 @@ +/* + 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.misslewars; + +public enum WinReasons { + NO_ENEMY, + PORTAL_DESTROYED +} diff --git a/MissileWars/src/de/steamwar/misslewars/commands/AcceptCommand.java b/MissileWars/src/de/steamwar/misslewars/commands/AcceptCommand.java new file mode 100644 index 00000000..60b4b056 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/commands/AcceptCommand.java @@ -0,0 +1,70 @@ +/* + * + * 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.misslewars.commands; + +import de.steamwar.command.SWCommand; +import de.steamwar.command.TypeValidator; +import de.steamwar.misslewars.Config; +import de.steamwar.misslewars.MWTeam; +import de.steamwar.misslewars.MissileWars; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class AcceptCommand extends SWCommand { + + public AcceptCommand() { + super("accept"); + } + + @Register + public void onCommand(@Validator Player player, String... varargs) { + MWTeam teamInvitation = MissileWars.getInvitation(player); + if (teamInvitation == null) { + player.sendMessage("§cDu wurdest nicht eingeladen."); + } else { + teamInvitation.acceptInvite(player); + message(teamInvitation, "§7Der Spieler §e" + player.getName() + "§7 ist dem Team §abeigetreten§7."); + } + } + + @ClassValidator(value = Player.class, local = true) + public TypeValidator validator() { + return new TypeValidator() { + @Override + public boolean validate(CommandSender commandSender, Player player, MessageSender messageSender) { + if (!Config.isChallenge()) { + messageSender.send("§cDieser Command ist deaktiviert."); + return false; + } + return true; + } + }; + } + + @Override + protected void sendMessage(CommandSender sender, String message, Object[] args) { + sender.sendMessage(message); + } + + private void message(MWTeam mwTeam, String s) { + mwTeam.getPlayers().forEach(player -> player.sendMessage(s)); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/commands/DeclineCommand.java b/MissileWars/src/de/steamwar/misslewars/commands/DeclineCommand.java new file mode 100644 index 00000000..f0df4aa9 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/commands/DeclineCommand.java @@ -0,0 +1,70 @@ +/* + * + * 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.misslewars.commands; + +import de.steamwar.command.SWCommand; +import de.steamwar.command.TypeValidator; +import de.steamwar.misslewars.Config; +import de.steamwar.misslewars.MWTeam; +import de.steamwar.misslewars.MissileWars; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class DeclineCommand extends SWCommand { + + public DeclineCommand() { + super("decline"); + } + + @Register + public void onCommand(@Validator Player player, String... varargs) { + MWTeam teamInvitation = MissileWars.getInvitation(player); + if (teamInvitation == null) { + player.sendMessage("§cDu wurdest nicht eingeladen."); + } else { + MWTeam.removeInvitations(player); + message(teamInvitation, "§7Der Spieler §e" + player.getName() + "§7 hat die Einladung §cabgelehnt§7."); + } + } + + @ClassValidator(value = Player.class, local = true) + public TypeValidator validator() { + return new TypeValidator() { + @Override + public boolean validate(CommandSender commandSender, Player player, MessageSender messageSender) { + if (!Config.isChallenge()) { + messageSender.send("§cDieser Command ist deaktiviert."); + return false; + } + return true; + } + }; + } + + @Override + protected void sendMessage(CommandSender sender, String message, Object[] args) { + sender.sendMessage(message); + } + + private void message(MWTeam mwTeam, String s) { + mwTeam.getPlayers().forEach(player -> player.sendMessage(s)); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/commands/InviteCommand.java b/MissileWars/src/de/steamwar/misslewars/commands/InviteCommand.java new file mode 100644 index 00000000..b0925723 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/commands/InviteCommand.java @@ -0,0 +1,99 @@ +/* + * + * 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.misslewars.commands; + +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.SWCommand; +import de.steamwar.command.TypeMapper; +import de.steamwar.command.TypeValidator; +import de.steamwar.misslewars.Config; +import de.steamwar.misslewars.MWTeam; +import de.steamwar.misslewars.MissileWars; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.Collection; +import java.util.stream.Collectors; + +public class InviteCommand extends SWCommand { + + public InviteCommand() { + super("invite", "inv"); + } + + @Register + public void onCommand(@Validator Player player, @AllowNull @OptionalValue("") Player invitedPlayer) { + MWTeam team = MissileWars.getTeam(player); + + if (!player.getUniqueId().equals(Config.RedLeader) && !player.getUniqueId().equals(Config.BlueLeader) || team == null) { + player.sendMessage("§cDu kannst keine Spieler einladen."); + } else if (invitedPlayer == null) { + player.sendMessage("§cDieser Spieler ist nicht online."); + } else if (MissileWars.getTeam(invitedPlayer) != null) { + player.sendMessage("§cDieser Spieler ist bereits in einem Team."); + } else if (MissileWars.getInvitation(invitedPlayer) != null) { + player.sendMessage("§cDieser Spieler wurde bereits eingeladen."); + } else { + team.invitePlayer(invitedPlayer); + player.sendMessage("§7Du hast §e" + invitedPlayer.getName() + " §7eingeladen."); + invitedPlayer.sendMessage("§7Du wurdest von §e" + player.getName() + "§7 in das Team §e" + MissileWars.getTeam(player).getColoredName() + "§7 eingeladen."); + invitedPlayer.sendMessage("§8/§eaccept §8- §7Zum akzeptieren."); + invitedPlayer.sendMessage("§8/§edecline §8- §7Zum ablehnen."); + } + } + + @ClassMapper(value = Player.class, local = true) + public TypeMapper typeMapper() { + return new TypeMapper<>() { + @Override + public Player map(CommandSender commandSender, String[] previousArguments, String s) { + return Bukkit.getPlayer(s); + } + + @Override + public Collection tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) { + return Bukkit.getOnlinePlayers() + .stream() + .filter(p -> MissileWars.getTeam(p) != null) + .filter(p -> MissileWars.getInvitation(p) != null) + .map(Player::getName) + .collect(Collectors.toList()); + } + }; + } + + @ClassValidator(value = Player.class, local = true) + public TypeValidator validator() { + return (commandSender, player, messageSender) -> { + if (!Config.isChallenge()) { + messageSender.send("§cDieser Command ist deaktiviert."); + return false; + } + return true; + }; + } + + @Override + protected void sendMessage(CommandSender sender, String message, Object[] args) { + sender.sendMessage(message); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/commands/SpectateCommand.java b/MissileWars/src/de/steamwar/misslewars/commands/SpectateCommand.java new file mode 100644 index 00000000..f70fb063 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/commands/SpectateCommand.java @@ -0,0 +1,69 @@ +/* + * + * 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.misslewars.commands; + +import de.steamwar.command.SWCommand; +import de.steamwar.command.TypeValidator; +import de.steamwar.misslewars.Config; +import de.steamwar.misslewars.MWTeam; +import de.steamwar.misslewars.MissileWars; +import org.bukkit.GameMode; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class SpectateCommand extends SWCommand { + + public SpectateCommand() { + super("spectate", "spec"); + } + + @Register + public void onCommand(@Validator Player player) { + MWTeam mwTeam = MissileWars.getTeam(player); + if (mwTeam == null) return; + if (mwTeam.size() == 1) { + player.sendMessage("§cDu bist alleine im Team, zuschauen ist daher nicht möglich."); + } + MissileWars.leave(player); + player.setGameMode(GameMode.SPECTATOR); + player.getInventory().clear(); + player.updateInventory(); + } + + @ClassValidator(value = Player.class, local = true) + public TypeValidator validator() { + return new TypeValidator() { + @Override + public boolean validate(CommandSender commandSender, Player player, MessageSender messageSender) { + if (Config.isChallenge()) { + messageSender.send("§cDieser Command ist deaktiviert."); + return false; + } + return true; + } + }; + } + + @Override + protected void sendMessage(CommandSender sender, String message, Object[] args) { + sender.sendMessage(message); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/countdowns/EndCountdown.java b/MissileWars/src/de/steamwar/misslewars/countdowns/EndCountdown.java new file mode 100644 index 00000000..292071a6 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/countdowns/EndCountdown.java @@ -0,0 +1,67 @@ +/* + 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.misslewars.countdowns; + +import de.steamwar.misslewars.*; +import de.steamwar.misslewars.listener.JoinListener; +import org.bukkit.Bukkit; +import org.bukkit.scheduler.BukkitTask; + +import java.util.EnumSet; + +public class EndCountdown extends StateDependent { + + private BukkitTask task; + + public EndCountdown() { + super(EnumSet.of(FightState.END)); + } + + @Override + public void enable() { + if (Config.isEvent()) { + task = Bukkit.getScheduler().runTaskLater(MissileWars.getPlugin(), this::stop, 1200); + } else { + task = Bukkit.getScheduler().runTaskLater(MissileWars.getPlugin(), this::restart, Config.EndTime); + } + } + + private void restart() { + FightWorld.resetWorld(); + MissileWars.waiting(); + } + + private void stop() { + //Staggered kick to prevent lobby overloading + if(Bukkit.getOnlinePlayers().isEmpty()){ + Bukkit.shutdown(); + return; + } + + Bukkit.getOnlinePlayers().iterator().next().kickPlayer(null); + Bukkit.getScheduler().runTaskLater(MissileWars.getPlugin(), this::stop, 10); + } + + @Override + public void disable() { + if (task != null && !task.isCancelled()) + task.cancel(); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/countdowns/ItemCountdown.java b/MissileWars/src/de/steamwar/misslewars/countdowns/ItemCountdown.java new file mode 100644 index 00000000..5270934d --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/countdowns/ItemCountdown.java @@ -0,0 +1,72 @@ +/* + 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.misslewars.countdowns; + +import de.steamwar.misslewars.Config; +import de.steamwar.misslewars.FightState; +import de.steamwar.misslewars.MissileWars; +import de.steamwar.misslewars.StateDependent; +import de.steamwar.misslewars.items.SpecialItem; +import org.bukkit.Bukkit; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitTask; + +import java.util.EnumSet; + +public class ItemCountdown extends StateDependent { + + private BukkitTask task; + private int lastTime = 0; + private int currenTime = 0; + + public ItemCountdown() { + super(EnumSet.of(FightState.FIGHTING)); + } + + private void run() { + currenTime++; + + int teamCount = Math.max(MissileWars.getBlueTeam().size(), MissileWars.getRedTeam().size()); + if (teamCount == 0) return; + int timeDelay = Config.ItemTime / teamCount; + + if (lastTime + timeDelay < currenTime) { + lastTime = currenTime; + + ItemStack itemStack = SpecialItem.getRandomItem(); + MissileWars.getBlueTeam().givePlayerItem(itemStack); + MissileWars.getRedTeam().givePlayerItem(itemStack); + } + + MissileWars.getBlueTeam().countdown(timeDelay, currenTime - lastTime); + MissileWars.getRedTeam().countdown(timeDelay, currenTime - lastTime); + } + + @Override + public void enable() { + task = Bukkit.getScheduler().runTaskTimer(MissileWars.getPlugin(), this::run, 0, 1); + } + + @Override + public void disable() { + if(task != null && !task.isCancelled()) + task.cancel(); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/countdowns/WaitingCountdown.java b/MissileWars/src/de/steamwar/misslewars/countdowns/WaitingCountdown.java new file mode 100644 index 00000000..57c85f77 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/countdowns/WaitingCountdown.java @@ -0,0 +1,52 @@ +/* + 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.misslewars.countdowns; + +import de.steamwar.misslewars.Config; +import de.steamwar.misslewars.FightState; +import de.steamwar.misslewars.MissileWars; +import de.steamwar.misslewars.StateDependent; +import org.bukkit.Bukkit; +import org.bukkit.scheduler.BukkitTask; + +import java.util.EnumSet; + +public class WaitingCountdown extends StateDependent { + + private BukkitTask task; + + public WaitingCountdown() { + super(EnumSet.of(FightState.WAITING)); + } + + @Override + public void enable() { + task = Bukkit.getScheduler().runTaskLater(MissileWars.getPlugin(), () -> { + if(Bukkit.getOnlinePlayers().isEmpty()) + Bukkit.shutdown(); + }, Config.WaitingTime); + } + + @Override + public void disable() { + if(task != null && !task.isCancelled()) + task.cancel(); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/items/CustomItem.java b/MissileWars/src/de/steamwar/misslewars/items/CustomItem.java new file mode 100644 index 00000000..51c689b8 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/items/CustomItem.java @@ -0,0 +1,84 @@ +/* + 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.misslewars.items; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; +import de.steamwar.misslewars.MissileWars; +import de.steamwar.misslewars.scripts.ScriptedItem; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Objects; + +public class CustomItem extends SpecialItem { + + private ScriptedItem scriptedItem; + + public CustomItem(ScriptedItem scriptedItem) { + this.scriptedItem = scriptedItem; + } + + @Override + public ItemStack getItem() { + return scriptedItem.getItemStack(); + } + + @Override + public boolean handleUse(Player p) { + return scriptedItem.execute(ScriptedItem.EventType.onClick, p, p.getLocation()); + } + + @Override + public void handleThrow(Entity e) { + scriptedItem.execute(ScriptedItem.EventType.onThrow, e, e.getLocation()); + } + + @Override + public void handleHit(Entity e, Location l) { + scriptedItem.execute(ScriptedItem.EventType.onHit, e, l); + } + + public static void init() { + File itemsFolder = new File(MissileWars.getPlugin().getDataFolder(), "items"); + if (!itemsFolder.exists() || !itemsFolder.canRead() || !itemsFolder.isDirectory()) throw new SecurityException("Items could not be loaded"); + for (File itemFile : Objects.requireNonNull(itemsFolder.listFiles())) { + if (!itemFile.canRead() || !itemFile.isFile()) continue; + try { + JsonObject jsonObject = new JsonParser().parse(new FileReader(itemFile)).getAsJsonObject(); + new CustomItem(new ScriptedItem(jsonObject)); + } catch (JsonSyntaxException | IOException e) { + e.printStackTrace(); + throw new SecurityException("Item JSON error " + itemFile, e); + } + } + } + + public ScriptedItem getScriptedItem() { + return scriptedItem; + } + +} diff --git a/MissileWars/src/de/steamwar/misslewars/items/Missile.java b/MissileWars/src/de/steamwar/misslewars/items/Missile.java new file mode 100644 index 00000000..6e648e49 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/items/Missile.java @@ -0,0 +1,135 @@ +/* + 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.misslewars.items; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bukkit.BukkitWorld; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats; +import com.sk89q.worldedit.function.mask.BlockTypeMask; +import com.sk89q.worldedit.function.operation.Operations; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.math.transform.AffineTransform; +import com.sk89q.worldedit.session.ClipboardHolder; +import com.sk89q.worldedit.world.World; +import com.sk89q.worldedit.world.block.BlockTypes; +import de.steamwar.misslewars.MissileWars; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class Missile extends SpecialItem { + + private static final World world = new BukkitWorld(Bukkit.getWorlds().get(0)); + + private final Clipboard clipboard; + private final ItemStack item; + + private Missile(File missileFile) { + String[] strings = missileFile.getName().split("\\."); + String name = strings[0]; + String material = strings[1]; + if (!material.endsWith("_SPAWN_EGG")) material += "_SPAWN_EGG"; + Material itemType = Material.valueOf(material); + + ClipboardFormat format = ClipboardFormats.findByFile(missileFile); + try { + assert format != null; + clipboard = format.getReader(new FileInputStream(missileFile)).read(); + } catch (IOException e) { + throw new SecurityException("Corrupt missile"); + } + + List lore = new ArrayList<>(); + lore(lore, strings, 2, "§7Speed"); + lore(lore, strings, 3, "§7Size"); + + EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, -1); + BlockTypeMask blockTypeMask = new BlockTypeMask(clipboard, BlockTypes.TNT); + lore.add("§7TNT §8: §e" + e.countBlocks(clipboard.getRegion(), blockTypeMask)); + + item = createItem(itemType, "§c" + name, 1, lore); + } + + private void lore(List lore, String[] args, int index, String tag) { + if (args.length > index) { + lore.add(tag + " §8: §e" + Integer.parseInt(args[index]) + "§8/§77"); + } else { + lore.add(tag + " §8: §e0§8/§77"); + } + } + + @Override + public ItemStack getItem() { + return item; + } + + @Override + public boolean handleUse(Player p) { + BlockVector3 dimensions = clipboard.getDimensions(); + Location location = p.getLocation(); + BlockVector3 v = BlockVector3.ZERO; + BlockVector3 offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin()); + AffineTransform aT = new AffineTransform(); + + double yaw = (p.getLocation().getYaw() + 360f) % 360; + if (yaw > 45 && yaw <= 135) aT = aT.rotateY(270); + else if (yaw > 135 && yaw <= 225) aT = aT.rotateY(180); + else if (yaw > 225 && yaw <= 315) aT = aT.rotateY(90); + + v = v.subtract(dimensions.getX()/2, dimensions.getY() + 2, -2).subtract(offset); + v = aT.apply(v.toVector3()).toBlockPoint(); + v = v.add(location.getBlockX(), location.getBlockY(), location.getBlockZ()); + + EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, -1); + ClipboardHolder ch = new ClipboardHolder(clipboard); + ch.setTransform(aT); + Operations.completeBlindly(ch.createPaste(e).to(v).ignoreAirBlocks(true).build()); + e.flushSession(); + return true; + } + + @Override + public boolean isMissile() { + return true; + } + + public static void init() { + File missileFolder = new File(MissileWars.getPlugin().getDataFolder(), "missiles"); + if (!missileFolder.exists() || !missileFolder.canRead() || !missileFolder.isDirectory()) throw new SecurityException("Missiles could not be loaded"); + for (File missileFile : Objects.requireNonNull(missileFolder.listFiles())) { + if (!missileFile.canRead() || !missileFile.isFile()) continue; + if (!missileFile.getName().endsWith(".schem")) continue; + new Missile(missileFile); + } + } + +} diff --git a/MissileWars/src/de/steamwar/misslewars/items/SpecialItem.java b/MissileWars/src/de/steamwar/misslewars/items/SpecialItem.java new file mode 100644 index 00000000..de8b6847 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/items/SpecialItem.java @@ -0,0 +1,132 @@ +/* + 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.misslewars.items; + +import de.steamwar.misslewars.Config; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public abstract class SpecialItem { + + private static final Random random = new Random(); + private static double count = 0; + private static int consecutiveSupportItems = 0; + + private static List supportItems = new ArrayList<>(); + private static List missileItems = new ArrayList<>(); + + SpecialItem() { + if (this.isMissile()) missileItems.add(this); + else supportItems.add(this); + } + + private String materialName = null; + public abstract ItemStack getItem(); + public abstract boolean handleUse(Player p); + public void handleThrow(Entity e) {} + public void handleHit(Entity e, Location l) {} + public boolean isMissile() { + return false; + } + + public ItemStack createItem(Material material, String name, int amount, List lore) { + ItemStack item = new ItemStack(material, amount); + ItemMeta meta = item.getItemMeta(); + assert meta != null; + meta.addItemFlags(ItemFlag.HIDE_ENCHANTS); + meta.setLore(lore); + meta.setDisplayName(name); + item.setItemMeta(meta); + return item; + } + + public static boolean handleUse(ItemStack item, Player player) { + if (player.hasPotionEffect(PotionEffectType.LEVITATION)) { + player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§cDu kannst dieses Item derzeit nicht nutzen!")); + return false; + } + return handleUse(item, player, missileItems) || handleUse(item, player, supportItems); + } + + private static boolean handleUse(ItemStack item, Player player, List items) { + for (SpecialItem specialItem : items) + if (item.isSimilar(specialItem.getItem())) return specialItem.handleUse(player); + return false; + } + + public static void handleThrow(ProjectileLaunchEvent e) { + String name = e.getEntity().getClass().getName().toLowerCase(); + for (SpecialItem specialItem : supportItems) { + if (specialItem.materialName == null) + specialItem.materialName = specialItem.getItem().getType().name().toLowerCase(); + if (name.contains(specialItem.materialName)) + specialItem.handleThrow(e.getEntity()); + } + } + + public static void handleHit(ProjectileHitEvent e) { + String name = e.getEntity().getClass().getName().toLowerCase(); + + Location location = null; + if (e.getHitEntity() != null) location = e.getHitEntity().getLocation(); + else if (e.getHitBlock() != null) location = e.getHitBlock().getLocation(); + if (location == null) return; + + for (SpecialItem specialItem : supportItems) { + if (name.contains(((CustomItem) specialItem).getScriptedItem().getEntityName())) { + specialItem.handleHit(e.getEntity(), location); + } + } + } + + public static ItemStack getRandomItem() { + if (Config.MissileChance == 0 || consecutiveSupportItems > 1) { + consecutiveSupportItems = 0; + return supportItems.get(random.nextInt(supportItems.size())).getItem(); + } + if (Config.MissileChance == 1) { + return missileItems.get(random.nextInt(missileItems.size())).getItem(); + } + + double missileChance = Config.MissileChance + count * 0.1; + if (random.nextDouble() > missileChance) { + count += Config.MissileChance; + consecutiveSupportItems++; + return supportItems.get(random.nextInt(supportItems.size())).getItem(); + } else { + count -= 1 - Config.MissileChance; + return missileItems.get(random.nextInt(missileItems.size())).getItem(); + } + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/listener/ArenaListener.java b/MissileWars/src/de/steamwar/misslewars/listener/ArenaListener.java new file mode 100644 index 00000000..4d7a7ecc --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/listener/ArenaListener.java @@ -0,0 +1,88 @@ +/* + 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.misslewars.listener; + +import de.steamwar.misslewars.Config; +import de.steamwar.misslewars.FightState; +import de.steamwar.misslewars.MWTeam; +import de.steamwar.misslewars.MissileWars; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityPickupItemEvent; +import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.event.entity.ItemDespawnEvent; +import org.bukkit.event.inventory.InventoryOpenEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerPickupArrowEvent; + +import java.util.EnumSet; +import java.util.Map; +import java.util.Objects; + +public class ArenaListener extends BasicListener { + + public ArenaListener() { + super(EnumSet.allOf(FightState.class)); + } + + @EventHandler + public void onMove(PlayerMoveEvent e) { + Location location = e.getTo(); + Player p = e.getPlayer(); + + assert location != null; + if(location.getY() < Config.ArenaMinY){ + if(p.getGameMode() == GameMode.SPECTATOR) + p.teleport(e.getFrom()); + else if(MissileWars.getFightState() == FightState.WAITING) + p.teleport(Objects.requireNonNull(MissileWars.getTeam(p)).getSpawn()); + else + p.damage(20.0f); + }else if( + location.getX() < Config.ArenaMinX || + location.getX() > Config.ArenaMaxX || + location.getZ() < Config.ArenaMinZ || + location.getZ() > Config.ArenaMaxZ){ + p.teleport(e.getFrom()); + } + } + + @EventHandler + public void onArrowPickup(PlayerPickupArrowEvent e){ + e.setCancelled(true); + } + + @EventHandler + public void onHunger(FoodLevelChangeEvent e){ + e.setCancelled(true); + } + + @EventHandler(ignoreCancelled = true) + public void onInventoryOpen(InventoryOpenEvent event) { + if(event.getView().getType() != InventoryType.PLAYER && + event.getView().getType() != InventoryType.CRAFTING && + event.getView().getType() != InventoryType.CREATIVE) + event.setCancelled(true); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/listener/BasicListener.java b/MissileWars/src/de/steamwar/misslewars/listener/BasicListener.java new file mode 100644 index 00000000..b210216e --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/listener/BasicListener.java @@ -0,0 +1,47 @@ +/* + 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.misslewars.listener; + +import de.steamwar.misslewars.FightState; +import de.steamwar.misslewars.MissileWars; +import de.steamwar.misslewars.StateDependent; +import org.bukkit.Bukkit; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; + +import java.util.Set; + +public abstract class BasicListener extends StateDependent implements Listener { + + + protected BasicListener(final Set active){ + super(active); + } + + @Override + public void enable(){ + Bukkit.getPluginManager().registerEvents(this, MissileWars.getPlugin()); + } + + @Override + public void disable(){ + HandlerList.unregisterAll(this); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/listener/BreakListener.java b/MissileWars/src/de/steamwar/misslewars/listener/BreakListener.java new file mode 100644 index 00000000..bbaf1a65 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/listener/BreakListener.java @@ -0,0 +1,41 @@ +/* + * + * 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.misslewars.listener; + +import de.steamwar.misslewars.FightState; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockBreakEvent; + +import java.util.EnumSet; + +public class BreakListener extends BasicListener { + + public BreakListener() { + super(EnumSet.of(FightState.WAITING)); + } + + @EventHandler(ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) { + event.setCancelled(true); + } + +} diff --git a/MissileWars/src/de/steamwar/misslewars/listener/ChatListener.java b/MissileWars/src/de/steamwar/misslewars/listener/ChatListener.java new file mode 100644 index 00000000..3e039b7b --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/listener/ChatListener.java @@ -0,0 +1,56 @@ +/* + 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.misslewars.listener; + +import de.steamwar.misslewars.FightState; +import de.steamwar.misslewars.MWTeam; +import de.steamwar.misslewars.MissileWars; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.AsyncPlayerChatEvent; + +import java.util.EnumSet; + +public class ChatListener extends BasicListener { + + public ChatListener() { + super(EnumSet.allOf(FightState.class)); + } + + @EventHandler + public void onChat(AsyncPlayerChatEvent e) { + e.setCancelled(true); + + Player p = e.getPlayer(); + MWTeam team = MissileWars.getTeam(p); + String message = e.getPlayer().getDisplayName() + "§8» §7" + e.getMessage(); + if (team == null) { + Bukkit.broadcastMessage(message); + } else { + if (e.getMessage().startsWith("+")) { + String teamMessage = "§8[" + team.getColorCode() + "TEAM§8] " + e.getPlayer().getDisplayName() + "§8» §7" + e.getMessage().substring(1); + team.getPlayers().forEach(player -> player.sendMessage(teamMessage)); + } else { + Bukkit.broadcastMessage(message); + } + } + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/listener/ConnectionListener.java b/MissileWars/src/de/steamwar/misslewars/listener/ConnectionListener.java new file mode 100644 index 00000000..dab36fa4 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/listener/ConnectionListener.java @@ -0,0 +1,61 @@ +/* + 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.misslewars.listener; + +import de.steamwar.misslewars.Config; +import de.steamwar.misslewars.FightState; +import de.steamwar.misslewars.MWTeam; +import de.steamwar.misslewars.MissileWars; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import java.util.EnumSet; + +public class ConnectionListener extends BasicListener{ + + public ConnectionListener(){ + super(EnumSet.allOf(FightState.class)); + } + + @EventHandler(priority = EventPriority.HIGH) + public void onJoin(PlayerJoinEvent e) { + e.getPlayer().setDisplayName("§7" + e.getPlayer().getName()); + e.getPlayer().setGameMode(GameMode.SPECTATOR); + e.getPlayer().teleport(MissileWars.getRedTeam().getSpawn().toVector().midpoint(MissileWars.getBlueTeam().getSpawn().toVector()).toLocation(e.getPlayer().getWorld())); + if(Config.test()) { + e.getPlayer().setOp(true); + } + } + + @EventHandler + public void onLeave(PlayerQuitEvent e) { + MWTeam.removeInvitations(e.getPlayer()); + MissileWars.leave(e.getPlayer()); + + if (Bukkit.getOnlinePlayers().isEmpty() || (Bukkit.getOnlinePlayers().contains(e.getPlayer()) && Bukkit.getOnlinePlayers().size() == 1)) { + Bukkit.shutdown(); + } + } + +} diff --git a/MissileWars/src/de/steamwar/misslewars/listener/DeathListener.java b/MissileWars/src/de/steamwar/misslewars/listener/DeathListener.java new file mode 100644 index 00000000..5e77523a --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/listener/DeathListener.java @@ -0,0 +1,89 @@ +/* + 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.misslewars.listener; + +import de.steamwar.misslewars.FightState; +import de.steamwar.misslewars.MWTeam; +import de.steamwar.misslewars.MissileWars; +import de.steamwar.misslewars.SpawnPlatformCreator; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.util.Vector; + +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Set; + +public class DeathListener extends BasicListener { + + private static final Vector ZERO = new Vector(0, 0, 0); + private final Set respawnedPlayers = new HashSet<>(); + + public DeathListener() { + super(EnumSet.allOf(FightState.class)); + } + + @EventHandler + public void onDeath(PlayerDeathEvent e) { + e.setDeathMessage(null); + if(Bukkit.getOnlinePlayers().size() > 10) { + for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { + onlinePlayer.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(e.getEntity().getDisplayName() + " §cstarb")); + } + } else { + Bukkit.broadcastMessage(e.getEntity().getDisplayName() + " §cstarb"); + } + } + + @EventHandler + public void onRespawn(PlayerRespawnEvent e){ + Player p = e.getPlayer(); + p.setFireTicks(0); + MWTeam team = MissileWars.getTeam(p); + if(team == null) + return; + + e.setRespawnLocation(team.getSpawn()); + e.getPlayer().setVelocity(ZERO); + respawnedPlayers.add(p); + } + + @EventHandler + public void onPlayerMove(PlayerMoveEvent event) { + if (respawnedPlayers.isEmpty()) return; + Player player = event.getPlayer(); + if (!respawnedPlayers.contains(player)) return; + respawnedPlayers.remove(player); + new SpawnPlatformCreator(player); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + respawnedPlayers.remove(event.getPlayer()); + } + +} diff --git a/MissileWars/src/de/steamwar/misslewars/listener/EndListener.java b/MissileWars/src/de/steamwar/misslewars/listener/EndListener.java new file mode 100644 index 00000000..14833544 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/listener/EndListener.java @@ -0,0 +1,40 @@ +/* + 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.misslewars.listener; + +import de.steamwar.misslewars.FightState; +import org.bukkit.GameMode; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; + +import java.util.EnumSet; + +public class EndListener extends BasicListener { + + public EndListener(){ + super(EnumSet.of(FightState.END)); + } + + @EventHandler + public void onJoin(PlayerJoinEvent e) { + e.setJoinMessage(null); + e.getPlayer().setGameMode(GameMode.SPECTATOR); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/listener/FightListener.java b/MissileWars/src/de/steamwar/misslewars/listener/FightListener.java new file mode 100644 index 00000000..7ed369f8 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/listener/FightListener.java @@ -0,0 +1,47 @@ +/* + 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.misslewars.listener; + +import de.steamwar.misslewars.FightState; +import de.steamwar.misslewars.MissileWars; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +import java.util.EnumSet; + +public class FightListener extends BasicListener { + + public FightListener() { + super(EnumSet.of(FightState.FIGHTING)); + } + + @EventHandler + public void onDamage(EntityDamageByEntityEvent e){ + if(!(e.getDamager() instanceof Player && e.getEntity() instanceof Player)) + return; + + Player damager = (Player)e.getDamager(); + Player reciever = (Player)e.getEntity(); + + if(MissileWars.getTeam(damager) == MissileWars.getTeam(reciever)) + e.setCancelled(true); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/listener/ItemListener.java b/MissileWars/src/de/steamwar/misslewars/listener/ItemListener.java new file mode 100644 index 00000000..4856dc17 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/listener/ItemListener.java @@ -0,0 +1,123 @@ +/* + 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.misslewars.listener; + +import de.steamwar.misslewars.FightState; +import de.steamwar.misslewars.MWTeam; +import de.steamwar.misslewars.MissileWars; +import de.steamwar.misslewars.items.SpecialItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.Action; +import org.bukkit.event.entity.EntityPickupItemEvent; +import org.bukkit.event.entity.ItemDespawnEvent; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Set; + +public class ItemListener extends BasicListener { + + private Set RED_ITEMS = new HashSet<>(); + private Set BLUE_ITEMS = new HashSet<>(); + + public ItemListener() { + super(EnumSet.of(FightState.FIGHTING)); + } + + @Override + public void enable() { + super.enable(); + RED_ITEMS.clear(); + BLUE_ITEMS.clear(); + } + + @EventHandler + public void onItemClick(PlayerInteractEvent e) { + ItemStack item = e.getItem(); + if (item == null) + return; + if (e.getPlayer().hasCooldown(item.getType())) return; + + if (e.getAction() != Action.RIGHT_CLICK_BLOCK && e.getAction() != Action.RIGHT_CLICK_AIR) + return; + + if (SpecialItem.handleUse(item, e.getPlayer()) && item.getType() != Material.SPLASH_POTION) { + item.setAmount(item.getAmount()-1); + e.getPlayer().updateInventory(); + e.setCancelled(true); + } + } + + @EventHandler + public void onThrow(ProjectileLaunchEvent e) { + SpecialItem.handleThrow(e); + } + + @EventHandler + public void onHit(ProjectileHitEvent e) { + SpecialItem.handleHit(e); + } + + @EventHandler + public void onItemDrop(PlayerDropItemEvent e){ + MWTeam mwTeam = MissileWars.getTeam(e.getPlayer()); + if (mwTeam == null) { + e.setCancelled(true); + return; + } + if (e.getItemDrop().getItemStack().isSimilar(MWTeam.bow)) { + e.setCancelled(true); + return; + } + if (mwTeam == MissileWars.getRedTeam()) { + RED_ITEMS.add(e.getItemDrop().getEntityId()); + } else { + BLUE_ITEMS.add(e.getItemDrop().getEntityId()); + } + } + + @EventHandler + public void onEntityPickupItem(EntityPickupItemEvent e) { + Player player = (Player) e.getEntity(); + MWTeam mwTeam = MissileWars.getTeam(player); + if (mwTeam == null) { + e.setCancelled(true); + return; + } + if (mwTeam == MissileWars.getRedTeam() && !RED_ITEMS.contains(e.getItem().getEntityId())) { + e.setCancelled(true); + } else if (mwTeam == MissileWars.getBlueTeam() && !BLUE_ITEMS.contains(e.getItem().getEntityId())) { + e.setCancelled(true); + } + } + + @EventHandler + public void onItemDespawn(ItemDespawnEvent event) { + RED_ITEMS.remove(event.getEntity().getEntityId()); + BLUE_ITEMS.remove(event.getEntity().getEntityId()); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/listener/JoinListener.java b/MissileWars/src/de/steamwar/misslewars/listener/JoinListener.java new file mode 100644 index 00000000..5947da8f --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/listener/JoinListener.java @@ -0,0 +1,101 @@ +/* + 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.misslewars.listener; + +import de.steamwar.misslewars.Config; +import de.steamwar.misslewars.FightState; +import de.steamwar.misslewars.MissileWars; +import de.steamwar.sql.SteamwarUser; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerJoinEvent; + +import java.util.EnumSet; + +public class JoinListener extends BasicListener { + + public JoinListener(){ + super(EnumSet.of(FightState.WAITING, FightState.FIGHTING)); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onJoin(PlayerJoinEvent e){ + e.setJoinMessage("§a» " + e.getPlayer().getDisplayName()); + join(e.getPlayer()); + } + + public static void join(Player p) { + if (Config.isEvent()) { + joinEvent(p); + return; + } + + if (Config.isChallenge()) { + joinChallenge(p); + return; + } + + joinNormal(p); + } + + private static void joinEvent(Player p) { + if (Config.EventTeamRedID == 0 && Config.EventTeamBlueID == 0) { + joinNormal(p); + return; + } + + int teamId = SteamwarUser.get(p.getUniqueId()).getTeam(); + if (teamId != Config.EventTeamRedID && teamId != Config.EventTeamBlueID) { + teamId = 0; + } + if (teamId == Config.EventTeamRedID && MissileWars.getRedTeam().size() < Config.MaximumTeamMembers) { + MissileWars.getRedTeam().join(p); + } else if (teamId == Config.EventTeamBlueID && MissileWars.getBlueTeam().size() < Config.MaximumTeamMembers) { + MissileWars.getBlueTeam().join(p); + } else { + p.teleport(MissileWars.getRedTeam().getSpawn().toVector().midpoint(MissileWars.getBlueTeam().getSpawn().toVector()).toLocation(p.getWorld())); + } + } + + private static void joinChallenge(Player p) { + if (Config.RedLeader.equals(p.getUniqueId())) { + MissileWars.getRedTeam().join(p); + } else if (Config.BlueLeader.equals(p.getUniqueId())) { + MissileWars.getBlueTeam().join(p); + } else { + p.teleport(MissileWars.getRedTeam().getSpawn().toVector().midpoint(MissileWars.getBlueTeam().getSpawn().toVector()).toLocation(p.getWorld())); + } + } + + private static void joinNormal(Player p) { + if (MissileWars.getRedTeam().size() == MissileWars.getBlueTeam().size()) { + if (Math.random() > 0.5) { + MissileWars.getRedTeam().join(p); + } else { + MissileWars.getBlueTeam().join(p); + } + } else if (MissileWars.getRedTeam().size() < MissileWars.getBlueTeam().size()) { + MissileWars.getRedTeam().join(p); + } else { + MissileWars.getBlueTeam().join(p); + } + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/listener/PortalDestructListener.java b/MissileWars/src/de/steamwar/misslewars/listener/PortalDestructListener.java new file mode 100644 index 00000000..c235ff35 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/listener/PortalDestructListener.java @@ -0,0 +1,62 @@ +/* + 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.misslewars.listener; + +import de.steamwar.misslewars.Config; +import de.steamwar.misslewars.FightState; +import de.steamwar.misslewars.MissileWars; +import de.steamwar.misslewars.WinReasons; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.entity.EntityExplodeEvent; + +import java.util.EnumSet; + +public class PortalDestructListener extends BasicListener { + + public PortalDestructListener(){ + super(EnumSet.of(FightState.FIGHTING)); + } + + @EventHandler + public void onBlockupdate(BlockPhysicsEvent e) { + if (e.getBlock().getType() != Material.NETHER_PORTAL) + return; + int z = e.getBlock().getZ(); + if (z == MissileWars.getRedTeam().getPortalZ()) + MissileWars.end(WinReasons.PORTAL_DESTROYED, MissileWars.getBlueTeam()); + if (z == MissileWars.getBlueTeam().getPortalZ()) + MissileWars.end(WinReasons.PORTAL_DESTROYED, MissileWars.getRedTeam()); + } + + @EventHandler + public void onExplosion(EntityExplodeEvent e){ + if(e.getEntityType() != EntityType.FIREBALL) + return; + + double z = e.getLocation().getZ(); + double distRed = Math.abs(Config.RedPortalZ + 0.5 - z); + double distBlue = Math.abs(Config.BluePortalZ + 0.5 - z); + if(distRed < 2 || distBlue < 2) + e.setCancelled(true); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/listener/WaitingListener.java b/MissileWars/src/de/steamwar/misslewars/listener/WaitingListener.java new file mode 100644 index 00000000..1180edc3 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/listener/WaitingListener.java @@ -0,0 +1,47 @@ +/* + 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.misslewars.listener; + +import de.steamwar.misslewars.FightState; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import java.util.EnumSet; + +public class WaitingListener extends BasicListener { + public WaitingListener() { + super(EnumSet.of(FightState.WAITING)); + } + + @EventHandler + public void onDisconnect(PlayerQuitEvent e){ + if (Bukkit.getOnlinePlayers().isEmpty() || (Bukkit.getOnlinePlayers().contains(e.getPlayer()) && Bukkit.getOnlinePlayers().size() == 1)) { + Bukkit.shutdown(); + } + } + + @EventHandler + public void onDamage(EntityDamageEvent e){ + if(e.getCause() != EntityDamageEvent.DamageCause.VOID) + e.setCancelled(true); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/listener/special/BarrierListener.java b/MissileWars/src/de/steamwar/misslewars/listener/special/BarrierListener.java new file mode 100644 index 00000000..5220778c --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/listener/special/BarrierListener.java @@ -0,0 +1,58 @@ +/* + * + * 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.misslewars.listener.special; + +import de.steamwar.misslewars.Config; +import de.steamwar.misslewars.FightState; +import de.steamwar.misslewars.listener.BasicListener; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockPhysicsEvent; + +import java.util.EnumSet; + +public class BarrierListener extends BasicListener { + + public BarrierListener() { + super(EnumSet.allOf(FightState.class)); + } + + private int middle = Config.ArenaMinZ + (Config.ArenaMaxZ - Config.ArenaMinZ) / 2; + + @EventHandler + public void onBlockPhysics(BlockPhysicsEvent event) { + if (!Config.Barrier) return; + Block block = event.getBlock(); + if (block.getZ() > middle - 10 && block.getZ() < middle + 10) { + switch (block.getType()) { + case SLIME_BLOCK: + case HONEY_BLOCK: + case TNT: + block.setType(Material.AIR); + break; + default: + break; + } + } + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/listener/special/SpaceListener.java b/MissileWars/src/de/steamwar/misslewars/listener/special/SpaceListener.java new file mode 100644 index 00000000..654811ab --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/listener/special/SpaceListener.java @@ -0,0 +1,82 @@ +/* + * + * 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.misslewars.listener.special; + +import de.steamwar.misslewars.Config; +import de.steamwar.misslewars.FightState; +import de.steamwar.misslewars.MissileWars; +import de.steamwar.misslewars.listener.BasicListener; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntitySpawnEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; + +import java.util.EnumSet; + +public class SpaceListener extends BasicListener { + + public SpaceListener() { + super(EnumSet.allOf(FightState.class)); + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + if (!Config.Space) return; + Bukkit.getScheduler().runTaskLater(MissileWars.getPlugin(), () -> { + Player player = event.getPlayer(); + player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, Integer.MAX_VALUE, 3)); + player.addPotionEffect(new PotionEffect(PotionEffectType.SLOW_FALLING, Integer.MAX_VALUE, 3)); + player.setHealth(0.5); + player.setHealthScale(0.5); + }, 5); + } + + @EventHandler + public void onPlayerRespawn(PlayerRespawnEvent event) { + if (!Config.Space) return; + Bukkit.getScheduler().runTaskLater(MissileWars.getPlugin(), () -> { + Player player = event.getPlayer(); + player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, Integer.MAX_VALUE, 3)); + player.addPotionEffect(new PotionEffect(PotionEffectType.SLOW_FALLING, Integer.MAX_VALUE, 3)); + player.setHealth(0.5); + player.setHealthScale(0.5); + }, 5); + } + + @EventHandler + public void onEntitySpawn(EntitySpawnEvent event) { + if (!Config.Space) return; + if (event.getEntity() instanceof Player) return; + event.getEntity().setGravity(false); + Vector vector = event.getEntity().getVelocity(); + if (event.getEntity() instanceof TNTPrimed) { + vector.setY(0); + } + event.getEntity().setVelocity(vector); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/scripts/RunnableScript.java b/MissileWars/src/de/steamwar/misslewars/scripts/RunnableScript.java new file mode 100644 index 00000000..5328bc31 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/scripts/RunnableScript.java @@ -0,0 +1,35 @@ +/* + 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.misslewars.scripts; + +import java.util.function.UnaryOperator; + +public interface RunnableScript { + boolean execute(RunnableScriptEvent runnableScriptEvent); + + interface ScriptFunction { + boolean execute(RunnableScriptEvent runnableScriptEvent, double... doubles); + } + + default boolean defaultExecution(ScriptFunction scriptFunction, boolean nullReturn, UnaryOperator returnValue, RunnableScriptEvent runnableScriptEvent, double... doubles) { + if (scriptFunction == null) return nullReturn; + return returnValue.apply(scriptFunction.execute(runnableScriptEvent, doubles)); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/scripts/RunnableScriptEvent.java b/MissileWars/src/de/steamwar/misslewars/scripts/RunnableScriptEvent.java new file mode 100644 index 00000000..8459f559 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/scripts/RunnableScriptEvent.java @@ -0,0 +1,82 @@ +/* + 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.misslewars.scripts; + +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +public class RunnableScriptEvent { + + public enum LocationType { + STATIC, + DYNAMIC, + DEFAULT, + CUSTOM + } + + public final ScriptedItem.EventType eventType; + public final Entity entity; + private final Location location; + private Location customLocation; + private LocationType locationType = LocationType.DEFAULT; + Script.ScriptExecutor scriptExecutor = null; + + public RunnableScriptEvent(ScriptedItem.EventType eventType, Entity entity, Location location) { + this.eventType = eventType; + this.entity = entity; + this.location = location; + } + + public Location getLocation() { + // Custom location + if (locationType == LocationType.CUSTOM && customLocation != null) return customLocation; + + // Static initial Location + if (locationType == LocationType.STATIC) return location; + + // Dynamic Location if entity is not null + if (locationType == LocationType.DYNAMIC) return entity != null ? entity.getLocation() : location; + + // Default Location is static if EventType is onClick otherwise dynamic + if (eventType == ScriptedItem.EventType.onClick) return location; + if (entity != null) return entity.getLocation(); + return location; + } + + public void setLocationType(LocationType locationType) { + if (locationType == null) return; + this.locationType = locationType; + } + + public void setCustomLocation(double x, double y, double z, float pitch, float yaw) { + this.customLocation = new Location(location.getWorld(), x, y, z, yaw, pitch); + } + + public Player getPlayer() { + return (Player) entity; + } + + public void resumeScriptExecution() { + if (scriptExecutor == null) return; + scriptExecutor.resume(); + } + +} diff --git a/MissileWars/src/de/steamwar/misslewars/scripts/Script.java b/MissileWars/src/de/steamwar/misslewars/scripts/Script.java new file mode 100644 index 00000000..095dfaf3 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/scripts/Script.java @@ -0,0 +1,97 @@ +/* + 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.misslewars.scripts; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import de.steamwar.misslewars.scripts.implemented.*; + +import java.util.ArrayList; +import java.util.List; + +public class Script { + + private List runnableScriptList = new ArrayList<>(); + + class ScriptExecutor { + + private int index = 0; + private final RunnableScriptEvent runnableScriptEvent; + + public ScriptExecutor(RunnableScriptEvent runnableScriptEvent) { + this.runnableScriptEvent = runnableScriptEvent; + runnableScriptEvent.scriptExecutor = this; + resume(); + } + + void resume() { + while (index < runnableScriptList.size()) { + if (!runnableScriptList.get(index++).execute(runnableScriptEvent)) return; + } + } + } + + public void execute(RunnableScriptEvent runnableScriptEvent) { + new ScriptExecutor(runnableScriptEvent); + } + + public static Script parseScript(JsonArray jsonArray) { + Script script = new Script(); + jsonArray.forEach(jsonElement -> { + RunnableScript runnableScript = parseScriptSnippet((JsonObject) jsonElement); + if (runnableScript == null) return; + script.runnableScriptList.add(runnableScript); + }); + return script; + } + + private static RunnableScript parseScriptSnippet(JsonObject jsonObject) { + if (!jsonObject.has("type")) return null; + switch (jsonObject.getAsJsonPrimitive("type").getAsString().toLowerCase()) { + case "delay": + return new DelayScript(jsonObject); + case "filter": + return new FilterScript(jsonObject); + case "remove": + return new RemoveScript(jsonObject); + case "launch": + return new LaunchScript(jsonObject); + case "location": + return new LocationScript(jsonObject); + case "paste": + return new PasteScript(jsonObject); + case "potion": + return new PotionScript(jsonObject); + case "sound": + return new SoundScript(jsonObject); + case "summon": + return new SummonScript(jsonObject); + case "slowmo": + return new SlowMoScript(jsonObject); + case "cooldown": + return new CooldownScript(jsonObject); + case "randomplayer": + return new RandomPlayerScript(jsonObject); + default: + return null; + } + } + +} diff --git a/MissileWars/src/de/steamwar/misslewars/scripts/ScriptedItem.java b/MissileWars/src/de/steamwar/misslewars/scripts/ScriptedItem.java new file mode 100644 index 00000000..4e1587d6 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/scripts/ScriptedItem.java @@ -0,0 +1,127 @@ +/* + 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.misslewars.scripts; + +import com.google.gson.JsonObject; +import de.steamwar.misslewars.scripts.utils.JsonUtils; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LingeringPotion; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.Damageable; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static de.steamwar.misslewars.scripts.utils.JsonUtils.getString; + +public class ScriptedItem { + + // "type": Material name (STRING) + // "name": Item name (STRING) + // "lore": Lore array (OPTIONAL STRING.ARRAY) + // "amount": Item amount (OPTIONAL [default 1] INT) + // "potion": Object with key value pairs for PotionType and Object containing duration and amplifier (OPTIONAL OBJECT) + // "uses": Uses of Item (OPTIONAL INT) + // "EVENT.": Event (OPTIONAL JSONobject.ARRAY) + // - onClick + // - onHit + // - onThrow + + public enum EventType { + onHit, + onThrow, + onClick + } + + private Map scriptMap = new HashMap<>(); + private String entityName = ""; + + private ItemStack itemStack; + + public ScriptedItem(JsonObject jsonObject) { + itemStack = createItemStack(jsonObject); + + getString(jsonObject, "entityName", string -> entityName = string); + + for (EventType eventType : EventType.values()) { + String eventString = "EVENT." + eventType.name(); + if (!jsonObject.has(eventString) || !jsonObject.get(eventString).isJsonArray()) continue; + scriptMap.put(eventType, Script.parseScript(jsonObject.getAsJsonArray(eventString))); + } + } + + private static ItemStack createItemStack(JsonObject jsonObject) { + ItemStack itemStack = new ItemStack(Material.valueOf(getString(jsonObject, "type", "")), JsonUtils.getInt(jsonObject, "amount", 1)); + ItemMeta itemMeta = itemStack.getItemMeta(); + if (itemMeta == null) return itemStack; + getString(jsonObject, "name", itemMeta::setDisplayName); + + if (jsonObject.has("lore")) { + List lore = new ArrayList<>(); + jsonObject.getAsJsonArray("lore").forEach(jsonElement -> lore.add(jsonElement.getAsString())); + itemMeta.setLore(lore); + } + + if (jsonObject.has("potion") && itemMeta instanceof PotionMeta) { + JsonObject potionObject = jsonObject.getAsJsonObject("potion"); + potionObject.entrySet().forEach(stringJsonElementEntry -> { + String key = stringJsonElementEntry.getKey(); + JsonObject currentObject = stringJsonElementEntry.getValue().getAsJsonObject(); + PotionEffectType potionEffectType = PotionEffectType.getByName(key); + if (potionEffectType == null) return; + int duration = JsonUtils.getInt(currentObject, "duration", 0); + int amplifier = JsonUtils.getInt(currentObject, "amplifier", 0); + PotionMeta potionMeta = (PotionMeta) itemMeta; + potionMeta.addCustomEffect(new PotionEffect(potionEffectType, duration, amplifier), true); + }); + } + + if (jsonObject.has("uses") && itemMeta instanceof Damageable) { + int uses = jsonObject.getAsJsonPrimitive("uses").getAsInt(); + Damageable damageable = (Damageable) itemMeta; + damageable.setDamage(itemStack.getType().getMaxDurability() - uses); + } + + itemStack.setItemMeta(itemMeta); + return itemStack; + } + + public boolean execute(EventType eventType, Entity entity, Location location) { + if (!scriptMap.containsKey(eventType)) return false; + scriptMap.get(eventType).execute(new RunnableScriptEvent(eventType, entity, location)); + return true; + } + + public ItemStack getItemStack() { + return itemStack; + } + + public String getEntityName() { + return entityName; + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/scripts/implemented/CooldownScript.java b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/CooldownScript.java new file mode 100644 index 00000000..9b6dfcf5 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/CooldownScript.java @@ -0,0 +1,31 @@ +package de.steamwar.misslewars.scripts.implemented; + +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import de.steamwar.misslewars.MissileWars; +import de.steamwar.misslewars.scripts.RunnableScript; +import de.steamwar.misslewars.scripts.RunnableScriptEvent; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +public class CooldownScript implements RunnableScript { + + private int cooldown = 0; + + public CooldownScript(JsonObject object) { + JsonPrimitive primitive = object.getAsJsonPrimitive("cooldown"); + if(primitive.isNumber()) cooldown = primitive.getAsInt(); + } + + @Override + public boolean execute(RunnableScriptEvent runnableScriptEvent) { + Material mainHand = runnableScriptEvent.getPlayer().getInventory().getItemInMainHand().getType(); + Material offHand = runnableScriptEvent.getPlayer().getInventory().getItemInOffHand().getType(); + Bukkit.getScheduler().runTaskLater(MissileWars.getPlugin(), () -> { + if (mainHand != Material.AIR) runnableScriptEvent.getPlayer().setCooldown(mainHand, cooldown); + if (offHand != Material.AIR) runnableScriptEvent.getPlayer().setCooldown(offHand, cooldown); + }, 1); + return true; + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/scripts/implemented/DelayScript.java b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/DelayScript.java new file mode 100644 index 00000000..f77b985a --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/DelayScript.java @@ -0,0 +1,62 @@ +/* + 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.misslewars.scripts.implemented; + +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import de.steamwar.misslewars.Config; +import de.steamwar.misslewars.MissileWars; +import de.steamwar.misslewars.scripts.RunnableScript; +import de.steamwar.misslewars.scripts.RunnableScriptEvent; +import org.bukkit.Bukkit; + +import java.util.HashMap; +import java.util.Map; + +public class DelayScript implements RunnableScript { + + private static final Map delayMap = new HashMap<>(); + + static { + delayMap.put("config.mineflytime", Config.ShieldFlyTime); + delayMap.put("config.shieldflytime", Config.ShieldFlyTime); + delayMap.put("config.endtime", Config.EndTime); + delayMap.put("config.waitingtime", Config.WaitingTime); + delayMap.put("config.itemtime", Config.ItemTime); + delayMap.put("config.platformtime", Config.PlatformTime); + + delayMap.put("config.tick", 1); + } + + private int delayTime = 0; + + public DelayScript(JsonObject delay) { + JsonPrimitive jsonPrimitive = delay.getAsJsonPrimitive("time"); + if (jsonPrimitive.isString()) delayTime = delayMap.getOrDefault(jsonPrimitive.getAsString().toLowerCase(), 0); + else if (jsonPrimitive.isNumber()) delayTime = jsonPrimitive.getAsInt(); + } + + @Override + public boolean execute(RunnableScriptEvent runnableScriptEvent) { + Bukkit.getScheduler().runTaskLater(MissileWars.getPlugin(), runnableScriptEvent::resumeScriptExecution, delayTime); + return false; + } + +} diff --git a/MissileWars/src/de/steamwar/misslewars/scripts/implemented/FilterScript.java b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/FilterScript.java new file mode 100644 index 00000000..4cf250c9 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/FilterScript.java @@ -0,0 +1,68 @@ +/* + 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.misslewars.scripts.implemented; + +import com.google.gson.JsonObject; +import de.steamwar.misslewars.MissileWars; +import de.steamwar.misslewars.scripts.RunnableScript; +import de.steamwar.misslewars.scripts.RunnableScriptEvent; +import org.bukkit.Location; + +import java.util.HashMap; +import java.util.Map; + +import static de.steamwar.misslewars.scripts.utils.JsonUtils.getBoolean; +import static de.steamwar.misslewars.scripts.utils.JsonUtils.getString; + +public class FilterScript implements RunnableScript { + + private static final Map filterMap = new HashMap<>(); + + static { + filterMap.put("nearportal", (runnableScriptEvent, doubles) -> { + Location location = runnableScriptEvent.getLocation(); + int bz = MissileWars.getBlueTeam().getPortalZ(); + int rz = MissileWars.getRedTeam().getPortalZ(); + int offset = (int) Math.signum(bz - rz) * 5; + + int blockZ = location.getBlockZ(); + if (offset > 0) return (blockZ > bz - offset) || (blockZ < rz + offset); + else return (blockZ < bz - offset) || (blockZ > rz + offset); + }); + filterMap.put("nearspawn", (runnableScriptEvent, doubles) -> { + Location location = runnableScriptEvent.getLocation(); + return MissileWars.getBlueTeam().getSpawn().distance(location) < 3 || MissileWars.getRedTeam().getSpawn().distance(location) < 3; + }); + } + + private boolean inverted; + private ScriptFunction filter; + + public FilterScript(JsonObject filter) { + this.filter = filterMap.getOrDefault(getString(filter, "filter", "").toLowerCase(), null); + inverted = getBoolean(filter, "invert", false); + } + + @Override + public boolean execute(RunnableScriptEvent runnableScriptEvent) { + return defaultExecution(filter, true, b -> b ^ inverted, runnableScriptEvent); + } + +} diff --git a/MissileWars/src/de/steamwar/misslewars/scripts/implemented/LaunchScript.java b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/LaunchScript.java new file mode 100644 index 00000000..83b44edf --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/LaunchScript.java @@ -0,0 +1,51 @@ +/* + 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.misslewars.scripts.implemented; + +import com.google.gson.JsonObject; +import de.steamwar.misslewars.scripts.RunnableScript; +import de.steamwar.misslewars.scripts.RunnableScriptEvent; +import de.steamwar.misslewars.scripts.ScriptedItem; +import de.steamwar.misslewars.scripts.utils.EntityUtils; +import de.steamwar.misslewars.scripts.utils.EntityUtils.ScriptShortcut; +import org.bukkit.entity.Projectile; + +public class LaunchScript implements RunnableScript { + + private ScriptFunction launch = null; + + public LaunchScript(JsonObject launch) { + ScriptShortcut scriptShortcut = EntityUtils.getEntity(launch.getAsJsonPrimitive("entity").getAsString(), EntityUtils.EntityType.Projectile); + if (scriptShortcut == null) return; + + this.launch = (runnableScriptEvent, doubles) -> { + Projectile projectile = runnableScriptEvent.getPlayer().launchProjectile(scriptShortcut.entityClass); + scriptShortcut.consumer.accept(launch, projectile, runnableScriptEvent); + return false; + }; + } + + @Override + public boolean execute(RunnableScriptEvent runnableScriptEvent) { + if (runnableScriptEvent.eventType != ScriptedItem.EventType.onClick) return true; + return defaultExecution(launch, false, b -> true, runnableScriptEvent); + } + +} diff --git a/MissileWars/src/de/steamwar/misslewars/scripts/implemented/LocationScript.java b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/LocationScript.java new file mode 100644 index 00000000..1fb272ed --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/LocationScript.java @@ -0,0 +1,89 @@ +/* + 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.misslewars.scripts.implemented; + +import com.google.gson.JsonObject; +import de.steamwar.misslewars.scripts.RunnableScript; +import de.steamwar.misslewars.scripts.RunnableScriptEvent; +import de.steamwar.misslewars.scripts.RunnableScriptEvent.LocationType; +import org.bukkit.Location; + +import java.util.HashMap; +import java.util.Map; + +import static de.steamwar.misslewars.scripts.utils.JsonUtils.getDouble; +import static de.steamwar.misslewars.scripts.utils.JsonUtils.getString; + +public class LocationScript implements RunnableScript { + + private static final Map locationTypeMap = new HashMap<>(); + private static final Map locationMap = new HashMap<>(); + + static { + locationTypeMap.put("static", LocationType.STATIC); + locationTypeMap.put("dynamic", LocationType.DYNAMIC); + locationTypeMap.put("custom", LocationType.CUSTOM); + locationTypeMap.put("default", LocationType.DEFAULT); + + locationMap.put("offsetentity", (runnableScriptEvent, doubles) -> { + if (runnableScriptEvent.entity == null) return false; + Location location1 = runnableScriptEvent.entity.getLocation(); + runnableScriptEvent.setCustomLocation(location1.getX() + doubles[0], location1.getY() + doubles[1], location1.getZ() + doubles[2], 0, 0); + return false; + }); + locationMap.put("offsetlocation", (runnableScriptEvent, doubles) -> { + Location location1 = runnableScriptEvent.getLocation(); + runnableScriptEvent.setCustomLocation(location1.getX() + doubles[0], location1.getY() + doubles[1], location1.getZ() + doubles[2], 0, 0); + return false; + }); + ScriptFunction absoluteLocation = (runnableScriptEvent, doubles) -> { + runnableScriptEvent.setCustomLocation(doubles[0], doubles[1], doubles[2], 0, 0); + return false; + }; + locationMap.put("absolute", absoluteLocation); + locationMap.put("fix", absoluteLocation); + locationMap.put("fixed", absoluteLocation); + } + + private LocationType locationType = null; + private ScriptFunction locationExecutor = null; + + private double x, y, z = 0; + + public LocationScript(JsonObject location) { + if (location.has("location")) { + JsonObject jsonObject = location.getAsJsonObject("location"); + getDouble(jsonObject, "x", value -> x = value); + getDouble(jsonObject, "y", value -> y = value); + getDouble(jsonObject, "z", value -> z = value); + locationExecutor = locationMap.getOrDefault(getString(jsonObject, "type", "").toLowerCase(), null); + locationType = LocationType.CUSTOM; + } else if (location.has("locationType")) { + locationType = locationTypeMap.getOrDefault(getString(location, "locationType", "").toLowerCase(), LocationType.DEFAULT); + } + } + + @Override + public boolean execute(RunnableScriptEvent runnableScriptEvent) { + runnableScriptEvent.setLocationType(locationType); + return defaultExecution(locationExecutor, true, b -> true, runnableScriptEvent, x, y, z); + } + +} diff --git a/MissileWars/src/de/steamwar/misslewars/scripts/implemented/PasteScript.java b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/PasteScript.java new file mode 100644 index 00000000..db1b2cb4 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/PasteScript.java @@ -0,0 +1,92 @@ +/* + 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.misslewars.scripts.implemented; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bukkit.BukkitWorld; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats; +import com.sk89q.worldedit.function.operation.Operations; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.session.ClipboardHolder; +import com.sk89q.worldedit.world.World; +import de.steamwar.misslewars.MissileWars; +import de.steamwar.misslewars.scripts.RunnableScript; +import de.steamwar.misslewars.scripts.RunnableScriptEvent; +import org.bukkit.Bukkit; +import org.bukkit.Location; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Objects; + +import static de.steamwar.misslewars.scripts.utils.JsonUtils.getBoolean; + +public class PasteScript implements RunnableScript { + + private static final World world = new BukkitWorld(Bukkit.getWorlds().get(0)); + + private final Clipboard clipboard; + private final BlockVector3 centeredOffset; + + private boolean centered, ignoreAir; + private int xOffset, yOffset, zOffset = 0; + + public PasteScript(JsonObject paste) { + String schemFileName = paste.getAsJsonPrimitive("schem").getAsString(); + if (!schemFileName.endsWith(".schem")) schemFileName += ".schem"; + + File schemFile = new File(MissileWars.getPlugin().getDataFolder(), schemFileName); + try { + clipboard = Objects.requireNonNull(ClipboardFormats.findByFile(schemFile)).getReader(new FileInputStream(schemFile)).read(); + } catch (IOException e) { + throw new SecurityException("Could not load " + schemFileName, e); + } + centeredOffset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin()).add(clipboard.getDimensions().divide(2)); + + centered = getBoolean(paste, "centered", false); + ignoreAir = getBoolean(paste, "ignoreAir", false); + if (paste.has("offset")) + return; + JsonArray jsonArray = paste.getAsJsonArray("offset"); + if (jsonArray.size() == 3) + return; + xOffset = jsonArray.get(0).getAsInt(); + yOffset = jsonArray.get(1).getAsInt(); + zOffset = jsonArray.get(2).getAsInt(); + } + + @Override + public boolean execute(RunnableScriptEvent runnableScriptEvent) { + Location location = runnableScriptEvent.getLocation(); + BlockVector3 paste = BlockVector3.at(location.getX() + xOffset, location.getY() + yOffset, location.getZ() + zOffset); + if (centered) paste = paste.subtract(centeredOffset); + + EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, -1); + Operations.completeBlindly(new ClipboardHolder(clipboard).createPaste(editSession).ignoreAirBlocks(ignoreAir).to(paste).build()); + editSession.flushSession(); + return true; + } + +} diff --git a/MissileWars/src/de/steamwar/misslewars/scripts/implemented/PotionScript.java b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/PotionScript.java new file mode 100644 index 00000000..34777dce --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/PotionScript.java @@ -0,0 +1,56 @@ +/* + 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.misslewars.scripts.implemented; + +import com.google.gson.JsonObject; +import de.steamwar.misslewars.scripts.RunnableScript; +import de.steamwar.misslewars.scripts.RunnableScriptEvent; +import de.steamwar.misslewars.scripts.ScriptedItem; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import static de.steamwar.misslewars.scripts.utils.JsonUtils.getBoolean; +import static de.steamwar.misslewars.scripts.utils.JsonUtils.getInt; + +public class PotionScript implements RunnableScript { + + private PotionEffect potionEffect = null; + + public PotionScript(JsonObject potion) { + int duration = getInt(potion, "duration", 1); + int amplifier = getInt(potion, "amplifier", 1); + boolean ambient = getBoolean(potion, "ambient", true); + boolean particles = getBoolean(potion, "particles", true); + boolean icon = getBoolean(potion, "icon", true); + + PotionEffectType potionEffectType = PotionEffectType.getByName(potion.getAsJsonPrimitive("potion").getAsString()); + if (potionEffectType == null) return; + potionEffect = new PotionEffect(potionEffectType, duration, amplifier, ambient, particles, icon); + } + + @Override + public boolean execute(RunnableScriptEvent runnableScriptEvent) { + if (potionEffect == null) return false; + if (runnableScriptEvent.eventType != ScriptedItem.EventType.onClick) return true; + runnableScriptEvent.getPlayer().addPotionEffect(potionEffect); + return true; + } + +} diff --git a/MissileWars/src/de/steamwar/misslewars/scripts/implemented/RandomPlayerScript.java b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/RandomPlayerScript.java new file mode 100644 index 00000000..240c5a24 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/RandomPlayerScript.java @@ -0,0 +1,54 @@ +/* + * + * 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.misslewars.scripts.implemented; + +import com.google.gson.JsonObject; +import de.steamwar.misslewars.MissileWars; +import de.steamwar.misslewars.scripts.RunnableScript; +import de.steamwar.misslewars.scripts.RunnableScriptEvent; +import org.bukkit.entity.Player; + +import java.util.Random; + +public class RandomPlayerScript implements RunnableScript { + + private Random random = new Random(); + + public RandomPlayerScript(JsonObject __) { + } + + @Override + public boolean execute(RunnableScriptEvent runnableScriptEvent) { + int size = MissileWars.getBlueTeam().getPlayers().size() + MissileWars.getRedTeam().getPlayers().size(); + if (size == 0) return true; + int index = random.nextInt(size); + Player player; + if (index >= MissileWars.getBlueTeam().getPlayers().size()) { + player = MissileWars.getRedTeam().getPlayers().get(index - MissileWars.getBlueTeam().getPlayers().size()); + } else { + player = MissileWars.getBlueTeam().getPlayers().get(index); + } + runnableScriptEvent.setLocationType(RunnableScriptEvent.LocationType.CUSTOM); + runnableScriptEvent.setCustomLocation(player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ(), player.getLocation().getPitch(), player.getLocation().getYaw()); + return true; + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/scripts/implemented/RemoveScript.java b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/RemoveScript.java new file mode 100644 index 00000000..ede587ed --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/RemoveScript.java @@ -0,0 +1,38 @@ +/* + 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.misslewars.scripts.implemented; + +import com.google.gson.JsonObject; +import de.steamwar.misslewars.scripts.RunnableScript; +import de.steamwar.misslewars.scripts.RunnableScriptEvent; +import org.bukkit.entity.Player; + +public class RemoveScript implements RunnableScript { + + public RemoveScript(JsonObject jsonObject) {} + + @Override + public boolean execute(RunnableScriptEvent runnableScriptEvent) { + if (runnableScriptEvent.entity instanceof Player) return true; + runnableScriptEvent.entity.remove(); + return true; + } + +} diff --git a/MissileWars/src/de/steamwar/misslewars/scripts/implemented/SlowMoScript.java b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/SlowMoScript.java new file mode 100644 index 00000000..54587fdf --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/SlowMoScript.java @@ -0,0 +1,44 @@ +/* + * + * 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.misslewars.scripts.implemented; + +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import de.steamwar.misslewars.scripts.RunnableScript; +import de.steamwar.misslewars.scripts.RunnableScriptEvent; +import de.steamwar.misslewars.slowmo.SlowMoRunner; + +public class SlowMoScript implements RunnableScript { + + private int slowMoTime = 0; + + public SlowMoScript(JsonObject jsonObject) { + JsonPrimitive jsonPrimitive = jsonObject.getAsJsonPrimitive("time"); + if (jsonPrimitive.isNumber()) slowMoTime = jsonPrimitive.getAsInt(); + } + + @Override + public boolean execute(RunnableScriptEvent runnableScriptEvent) { + SlowMoRunner.addSlowMoTime(slowMoTime); + return true; + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/scripts/implemented/SoundScript.java b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/SoundScript.java new file mode 100644 index 00000000..32e40bb3 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/SoundScript.java @@ -0,0 +1,51 @@ +/* + 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.misslewars.scripts.implemented; + +import com.google.gson.JsonObject; +import de.steamwar.misslewars.scripts.RunnableScript; +import de.steamwar.misslewars.scripts.RunnableScriptEvent; +import de.steamwar.misslewars.scripts.ScriptedItem; +import org.bukkit.Sound; + +import static de.steamwar.misslewars.scripts.utils.JsonUtils.getFloat; +import static de.steamwar.misslewars.scripts.utils.JsonUtils.getString; + +public class SoundScript implements RunnableScript { + + private Sound sound; + private float volume; + private float pitch; + + public SoundScript(JsonObject sound) { + getString(sound, "sound", value -> this.sound = Sound.valueOf(value)); + volume = getFloat(sound, "volume", 100); + pitch = getFloat(sound, "pitch", 1); + } + + @Override + public boolean execute(RunnableScriptEvent runnableScriptEvent) { + if (sound == null) return false; + if (runnableScriptEvent.eventType != ScriptedItem.EventType.onClick) return true; + runnableScriptEvent.getPlayer().playSound(runnableScriptEvent.getPlayer().getLocation(), sound, volume, pitch); + return true; + } + +} diff --git a/MissileWars/src/de/steamwar/misslewars/scripts/implemented/SummonScript.java b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/SummonScript.java new file mode 100644 index 00000000..a85ea3a6 --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/scripts/implemented/SummonScript.java @@ -0,0 +1,49 @@ +/* + 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.misslewars.scripts.implemented; + +import com.google.gson.JsonObject; +import de.steamwar.misslewars.scripts.RunnableScript; +import de.steamwar.misslewars.scripts.RunnableScriptEvent; +import de.steamwar.misslewars.scripts.utils.EntityUtils; +import de.steamwar.misslewars.scripts.utils.EntityUtils.ScriptShortcut; +import org.bukkit.entity.Entity; + +public class SummonScript implements RunnableScript { + + private ScriptFunction summon = null; + + public SummonScript(JsonObject summon) { + ScriptShortcut scriptShortcut = EntityUtils.getEntity(summon.getAsJsonPrimitive("entity").getAsString(), EntityUtils.EntityType.Normal); + if (scriptShortcut == null) return; + + this.summon = (runnableScriptEvent, doubles) -> { + Entity entity = runnableScriptEvent.entity.getWorld().spawn(runnableScriptEvent.getLocation(), scriptShortcut.entityClass); + scriptShortcut.consumer.accept(summon, entity, runnableScriptEvent); + return false; + }; + } + + @Override + public boolean execute(RunnableScriptEvent runnableScriptEvent) { + return defaultExecution(summon, false, b -> true, runnableScriptEvent); + } + +} diff --git a/MissileWars/src/de/steamwar/misslewars/scripts/utils/EntityUtils.java b/MissileWars/src/de/steamwar/misslewars/scripts/utils/EntityUtils.java new file mode 100644 index 00000000..823751ee --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/scripts/utils/EntityUtils.java @@ -0,0 +1,99 @@ +/* + 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.misslewars.scripts.utils; + +import com.google.gson.JsonObject; +import de.steamwar.misslewars.scripts.RunnableScriptEvent; +import org.bukkit.entity.*; + +import static de.steamwar.misslewars.scripts.utils.JsonUtils.*; + +public class EntityUtils { + + private EntityUtils() { + throw new IllegalStateException("Utility class"); + } + + public static void setEntityOptions(Entity entity, JsonObject jsonObject) { + getDouble(jsonObject, "velocity", aDouble -> entity.setVelocity(entity.getVelocity().multiply(aDouble))); + getBoolean(jsonObject, "glowing", entity::setGlowing); + getBoolean(jsonObject, "gravity", entity::setGravity); + } + + public static void setProjectileOptions(Projectile projectile, JsonObject jsonObject) { + getBoolean(jsonObject, "bounce", projectile::setBounce); + setEntityOptions(projectile, jsonObject); + } + + public static void setExplosiveOptions(Explosive explosive, JsonObject jsonObject) { + getFloat(jsonObject, "yield", explosive::setYield); + getBoolean(jsonObject, "incendiary", explosive::setIsIncendiary); + setEntityOptions(explosive, jsonObject); + } + + public static void setFireballOptions(Fireball fireball, JsonObject jsonObject) { + setProjectileOptions(fireball, jsonObject); + setExplosiveOptions(fireball, jsonObject); + } + + public static void setTNTPrimedOptions(TNTPrimed tntPrimed, JsonObject jsonObject) { + getInt(jsonObject, "fuse", tntPrimed::setFuseTicks); + setExplosiveOptions(tntPrimed, jsonObject); + } + + public enum EntityType { + Projectile, + Normal + } + + public static ScriptShortcut getEntity(String name, EntityType entityType) { + switch (name.toLowerCase()) { + case "tntprimed": + if (entityType != EntityType.Normal) return null; + return new ScriptShortcut<>(TNTPrimed.class, (jsonObject, entity, runnableScriptEvent) -> setTNTPrimedOptions(entity, jsonObject)); + + case "fireball": + return new ScriptShortcut<>(Fireball.class, (jsonObject, entity, runnableScriptEvent) -> { + setFireballOptions(entity, jsonObject); + entity.setDirection(runnableScriptEvent.getLocation().getDirection()); + }); + case "arrow": + return new ScriptShortcut<>(Arrow.class, (jsonObject, entity, runnableScriptEvent) -> setProjectileOptions(entity, jsonObject)); + } + return null; + } + + public static class ScriptShortcut { + + public Class entityClass; + public TriConsumer consumer; + + public ScriptShortcut(Class entityClass, TriConsumer consumer) { + this.entityClass = entityClass; + this.consumer = consumer; + } + + } + + public interface TriConsumer { + void accept(T t, R r, K k); + } + +} diff --git a/MissileWars/src/de/steamwar/misslewars/scripts/utils/JsonUtils.java b/MissileWars/src/de/steamwar/misslewars/scripts/utils/JsonUtils.java new file mode 100644 index 00000000..f0a703ad --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/scripts/utils/JsonUtils.java @@ -0,0 +1,51 @@ +package de.steamwar.misslewars.scripts.utils; + +import com.google.gson.JsonObject; + +import java.util.function.Consumer; +import java.util.function.DoubleConsumer; +import java.util.function.IntConsumer; + +public class JsonUtils { + + private JsonUtils() { + throw new IllegalStateException("Utility class"); + } + + public static boolean getBoolean(JsonObject jsonObject, String key, boolean defaultValue) { + return jsonObject.has(key) ? jsonObject.getAsJsonPrimitive(key).getAsBoolean() : defaultValue; + } + + public static int getInt(JsonObject jsonObject, String key, int defaultValue) { + return jsonObject.has(key) ? jsonObject.getAsJsonPrimitive(key).getAsInt() : defaultValue; + } + + public static float getFloat(JsonObject jsonObject, String key, float defaultValue) { + return jsonObject.has(key) ? jsonObject.getAsJsonPrimitive(key).getAsFloat() : defaultValue; + } + + public static String getString(JsonObject jsonObject, String key, String defaultValue) { + return jsonObject.has(key) ? jsonObject.getAsJsonPrimitive(key).getAsString() : defaultValue; + } + + public static void getBoolean(JsonObject jsonObject, String key, Consumer booleanConsumer) { + if (jsonObject.has(key)) booleanConsumer.accept(jsonObject.getAsJsonPrimitive(key).getAsBoolean()); + } + + public static void getInt(JsonObject jsonObject, String key, IntConsumer booleanConsumer) { + if (jsonObject.has(key)) booleanConsumer.accept(jsonObject.getAsJsonPrimitive(key).getAsInt()); + } + + public static void getDouble(JsonObject jsonObject, String key, DoubleConsumer booleanConsumer) { + if (jsonObject.has(key)) booleanConsumer.accept(jsonObject.getAsJsonPrimitive(key).getAsDouble()); + } + + public static void getFloat(JsonObject jsonObject, String key, Consumer booleanConsumer) { + if (jsonObject.has(key)) booleanConsumer.accept(jsonObject.getAsJsonPrimitive(key).getAsFloat()); + } + + public static void getString(JsonObject jsonObject, String key, Consumer booleanConsumer) { + if (jsonObject.has(key)) booleanConsumer.accept(jsonObject.getAsJsonPrimitive(key).getAsString()); + } + +} diff --git a/MissileWars/src/de/steamwar/misslewars/slowmo/SlowMoRunner.java b/MissileWars/src/de/steamwar/misslewars/slowmo/SlowMoRunner.java new file mode 100644 index 00000000..7a637d5c --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/slowmo/SlowMoRunner.java @@ -0,0 +1,56 @@ +/* + * + * 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.misslewars.slowmo; + +import de.steamwar.misslewars.MissileWars; +import org.bukkit.Bukkit; + +public class SlowMoRunner { + + private static long currentTime = 0; + private static long current = 0; + + public static void addSlowMoTime(int time) { + currentTime += time; + } + + public static void resetSlowMoTime() { + currentTime = 0; + } + + static { + Bukkit.getScheduler().runTaskTimer(MissileWars.getPlugin(), () -> { + if(currentTime > 0) { + current += 1; + if (current % 5 == 0) { + SlowMoUtils.unfreeze(); + current = 0; + } else { + SlowMoUtils.freeze(); + } + currentTime--; + } else { + SlowMoUtils.unfreeze(); + } + }, 0, 1); + } +} diff --git a/MissileWars/src/de/steamwar/misslewars/slowmo/SlowMoUtils.java b/MissileWars/src/de/steamwar/misslewars/slowmo/SlowMoUtils.java new file mode 100644 index 00000000..dbde1f0f --- /dev/null +++ b/MissileWars/src/de/steamwar/misslewars/slowmo/SlowMoUtils.java @@ -0,0 +1,76 @@ +/* + * + * 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.misslewars.slowmo; + +import com.comphenix.tinyprotocol.Reflection; +import org.bukkit.Bukkit; +import org.bukkit.World; + +import java.lang.reflect.Field; + +public class SlowMoUtils { + + private static final Field field; + public static final boolean freezeEnabled; + + private static final Reflection.MethodInvoker getWorldHandle = Reflection.getTypedMethod(Reflection.getClass("{obc}.CraftWorld"), "getHandle", null); + private static boolean frozen = false; + + private static final World world; + + static { + Field temp; + try { + temp = Reflection.getClass("{nms.server.level}.WorldServer").getField("freezed"); + } catch (NoSuchFieldException e) { + temp = null; + } + field = temp; + if (field != null) field.setAccessible(true); + freezeEnabled = field != null; + world = Bukkit.getWorlds().get(0); + } + + public static void freeze() { + setFreeze(world, true); + } + + public static void unfreeze() { + setFreeze(world, false); + } + + public static boolean frozen() { + return freezeEnabled && frozen; + } + + private static void setFreeze(World world, boolean state) { + if (freezeEnabled) { + if (frozen == state) return; + try { + field.set(getWorldHandle.invoke(world), state); + frozen = state; + } catch (IllegalAccessException e) { + // Ignored; + } + } + } +} diff --git a/MissileWars/src/plugin.yml b/MissileWars/src/plugin.yml new file mode 100644 index 00000000..b05dc547 --- /dev/null +++ b/MissileWars/src/plugin.yml @@ -0,0 +1,17 @@ +name: MissileWars +prefix: MW +main: de.steamwar.misslewars.MissileWars +authors: + - Jan9103 + - Lixfel + - YoyoNow +version: "1.0" +api-version: "1.13" +depend: + - WorldEdit + - SpigotCore +commands: + spectate: + invite: + accept: + decline: \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 39cbbfdd..310f80cc 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -22,6 +22,8 @@ rootProject.name = "SteamWar" include("CommandFramework") include("CommonCore") +include("MissileWars") + include("SpigotCore") include("SpigotCore:SpigotCore_8") include("SpigotCore:SpigotCore_9")