diff --git a/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/format/GameFormatter.java b/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/format/GameFormatter.java index 75d0a1a..e5f61a8 100644 --- a/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/format/GameFormatter.java +++ b/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/format/GameFormatter.java @@ -210,7 +210,10 @@ public class GameFormatter { } public void sendList(Audience audience, Collection games) { - if(games.isEmpty()) return; + if(games.isEmpty()) { + audience.sendMessage(new WarningComponent("game.none")); + return; + } audience.sendMessage( new Component( diff --git a/Commons/bungee/src/main/java/tc/oc/commons/bungee/listeners/PingListener.java b/Commons/bungee/src/main/java/tc/oc/commons/bungee/listeners/PingListener.java index 00352c4..2cb8ac2 100644 --- a/Commons/bungee/src/main/java/tc/oc/commons/bungee/listeners/PingListener.java +++ b/Commons/bungee/src/main/java/tc/oc/commons/bungee/listeners/PingListener.java @@ -31,7 +31,7 @@ import static tc.oc.commons.core.stream.Collectors.toImmutableSet; @Singleton public class PingListener implements Listener, PluginFacet { - private static final int MAX_PLAYERS = 3000; + private static final int MAX_PLAYERS = 300; private final Logger logger; private final Random random = new Random(); diff --git a/Commons/core/src/main/i18n/templates/commons/Commons.properties b/Commons/core/src/main/i18n/templates/commons/Commons.properties index 9da4c73..30f03d1 100644 --- a/Commons/core/src/main/i18n/templates/commons/Commons.properties +++ b/Commons/core/src/main/i18n/templates/commons/Commons.properties @@ -101,6 +101,7 @@ game.waitingForPlayers = Waiting for {0} more players to join {1}... game.left = Left {0} game.unknown = Unknown game '{0}' game.offline = Sorry, {0} is offline right now +game.none = There are currently no playable games game.empty = There are no {0} matches happening right now game.choose = Click on a game below, or type {0} or {1} game.numOnline = {0} players diff --git a/Commons/core/src/main/i18n/templates/lobby/LobbyErrors.properties b/Commons/core/src/main/i18n/templates/lobby/LobbyErrors.properties index 98d8baa..8713b1e 100644 --- a/Commons/core/src/main/i18n/templates/lobby/LobbyErrors.properties +++ b/Commons/core/src/main/i18n/templates/lobby/LobbyErrors.properties @@ -3,3 +3,7 @@ gizmo.gun.empty = No Droplets available to shoot raindrops.purchase.fail = You do not have enough Droplets to purchase this purchase.purchase.fail = Purchase failed + +version.too.old.gizmo = This gizmo requires at least Minecraft 1.9 + +gizmo.use.cooldown = You must wait to use this gizmo again \ No newline at end of file diff --git a/Commons/core/src/main/i18n/templates/lobby/LobbyMessages.properties b/Commons/core/src/main/i18n/templates/lobby/LobbyMessages.properties index 084432a..e69e0c9 100644 --- a/Commons/core/src/main/i18n/templates/lobby/LobbyMessages.properties +++ b/Commons/core/src/main/i18n/templates/lobby/LobbyMessages.properties @@ -57,4 +57,4 @@ trial.joinFull = join full servers trial.chooseTeam = choose their team # {0} = shop URL -trial.upgrade = Visit {0} to extend your membership. +trial.upgrade = Visit {0} to extend your membership. \ No newline at end of file diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/Lobby.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/Lobby.java index 4c0dfa6..0ed8613 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/Lobby.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/Lobby.java @@ -1,7 +1,6 @@ package tc.oc.lobby.bukkit; import javax.inject.Inject; - import org.bukkit.Bukkit; import org.bukkit.event.Listener; import org.bukkit.permissions.Permission; diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/LobbyConfig.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/LobbyConfig.java index 1cd3ece..1c01f25 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/LobbyConfig.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/LobbyConfig.java @@ -3,7 +3,6 @@ package tc.oc.lobby.bukkit; import java.util.List; import java.util.logging.Level; import javax.inject.Inject; - import org.bukkit.Location; import org.bukkit.World; import org.bukkit.configuration.Configuration; diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/LobbyManifest.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/LobbyManifest.java index f14379e..e2bf3c8 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/LobbyManifest.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/LobbyManifest.java @@ -7,6 +7,7 @@ import tc.oc.commons.core.inject.HybridManifest; import tc.oc.commons.core.plugin.PluginFacetBinder; import tc.oc.lobby.bukkit.gizmos.GizmoUtils; import tc.oc.lobby.bukkit.gizmos.gun.GunGizmo; +import tc.oc.lobby.bukkit.gizmos.halloween.ghost.GhostGizmo; import tc.oc.lobby.bukkit.listeners.PlayerListener; import tc.oc.lobby.bukkit.listeners.PortalsListener; import tc.oc.lobby.bukkit.listeners.RaindropsListener; @@ -24,6 +25,7 @@ public class LobbyManifest extends HybridManifest { requestStaticInjection(GizmoUtils.class); requestStaticInjection(GunGizmo.class); + requestStaticInjection(GhostGizmo.class); } @Provides World world(Server server) { diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/Settings.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/Settings.java index f39d8d5..dce14d1 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/Settings.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/Settings.java @@ -1,16 +1,12 @@ package tc.oc.lobby.bukkit; -import me.anxuiz.settings.*; -import me.anxuiz.settings.bukkit.PlayerSettingCallback; +import me.anxuiz.settings.Setting; +import me.anxuiz.settings.SettingBuilder; +import me.anxuiz.settings.SettingCallbackManager; +import me.anxuiz.settings.SettingRegistry; +import me.anxuiz.settings.TypeParseException; import me.anxuiz.settings.bukkit.PlayerSettings; import me.anxuiz.settings.types.EnumType; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import tc.oc.commons.bukkit.hologram.Hologram; -import tc.oc.commons.bukkit.hologram.content.HologramAnimation; -import tc.oc.commons.bukkit.util.ItemCreator; - -import javax.annotation.Nonnull; public class Settings { diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/SignUpdater.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/SignUpdater.java index 4e8beb7..dde19cb 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/SignUpdater.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/SignUpdater.java @@ -1,5 +1,7 @@ package tc.oc.lobby.bukkit; +import com.google.common.cache.LoadingCache; +import com.google.common.collect.ImmutableSet; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; @@ -16,9 +18,6 @@ import java.util.logging.Logger; import java.util.stream.Stream; import javax.annotation.Nullable; import javax.inject.Inject; - -import com.google.common.cache.LoadingCache; -import com.google.common.collect.ImmutableSet; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.TranslatableComponent; diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/Utils.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/Utils.java index 49c01bd..33b4722 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/Utils.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/Utils.java @@ -1,8 +1,13 @@ package tc.oc.lobby.bukkit; import java.util.List; - -import net.minecraft.server.*; +import net.minecraft.server.EntityPlayer; +import net.minecraft.server.Packet; +import net.minecraft.server.PacketPlayOutScoreboardDisplayObjective; +import net.minecraft.server.PacketPlayOutScoreboardScore; +import net.minecraft.server.ScoreboardObjective; +import net.minecraft.server.ScoreboardScore; +import net.minecraft.server.ScoreboardServer; import org.bukkit.ChatColor; import org.bukkit.GameMode; import org.bukkit.Material; @@ -57,6 +62,7 @@ public class Utils { player.setGravity(true); player.setPotionParticles(false); player.hideTitle(); + player.setCollidesWithEntities(false); player.getWorld().spawnParticle(Particle.CLOUD, player.getLocation(), 15, 0.5, 0.5, 0.5, 0); } diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/Gizmo.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/Gizmo.java index 6480c55..169eeaa 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/Gizmo.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/Gizmo.java @@ -1,8 +1,7 @@ package tc.oc.lobby.bukkit.gizmos; -import java.util.List; - import com.google.common.collect.Lists; +import java.util.List; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -10,7 +9,7 @@ import org.bukkit.event.Listener; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import tc.oc.lobby.bukkit.LobbyTranslations; -import tc.oc.lobby.bukkit.gizmos.halloween.HeadlessHorsemanGizmo; +import tc.oc.lobby.bukkit.gizmos.halloween.HalloweenGizmo; import tc.oc.lobby.bukkit.listeners.RaindropsListener; public abstract class Gizmo implements Listener { @@ -29,7 +28,7 @@ public abstract class Gizmo implements Listener { this.initialize(); } - + protected abstract void initialize(); public String getName(Player viewer) { @@ -61,7 +60,7 @@ public abstract class Gizmo implements Listener { } public String getCostText(Player player) { - if (this.getClass().isInstance(HeadlessHorsemanGizmo.class)) { + if (this instanceof HalloweenGizmo) { return ChatColor.YELLOW + LobbyTranslations.get().t("gizmo.specialEvent", player); } else if(this.getClass().isInstance(Gizmos.purchasingMap.get(player))) { return ChatColor.GOLD + LobbyTranslations.get().t("gizmo.purchasing", player); @@ -77,7 +76,7 @@ public abstract class Gizmo implements Listener { } public boolean ownsGizmo(Player player) { - if(cost <= 0) { + if(cost <= 0 && (!(this instanceof HalloweenGizmo))) { return true; } else { return player.hasPermission(this.getPermissionNode()); diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/GizmoUtils.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/GizmoUtils.java index c3f0b0b..bdcf325 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/GizmoUtils.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/GizmoUtils.java @@ -1,8 +1,7 @@ package tc.oc.lobby.bukkit.gizmos; -import javax.inject.Inject; - import com.google.common.collect.Lists; +import javax.inject.Inject; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -12,17 +11,17 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import tc.oc.api.bukkit.users.Users; import tc.oc.api.docs.PlayerId; -import tc.oc.lobby.bukkit.Lobby; -import tc.oc.minecraft.scheduler.SyncExecutor; import tc.oc.api.users.PurchaseGizmoRequest; import tc.oc.api.users.UserService; +import tc.oc.commons.bukkit.raindrops.PlayerRecieveRaindropsEvent; import tc.oc.commons.core.chat.Component; import tc.oc.commons.core.commands.CommandFutureCallback; import tc.oc.commons.core.formatting.StringUtils; +import tc.oc.lobby.bukkit.Lobby; import tc.oc.lobby.bukkit.LobbyTranslations; import tc.oc.lobby.bukkit.Utils; import tc.oc.lobby.bukkit.listeners.RaindropsListener; -import tc.oc.commons.bukkit.raindrops.PlayerRecieveRaindropsEvent; +import tc.oc.minecraft.scheduler.SyncExecutor; public class GizmoUtils { diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/Gizmos.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/Gizmos.java index 3ceaaa3..85e483b 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/Gizmos.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/Gizmos.java @@ -1,10 +1,9 @@ package tc.oc.lobby.bukkit.gizmos; -import java.util.List; -import java.util.Map; - import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import java.util.List; +import java.util.Map; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -20,7 +19,8 @@ import tc.oc.lobby.bukkit.LobbyTranslations; import tc.oc.lobby.bukkit.gizmos.chicken.ChickenGizmo; import tc.oc.lobby.bukkit.gizmos.empty.EmptyGizmo; import tc.oc.lobby.bukkit.gizmos.gun.GunGizmo; -import tc.oc.lobby.bukkit.gizmos.halloween.HeadlessHorsemanGizmo; +import tc.oc.lobby.bukkit.gizmos.halloween.ghost.GhostGizmo; +import tc.oc.lobby.bukkit.gizmos.halloween.horse.HeadlessHorsemanGizmo; import tc.oc.lobby.bukkit.gizmos.launcher.LauncherGizmo; import tc.oc.lobby.bukkit.gizmos.popper.PopperGizmo; import tc.oc.lobby.bukkit.gizmos.rocket.RocketGizmo; @@ -32,10 +32,10 @@ public class Gizmos implements Listener { public static GunGizmo gunGizmo = new GunGizmo("Raindrop Gun", ChatColor.AQUA.toString(), "Gift raindrops with a punch :D", Material.IRON_HOE, 7500); public static ChickenGizmo chickenGizmo = new ChickenGizmo("Chickenifier5000", ChatColor.YELLOW.toString(), "bok B'GAWK", Material.EGG, 10000); public static LauncherGizmo launcherGizmo = new LauncherGizmo("Murica", ChatColor.RED.toString(), "Show your pride!", Material.FEATHER, 17760); - //TODO: Replace cost and handle permissions - public static HeadlessHorsemanGizmo headlessHorsemanGizmo = new HeadlessHorsemanGizmo("The Headless Horseman", ChatColor.RED.toString(), "You have been taken over by the darkness...", Material.NETHER_STAR, 999999); + public static HeadlessHorsemanGizmo headlessHorsemanGizmo = new HeadlessHorsemanGizmo("The Headless Horseman", ChatColor.RED.toString(), "You have been taken over by the darkness...", Material.NETHER_STAR); + public static GhostGizmo ghostGizmo = new GhostGizmo("Ghosts", ChatColor.RED.toString(), "Surround yourself in ghosts!", Material.BONE); - public static final List gizmos = Lists.newArrayList(emptyGizmo, popperGizmo, rocketGizmo, gunGizmo, chickenGizmo, launcherGizmo, headlessHorsemanGizmo); + public static final List gizmos = Lists.newArrayList(emptyGizmo, popperGizmo, rocketGizmo, gunGizmo, chickenGizmo, launcherGizmo, headlessHorsemanGizmo, ghostGizmo); public static Map gizmoMap = Maps.newHashMap(); public static Map purchasingMap = Maps.newHashMap(); diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/chicken/ChickenGizmo.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/chicken/ChickenGizmo.java index f5ce37d..cc4db24 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/chicken/ChickenGizmo.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/chicken/ChickenGizmo.java @@ -1,12 +1,11 @@ package tc.oc.lobby.bukkit.gizmos.chicken; +import com.google.common.collect.Maps; +import com.google.inject.Injector; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; - -import com.google.common.collect.Maps; -import com.google.inject.Injector; import net.md_5.bungee.api.chat.TranslatableComponent; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -22,6 +21,7 @@ import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerQuitEvent; import tc.oc.api.bukkit.users.Users; import tc.oc.commons.bukkit.nick.IdentityProvider; +import tc.oc.commons.bukkit.raindrops.RaindropUtil; import tc.oc.commons.bukkit.util.NMSHacks; import tc.oc.commons.core.chat.Component; import tc.oc.lobby.bukkit.Lobby; @@ -29,7 +29,6 @@ import tc.oc.lobby.bukkit.LobbyTranslations; import tc.oc.lobby.bukkit.gizmos.Gizmo; import tc.oc.lobby.bukkit.gizmos.GizmoConfig; import tc.oc.lobby.bukkit.gizmos.Gizmos; -import tc.oc.commons.bukkit.raindrops.RaindropUtil; public class ChickenGizmo extends Gizmo implements Listener { diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/gun/GunGizmo.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/gun/GunGizmo.java index 93eaac7..844aa94 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/gun/GunGizmo.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/gun/GunGizmo.java @@ -1,13 +1,12 @@ package tc.oc.lobby.bukkit.gizmos.gun; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import javax.inject.Inject; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; import net.md_5.bungee.api.chat.TranslatableComponent; import org.bukkit.Bukkit; import org.bukkit.ChatColor; diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/HalloweenGizmo.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/HalloweenGizmo.java new file mode 100644 index 0000000..651bb18 --- /dev/null +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/HalloweenGizmo.java @@ -0,0 +1,26 @@ +package tc.oc.lobby.bukkit.gizmos.halloween; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import tc.oc.lobby.bukkit.gizmos.Gizmo; +import tc.oc.lobby.bukkit.gizmos.Gizmos; + +public abstract class HalloweenGizmo extends Gizmo { + + public HalloweenGizmo(String name, String prefix, String description, Material icon) { + super(name, prefix, description, icon, 0); + } + + @Override + public boolean canPurchase(Player player) { + // HACK: Players can only have one hallow gizmo + return (player.hasPermission("lobby.gizmo.buy.hallow") && !ownsAny(player)) || player.isOp(); + } + + private boolean ownsAny(Player player) { + for (Gizmo gizmo : Gizmos.gizmos) { + if (gizmo instanceof HalloweenGizmo && gizmo.ownsGizmo(player)) return true; + } + return false; + } +} diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/ghost/GhostGizmo.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/ghost/GhostGizmo.java new file mode 100644 index 0000000..35375da --- /dev/null +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/ghost/GhostGizmo.java @@ -0,0 +1,49 @@ +package tc.oc.lobby.bukkit.gizmos.halloween.ghost; + +import java.time.Duration; +import java.time.Instant; +import javax.inject.Inject; +import net.md_5.bungee.api.chat.TranslatableComponent; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerInteractEvent; +import tc.oc.commons.bukkit.chat.Audiences; +import tc.oc.commons.bukkit.util.OnlinePlayerMapAdapter; +import tc.oc.lobby.bukkit.Lobby; +import tc.oc.lobby.bukkit.gizmos.Gizmos; +import tc.oc.lobby.bukkit.gizmos.halloween.HalloweenGizmo; + +public class GhostGizmo extends HalloweenGizmo implements Listener { + private final OnlinePlayerMapAdapter coolDowns = new OnlinePlayerMapAdapter<>(Lobby.get()); + private static final Duration COOLDOWN = Duration.ofMinutes(1); + + @Inject private static Audiences audiences; + + public GhostGizmo(String name, String prefix, String description, Material icon) { + super(name, prefix, description, icon); + this.coolDowns.enable(); + } + + @Override + protected void initialize() { + Bukkit.getPluginManager().registerEvents(this, Lobby.get()); + } + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + Player player = event.getPlayer(); + + if (!(Gizmos.gizmoMap.get(player) instanceof GhostGizmo)) return; + if (player.getItemInHand().getType() != this.getIcon()) return; + if (coolDowns.get(player) == null || coolDowns.get(player).isBefore(Instant.now().minus(COOLDOWN))) { + coolDowns.put(player, Instant.now()); + new GhostTask(player).runTask(0, 1); + } else { + audiences.get(player).sendWarning(new TranslatableComponent("gizmo.use.cooldown"), true); + } + + } +} diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/ghost/GhostTask.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/ghost/GhostTask.java new file mode 100644 index 0000000..3974f95 --- /dev/null +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/ghost/GhostTask.java @@ -0,0 +1,115 @@ +package tc.oc.lobby.bukkit.gizmos.halloween.ghost; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.Skin; +import org.bukkit.Sound; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.LeatherArmorMeta; +import org.bukkit.plugin.Plugin; +import org.bukkit.util.EulerAngle; +import org.bukkit.util.Vector; +import tc.oc.commons.bukkit.item.ItemBuilder; +import tc.oc.commons.bukkit.scheduler.RepeatingRunnable; +import tc.oc.commons.bukkit.util.Vectors; +import tc.oc.lobby.bukkit.Lobby; + +public class GhostTask extends RepeatingRunnable { + + private static final Skin GHOST = new Skin("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlc" + + "y5taW5lY3JhZnQubmV0L3RleHR1cmUvZWY3YTRmOTVlNWZlOTliNDViZTYxYmIzMzg4MmMxMmE5M2IyMmQyOTdmZDE3NjVhYjIxZTc3" + + "NDhkYzZiOGNmMyJ9fX0=", null); + private static final ItemStack HEAD = new ItemBuilder().material(Material.SKULL_ITEM).durability(3).skin(null, UUID.randomUUID(), GHOST).get(); + private static final ItemStack CHEST = new ItemBuilder().material(Material.LEATHER_CHESTPLATE).get(); + + private static final int TOTAL_TICKS = 20 * 20; + private static final int NUM_GHOSTS = 3; + + private final Player player; + private final List ghosts; + + static { + LeatherArmorMeta meta = (LeatherArmorMeta) CHEST.getItemMeta(); + meta.setColor(Color.BLACK); + CHEST.setItemMeta(meta); + } + + public GhostTask(Player player) { + super(TOTAL_TICKS); + this.player = player; + this.ghosts = new ArrayList<>(); + for (int i = 0; i < NUM_GHOSTS; i++) { + // proportion as to how far the ghost should be in the circle + double prop = i / (double) NUM_GHOSTS; + + Vector v = new Vector(3, .5, 0); + Vectors.rotateAroundAxisY(v, prop * 2 * Math.PI); + + Location spawnLoc = player.getLocation().add(v); + spawnLoc.setDirection(player.getEyeLocation().subtract(spawnLoc.clone().add(0, player.getEyeHeight(), 0)).toVector()); + ghosts.add(createGhost(spawnLoc)); + } + } + + @Override + protected void repeat() { + // end condition + if (getIteration() == TOTAL_TICKS - 1) { + player.getWorld().playSound(player.getLocation(), Sound.BLOCK_SNOW_BREAK, .5f, .75f); + for (ArmorStand ghost : ghosts) { + ghost.remove(); + player.getWorld().spawnParticle(Particle.EXPLOSION_HUGE, ghost.getLocation().add(0, 1, 0), 1, 0, 0, 0, .5); + } + } + + // otherwise... + for (int i = 0; i < NUM_GHOSTS; i++) { + ArmorStand ghost = ghosts.get(i); + + // proportion as to how far the ghost should be in the circle + double prop = i / (double) NUM_GHOSTS; + + // proportion as to how far in the animation we are + double offset = getIteration() / (double) TOTAL_TICKS; + + Vector v = new Vector(3, .5, 0); + Vectors.rotateAroundAxisY(v, prop * 2 * Math.PI + offset * 10); + + // put ghost in proper location + Location nextLoc = player.getLocation().add(v); + nextLoc.setDirection(player.getEyeLocation().subtract(nextLoc.clone().add(0, player.getEyeHeight(), 0)).toVector()); + ghost.teleport(nextLoc); + + // now lets spawn particles + player.getWorld().spawnParticle(Particle.SMOKE_LARGE, ghost.getLocation().add(0, 1, 0), 3, 1, .3, 0, .1); + if (getIteration() % 4 == 0) { + player.getWorld().spawnParticle(Particle.FLAME, ghost.getLocation().add(0, 1, 0), 1, 0, .5, 0, .2); + } + } + } + + @Override + protected Plugin plugin() { + return Lobby.get(); + } + + private ArmorStand createGhost(Location l) { + ArmorStand stand = l.getWorld().spawn(l, ArmorStand.class); + stand.setVisible(false); + stand.setBasePlate(false); + stand.setHelmet(HEAD); + stand.setChestplate(CHEST); + stand.setMarker(false); + stand.setGravity(false); + stand.setHeadPose(new EulerAngle(.4, 0, 0)); + + return stand; + } +} diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/HeadlessHorse.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/horse/HeadlessHorse.java similarity index 74% rename from Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/HeadlessHorse.java rename to Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/horse/HeadlessHorse.java index 5ecf618..6f99001 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/HeadlessHorse.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/horse/HeadlessHorse.java @@ -1,13 +1,12 @@ -package tc.oc.lobby.bukkit.gizmos.halloween; +package tc.oc.lobby.bukkit.gizmos.halloween.horse; -import com.google.common.collect.ImmutableList; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.AbstractHorse; import org.bukkit.entity.Horse; -import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.HorseInventory; import org.bukkit.inventory.ItemStack; import tc.oc.commons.core.util.Optionals; @@ -27,20 +26,26 @@ public class HeadlessHorse { protected AbstractHorse spawn(Location location, Class horse) { AbstractHorse entity = viewer.getWorld().spawn(location, horse); this.horse = entity; - Optionals.cast(horse, Horse.class).ifPresent(living -> { + Optionals.cast(entity, Horse.class).ifPresent(living -> { living.setRemoveWhenFarAway(true); living.setCollidable(false); living.setCanPickupItems(false); living.setInvulnerable(true); living.setAdult(); + EntityEquipment entityEquipment = living.getEquipment(); entityEquipment.setHelmetDropChance(0); entityEquipment.setChestplateDropChance(0); entityEquipment.setLeggingsDropChance(0); entityEquipment.setBootsDropChance(0); - entity.setTamed(true); - living.getInventory().setSaddle(new ItemStack(Material.SADDLE)); - living.setPassengers(ImmutableList.of(viewer)); + + living.setDomestication(1); + living.setMaxDomestication(1); + living.setTamed(true); + living.setOwner(viewer); + living.setPassenger(viewer); + HorseInventory inventory = living.getInventory(); + inventory.setSaddle(new ItemStack(Material.SADDLE)); }); return entity; } diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/HeadlessHorseman.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/horse/HeadlessHorseman.java similarity index 97% rename from Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/HeadlessHorseman.java rename to Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/horse/HeadlessHorseman.java index 1d99f5e..60ee3e9 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/HeadlessHorseman.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/horse/HeadlessHorseman.java @@ -1,4 +1,4 @@ -package tc.oc.lobby.bukkit.gizmos.halloween; +package tc.oc.lobby.bukkit.gizmos.halloween.horse; import com.google.common.collect.ImmutableMap; import org.bukkit.Color; diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/HeadlessHorsemanGizmo.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/horse/HeadlessHorsemanGizmo.java similarity index 57% rename from Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/HeadlessHorsemanGizmo.java rename to Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/horse/HeadlessHorsemanGizmo.java index 331f0e6..6f4cdcd 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/HeadlessHorsemanGizmo.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/halloween/horse/HeadlessHorsemanGizmo.java @@ -1,4 +1,4 @@ -package tc.oc.lobby.bukkit.gizmos.halloween; +package tc.oc.lobby.bukkit.gizmos.halloween.horse; import java.util.Map; import java.util.WeakHashMap; @@ -6,21 +6,26 @@ import org.bukkit.Bukkit; import org.bukkit.Effect; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.PoseFlag; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.scheduler.BukkitRunnable; +import tc.oc.commons.bukkit.chat.WarningComponent; import tc.oc.lobby.bukkit.Lobby; -import tc.oc.lobby.bukkit.gizmos.Gizmo; import tc.oc.lobby.bukkit.gizmos.Gizmos; +import tc.oc.lobby.bukkit.gizmos.halloween.HalloweenGizmo; +import tc.oc.minecraft.protocol.MinecraftVersion; -public class HeadlessHorsemanGizmo extends Gizmo implements Listener { +public class HeadlessHorsemanGizmo extends HalloweenGizmo implements Listener { private Map mutated; private Map horseByPlayer; - public HeadlessHorsemanGizmo(String name, String prefix, String description, Material icon, int cost) { - super(name, prefix, description, icon, cost); + public HeadlessHorsemanGizmo(String name, String prefix, String description, Material icon) { + super(name, prefix, description, icon); this.mutated = new WeakHashMap<>(); this.horseByPlayer = new WeakHashMap<>(); } @@ -37,10 +42,14 @@ public class HeadlessHorsemanGizmo extends Gizmo implements Listener { final Player player = e.getPlayer(); if(mutated.get(player) == null) { - HeadlessHorseman horseman = new HeadlessHorseman(player); - mutated.put(player, horseman); - horseByPlayer.put(player, horseman.getHeadlessHorse()); - createEffect(player); + if (MinecraftVersion.atLeast(MinecraftVersion.MINECRAFT_1_9, player.getProtocolVersion())) { + HeadlessHorseman horseman = new HeadlessHorseman(player); + mutated.put(player, horseman); + horseByPlayer.put(player, horseman.getHeadlessHorse()); + createEffect(player); + } else { + player.sendMessage(new WarningComponent("version.too.old.gizmo")); + } } else { mutated.get(player).restore(); mutated.remove(player); @@ -48,6 +57,25 @@ public class HeadlessHorsemanGizmo extends Gizmo implements Listener { } } + @EventHandler + public void onDismount(PlayerMoveEvent event) { + if (event.getEntityTo().poseFlags().contains(PoseFlag.RIDING)) return; + if (!mutated.containsKey(event.getPlayer())) return; + + mutated.get(event.getPlayer()).restore(); + mutated.remove(event.getPlayer()); + horseByPlayer.remove(event.getPlayer()); + } + + @EventHandler + public void onQuit(PlayerQuitEvent event) { + if (!mutated.containsKey(event.getPlayer())) return; + + mutated.get(event.getPlayer()).restore(); + mutated.remove(event.getPlayer()); + horseByPlayer.remove(event.getPlayer()); + } + private void createEffect(Player viewer) { new BukkitRunnable() { @Override diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/launcher/LauncherGizmo.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/launcher/LauncherGizmo.java index b9a3d6b..22aa984 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/launcher/LauncherGizmo.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/launcher/LauncherGizmo.java @@ -1,6 +1,10 @@ package tc.oc.lobby.bukkit.gizmos.launcher; -import org.bukkit.*; +import org.bukkit.Bukkit; +import org.bukkit.Color; +import org.bukkit.FireworkEffect; +import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.entity.EntityType; import org.bukkit.entity.Firework; import org.bukkit.entity.Player; diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/popper/PopperGizmo.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/popper/PopperGizmo.java index 98a6e08..e2676b5 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/popper/PopperGizmo.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/popper/PopperGizmo.java @@ -1,7 +1,7 @@ package tc.oc.lobby.bukkit.gizmos.popper; +import com.google.common.collect.Maps; import java.util.Map; - import net.md_5.bungee.api.chat.TranslatableComponent; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -11,17 +11,15 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageEvent; - -import com.google.common.collect.Maps; import org.bukkit.event.player.PlayerQuitEvent; import tc.oc.api.bukkit.users.Users; +import tc.oc.commons.bukkit.raindrops.RaindropUtil; import tc.oc.commons.core.chat.Component; import tc.oc.lobby.bukkit.Lobby; import tc.oc.lobby.bukkit.LobbyTranslations; import tc.oc.lobby.bukkit.gizmos.Gizmo; import tc.oc.lobby.bukkit.gizmos.GizmoConfig; import tc.oc.lobby.bukkit.gizmos.Gizmos; -import tc.oc.commons.bukkit.raindrops.RaindropUtil; public class PopperGizmo extends Gizmo implements Listener { public Map poppedCount = Maps.newHashMap(); diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/rocket/Rocket.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/rocket/Rocket.java index 448ca63..6cf4d3b 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/rocket/Rocket.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/rocket/Rocket.java @@ -1,13 +1,11 @@ package tc.oc.lobby.bukkit.gizmos.rocket; +import com.google.common.collect.Lists; import java.util.List; - import org.bukkit.entity.Firework; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import com.google.common.collect.Lists; - public class Rocket { public Rocket(Player observer, Player victim, List fireworks) { this.observer = observer; diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/rocket/RocketGizmo.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/rocket/RocketGizmo.java index 5efe089..befc365 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/rocket/RocketGizmo.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/rocket/RocketGizmo.java @@ -2,6 +2,8 @@ package tc.oc.lobby.bukkit.gizmos.rocket; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import java.util.List; +import java.util.Map; import net.md_5.bungee.api.chat.TranslatableComponent; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -14,16 +16,13 @@ import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.util.Vector; import tc.oc.api.bukkit.users.Users; +import tc.oc.commons.bukkit.raindrops.RaindropUtil; import tc.oc.commons.core.chat.Component; import tc.oc.lobby.bukkit.Lobby; import tc.oc.lobby.bukkit.LobbyTranslations; import tc.oc.lobby.bukkit.gizmos.Gizmo; import tc.oc.lobby.bukkit.gizmos.GizmoConfig; import tc.oc.lobby.bukkit.gizmos.Gizmos; -import tc.oc.commons.bukkit.raindrops.RaindropUtil; - -import java.util.List; -import java.util.Map; public class RocketGizmo extends Gizmo implements Listener { public final List rockets = Lists.newArrayList(); diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/rocket/RocketTask.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/rocket/RocketTask.java index 3f919c7..59d6a7b 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/rocket/RocketTask.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/rocket/RocketTask.java @@ -1,10 +1,9 @@ package tc.oc.lobby.bukkit.gizmos.rocket; +import java.util.Iterator; import org.bukkit.util.Vector; import tc.oc.lobby.bukkit.gizmos.Gizmos; -import java.util.Iterator; - public class RocketTask implements Runnable{ @Override public void run() { diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/rocket/RocketUtils.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/rocket/RocketUtils.java index 13f7d31..df878b2 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/rocket/RocketUtils.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/gizmos/rocket/RocketUtils.java @@ -1,11 +1,15 @@ package tc.oc.lobby.bukkit.gizmos.rocket; +import com.google.common.collect.Lists; import java.util.List; import java.util.Random; - import net.minecraft.server.Packet; import net.minecraft.server.PacketPlayOutEntity; -import org.bukkit.*; +import org.bukkit.Color; +import org.bukkit.Effect; +import org.bukkit.FireworkEffect; +import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.entity.EntityType; import org.bukkit.entity.Firework; @@ -13,8 +17,6 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.FireworkMeta; import org.bukkit.util.Vector; - -import com.google.common.collect.Lists; import tc.oc.lobby.bukkit.gizmos.GizmoConfig; public class RocketUtils { diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/listeners/PlayerListener.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/listeners/PlayerListener.java index e80a8e4..03d2b22 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/listeners/PlayerListener.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/listeners/PlayerListener.java @@ -1,11 +1,19 @@ package tc.oc.lobby.bukkit.listeners; +import static net.md_5.bungee.api.ChatColor.AQUA; +import static net.md_5.bungee.api.ChatColor.DARK_AQUA; +import static net.md_5.bungee.api.ChatColor.DARK_PURPLE; +import static net.md_5.bungee.api.ChatColor.GOLD; +import static net.md_5.bungee.api.ChatColor.GREEN; +import static net.md_5.bungee.api.ChatColor.LIGHT_PURPLE; + +import com.google.common.eventbus.Subscribe; +import java.time.Duration; +import java.time.Instant; import java.util.Random; import java.util.logging.Level; import javax.annotation.Nullable; import javax.inject.Inject; - -import com.google.common.eventbus.Subscribe; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.TranslatableComponent; import org.bukkit.Location; @@ -24,11 +32,9 @@ import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerRespawnEvent; -import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.geometry.Cuboid; +import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.plugin.Plugin; -import java.time.Duration; -import java.time.Instant; import tc.oc.api.bukkit.users.OnlinePlayers; import tc.oc.api.docs.User; import tc.oc.api.docs.virtual.ServerDoc; @@ -38,6 +44,7 @@ import tc.oc.commons.bukkit.bossbar.BossBarFactory; import tc.oc.commons.bukkit.chat.Audiences; import tc.oc.commons.bukkit.chat.ComponentRenderContext; import tc.oc.commons.bukkit.chat.HeaderComponent; +import tc.oc.commons.bukkit.chat.Links; import tc.oc.commons.bukkit.event.ObserverKitApplyEvent; import tc.oc.commons.bukkit.event.UserLoginEvent; import tc.oc.commons.core.chat.Audience; @@ -49,9 +56,6 @@ import tc.oc.commons.core.restart.RequestRestartEvent; import tc.oc.commons.core.util.TimeUtils; import tc.oc.lobby.bukkit.LobbyConfig; import tc.oc.lobby.bukkit.Utils; -import tc.oc.commons.bukkit.chat.Links; - -import static net.md_5.bungee.api.ChatColor.*; public class PlayerListener implements PluginFacet, Listener { class SignUpdate implements ServerDoc.StatusUpdate { diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/listeners/PortalsListener.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/listeners/PortalsListener.java index febf3fa..a525304 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/listeners/PortalsListener.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/listeners/PortalsListener.java @@ -1,26 +1,32 @@ package tc.oc.lobby.bukkit.listeners; +import com.google.common.collect.Sets; import com.google.inject.Inject; +import java.time.Duration; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerMoveEvent; import tc.oc.commons.bukkit.teleport.Navigator; import tc.oc.commons.core.plugin.PluginFacet; +import tc.oc.commons.core.scheduler.Scheduler; import tc.oc.lobby.bukkit.portals.Portal; import tc.oc.lobby.bukkit.portals.PortalsConfig; -import java.util.HashSet; -import java.util.Set; - public class PortalsListener implements PluginFacet, Listener { private final Set portals = new HashSet(); + private final Set connecting = Sets.newConcurrentHashSet(); private PortalsConfig config; + private Scheduler scheduler; @Inject - PortalsListener(PortalsConfig config) { + PortalsListener(PortalsConfig config, Scheduler scheduler) { this.config = config; + this.scheduler = scheduler; } public void enable() { @@ -34,8 +40,11 @@ public class PortalsListener implements PluginFacet, Listener { for (Portal portal : portals) { if (portal.getCuboid().contains(event.getPlayer().getLocation().position())) { Navigator.Connector connector = portal.getConnector(); - if(connector.isConnectable()) { + UUID uuid = event.getPlayer().getUniqueId(); + if(connector.isConnectable() && !connecting.contains(uuid)) { connector.teleport(event.getPlayer()); + connecting.add(uuid); + scheduler.createDelayedTask(Duration.ofSeconds(5), () -> connecting.remove(uuid)); break; } } diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/listeners/RaindropsListener.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/listeners/RaindropsListener.java index 87952fb..73e0adc 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/listeners/RaindropsListener.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/listeners/RaindropsListener.java @@ -1,10 +1,9 @@ package tc.oc.lobby.bukkit.listeners; +import com.google.common.collect.Maps; import java.util.Map; import javax.inject.Inject; import javax.inject.Singleton; - -import com.google.common.collect.Maps; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; diff --git a/Lobby/src/main/java/tc/oc/lobby/bukkit/portals/PortalsConfig.java b/Lobby/src/main/java/tc/oc/lobby/bukkit/portals/PortalsConfig.java index f0efd34..63abe76 100644 --- a/Lobby/src/main/java/tc/oc/lobby/bukkit/portals/PortalsConfig.java +++ b/Lobby/src/main/java/tc/oc/lobby/bukkit/portals/PortalsConfig.java @@ -1,18 +1,17 @@ package tc.oc.lobby.bukkit.portals; -import org.bukkit.geometry.Cuboid; -import tc.oc.commons.bukkit.config.ExternalConfiguration; -import tc.oc.commons.bukkit.configuration.ConfigUtils; -import tc.oc.commons.bukkit.teleport.Navigator; -import tc.oc.commons.core.logging.Loggers; - -import javax.inject.Inject; -import javax.inject.Singleton; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; +import javax.inject.Inject; +import javax.inject.Singleton; +import org.bukkit.geometry.Cuboid; +import tc.oc.commons.bukkit.config.ExternalConfiguration; +import tc.oc.commons.bukkit.configuration.ConfigUtils; +import tc.oc.commons.bukkit.teleport.Navigator; +import tc.oc.commons.core.logging.Loggers; @Singleton public class PortalsConfig extends ExternalConfiguration { diff --git a/PGM/src/main/java/tc/oc/pgm/commands/PollCommands.java b/PGM/src/main/java/tc/oc/pgm/commands/PollCommands.java index 9fa2f47..f6266c2 100644 --- a/PGM/src/main/java/tc/oc/pgm/commands/PollCommands.java +++ b/PGM/src/main/java/tc/oc/pgm/commands/PollCommands.java @@ -15,6 +15,8 @@ import tc.oc.commons.bukkit.tokens.TokenUtil; import tc.oc.commons.core.commands.Commands; import tc.oc.commons.core.formatting.StringUtils; import tc.oc.commons.core.restart.RestartManager; +import tc.oc.parse.ParseException; +import tc.oc.parse.primitive.BooleanParser; import tc.oc.pgm.Config; import tc.oc.pgm.PGM; import tc.oc.pgm.map.PGMMap; @@ -37,8 +39,13 @@ import static tc.oc.commons.bukkit.commands.CommandUtils.newCommandException; public class PollCommands implements Commands { + private static final String VOTE_FOR = ChatColor.GREEN + "in favor of"; + private static final String VOTE_AGAINST = ChatColor.RED + "against"; + @Inject private static RestartManager restartManager; + @Inject + private static BooleanParser booleanParser; @Command( aliases = {"poll"}, @@ -62,15 +69,14 @@ public class PollCommands implements Commands { Player voter = tc.oc.commons.bukkit.commands.CommandUtils.senderToPlayer(sender); Poll currentPoll = PGM.getPollManager().getPoll(); if(currentPoll != null) { - if(args.getString(0).equalsIgnoreCase("yes")) { - currentPoll.voteFor(voter.getName()); - sender.sendMessage(ChatColor.GREEN + "You have voted for the current poll."); - } else if (args.getString(0).equalsIgnoreCase("no")) { - currentPoll.voteAgainst(voter.getName()); - sender.sendMessage(ChatColor.RED + "You have voted against the current poll."); - } else { - throw new CommandException("Accepted values: yes|no"); + boolean vote; + try { + vote = booleanParser.parse(args.getString(0)); + } catch (ParseException e) { + throw new CommandException("Please vote yes or no!"); } + currentPoll.vote(vote, voter.getName()); + sender.sendMessage(ChatColor.AQUA + "You voted " + (vote ? VOTE_FOR : VOTE_AGAINST) + ChatColor.AQUA + " the current poll."); } else { throw new CommandException("There is currently no poll running."); } @@ -226,7 +232,6 @@ public class PollCommands implements Commands { } pollManager.startPoll(poll); Bukkit.getServer().broadcastMessage(Poll.boldAqua + poll.getInitiator() + Poll.normalize + " has started a poll " + poll.getDescriptionMessage()); - Bukkit.broadcastMessage(Poll.tutorialMessage()); } } } diff --git a/PGM/src/main/java/tc/oc/pgm/damage/HitboxPlayerFacet.java b/PGM/src/main/java/tc/oc/pgm/damage/HitboxPlayerFacet.java index 4dea68f..3a56f14 100644 --- a/PGM/src/main/java/tc/oc/pgm/damage/HitboxPlayerFacet.java +++ b/PGM/src/main/java/tc/oc/pgm/damage/HitboxPlayerFacet.java @@ -78,7 +78,7 @@ public class HitboxPlayerFacet implements MatchPlayerFacet { final Location location = player.getLocation(); final double radius = width / 2; return Cuboid.between(location.position().minus(radius, 0, radius), - location.position().plus(radius, PLAYER_HEIGHT, radius)); + location.position().plus(radius, PLAYER_HEIGHT, radius)); } else { return player.getBoundingBox(); } @@ -151,9 +151,9 @@ public class HitboxPlayerFacet implements MatchPlayerFacet { private boolean isAttacker(Player attacker) { final MatchPlayer mp = match.getPlayer(attacker); return mp != null && - mp.canInteract() && - (mapInfo.friendlyFire || - !mp.getParty().equals(matchPlayer.getParty())); + mp.canInteract() && + (mapInfo.friendlyFire || + !mp.getParty().equals(matchPlayer.getParty())); } private void updateFakeLocations(Location c) { diff --git a/PGM/src/main/java/tc/oc/pgm/doublejump/DoubleJumpMatchModule.java b/PGM/src/main/java/tc/oc/pgm/doublejump/DoubleJumpMatchModule.java index eef48c8..c523f4b 100644 --- a/PGM/src/main/java/tc/oc/pgm/doublejump/DoubleJumpMatchModule.java +++ b/PGM/src/main/java/tc/oc/pgm/doublejump/DoubleJumpMatchModule.java @@ -113,7 +113,9 @@ public class DoubleJumpMatchModule extends MatchModule implements Listener { impulse.setY(0.75 + Math.abs(impulse.getY()) * 0.5); impulse.multiply(jumper.kit.power / 3f); - event.getPlayer().applyImpulse(impulse, true); + // HACK: Shiny broke the impulse API + // event.getPlayer().applyImpulse(impulse, true); + event.getPlayer().setVelocity(player.getVelocity().plus(impulse)); player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ZOMBIE_INFECT, 0.5f, 1.8f); } diff --git a/PGM/src/main/java/tc/oc/pgm/polls/Poll.java b/PGM/src/main/java/tc/oc/pgm/polls/Poll.java index 5c827cb..c3d4dbc 100644 --- a/PGM/src/main/java/tc/oc/pgm/polls/Poll.java +++ b/PGM/src/main/java/tc/oc/pgm/polls/Poll.java @@ -1,11 +1,16 @@ package tc.oc.pgm.polls; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.ChatColor; +import org.bukkit.Server; +import tc.oc.commons.core.chat.Components; + import java.util.HashMap; import java.util.Map; -import org.bukkit.ChatColor; -import org.bukkit.Server; - public abstract class Poll implements Runnable { protected final Map votes = new HashMap(); protected final long startTime = System.currentTimeMillis(); @@ -22,7 +27,7 @@ public abstract class Poll implements Runnable { this.pollManager = pollManager; this.server = server; this.initiator = initiator; - this.voteFor(initiator); + this.vote(true, initiator); timeLeftSeconds = 60; } @@ -83,20 +88,30 @@ public abstract class Poll implements Runnable { return normalize + "Yes: " + boldAqua + this.getVotesFor() + " " + normalize + "No: " + boldAqua + this.getVotesAgainst(); } - public static String tutorialMessage() { - return normalize + "Use " + boldAqua + "/vote [yes|no]" + normalize + " to vote"; + public static BaseComponent tutorialMessage() { + BaseComponent yes = Components.clickEvent(new TextComponent("YES"), ClickEvent.Action.RUN_COMMAND, "/vote yes"); + yes = Components.hoverEvent(yes, HoverEvent.Action.SHOW_TEXT, new TextComponent("Vote in favor of the poll.")); + yes.setColor(net.md_5.bungee.api.ChatColor.GREEN); + + BaseComponent no = Components.clickEvent(new TextComponent("NO"), ClickEvent.Action.RUN_COMMAND, "/vote no"); + no = Components.hoverEvent(no, HoverEvent.Action.SHOW_TEXT, new TextComponent("Vote against the poll.")); + no.setColor(net.md_5.bungee.api.ChatColor.RED); + + return new TextComponent( + Components.color(new TextComponent("Click "), net.md_5.bungee.api.ChatColor.DARK_AQUA), + yes, + Components.color(new TextComponent(" or "), net.md_5.bungee.api.ChatColor.DARK_AQUA), + no, + Components.color(new TextComponent(" to vote!"), net.md_5.bungee.api.ChatColor.DARK_AQUA) + ); } public boolean hasVoted(String playerName) { return this.votes.containsKey(playerName); } - public void voteFor(String playerName) { - this.votes.put(playerName, true); - } - - public void voteAgainst(String playerName) { - this.votes.put(playerName, false); + public void vote(boolean yes, String playerName) { + this.votes.put(playerName, yes); } @Override @@ -106,6 +121,7 @@ public abstract class Poll implements Runnable { this.pollManager.endPoll(PollEndReason.Completed); } else if(timeLeftSeconds % 15 == 0 || (timeLeftSeconds < 15 && timeLeftSeconds % 5 == 0)) { this.server.broadcastMessage(this.getStatusMessage()); + this.server.broadcast(tutorialMessage()); } this.decrementTimeLeft(); } diff --git a/PGM/src/main/java/tc/oc/pgm/tokens/gui/MainTokenMenu.java b/PGM/src/main/java/tc/oc/pgm/tokens/gui/MainTokenMenu.java index 7678113..665693e 100644 --- a/PGM/src/main/java/tc/oc/pgm/tokens/gui/MainTokenMenu.java +++ b/PGM/src/main/java/tc/oc/pgm/tokens/gui/MainTokenMenu.java @@ -1,6 +1,7 @@ package tc.oc.pgm.tokens.gui; import org.bukkit.ChatColor; +import tc.oc.commons.bukkit.chat.WarningComponent; import tc.oc.commons.bukkit.gui.buttons.Button; import tc.oc.commons.bukkit.gui.interfaces.ChestInterface; import tc.oc.commons.bukkit.tokens.TokenUtil; @@ -8,6 +9,7 @@ import tc.oc.commons.bukkit.util.Constants; import tc.oc.commons.bukkit.util.ItemCreator; import org.bukkit.Material; import org.bukkit.entity.Player; +import tc.oc.pgm.Config; import tc.oc.pgm.menu.gui.MainMenuInterface; import java.util.ArrayList; @@ -51,7 +53,11 @@ public class MainTokenMenu extends ChestInterface { , 15) { @Override public void function(Player player) { - player.openInventory(new MutationTokenInterface(player).getInventory()); + if (Config.Poll.enabled()) { + player.openInventory(new MutationTokenInterface(player).getInventory()); + } else { + player.sendMessage(new WarningComponent("poll.disabled")); + } } }); diff --git a/Util/bukkit/src/main/java/tc/oc/commons/bukkit/scheduler/RepeatingRunnable.java b/Util/bukkit/src/main/java/tc/oc/commons/bukkit/scheduler/RepeatingRunnable.java new file mode 100644 index 0000000..4e02988 --- /dev/null +++ b/Util/bukkit/src/main/java/tc/oc/commons/bukkit/scheduler/RepeatingRunnable.java @@ -0,0 +1,94 @@ +package tc.oc.commons.bukkit.scheduler; + +import java.util.function.Predicate; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitTask; + +public abstract class RepeatingRunnable implements Runnable { + + private final Predicate condition; + private int taskId = -1; + private int iteration = 0; + + public RepeatingRunnable() { + this(dummy -> true); + } + + public RepeatingRunnable(Predicate condition) { + this.condition = condition; + } + + public RepeatingRunnable(final int repeat) { + this(iteration -> iteration < repeat); + } + + public final void run() { + try { + if (condition.test(iteration)) { + repeat(); + } else { + cancel(); + } + } catch (Exception e) { + e.printStackTrace(); + } + + iteration++; + } + + protected abstract void repeat(); + + protected abstract Plugin plugin(); + + public synchronized void cancel() throws IllegalStateException { + Bukkit.getScheduler().cancelTask(this.getTaskId()); + } + + public synchronized int getTaskId() throws IllegalStateException { + int id = this.taskId; + if (id == -1) { + throw new IllegalStateException("Not scheduled yet"); + } else { + return id; + } + } + + public synchronized BukkitTask runTask(long delay, long period) throws IllegalArgumentException, + IllegalStateException { + this.checkState(); + return this.setupId(Bukkit.getScheduler().runTaskTimer(plugin(), this, delay, period)); + } + + private void checkState() { + if (this.taskId != -1) { + throw new IllegalStateException("Already scheduled as " + this.taskId); + } + } + + private BukkitTask setupId(BukkitTask task) { + this.taskId = task.getTaskId(); + return task; + } + + public synchronized BukkitTask runTaskAsync(long delay, long period) throws IllegalArgumentException, + IllegalStateException { + this.checkState(); + return this.setupId(Bukkit.getScheduler().runTaskTimerAsynchronously(plugin(), this, delay, + period)); + } + + public int getIteration() { + return iteration; + } + + @Override + public int hashCode() { + return getTaskId(); + } + + @Override + public String toString() { + return Integer.toString(getTaskId()); + } +} diff --git a/Util/bukkit/src/main/java/tc/oc/commons/bukkit/util/Vectors.java b/Util/bukkit/src/main/java/tc/oc/commons/bukkit/util/Vectors.java index 2bdb246..22ead6f 100644 --- a/Util/bukkit/src/main/java/tc/oc/commons/bukkit/util/Vectors.java +++ b/Util/bukkit/src/main/java/tc/oc/commons/bukkit/util/Vectors.java @@ -45,4 +45,89 @@ public class Vectors { Numbers.parse(components[1], Double.class, true), Numbers.parse(components[2], Double.class, true)); } + + public static final Vector rotateAroundAxisX(Vector v, double rad) { + double y, z, cos, sin; + cos = Math.cos(rad); + sin = Math.sin(rad); + y = v.getY() * cos - v.getZ() * sin; + z = v.getY() * sin + v.getZ() * cos; + return v.setY(y).setZ(z); + } + + public static final Vector rotateAroundAxisY(Vector v, double rad) { + double x, z, cos, sin; + cos = Math.cos(rad); + sin = Math.sin(rad); + x = v.getX() * cos + v.getZ() * sin; + z = v.getX() * -sin + v.getZ() * cos; + return v.setX(x).setZ(z); + } + + public static final Vector rotateAroundAxisZ(Vector v, double rad) { + double x, y, cos, sin; + cos = Math.cos(rad); + sin = Math.sin(rad); + x = v.getX() * cos - v.getY() * sin; + y = v.getX() * sin + v.getY() * cos; + return v.setX(x).setY(y); + } + + public static final Vector rotateVector(Vector v, double radX, double radY, double radZ) { + rotateAroundAxisX(v, radX); + rotateAroundAxisY(v, radY); + rotateAroundAxisZ(v, radZ); + return v; + } + + /** + * Rotate a vector about a location using that location's direction + * + * @param v + * @param location + * @return + */ + public static final Vector rotateVector(Vector v, Location location) { + double yaw = Math.toRadians(-1 * (location.getYaw() + 90)); + double pitch = Math.toRadians(-location.getPitch()); + return rotateVector(v, pitch, yaw); + } + + /** + * This handles non-unit vectors, with yaw and pitch instead of X,Y,Z angles. + * + * Thanks to SexyToad! + * + * @param v + * @param pitchRadians + * @param yawRadians + * @return + */ + public static final Vector rotateVector(Vector v, double pitchRadians, double yawRadians) { + double cosYaw = Math.cos(yawRadians); + double cosPitch = Math.cos(pitchRadians); + double sinYaw = Math.sin(yawRadians); + double sinPitch = Math.sin(pitchRadians); + + double initialX, initialY, initialZ; + double x, y, z; + + // Z_Axis rotation (Pitch) + initialX = v.getX(); + initialY = v.getY(); + x = initialX * cosPitch - initialY * sinPitch; + y = initialX * sinPitch + initialY * cosPitch; + + // Y_Axis rotation (Yaw) + initialZ = v.getZ(); + initialX = x; + z = initialZ * cosYaw - initialX * sinYaw; + x = initialZ * sinYaw + initialX * cosYaw; + + return v.setX(x).setY(y).setZ(z); + } + + public static final double angleToXAxis(Vector vector) { + return Math.atan2(vector.getX(), vector.getY()); + } } diff --git a/Util/core/src/main/java/tc/oc/commons/core/util/Holidays.java b/Util/core/src/main/java/tc/oc/commons/core/util/Holidays.java index 32315a6..9907a1d 100644 --- a/Util/core/src/main/java/tc/oc/commons/core/util/Holidays.java +++ b/Util/core/src/main/java/tc/oc/commons/core/util/Holidays.java @@ -7,6 +7,8 @@ import java.util.Set; import com.google.common.collect.Sets; import tc.oc.commons.core.stream.Collectors; +import javax.annotation.Nullable; + public interface Holidays { ZoneOffset ZONE = ZoneOffset.UTC; @@ -15,13 +17,13 @@ public interface Holidays { public final String key; public final MonthDay start; - public final MonthDay end; + @Nullable public final MonthDay end; Holiday(String key, MonthDay date) { - this(key, date, date); + this(key, date, null); } - Holiday(String key, MonthDay start, MonthDay end) { + Holiday(String key, MonthDay start, @Nullable MonthDay end) { this.key = key; this.start = start; this.end = end; @@ -29,8 +31,10 @@ public interface Holidays { public boolean isNow() { final MonthDay now = MonthDay.now(ZONE); - return !(start.isBefore(end) ? now.isBefore(start) || now.isAfter(end) - : now.isBefore(start) && now.isAfter(end)); + if (end != null) { + return !(now.isBefore(start) || now.isAfter(end)); + } else + return start.equals(now); } }