Add LobbySystem2.0 (LobbySystem_2) module

This commit is contained in:
2024-08-05 08:57:51 +02:00
parent 5fe3d22031
commit a760366d30
110 changed files with 156908 additions and 0 deletions
+65
View File
@@ -0,0 +1,65 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
plugins {
id("java")
id("base")
id("com.github.johnrengelman.shadow")
}
group = "de.steamwar"
version = ""
tasks.compileJava {
options.encoding = "UTF-8"
}
tasks.build {
finalizedBy(tasks.shadowJar)
}
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:worldedit:1.15")
compileOnly("org.spigotmc:spigot-api:1.20-R0.1-SNAPSHOT")
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,72 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby;
import de.steamwar.lobby.display.Hologram;
import de.steamwar.lobby.jumpandrun.JumpAndRun;
import de.steamwar.lobby.portal.Portal;
import org.bukkit.Location;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.serialization.ConfigurationSerialization;
import org.bukkit.util.Vector;
import java.util.ArrayList;
import java.util.List;
public class Config {
static {
ConfigurationSerialization.registerClass(Portal.class);
ConfigurationSerialization.registerClass(Hologram.class);
}
private final FileConfiguration yml;
private Location waitingHallSpawn;
public Config(FileConfiguration yml) {
this.yml = yml;
yml.getList("portals", Portal.getPortals());
yml.getList("holograms", Hologram.getHolograms());
JumpAndRun.actualPoints = (List<Vector>) yml.getList("jumpPoints", new ArrayList<>());
JumpAndRun.points.addAll(JumpAndRun.actualPoints);
// Remove 2 Blocks in Tree
JumpAndRun.points.remove(141);
JumpAndRun.points.remove(140);
waitingHallSpawn = yml.getLocation("waitingHallSpawn");
}
public Location getWaitingHallSpawn() {
return waitingHallSpawn;
}
public void setWaitingHallSpawn(Location waitingHallSpawn) {
this.waitingHallSpawn = waitingHallSpawn;
save();
}
public void save() {
yml.set("portals", Portal.getPortals());
yml.set("holograms", Hologram.getHolograms());
yml.set("waitingHallSpawn", waitingHallSpawn);
yml.set("jumpPoints", JumpAndRun.actualPoints);
LobbySystem.getPlugin().saveConfig();
}
}
@@ -0,0 +1,119 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby;
import com.google.common.io.ByteArrayDataInput;
import de.steamwar.lobby.portal.FightserverPortal;
import de.steamwar.network.packets.common.FightInfoPacket;
import org.bukkit.Bukkit;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.function.Consumer;
public class Fightserver {
private static final Map<String, Fightserver> servers = new HashMap<>();
public static void init() {
Bukkit.getScheduler().runTaskTimer(LobbySystem.getPlugin(), Fightserver::removeStopped, 20, 20);
}
public static void newFightInfo(FightInfoPacket in) {
Fightserver server = servers.get(in.getServerName());
if (server == null) {
new Fightserver(in);
} else {
server.update(in);
}
}
private static void removeStopped() {
Instant timeout = Instant.now().minus(5, ChronoUnit.SECONDS);
Iterator<Map.Entry<String, Fightserver>> it = servers.entrySet().iterator();
while(it.hasNext()) {
Map.Entry<String, Fightserver> server = it.next();
if(timeout.isAfter(server.getValue().lastUpdate)) {
server.getValue().remove();
it.remove();
}
}
}
private final List<FightserverPortal> portals = new ArrayList<>();
private FightInfoPacket fightInfo;
private Instant lastUpdate;
private Fightserver(FightInfoPacket fightInfo) {
this.fightInfo = fightInfo;
update(fightInfo);
setupPortal(getGameMode().toLowerCase());
setupPortal("all");
servers.put(getServerName(), this);
}
private void setupPortal(String gameMode) {
FightserverPortal portal = FightserverPortal.findFree(gameMode);
if(portal == null)
return;
portals.add(portal);
portal.setServer(this);
}
public String getGameMode() {
return fightInfo.getGameMode();
}
public String getServerName() {
return fightInfo.getServerName();
}
public FightInfoPacket current() {
return fightInfo;
}
private void update(FightInfoPacket fightInfo) {
FightInfoPacket old = this.fightInfo;
this.fightInfo = fightInfo;
lastUpdate = Instant.now();
update(old.getBluePlayers(), fightInfo.getBluePlayers(), FightserverPortal::updateBluePlayers);
update(old.getRedPlayers(), fightInfo.getRedPlayers(), FightserverPortal::updateRedPlayers);
update(old.getCountdown(), fightInfo.getCountdown(), FightserverPortal::updateText);
update(old.getFightState(), fightInfo.getFightState(), FightserverPortal::updateText);
}
private <T> void update(T old, T current, Consumer<FightserverPortal> observer) {
if(!old.equals(current))
portals.forEach(observer);
}
private void remove() {
portals.forEach(portal -> portal.setServer(null));
portals.clear();
}
}
@@ -0,0 +1,48 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby;
import de.steamwar.lobby.jumpandrun.JumpAndRun;
import de.steamwar.network.packets.PacketHandler;
import de.steamwar.network.packets.common.FightInfoPacket;
import de.steamwar.network.packets.server.StartingServerPacket;
import de.steamwar.sql.SteamwarUser;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent;
import java.util.Objects;
public class LobbyPacketHandler extends PacketHandler {
@Handler
public void handleFightserver(FightInfoPacket packet) {
Fightserver.newFightInfo(packet);
}
@Handler
public void serverStarting(StartingServerPacket packet) {
Player player = Objects.requireNonNull(Bukkit.getPlayer(SteamwarUser.get(packet.getUser()).getUUID()));
player.teleport(LobbySystem.config().getWaitingHallSpawn(), PlayerTeleportEvent.TeleportCause.PLUGIN);
if (JumpAndRun.isPlayerInJumpAndRun(player)) {
JumpAndRun.reset(player);
}
}
}
@@ -0,0 +1,108 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby;
import de.steamwar.entity.REntityServer;
import de.steamwar.lobby.command.FlyCommand;
import de.steamwar.lobby.command.HologramCommand;
import de.steamwar.lobby.command.ModifyCommand;
import de.steamwar.lobby.command.PortalCommand;
import de.steamwar.lobby.jumpandrun.JumpAndRun;
import de.steamwar.lobby.jumpandrun.JumpAndRunCommand;
import de.steamwar.lobby.listener.*;
import de.steamwar.lobby.map.CustomMap;
import de.steamwar.lobby.particle.ParticleListener;
import de.steamwar.lobby.special.advent.AdventsCalendar;
import de.steamwar.lobby.team.TeamPlayer;
import de.steamwar.message.Message;
import org.bukkit.plugin.java.JavaPlugin;
public class LobbySystem extends JavaPlugin {
private static Message message;
private static LobbySystem plugin;
private static Config config;
private static REntityServer entityServer;
private static REntityServer debugEntityServer;
@Override
public void onLoad() {
plugin = this;
}
@Override
public void onEnable() {
message = new Message("de.steamwar.lobby.LobbySystem", getClassLoader());
entityServer = new REntityServer();
debugEntityServer = new REntityServer();
CustomMap.init();
Fightserver.init();
new Portals();
new PortalCommand();
new HologramCommand();
new FlyCommand();
new ModifyCommand();
new JumpAndRun();
new JumpAndRunCommand();
config = new Config(getConfig());
new PlayerSpawn();
new DoubleJumpListener();
new ParticleListener();
new InventoryInteraction();
new WorldInteraction();
new PlayerSeatListener();
new MapsRotateListener();
new TeleporterListener();
new TeamPlayer();
// EggHunt.init();
AdventsCalendar.init();
new AlphaWall(l -> l.getX() > 999, AlphaWall.REFLECT_X);
new AlphaWall(l -> l.getX() < 2977, AlphaWall.REFLECT_X);
new AlphaWall(l -> l.getZ() > 892, AlphaWall.REFLECT_Z);
new AlphaWall(l -> l.getZ() < 1794, AlphaWall.REFLECT_Z);
new LobbyPacketHandler().register();
}
@Override
public void onDisable() {
}
public static LobbySystem getPlugin() {
return plugin;
}
public static Config config() {
return config;
}
public static Message getMessage() {
return message;
}
public static REntityServer getEntityServer(boolean debug) {
return debug ? debugEntityServer : entityServer;
}
}
@@ -0,0 +1,275 @@
PREFIX = §eLobby§8System§8»
TIME = HH:mm:ss
DATE=........
COMMAND_HELP_HEAD=§7---=== (§e{0}§7) ===---
# ServerTeamNPC's
NPC_CHAT_1 = §fHello, I''m {0} and I''m a(n) {1}.
NPC_CHAT_2 = §fWelcome on §eSteam§8War§f, have fun.
# Portal Command
PORTAL_COMMAND_LIST_HELP = §8/§7portal §elist §8- §7Lists all portals
PORTAL_COMMAND_ADD_HELP = §8/§7portal §ecreate §8[§7PortalType§8] §8[§7PortalName§8] §8- §7Adds a portal
PORTAL_COMMAND_REMOVE_HELP = §8/§7portal §eremove §8[§7PortalName§8] §8- §7Removes a portal
PORTAL_COMMAND_LIST_SHORT_INFO = §e{0} §8- §7{1} §7Pos1§8(§7{2}§8) §7Pos2§8(§7{3}§8)
PORTAL_NO_WORLDEDIT_SELECTION = §cNo WorldEdit selection
# Particle
PARTICLE_INVENTORY = §0Particle
PARTICLE_DESELECT = §8No particle
PARTICLE_SHOW_HAS_ALL = §8You have all particles
PARTICLE_SHOW_ALL = §aShow all
PARTICLE_SHOW_UNLOCKED = §cShow unlocked
PARTICLE_UNLOCKED_BY = §eUnlocked by
PARTICLE_UNLOCKED_BY_TEAM = §fJoin a team
PARTICLE_UNLOCKED_BY_SPECIFIC_TEAM = §fTeam {0}
PARTICLE_UNLOCKED_BY_SPECIFIC_TEAM_EASTER = §fTeam {0} (Easter Egg Hunt)
PARTICLE_UNLOCKED_BY_SPECIFIC_USER = §fUser {0}
PARTICLE_UNLOCKED_BY_SPECIFIC_USER_EASTER = §fUser {0} (Easter Egg Hunt)
PARTICLE_UNLOCKED_BY_EVENT = §fEvent participation
PARTICLE_UNLOCKED_BY_SERVER_TEAM = §fServer Team
PARTICLE_UNLOCKED_BY_EVENT_PLACEMENT = §f{0} 1., 2. or 3. Place
PARTICLE_UNLOCKED_BY_EVENT_PARTICIPATION = §f{0}
PARTICLE_UNLOCKED_BY_EASTER_EGG_HUNT_HALF = §fFind 45 Easter Eggs
PARTICLE_UNLOCKED_BY_EASTER_EGG_HUNT_DIFFICULTY = §fFind all Easter Eggs with difficulty {0}
PARTICLE_ATTRIBUTE = §eAttributes§7:
PARTICLE_ATTRIBUTE_CIRCLE = §8-§f Ring
PARTICLE_ATTRIBUTE_BI_CIRCLE = §8-§f Double ring
PARTICLE_ATTRIBUTE_CLOUD = §8-§f Cloud
PARTICLE_ATTRIBUTE_TICK = §8-§f Always active
PARTICLE_ATTRIBUTE_NON_FLOOR = §8-§f In air
PARTICLE_ATTRIBUTE_FLOOR = §8-§f On ground
PARTICLE_ATTRIBUTE_NON_FLYING = §8-§f Not flying
PARTICLE_ATTRIBUTE_FLYING = §8-§f Flying
PARTICLE_ATTRIBUTE_WING = §8-§f Wings
PARTICLE_ATTRIBUTE_SNEAKING = §8-§f Sneaking
PARTICLE_ATTRIBUTE_NON_MOVING = §8-§f Not moving
PARTICLE_ATTRIBUTE_SEPARATOR = §f
PARTICLE_SELECT = §eClick to select
PARTICLE_LOCKED = §c§lLocked
PARTICLE_DEACTIVATED = §cThere are too many players online, particles are deactivated
PARTICLE_SNEEZE = §aSneeze
PARTICLE_SMOKE = §7Smoke
PARTICLE_FIRE = §cFire
PARTICLE_WATER = §bWater
PARTICLE_HEART = §cHearts
PARTICLE_NOTES = §eNotes
PARTICLE_NAUTILUS = §aNautilus
PARTICLE_SNOWBALL = §fSnowball
PARTICLE_EFFECT = §5Effect
PARTICLE_CAMPFIRE = §7Smoke
PARTICLE_MAGIC = §5Magic
PARTICLE_ANGRY = §4Angry
PARTICLE_SLIME = §aSlime
PARTICLE_MOB = §7Mob
PARTICLE_SQUID = §8Squid
PARTICLE_BUBBLE = §aBubbles
PARTICLE_HONEY = §6Honey
PARTICLE_NECTAR = §6Nectar
PARTICLE_FIREWORK = §7Firework
PARTICLE_DRAGON_BREATH = §5Dragon breath
PARTICLE_DAMAGE = §5Damage
PARTICLE_DOLPHIN = §dDolphin
PARTICLE_WITCH = §5Witch
PARTICLE_ENCHANTING = §eEnchantment
PARTICLE_HAPPY = §2Joy
PARTICLE_FLAME = §7Flames
PARTICLE_END_ROD = §fEnd Rod
PARTICLE_CLOUD = §7Cloud
PARTICLE_TOTEM = §aTotem
PARTICLE_TOWN = §5Town
PARTICLE_ENCHANTING_CIRCLE = §fEnchanted
PARTICLE_WATER_FIRE = §bWater§7/§cFire
PARTICLE_MAGIC_ENCHANTING = §5Magic/Enchantment
PARTICLE_WINGS_EVIL = §5Purple wings
PARTICLE_PLAYER_HAYLIM_AURA = §fHaylim\'s Aura
PARTICLE_PLAYER_RONGAMER99091_AURA = §7Smoke Granade
PARTICLE_PLAYER_PLOMPA = §9ECAL
PARTICLE_TEAM_PULSE_AURA_1 = §fPulse Aura §cFlame
PARTICLE_TEAM_PULSE_AURA_2 = §fPulse Aura §7End Rod
PARTICLE_TEAM_PULSE_AURA_3 = §fPulse Aura §fEnchanted
PARTICLE_TEAM_PULSE_LOGO = §fPulse Logo
PARTICLE_TEAM_PULSE_HEART_BEAT = §cHeart Beat
PARTICLE_RAINCLOUD_NORMAL = §fRaincloud
PARTICLE_RAINCLOUD_RED = §fLava cloud
PARTICLE_RAINCLOUD_YELLOW = §fNectar cloud
PARTICLE_RAINCLOUD_ORANGE = §fHoney cloud
PARTICLE_RAINCLOUD_GREEN = §fSpore Blossom cloud
PARTICLE_RAINCLOUD_PURPLE = §fObsidian Tears cloud
PARTICLE_RAINCLOUD_NAUTILUS = §fNautilus cloud
PARTICLE_RAINCLOUD_ENCHANTMENT = §fEnchantment cloud
PARTICLE_RAINCLOUD_SLIME = §fSlime cloud
PARTICLE_RAINCLOUD_HAIL = §fHail cloud
PARTICLE_RAINCLOUD_SNOW = §fSnow cloud
PARTICLE_RAINCLOUD_TOTEM = §fTotem cloud
PARTICLE_EVENT_ENCHANTING = §cEnchantment
PARTICLE_EVENT_CLOUD = §fClouds
PARTICLE_EVENT_SMOKE = §7Smoke
PARTICLE_EVENT_WATER = §bWater
PARTICLE_EVENT_WINGS = §fWings
PARTICLE_EVENT_RAIN_CLOUD = §fRandom Raincloud
PARTICLE_EVENT_WGS = §fWGS
PARTICLE_EVENT_WARGEARCLASH = §fClash
PARTICLE_EGG_HUNT_EASY = §aGreenery
PARTICLE_EGG_HUNT_MEDIUM = §eHide and Seek
PARTICLE_EGG_HUNT_HARD = §cOrbit
PARTICLE_EGG_HUNT_EXTREME = §5Purple rain
PARTICLE_EGG_HUNT_ADVANCED = §5Lift off
PARTICLE_EGG_HUNT_HALF = §fThe hunt is on
JUMP_AND_RUN_PROGRESS = §e{0}§8/§f{1} §c{2} §7{3}
JUMP_AND_RUN_CANCEL = {0}
JUMP_AND_RUN_TIME = mm:ss,SSS
JUMP_AND_RUN_FINISHED = §aFinished in {0} with {1} fails
JUMP_AND_RUN_PERSONAL_BEST = §aNice! You beat your personal best by {0}
JUMP_AND_RUN_PERSONAL_BEST_TIME = §aPersonal best in {0}
JUMP_AND_RUN_PERSONAL_BEST_NO_TIME = §cNo personal best
JUMP_AND_RUN_REPLAY_ENABLED = §aReplay enabled
JUMP_AND_RUN_REPLAY_DISABLED = §cReplay disabled
# Games
GAMES_TICTACTOE = TicTacToe
GAMES_CONNECT_4 = Connect 4
GAMES_ALREADY_PRESENT = §cYou already have an open invitation
GAMES_NO_SELF = §cYou can\'t play against yourself
GAMES_CHALLENGED_BY = §e{0} §7challenged you to a game of §e{1}
GAMES_CHALLENGED_BY_HOVER = §7Click to accept
GAMES_WON = §6{0} has won!
GAMES_DRAW = §6Draw!
GAMES_TURN = {0}\'s turn
GAMES_LEFT = §7{0} left the game
BOAT_RACE_TIME = §7Finished in §e{0}
BOAT_RACE_NEW_BEST = §aNew best time!
BOAT_RACE_TITLE = §6Checkpoint {0}/6§7: {1} §8• §e{2}km/h
# Easter Egg Hunt
DIFFICULTY_EASY = §aEasy
DIFFICULTY_MEDIUM = §eMedium
DIFFICULTY_HARD = §cHard
DIFFICULTY_EXTREME = §5Extreme
DIFFICULTY_ADVANCED = §5Advanced
EASTER_EGG_MENU = §0Easter Egg Hunt {0}/{1}
EASTER_EGG_SELECTION_ALL = §eAll
EASTER_EGG_SELECTION_FOUND = §aFound
EASTER_EGG_SELECTION_NOT_FOUND = §cNot found
EASTER_EGG_0 = Where everything began
EASTER_EGG_1 = Jump and Run
EASTER_EGG_2 = Carry me please
EASTER_EGG_3 = The crane
EASTER_EGG_4 = Trust fall
EASTER_EGG_5 = Run forrest run
EASTER_EGG_6 = Important Delivery
EASTER_EGG_7 = Ei believe I can fly
EASTER_EGG_8 = Paper airplane differently
EASTER_EGG_9 = How did we get here?
EASTER_EGG_10 = Carving the pumpkin
EASTER_EGG_11 = Flying into sunset
EASTER_EGG_12 = Just a bunch of NPCs
EASTER_EGG_13 = Ei'm waiting
EASTER_EGG_14 = Secret Santa
EASTER_EGG_15 = Emergency Meeting
EASTER_EGG_16 = WGS2022
EASTER_EGG_17 = The world in Preditors hands
EASTER_EGG_18 = Split personalities
EASTER_EGG_19 = The emperor traveling
EASTER_EGG_20 = Guinness
EASTER_EGG_21 = Gulsch Kanone
EASTER_EGG_22 = Ei mit Bard
EASTER_EGG_23 = Mines of Moria
EASTER_EGG_24 = Heart of the mountain
EASTER_EGG_25 = Fly me to the moon
EASTER_EGG_26 = Visitors from another world
EASTER_EGG_27 = Sewage
EASTER_EGG_28 = Sewage Valley
EASTER_EGG_29 = Beginning of the End
EASTER_EGG_30 = Egghaust
EASTER_EGG_31 = Touchdown
EASTER_EGG_32 = Advanced Rocketry
EASTER_EGG_33 = Borderlands
EASTER_EGG_34 = Kiss the frog
EASTER_EGG_35 = Niagara Falls
EASTER_EGG_36 = The Escapist
EASTER_EGG_37 = Mini Egg
EASTER_EGG_38 = Goblin Cave
EASTER_EGG_39 = Asse
EASTER_EGG_40 = Yggdrasil
EASTER_EGG_41 = Bridge Review
EASTER_EGG_42 = May the cucumber be with you
EASTER_EGG_43 = Most hard working builder on SW
EASTER_EGG_44 = There is another
EASTER_EGG_45 = Frozen
EASTER_EGG_46 = In front of the forrest
EASTER_EGG_47 = Yes Mr. President
EASTER_EGG_48 = [PL]ague and Pain
EASTER_EGG_49 = Elevator music
EASTER_EGG_50 = Blue (Da Ba Dee)
EASTER_EGG_51 = Peak niveau
EASTER_EGG_52 = wuuuzzzzuuuuup
EASTER_EGG_53 = Point Plank
EASTER_EGG_54 = §eSteam§8War
EASTER_EGG_55 = Read the fineprint
EASTER_EGG_56 = The same we do every night Pinky
EASTER_EGG_57 = (Don\'t) JUMP
EASTER_EGG_58 = Yin and Yang
EASTER_EGG_59 = Just hanging around
EASTER_EGG_60 = Chick-fil-A
EASTER_EGG_61 = Today in the interview
EASTER_EGG_62 = Ahoy cadets
EASTER_EGG_63 = This is the way
EASTER_EGG_64 = Hamburg meine Perle
EASTER_EGG_65 = Icicle
EASTER_EGG_66 = Easter Rock
EASTER_EGG_67 = Eurasia
EASTER_EGG_68 = Kola-Bohrung
EASTER_EGG_69 = The hobbit
EASTER_EGG_70 = Jungle camp
EASTER_EGG_71 = Nutshell
EASTER_EGG_72 = Fisherman´s Friend
EASTER_EGG_73 = Point nemo
EASTER_EGG_74 = I'm Groot
EASTER_EGG_75 = Crossing
EASTER_EGG_76 = Breakthrough
EASTER_EGG_77 = Doomsday Valley
EASTER_EGG_78 = North Carolina
EASTER_EGG_79 = 16 inches of power
EASTER_EGG_80 = Melons
EASTER_EGG_81 = Maintainance
EASTER_EGG_82 = Map Room
EASTER_EGG_83 = The World upside down
EASTER_EGG_84 = Dirty Chamber
EASTER_EGG_85 = Old server Team
EASTER_EGG_86 = Union
EASTER_EGG_87 = Mushroom
EASTER_EGG_88 = Advertisement
EASTER_EGG_89 = Stairway to heaven
# Advent Calendar
ADVENT_CALENDAR_TITLE=§eAdvent Calendar
ADVENT_CALENDAR_DAY=§7Day§8: §e{0}
ADVENT_CALENDAR_MESSAGE=§eDid you already open your advent calendar? Click the Big Presents to claim!
ADVENT_CALENDAR_OPEN=§7You got §e{0} §7from the advent calendar!
@@ -0,0 +1,264 @@
PREFIX = §eLobby§8System§8»
TIME = HH:mm:ss
DATE=........
COMMAND_HELP_HEAD=§7---=== (§e{0}§7) ===---
# ServerTeamNPC's
NPC_CHAT_1 = §fHallo, ich bin {0} und bin ein {1}.
NPC_CHAT_2 = §fWillkommen auf §eSteam§8War§f, viel Spaß dir.
# Portal Command
PORTAL_COMMAND_LIST_HELP = §8/§7portal §elist §8- §7Listet alle Portale auf
PORTAL_COMMAND_ADD_HELP = §8/§7portal §ecreate §8[§7PortalType§8] §8[§7PortalName§8] §8- §7Fügt ein Portal hinzu
PORTAL_COMMAND_REMOVE_HELP = §8/§7portal §eremove §8[§7PortalName§8] §8- §7Entfernt ein Portal
PORTAL_COMMAND_LIST_SHORT_INFO = §e{0} §8- §7{1} §7Pos1§8(§7{2}§8) §7Pos2§8(§7{3}§8)
PORTAL_NO_WORLDEDIT_SELECTION = §cKeine WorldEdit Selection
# Particle
PARTICLE_INVENTORY = §0Partikel
PARTICLE_DESELECT = §8Keine Partikel
PARTICLE_SHOW_HAS_ALL = §8Du hast alle Partikel
PARTICLE_SHOW_ALL = §aZeige alle
PARTICLE_SHOW_UNLOCKED = §cZeige freigeschaltete
PARTICLE_UNLOCKED_BY = §eFreigeschaltet durch
PARTICLE_UNLOCKED_BY_TEAM = §fTeambeitritt
PARTICLE_UNLOCKED_BY_SPECIFIC_TEAM = §fTeam {0}
PARTICLE_UNLOCKED_BY_SPECIFIC_TEAM_EASTER = §fTeam {0} (Oster-Eierer-Suche)
PARTICLE_UNLOCKED_BY_SPECIFIC_USER = §fUser {0}
PARTICLE_UNLOCKED_BY_SPECIFIC_USER_EASTER = §fUser {0} (Oster-Eierer-Suche)
PARTICLE_UNLOCKED_BY_EVENT = §fEventteilnahme
PARTICLE_UNLOCKED_BY_SERVER_TEAM = §fServerteam
PARTICLE_UNLOCKED_BY_EVENT_PLACEMENT = §f{0} 1., 2. oder 3. Platz
PARTICLE_UNLOCKED_BY_EVENT_PARTICIPATION = §f{0}
PARTICLE_UNLOCKED_BY_EASTER_EGG_HUNT_HALF = §fFinde 45 Oster-Eierer
PARTICLE_UNLOCKED_BY_EASTER_EGG_HUNT_DIFFICULTY = §fAlle Eierer mit Schwierigkeit {0} finden
PARTICLE_ATTRIBUTE_CIRCLE = §8-§f Ring
PARTICLE_ATTRIBUTE_BI_CIRCLE = §8-§f Doppelring
PARTICLE_ATTRIBUTE_CLOUD = §8-§f Wolke
PARTICLE_ATTRIBUTE_TICK = §8-§f Immer aktiv
PARTICLE_ATTRIBUTE_NON_FLOOR = §8-§f In der Luft
PARTICLE_ATTRIBUTE_FLOOR = §8-§f Auf dem Boden
PARTICLE_ATTRIBUTE_NON_FLYING = §8-§f Nicht am Fliegen
PARTICLE_ATTRIBUTE_FLYING = §8-§f Am Fliegen
PARTICLE_ATTRIBUTE_WING = §8-§f Flügel
PARTICLE_ATTRIBUTE_SNEAKING = §8-§f Ducken
PARTICLE_ATTRIBUTE_NON_MOVING = §8-§f Beim Stehen
PARTICLE_ATTRIBUTE = §eAttribute§7:
PARTICLE_SELECT = §eZum Auswählen klicken
PARTICLE_LOCKED = §c§lGesperrt
PARTICLE_DEACTIVATED = §cEs sind zu viele Spieler online! Partikel sind deaktiviert.
PARTICLE_SNEEZE = §aSneeze
PARTICLE_SMOKE = §7Rauch
PARTICLE_FIRE = §cFeuer
PARTICLE_WATER = §bWasser
PARTICLE_HEART = §cHerzen
PARTICLE_NOTES = §eNoten
PARTICLE_NAUTILUS = §aNautilus
PARTICLE_SNOWBALL = §fSchneeball
PARTICLE_EFFECT = §5Effekt
PARTICLE_CAMPFIRE = §7Rauch
PARTICLE_MAGIC = §5Magie
PARTICLE_ANGRY = §4Wut
PARTICLE_SLIME = §aSchleim
PARTICLE_MOB = §7Mob
PARTICLE_SQUID = §8Tintenfisch
PARTICLE_BUBBLE = §aBlasen
PARTICLE_HONEY = §6Honig
PARTICLE_NECTAR = §6Nektar
PARTICLE_FIREWORK = §7Feuerwerk
PARTICLE_DRAGON_BREATH = §5Drachenatem
PARTICLE_DAMAGE = §5Schaden
PARTICLE_DOLPHIN = §dDelphin
PARTICLE_WITCH = §5Hexe
PARTICLE_ENCHANTING = §eZauber
PARTICLE_HAPPY = §2Freude
PARTICLE_FLAME = §7Flammen
PARTICLE_END_ROD = §fEnd Rod
PARTICLE_CLOUD = §7Wolke
PARTICLE_TOTEM = §aTotem
PARTICLE_TOWN = §5Town
PARTICLE_ENCHANTING_CIRCLE = §fVerzaubert
PARTICLE_WATER_FIRE = §bWasser§7/§cFeuer
PARTICLE_MAGIC_ENCHANTING = §5Magie§7/§eZauber
PARTICLE_WINGS_EVIL = §5Lila Flügel
PARTICLE_PLAYER_RONGAMER99091_AURA = §7Rauchgranate
PARTICLE_TEAM_PULSE_HEART_BEAT = §cHerzschlag
PARTICLE_RAINCLOUD_NORMAL = §fRegenwolke
PARTICLE_RAINCLOUD_RED = §fLavawolke
PARTICLE_RAINCLOUD_YELLOW = §fNektarwolke
PARTICLE_RAINCLOUD_ORANGE = §fHonigwolke
PARTICLE_RAINCLOUD_GREEN = §fSporenwolke
PARTICLE_RAINCLOUD_PURPLE = §fObsidanwolke
PARTICLE_RAINCLOUD_NAUTILUS = §fNautiluswolke
PARTICLE_RAINCLOUD_ENCHANTMENT = §fVerzauberungswolke
PARTICLE_RAINCLOUD_SLIME = §fSchleimwolke
PARTICLE_RAINCLOUD_HAIL = §fHagelwolke
PARTICLE_RAINCLOUD_SNOW = §fSchneewolke
PARTICLE_RAINCLOUD_TOTEM = §fTotemwolke
PARTICLE_EVENT_ENCHANTING = §cVerzaubert
PARTICLE_EVENT_CLOUD = §fWolken
PARTICLE_EVENT_SMOKE = §7Rauch
PARTICLE_EVENT_WATER = §bWasser
PARTICLE_EVENT_WINGS = §fFlügel
PARTICLE_EVENT_RAIN_CLOUD = §fRegenwolke
PARTICLE_EVENT_WGS = §fWGS
PARTICLE_EVENT_WARGEARCLASH = §fClash
PARTICLE_EGG_HUNT_EASY = §aGrünplfanzen
PARTICLE_EGG_HUNT_MEDIUM = §eVersteckspiel
PARTICLE_EGG_HUNT_HARD = §cOrbit
PARTICLE_EGG_HUNT_EXTREME = §5Lila regen
PARTICLE_EGG_HUNT_ADVANCED = §5Abheben
PARTICLE_EGG_HUNT_HALF = §fDie Jagd ist eröffnet
JUMP_AND_RUN_FINISHED = §aBeendet in {0} mit {1} Fails
JUMP_AND_RUN_PERSONAL_BEST = §aNice! Du hast deinen Rekord um {0} verbessert!
JUMP_AND_RUN_PERSONAL_BEST_TIME = §aDein Rekord ist {0}
JUMP_AND_RUN_PERSONAL_BEST_NO_TIME = §cDu hast noch keinen Rekord
JUMP_AND_RUN_REPLAY_ENABLED = §aReplay aktiviert
JUMP_AND_RUN_REPLAY_DISABLED = §cReplay deaktiviert
# Games
GAMES_TICTACTOE = TicTacToe
GAMES_CONNECT_4 = Vier Gewinnt
GAMES_ALREADY_PRESENT = §cDu hast bereits eine Herausforderung!
GAMES_NO_SELF = §cDu kannst dich nicht selbst herausfordern!
GAMES_CHALLENGED_BY = §e{0} §7hat dich zu einem Spiel §e{1}§7 herausgefordert!
GAMES_CHALLENGED_BY_HOVER = §7Klicke hier, um das Spiel zu bestätigen
GAMES_WON = §6{0} hat das Spiel gewonnen!
GAMES_DRAW = §6Unentschieden!
GAMES_TURN = {0} ist dran
GAMES_LEFT = §7{0} hat das Spiel verlassen
BOAT_RACE_TIME = §7Abgeschlossen in {0}
BOAT_RACE_NEW_BEST = §aNeue Bestzeit!
# Easter Egg Hunt
DIFFICULTY_EASY = §aLeicht
DIFFICULTY_MEDIUM = §eMedium
DIFFICULTY_HARD = §cHart
DIFFICULTY_EXTREME = §5Extrem
DIFFICULTY_ADVANCED = §5Advanced
EASTER_EGG_MENU = §0Oster Eier Suche {0}/{1}
EASTER_EGG_SELECTION_ALL = §eAlle
EASTER_EGG_SELECTION_FOUND = §aGefunden
EASTER_EGG_SELECTION_NOT_FOUND = §cNicht gefunden
EASTER_EGG_0 = Wo alles begann
EASTER_EGG_1 = Jump and Run
EASTER_EGG_2 = Carry me please
EASTER_EGG_3 = Der Kran
EASTER_EGG_4 = Trust fall
EASTER_EGG_5 = Run forrest run
EASTER_EGG_6 = Wichtige Zustellung
EASTER_EGG_7 = Ei believe I can fly
EASTER_EGG_8 = Papierflieger mal anders
EASTER_EGG_9 = Wie sind wir hier hingekommen?
EASTER_EGG_10 = Kürbisschnitzen
EASTER_EGG_11 = Flug in den Sonnentunergang
EASTER_EGG_12 = Ein haufen NPCs
EASTER_EGG_13 = Ei'm waiting
EASTER_EGG_14 = Secret Santa
EASTER_EGG_15 = Emergency Meeting
EASTER_EGG_16 = WGS2022
EASTER_EGG_17 = Die Welt in den Händen von Preditors
EASTER_EGG_18 = Gespaltene Persönlichkeiten
EASTER_EGG_19 = Der Kaiser auf reisen
EASTER_EGG_20 = Guinness
EASTER_EGG_21 = Gulsch Kanone
EASTER_EGG_22 = Ei mit Bard
EASTER_EGG_23 = Die Minen von Moria
EASTER_EGG_24 = Das Herz des Berges
EASTER_EGG_25 = Fly me to the moon
EASTER_EGG_26 = Besucher aus einer anderen Welt
EASTER_EGG_27 = Abwasser
EASTER_EGG_28 = Tal der Abwässer
EASTER_EGG_29 = Der Anfang vom Ende
EASTER_EGG_30 = Egghaust
EASTER_EGG_31 = Touchdown
EASTER_EGG_32 = Advanced Rocketry
EASTER_EGG_33 = Borderlands
EASTER_EGG_34 = Küss den Frosch
EASTER_EGG_35 = Niagara Fälle
EASTER_EGG_36 = The Escapist
EASTER_EGG_37 = Mini Ei
EASTER_EGG_38 = Koboldhöhle
EASTER_EGG_39 = Asse
EASTER_EGG_40 = Yggdrasil
EASTER_EGG_41 = Bridge Review
EASTER_EGG_42 = Möge die Gurke mit dir sein
EASTER_EGG_43 = Most hard working builder on SW
EASTER_EGG_44 = There is another
EASTER_EGG_45 = Frozen
EASTER_EGG_46 = Vor dem Wald
EASTER_EGG_47 = Yes Mr. President
EASTER_EGG_48 = [PL]ague and Pain
EASTER_EGG_49 = Elevator music
EASTER_EGG_50 = Blue (Da Ba Dee)
EASTER_EGG_51 = Peak niveau
EASTER_EGG_52 = wuuuzzzzuuuuup
EASTER_EGG_53 = Point Plank
EASTER_EGG_54 = §eSteam§8War
EASTER_EGG_55 = Lese das Kleingedruckte
EASTER_EGG_56 = The same we do every night Pinky
EASTER_EGG_57 = (Nicht) SPRINGEN
EASTER_EGG_58 = Yin und Yang
EASTER_EGG_59 = Just hanging around
EASTER_EGG_60 = Chick-fil-A
EASTER_EGG_61 = Heute im Interview
EASTER_EGG_62 = Ahoi Kadetten
EASTER_EGG_63 = Das ist der Weg
EASTER_EGG_64 = Hamburg meine Perle
EASTER_EGG_65 = Eiszapfen
EASTER_EGG_66 = Easter Rock
EASTER_EGG_67 = Eurasia
EASTER_EGG_68 = Kola-Bohrung
EASTER_EGG_69 = Der hobbit
EASTER_EGG_70 = Jungel Kamp
EASTER_EGG_71 = Nussschale
EASTER_EGG_72 = Fisherman´s Friend
EASTER_EGG_73 = Point nemo
EASTER_EGG_74 = Ich bin Groot
EASTER_EGG_75 = Kreuzung
EASTER_EGG_76 = Durchbruch
EASTER_EGG_77 = Doomsday Valley
EASTER_EGG_78 = North Carolina
EASTER_EGG_79 = 16 inches of power
EASTER_EGG_80 = Melonen
EASTER_EGG_81 = Wartungsarbeiten
EASTER_EGG_82 = Kartenraum
EASTER_EGG_83 = Die Welt steht Kopf
EASTER_EGG_84 = Schmutziges Kabuff
EASTER_EGG_85 = Altes Serverteam
EASTER_EGG_86 = Union
EASTER_EGG_87 = Mushroom
EASTER_EGG_88 = Werbung
EASTER_EGG_89 = Stairway to heaven
# Advent Calendar
ADVENT_CALENDAR_TITLE=§eAdventskalender
ADVENT_CALENDAR_DAY=§7Tag§8: §e{0}
ADVENT_CALENDAR_MESSAGE=§eHast du heute schon dein Geschenk geholt? Klicke die großen Geschenke zum erhalten!
ADVENT_CALENDAR_OPEN=§7Du hast §e{0}§7 aus dem Adventskalender erhalten!
@@ -0,0 +1,161 @@
package de.steamwar.lobby.boatrace;
import de.steamwar.entity.REntity;
import de.steamwar.entity.REntityServer;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.util.Leaderboard;
import de.steamwar.sql.UserConfig;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
import org.bukkit.entity.Boat;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.vehicle.VehicleExitEvent;
import org.bukkit.event.vehicle.VehicleMoveEvent;
import org.bukkit.scheduler.BukkitTask;
import java.util.EventListener;
import static de.steamwar.lobby.util.Leaderboard.renderTime;
public class BoatRace implements EventListener, Listener {
private static final double MIN_HEIGHT = 4.3;
public static final REntityServer boatNpcServer;
private static boolean oneNotStarted = false;
private static final Leaderboard leaderboard;
static {
boatNpcServer = new REntityServer();
REntity starter = new REntity(boatNpcServer, EntityType.VILLAGER, BoatRacePositions.NPC);
boatNpcServer.setCallback((player, rEntity, entityAction) -> {
if (rEntity != starter) return;
Bukkit.getWorlds().get(0).getEntities().stream().filter(entity -> entity.getType() == EntityType.ENDER_CRYSTAL).forEach(Entity::remove);
if (entityAction == REntityServer.EntityAction.INTERACT && !oneNotStarted) {
oneNotStarted = true;
new BoatRace(player);
}
});
leaderboard = new Leaderboard(boatNpcServer, "lobby@boatrace", BoatRacePositions.LEADERBOARD, 5);
}
private final Player player;
private Boat boat;
private int nextCheckpoint = 0;
private long startTime;
private final BukkitTask task;
private final BossBar bossBar;
private boolean hasBacked = false;
private double lastDistance;
@EventHandler
public void onBoatMove(VehicleMoveEvent event) {
if (event.getVehicle() != boat) return;
lastDistance = event.getFrom().distance(event.getTo());
if(nextCheckpoint == 0 && inRegion(player, BoatRacePositions.BACKWARDS[0], BoatRacePositions.BACKWARDS[1])) {
player.eject();
player.teleport(BoatRacePositions.END);
oneNotStarted = false;
return;
}
if(player.getLocation().getY() < MIN_HEIGHT) {
Location[] backTo = BoatRacePositions.CHECKPOINTS[nextCheckpoint - 1];
Location avg = new Location(backTo[0].getWorld(), (backTo[0].getX() + backTo[1].getX()) / 2, Math.max(backTo[0].getY(), backTo[1].getY()), (backTo[0].getZ() + backTo[1].getZ()) / 2, backTo[0].getYaw(), backTo[0].getPitch());
Boat nboat = Bukkit.getWorlds().get(0).spawn(avg, Boat.class);
nboat.setBoatType(boat.getBoatType());
hasBacked = true;
player.eject();
boat.remove();
boat = nboat;
boat.addPassenger(player);
player.playSound(avg, Sound.ENTITY_ENDERMAN_TELEPORT, 1, 1);
return;
}
Location[] checkpoint = BoatRacePositions.CHECKPOINTS[nextCheckpoint];
if(inRegion(player, checkpoint[0], checkpoint[1])) {
if(nextCheckpoint == 0) {
oneNotStarted = false;
startTime = System.currentTimeMillis();
bossBar.addPlayer(player);
bossBar.setVisible(true);
}
nextCheckpoint++;
if (nextCheckpoint == BoatRacePositions.CHECKPOINTS.length) {
long time = System.currentTimeMillis() - startTime;
boat.remove();
player.eject();
player.teleport(BoatRacePositions.END);
player.playSound(player.getLocation(), Sound.UI_TOAST_CHALLENGE_COMPLETE, 1, 1);
bossBar.removeAll();
HandlerList.unregisterAll(this);
task.cancel();
LobbySystem.getMessage().send("BOAT_RACE_TIME", player, renderTime(time));
String conf = UserConfig.getConfig(player.getUniqueId(), "lobby@boatrace");
long best = Long.parseLong(conf == null ? String.valueOf(Long.MAX_VALUE) : conf);
if (time < best) {
LobbySystem.getMessage().send("BOAT_RACE_NEW_BEST", player);
UserConfig.updatePlayerConfig(player.getUniqueId(), "lobby@boatrace", String.valueOf(time));
leaderboard.update();
}
} else {
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1);
}
}
}
@EventHandler
public void onVehicleExit(VehicleExitEvent event) {
if (event.getVehicle() != boat) return;
if (event.getExited() != player) return;
if (hasBacked) return;
HandlerList.unregisterAll(this);
task.cancel();
bossBar.removeAll();
boat.remove();
player.teleport(BoatRacePositions.END);
oneNotStarted = false;
}
public BoatRace(Player player) {
this.player = player;
boat = Bukkit.getWorlds().get(0).spawn(BoatRacePositions.START, Boat.class);
// boat.setBoatType(Boat.Type.values()[new Random().nextInt(Boat.Type.values().length)]);
boat.addPassenger(player);
bossBar = Bukkit.createBossBar("", BarColor.BLUE, BarStyle.SOLID);
task = Bukkit.getScheduler().runTaskTimer(LobbySystem.getPlugin(), () -> {
hasBacked = false;
if (nextCheckpoint != 0) {
double kmh = lastDistance * 20 * 3.6;
bossBar.setProgress((nextCheckpoint - 1d) / (BoatRacePositions.CHECKPOINTS.length - 1d));
bossBar.setTitle(LobbySystem.getMessage().parse("BOAT_RACE_TITLE", player, nextCheckpoint, renderTime(System.currentTimeMillis() - startTime), (int) kmh));
}
}, 0, 1);
Bukkit.getPluginManager().registerEvents(this, LobbySystem.getPlugin());
}
private boolean inRegion(Player p, Location loc1, Location loc2) {
double x1 = Math.min(loc1.getX(), loc2.getX());
double y1 = Math.min(loc1.getY(), loc2.getY());
double z1 = Math.min(loc1.getZ(), loc2.getZ());
double x2 = Math.max(loc1.getX(), loc2.getX()) + 1;
double y2 = Math.max(loc1.getY(), loc2.getY()) + 1;
double z2 = Math.max(loc1.getZ(), loc2.getZ()) + 1;
return p.getLocation().getX() >= x1 && p.getLocation().getY() >= y1 && p.getLocation().getZ() >= z1 && p.getLocation().getX() < x2 && p.getLocation().getY() < y2 && p.getLocation().getZ() < z2;
}
}
@@ -0,0 +1,55 @@
package de.steamwar.lobby.boatrace;
import org.bukkit.Bukkit;
import org.bukkit.Location;
public class BoatRacePositions {
public static final Location LEADERBOARD = loc(2414, 7, 1542.5);
public static final Location NPC = loc(2424.5, 5, 1544.5, -180, 0);
public static final Location START = loc(2410.5, 6, 1537.5, -90, 0);
public static final Location[][] CHECKPOINTS = new Location[][] {
new Location[] {
loc(2414, 4, 1528, -90, 0),
loc(2415, 8, 1542),
},
new Location[] {
loc(2484, 4, 1456, -180, 0),
loc(2494, 8, 1459),
},
new Location[] {
loc(2310, 4, 1475, 0, 0),
loc(2321, 8, 1477),
},
new Location[] {
loc(2428, 4, 1448, -90, 0),
loc(2430, 8, 1458),
},
new Location[] {
loc(2392, 4, 1492, 90, 0),
loc(2394, 8, 1502),
},
new Location[] {
loc(2414, 4, 1528, -90, 0),
loc(2416, 8, 1542),
},
};
public static final Location[] BACKWARDS = new Location[] {
loc(2407, 3,1526),
loc(2408, 9,1544)
};
public static final Location END = loc(2449.5, 6, 1550, -180, 0);
private static Location loc(double x, double y, double z) {
return new Location(Bukkit.getWorlds().get(0), x, y, z);
}
private static Location loc(double x, double y, double z, float yaw, float pitch) {
return new Location(Bukkit.getWorlds().get(0), x, y, z, yaw, pitch);
}
}
@@ -0,0 +1,51 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.command;
import de.steamwar.command.SWCommand;
import de.steamwar.lobby.util.LobbyPlayer;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.UserPerm;
import org.bukkit.entity.Player;
public class FlyCommand extends SWCommand {
public FlyCommand() {
super("fly");
}
@Register
public void genericCommand(Player player) {
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
if (!user.hasPerm(UserPerm.TEAM)) {
player.sendMessage("§cUnbekannter Befehl.");
return;
}
LobbyPlayer lobbyPlayer = LobbyPlayer.getLobbyPlayer(player);
boolean newFlightState = !lobbyPlayer.isFlying();
lobbyPlayer.setFly(newFlightState);
player.setAllowFlight(newFlightState);
player.setFlying(newFlightState);
player.sendMessage("§7Du kannst jetzt " + (newFlightState ? "§afliegen§7." : "§cnicht §7mehr fliegen."));
}
}
@@ -0,0 +1,67 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.command;
import de.steamwar.command.SWCommand;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.display.Hologram;
import org.bukkit.entity.Player;
public class HologramCommand extends SWCommand {
public HologramCommand() {
super("hologram");
}
@Register(help = true)
public void genericHelp(Player player, String... args) {
if (PortalCommand.noPermissions(player)) return;
player.sendMessage("/hologram create <id> <text>");
player.sendMessage("/hologram list");
player.sendMessage("/hologram delete <id>");
}
@Register("create")
public void portalCreate(Player player, String id, String... text) {
if (PortalCommand.noPermissions(player)) return;
new Hologram(id, player.getLocation(), String.join(" ", text).replace("&", "§"), false);
LobbySystem.config().save();
}
@Register("list")
public void portalList(Player player) {
if (PortalCommand.noPermissions(player)) return;
Hologram.getHolograms().forEach(hologram -> player.sendMessage(hologram.toString()));
}
@Register("delete")
public void portalDelete(Player player, String id) {
if (PortalCommand.noPermissions(player)) return;
Hologram hologram = Hologram.getHologram(id);
if (hologram == null)
return;
hologram.delete();
LobbySystem.config().save();
}
}
@@ -0,0 +1,88 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.command;
import de.steamwar.command.SWCommand;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.listener.PlayerSpawn;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.UserPerm;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.HashSet;
import java.util.Set;
public class ModifyCommand extends SWCommand implements Listener {
private static final Set<HumanEntity> modifying = new HashSet<>();
public static boolean modifying(HumanEntity player) {
return modifying.contains(player);
}
public ModifyCommand() {
super("modify");
Bukkit.getPluginManager().registerEvents(this, LobbySystem.getPlugin());
}
@Register
public void modify(Player player) {
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
if(!user.hasPerm(UserPerm.ADMINISTRATION)) {
return;
}
if(modifying(player)) {
modifying.remove(player);
LobbySystem.getEntityServer(true).removePlayer(player);
player.setGameMode(GameMode.ADVENTURE);
player.setOp(false);
PlayerSpawn.giveItems(player);
}else {
modifying.add(player);
LobbySystem.getEntityServer(true).addPlayer(player);
player.setGameMode(GameMode.CREATIVE);
player.setOp(true);
}
}
@EventHandler
public void onLeave(PlayerQuitEvent event) {
Player player = event.getPlayer();
modifying.remove(player);
player.setOp(false);
}
@Register("waitinghallspawn")
public void setWaitingHallSpawn(Player player) {
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
if(!user.hasPerm(UserPerm.ADMINISTRATION))
return;
LobbySystem.config().setWaitingHallSpawn(player.getLocation());
}
}
@@ -0,0 +1,168 @@
package de.steamwar.lobby.command;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.RegionSelector;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeMapper;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.portal.*;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.UserPerm;
import lombok.Data;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
public class PortalCommand extends SWCommand {
public PortalCommand() {
super("portal");
}
public static boolean noPermissions(Player player) {
SteamwarUser steamwarUser = SteamwarUser.get(player.getUniqueId());
return !steamwarUser.hasPerm(UserPerm.ADMINISTRATION);
}
@Register
public void genericHelp(Player player, String... args) {
if (noPermissions(player)) return;
LobbySystem.getMessage().sendPrefixless("COMMAND_HELP_HEAD", player, "portal");
LobbySystem.getMessage().sendPrefixless("PORTAL_COMMAND_LIST_HELP", player);
LobbySystem.getMessage().sendPrefixless("PORTAL_COMMAND_ADD_HELP", player);
LobbySystem.getMessage().sendPrefixless("PORTAL_COMMAND_REMOVE_HELP", player);
}
@Register("list")
public void portalList(Player player) {
if (noPermissions(player)) return;
LobbySystem.getMessage().sendPrefixless("COMMAND_HELP_HEAD", player, "portal list");
Portal.getPortals().forEach(portal -> {
LobbySystem.getMessage().sendPrefixless("PORTAL_COMMAND_LIST_SHORT_INFO", player, portal.type().name(), portal.getId(), portal.getPos1().toVector().toString(), portal.getPos2().toVector().toString());
});
}
@Register({"create", "command"})
public void portalAddCommand(Player player, String portalName, String... command) {
if (noPermissions(player)) return;
PortalLocations tuple = getSelection(player);
if (tuple == null) return;
new Portal(portalName, tuple.k, tuple.v, portal -> new CommandPortal(String.join(" ", command)));
}
@Register({"create", "fight"})
public void portalAddFightserver(Player player, String portalName, String gamemode, int order, String target) {
if (noPermissions(player)) return;
PortalLocations tuple = getSelection(player);
if (tuple == null) return;
new Portal(portalName, tuple.k, tuple.v, portal -> new FightserverPortal(portal, gamemode.toLowerCase(), order, target, new ArrayList<>(), new ArrayList<>()));
}
@Register({"create", "teleport"})
public void portalAddTeleport(Player player, String portalName, String portalDestination) {
if (noPermissions(player)) return;
PortalLocations tuple = getSelection(player);
if (tuple == null) return;
new Portal(portalName, tuple.k, tuple.v, portal -> new TeleportPortal(portal, portalDestination));
}
@Register({"create", "stack"})
public void portalAddStack(Player player, String portalName, String portalDestination, String... command) {
if (noPermissions(player)) return;
PortalLocations tuple = getSelection(player);
if (tuple == null) return;
new Portal(portalName, tuple.k, tuple.v, portal -> new StackPortal(portal, portalDestination, String.join(" ", command)));
}
@Register({"depth"})
public void portalDepth(Player player, Portal portal, double depth) {
portal.setDepth(depth);
}
@Register({"addblue"})
public void portalAddBlue(Player player, Portal portal) {
FightserverPortal handler = (FightserverPortal) portal.getHandler();
handler.addBlue(locationOfPlayer(player));
}
@Register({"addred"})
public void portalAddRed(Player player, Portal portal) {
FightserverPortal handler = (FightserverPortal) portal.getHandler();
handler.addRed(locationOfPlayer(player));
}
private Location locationOfPlayer(Player player) {
Location l = player.getLocation();
l.setYaw(((CraftPlayer)player).getHandle().cm());
return l;
}
@Register({"removeblue"})
public void portalRemoveBlue(Player player, Portal portal, int i) {
FightserverPortal handler = (FightserverPortal) portal.getHandler();
handler.removeBlue(i-1);
}
@Register({"removered"})
public void portalRemoveRed(Player player, Portal portal, int i) {
FightserverPortal handler = (FightserverPortal) portal.getHandler();
handler.removeRed(i-1);
}
@Register("remove")
public void portalRemove(Player player, Portal portal) {
if (noPermissions(player)) return;
portal.delete();
}
@ClassMapper(value = Portal.class, local = true)
public TypeMapper<Portal> portalTypeMapper() {
return new TypeMapper<Portal>() {
@Override
public List<String> tabCompletes(CommandSender commandSender, String[] strings, String s) {
return new ArrayList<>(Portal.getPortalNames());
}
@Override
public Portal map(CommandSender commandSender, String[] previousArguments, String s) {
return Portal.getPortal(s);
}
};
}
@Data
private static class PortalLocations {
private final Location k;
private final Location v;
}
private PortalLocations getSelection(Player player) {
RegionSelector regionSelector = WorldEdit.getInstance()
.getSessionManager()
.get(BukkitAdapter.adapt(player))
.getRegionSelector(BukkitAdapter.adapt(player.getWorld()));
try {
CuboidRegion region = (CuboidRegion)regionSelector.getRegion();
return new PortalLocations(adapt(player.getWorld(), region.getPos1()), adapt(player.getWorld(), region.getPos2()));
} catch (IncompleteRegionException e) {
LobbySystem.getMessage().send("PORTAL_NO_WORLDEDIT_SELECTION", player);
return null;
}
}
private Location adapt(World world, BlockVector3 blockVector3) {
return new Location(world, blockVector3.getBlockX() + 0.5, blockVector3.getBlockY(), blockVector3.getBlockZ() + 0.5);
}
}
@@ -0,0 +1,86 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.display;
import de.steamwar.entity.RArmorStand;
import de.steamwar.lobby.LobbySystem;
import org.bukkit.Location;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Hologram implements ConfigurationSerializable {
private static final Map<String, Hologram> holograms = new HashMap<>();
public static List<Hologram> getHolograms() {
return new ArrayList<>(holograms.values());
}
public static Hologram getHologram(String id) {
return holograms.get(id);
}
private final String id;
private final Location location;
private final RArmorStand entity;
public Hologram(Map<String, Object> map) {
this((String) map.get("id"), (Location) map.get("location"), (String) map.get("text"), false);
}
public Hologram(String id, Location location, String text, boolean debugHologram) {
this.id = id;
this.location = location;
this.entity = new RArmorStand(LobbySystem.getEntityServer(debugHologram), location, RArmorStand.Size.MARKER);
entity.setInvisible(true);
entity.setDisplayName(text);
if(id != null)
holograms.put(id, this);
}
public void updateText(String text) {
entity.setDisplayName(text);
}
@Override
public Map<String, Object> serialize() {
Map<String, Object> map = new HashMap<>();
map.put("id", id);
map.put("location", location);
map.put("text", entity.getDisplayName());
return map;
}
public void delete() {
entity.die();
if(id != null)
holograms.remove(id);
}
@Override
public String toString() {
return id + " " + entity.getDisplayName();
}
}
@@ -0,0 +1,75 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.display;
import de.steamwar.entity.RPlayer;
import de.steamwar.lobby.LobbySystem;
import org.bukkit.Location;
import java.util.UUID;
public class NPC {
private Location location;
private final RPlayer entity;
public NPC(Location location, UUID uuid, String name) {
this.location = location;
this.entity = new RPlayer(LobbySystem.getEntityServer(false), uuid, name, location);
}
public void setLocation(Location location) {
if (isSimilarLocation(location)) {
return;
}
this.location = location;
entity.move(location);
}
private boolean isSimilarLocation(Location location) {
if (this.location == null) {
return false;
}
if (Location.normalizeYaw(this.location.getYaw()) != Location.normalizeYaw(location.getYaw())) {
return false;
}
if (Location.normalizePitch(this.location.getPitch()) != Location.normalizePitch(location.getPitch())) {
return false;
}
if (Math.abs(this.location.getX() - location.getX()) > 0.1) {
return false;
}
if (Math.abs(this.location.getY() - location.getY()) > 0.1) {
return false;
}
return !(Math.abs(this.location.getZ() - location.getZ()) > 0.1);
}
public Location getLocation() {
return location;
}
public UUID getUuid() {
return entity.getUuid();
}
public void delete() {
entity.die();
}
}
@@ -0,0 +1,180 @@
package de.steamwar.lobby.jumpandrun;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.listener.BasicListener;
import de.steamwar.lobby.listener.PlayerSpawn;
import de.steamwar.lobby.util.Leaderboard;
import de.steamwar.sql.UserConfig;
import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import java.text.SimpleDateFormat;
import java.util.*;
public class JumpAndRun extends BasicListener {
public static final String JUMP_AND_RUN_CONFIG = "jump_and_run";
private static final String BAR_EMPTY = "||||||||||||||||||||||||||||||";
public static List<Vector> points = new ArrayList<>();
public static List<Vector> actualPoints = new ArrayList<>();
private static final Map<Player, Integer> CURRENT_POS = new HashMap<>();
private static final Map<Player, Integer> FAILS = new HashMap<>();
private static final Map<Player, Long> START = new HashMap<>();
private static final Map<Player, Long> CLICKED = new HashMap<>();
private static final Map<Player, Integer> CLICKED_COUNT = new HashMap<>();
private static final Leaderboard LEADERBOARD = new Leaderboard(LobbySystem.getEntityServer(false), JUMP_AND_RUN_CONFIG, new Location(Bukkit.getWorlds().get(0), 2338.5, 42.5, 1231.5), 5);
{
Bukkit.getScheduler().runTaskTimer(LobbySystem.getPlugin(), () -> {
Set<Player> toReset = new HashSet<>();
CURRENT_POS.forEach((player, index) -> {
if (System.currentTimeMillis() - CLICKED.getOrDefault(player, 0L) > 500) {
CLICKED.remove(player);
CLICKED_COUNT.remove(player);
} else {
CLICKED_COUNT.put(player, CLICKED_COUNT.getOrDefault(player, -1) + 1);
}
Location location = player.getLocation();
Vector point = points.get(index);
if (index < points.size() - 1) {
Vector nextPoint = points.get(index + 1);
double y = Math.min(point.getY(), nextPoint.getY()) - 2;
if (location.getY() < y) {
location.setX(point.getX());
location.setY(point.getY());
location.setZ(point.getZ());
player.teleport(location);
player.playSound(location, Sound.ENTITY_ENDERMAN_TELEPORT, 1, 1);
FAILS.put(player, FAILS.getOrDefault(player, 0) + 1);
}
}
int count = CLICKED_COUNT.getOrDefault(player, -1);
if (count >= 0) {
if (count > 60) {
toReset.add(player);
return;
}
count = Math.min(count / 2, 30);
LobbySystem.getMessage().sendPrefixless("JUMP_AND_RUN_CANCEL", player, ChatMessageType.ACTION_BAR, "§e" + BAR_EMPTY.substring(0, count) + "§7" + BAR_EMPTY.substring(count));
} else {
long time = System.currentTimeMillis() - START.get(player);
SimpleDateFormat format = new SimpleDateFormat(LobbySystem.getMessage().parse("JUMP_AND_RUN_TIME", player), Locale.ROOT);
String parsed = format.format(new Date(time));
LobbySystem.getMessage().sendPrefixless("JUMP_AND_RUN_PROGRESS", player, ChatMessageType.ACTION_BAR, index + 1, points.size(), FAILS.get(player), parsed);
}
});
toReset.forEach(player -> {
reset(player);
player.teleport(Bukkit.getWorlds().get(0).getSpawnLocation().clone().add(0.5, 0, 0.5));
});
}, 1, 1);
}
public static boolean isPlayerInJumpAndRun(Player player) {
return CURRENT_POS.containsKey(player);
}
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
Location location = event.getTo();
Location checkLocation = location.clone();
checkLocation.setY(checkLocation.getY() - 0.1);
if (checkLocation.getBlock().getType() == Material.AIR) {
return;
}
int index = CURRENT_POS.getOrDefault(event.getPlayer(), -1) + 1;
if (index >= points.size()) {
return;
}
Vector point = points.get(index);
if (location.getY() < point.getY()) {
return;
}
if (location.toVector().distanceSquared(point) >= 12.25) {
return;
}
CURRENT_POS.put(event.getPlayer(), index);
event.getPlayer().playSound(event.getPlayer().getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 0.4F, 1);
if (index < points.size() - 1) {
event.getPlayer().setCompassTarget(points.get(index + 1).toLocation(location.getWorld()));
}
if (index == 0) {
event.getPlayer().setAllowFlight(false);
event.getPlayer().getInventory().clear();
event.getPlayer().updateInventory();
event.getPlayer().getInventory().setItem(4, new ItemStack(Material.COMPASS, 1));
FAILS.put(event.getPlayer(), 0);
START.put(event.getPlayer(), System.currentTimeMillis());
}
if (index == points.size() - 1) {
long time = System.currentTimeMillis() - START.get(event.getPlayer());
SimpleDateFormat format = new SimpleDateFormat(LobbySystem.getMessage().parse("JUMP_AND_RUN_TIME", event.getPlayer()), Locale.ROOT);
String parsed = format.format(new Date(time));
LobbySystem.getMessage().sendPrefixless("JUMP_AND_RUN_FINISHED", event.getPlayer(), parsed, FAILS.get(event.getPlayer()));
updateJumpAndRunTime(event.getPlayer(), time);
reset(event.getPlayer());
}
}
private void updateJumpAndRunTime(Player player, long time) {
String jumpAndRunTimeConfig = UserConfig.getConfig(player.getUniqueId(), JUMP_AND_RUN_CONFIG);
if (jumpAndRunTimeConfig == null) {
UserConfig.updatePlayerConfig(player.getUniqueId(), JUMP_AND_RUN_CONFIG, time + "");
} else {
long jumpAndRunTime = Long.parseLong(jumpAndRunTimeConfig);
if (time < jumpAndRunTime) {
SimpleDateFormat format = new SimpleDateFormat(LobbySystem.getMessage().parse("JUMP_AND_RUN_TIME", player), Locale.ROOT);
String parsed = format.format(new Date(jumpAndRunTime - time));
LobbySystem.getMessage().sendPrefixless("JUMP_AND_RUN_PERSONAL_BEST", player, parsed);
UserConfig.updatePlayerConfig(player.getUniqueId(), JUMP_AND_RUN_CONFIG, time + "");
LEADERBOARD.update();
}
}
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
CURRENT_POS.remove(player);
START.remove(player);
FAILS.remove(player);
CLICKED.remove(player);
CLICKED_COUNT.remove(player);
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getItem() == null) return;
if (event.getItem().getType() != Material.COMPASS) return;
if (event.getAction() != Action.RIGHT_CLICK_AIR && event.getAction() != Action.RIGHT_CLICK_BLOCK) return;
event.setCancelled(true);
CLICKED.put(event.getPlayer(), System.currentTimeMillis());
}
public static void reset(Player player) {
PlayerSpawn.giveItems(player);
player.setAllowFlight(true);
CURRENT_POS.remove(player);
START.remove(player);
FAILS.remove(player);
CLICKED.remove(player);
CLICKED_COUNT.remove(player);
}
}
@@ -0,0 +1,30 @@
package de.steamwar.lobby.jumpandrun;
import de.steamwar.command.SWCommand;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.sql.UserConfig;
import org.bukkit.entity.Player;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class JumpAndRunCommand extends SWCommand {
public JumpAndRunCommand() {
super("jumpandrun");
}
@Register
public void genericCommand(Player player, String... args) {
String time = UserConfig.getConfig(player.getUniqueId(), JumpAndRun.JUMP_AND_RUN_CONFIG);
if (time == null) {
LobbySystem.getMessage().sendPrefixless("JUMP_AND_RUN_PERSONAL_BEST_NO_TIME", player);
return;
}
long timeLong = Long.parseLong(time);
SimpleDateFormat format = new SimpleDateFormat(LobbySystem.getMessage().parse("JUMP_AND_RUN_TIME", player), Locale.ROOT);
String parsed = format.format(new Date(timeLong));
LobbySystem.getMessage().sendPrefixless("JUMP_AND_RUN_PERSONAL_BEST_TIME", player, parsed);
}
}
@@ -0,0 +1,54 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.listener;
import de.steamwar.lobby.command.ModifyCommand;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import java.util.function.Function;
public class AlphaWall extends BasicListener {
public static float REFLECT_X = 360f;
public static float REFLECT_Z = 180f;
private final Function<Location, Boolean> allowed;
private final float reflect;
public AlphaWall(Function<Location, Boolean> allowed, float reflect) {
this.allowed = allowed;
this.reflect = reflect;
}
@EventHandler
public void onMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
if(ModifyCommand.modifying(player) || allowed.apply(event.getTo()))
return;
Location to = event.getFrom().clone();
to.setYaw(reflect - to.getYaw());
player.teleport(to, PlayerTeleportEvent.TeleportCause.PLUGIN);
}
}
@@ -0,0 +1,31 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.listener;
import de.steamwar.lobby.LobbySystem;
import org.bukkit.Bukkit;
import org.bukkit.event.Listener;
public class BasicListener implements Listener {
public BasicListener () {
Bukkit.getPluginManager().registerEvents(this, LobbySystem.getPlugin());
}
}
@@ -0,0 +1,83 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.listener;
import de.steamwar.lobby.jumpandrun.JumpAndRun;
import de.steamwar.lobby.util.LobbyPlayer;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerToggleFlightEvent;
import org.bukkit.util.Vector;
public class DoubleJumpListener extends BasicListener {
double multiplyer = 1.4;
@EventHandler
public void handlePlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
player.setAllowFlight(true);
player.setFlying(false);
}
@EventHandler
public void handlePlayerToggleFlight(PlayerToggleFlightEvent event) {
Player player = event.getPlayer();
if (JumpAndRun.isPlayerInJumpAndRun(player)) return;
if (player.getGameMode() != GameMode.ADVENTURE && player.getGameMode() != GameMode.SURVIVAL) {
return;
}
if (LobbyPlayer.getLobbyPlayer(player).isFlying()) {
return;
}
event.setCancelled(true);
player.setAllowFlight(false);
player.setFlying(false);
Vector direction = player.getLocation().getDirection();
direction.setX(direction.getX() * multiplyer);
direction.setY(direction.getY() * (multiplyer / 2));
direction.setZ(direction.getZ() * multiplyer);
player.setVelocity(direction.add(new Vector(0, 1.2, 0)));
player.playSound(player.getLocation(), Sound.ENTITY_FIREWORK_ROCKET_LAUNCH, 1.0F, 1.0F);
}
@EventHandler
public void handlePlayerMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
if (JumpAndRun.isPlayerInJumpAndRun(player)) return;
if(player.getLocation().add(0, -1, 0).getBlock().getType() == Material.AIR) return;
if (LobbyPlayer.getLobbyPlayer(player).isFlying()) return;
player.setAllowFlight(true);
if (player.getGameMode() == GameMode.ADVENTURE || player.getGameMode() == GameMode.SURVIVAL) {
player.setFlying(false);
}
}
}
@@ -0,0 +1,85 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.listener;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.command.ModifyCommand;
import de.steamwar.lobby.special.advent.AdventsCalendar;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
import org.bukkit.inventory.ItemStack;
public class InventoryInteraction extends BasicListener {
@EventHandler
public void handlePlayerInteract(PlayerInteractEvent event) {
ItemStack item = event.getItem();
if(item == null)
return;
if(item.getType() == Material.FIREWORK_ROCKET && (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK)) {
int offset;
if (AdventsCalendar.active()) {
offset = -1;
} else {
offset = 0;
}
Bukkit.getScheduler().runTaskLater(LobbySystem.getPlugin(), () -> {
event.getPlayer().getInventory().setItem(PlayerSpawn.FIREWORK_SLOT + offset, PlayerSpawn.FIREWORK);
}, 1L);
return;
}
if(!ModifyCommand.modifying(event.getPlayer()))
event.setCancelled(true);
}
@EventHandler
public void handlePlayerDropItem(PlayerDropItemEvent event) {
event.setCancelled(true);
}
@EventHandler
public void handlePlayerPickupItem(PlayerPickupItemEvent event) {
event.setCancelled(true);
}
@EventHandler(priority = EventPriority.LOWEST)
public void handleInventoryClick(InventoryClickEvent event) {
if(!ModifyCommand.modifying(event.getWhoClicked()))
event.setCancelled(true);
}
@EventHandler
public void handlePlayerSwapHandItemsEvent(PlayerSwapHandItemsEvent event) {
if(!ModifyCommand.modifying(event.getPlayer()))
event.setCancelled(true);
}
}
@@ -0,0 +1,38 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.listener;
import de.steamwar.lobby.command.ModifyCommand;
import org.bukkit.entity.ItemFrame;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerInteractEntityEvent;
public class MapsRotateListener extends BasicListener {
@EventHandler
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
if (ModifyCommand.modifying(event.getPlayer())) {
return;
}
if (event.getRightClicked() instanceof ItemFrame) {
event.setCancelled(true);
}
}
}
@@ -0,0 +1,119 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.listener;
import de.steamwar.lobby.LobbySystem;
import org.bukkit.*;
import org.bukkit.block.data.Bisected;
import org.bukkit.block.data.type.Stairs;
import org.bukkit.entity.AbstractArrow;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scheduler.BukkitRunnable;
import org.spigotmc.event.entity.EntityDismountEvent;
import java.util.HashSet;
import java.util.Set;
public class PlayerSeatListener extends BasicListener{
public static final World world = Bukkit.getWorlds().get(0);
private Set<Location> seats = new HashSet<>();
static {
new BukkitRunnable() {
@Override
public void run() {
for(Arrow arrow : world.getEntitiesByClass(Arrow.class)) {
arrow.setTicksLived(1);
}
}
}.runTaskTimer(LobbySystem.getPlugin(), 20*60,20*60);
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getPlayer().isGliding())
return;
if (event.getAction() != Action.RIGHT_CLICK_BLOCK)
return;
if (!event.getClickedBlock().getType().name().toLowerCase().contains("stairs"))
return;
if (event.getPlayer().getGameMode() != GameMode.ADVENTURE && event.getPlayer().getGameMode() != GameMode.SURVIVAL)
return;
if (((Stairs) event.getClickedBlock().getBlockData()).getHalf() != Bisected.Half.BOTTOM)
return;
if (((Stairs) event.getClickedBlock().getBlockData()).getShape() != Stairs.Shape.STRAIGHT)
return;
if (event.getPlayer().isInsideVehicle() && isArrow(event.getPlayer().getVehicle()))
event.getPlayer().getVehicle().remove();
if (event.getClickedBlock().getRelative(0, 1, 0).getType() != Material.AIR)
return;
Location location = event.getClickedBlock().getLocation();
Location seatLocation = getSeatLocation(location);
if (seats.contains(seatLocation))
return;
seats.add(seatLocation);
Arrow arrow = (Arrow) event.getPlayer().getWorld().spawnEntity(location.add(0.5, 0, 0.5), EntityType.ARROW);
arrow.setGravity(false);
arrow.setPickupStatus(AbstractArrow.PickupStatus.DISALLOWED);
arrow.addPassenger(event.getPlayer());
arrow.setPersistent(true);
}
@EventHandler
public void onEntityDismount(EntityDismountEvent event) {
seats.remove(getSeatLocation(event.getDismounted().getLocation()));
if (event.getEntityType() != EntityType.PLAYER && !isArrow(event.getDismounted()))
return;
event.getDismounted().remove();
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
if (event.getPlayer().isInsideVehicle() && isArrow(event.getPlayer().getVehicle()))
event.getPlayer().getVehicle().remove();
}
public Location getSeatLocation(Location location) {
return new Location(world,location.getBlockX(), location.getBlockY(), location.getBlockZ());
}
private boolean isArrow(Entity entity) {
return entity.getType() == EntityType.ARROW;
}
}
@@ -0,0 +1,91 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.listener;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.boatrace.BoatRace;
import de.steamwar.lobby.special.advent.AdventsCalendar;
import de.steamwar.lobby.util.ItemBuilder;
import de.steamwar.network.NetworkSender;
import de.steamwar.network.packets.client.ImALobbyPacket;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
public class PlayerSpawn extends BasicListener {
public static final int FIREWORK_SLOT = 2;
public static final ItemStack FIREWORK = new ItemBuilder(Material.FIREWORK_ROCKET, 1).setDisplayName("§5Rakete").build();
public static final int PARTICLE_SLOT = 6;
public static final int NETHER_STAR_SLOT = 4;
public static final ItemStack PARTICLE = new ItemBuilder(Material.NAME_TAG).setDisplayName("§6Partikel").setUnbreakable(true).removeAllAttributes().build();
private static final ItemStack ELYTRA = new ItemBuilder(Material.ELYTRA).setDisplayName("§5Elytra").setUnbreakable(true).removeAllAttributes().build();
public static final ItemStack NETHER_STAR = new ItemBuilder(Material.NETHER_STAR).setDisplayName("§5Teleporter").setUnbreakable(true).removeAllAttributes().build();
@EventHandler(priority = EventPriority.HIGH)
public void onJoin(PlayerJoinEvent e) {
Player player = e.getPlayer();
e.setJoinMessage(null);
player.setGameMode(GameMode.ADVENTURE);
player.setWalkSpeed(0.5f);
player.teleport(Bukkit.getWorlds().get(0).getSpawnLocation().clone().add(0.5, 0, 0.5));
player.setHealth(20);
player.setFoodLevel(20);
giveItems(player);
LobbySystem.getEntityServer(false).addPlayer(player);
BoatRace.boatNpcServer.addPlayer(player);
Bukkit.getScheduler().runTaskLater(LobbySystem.getPlugin(), () -> NetworkSender.send(new ImALobbyPacket(), player), 20);
}
public static void giveItems(Player player) {
PlayerInventory inventory = player.getInventory();
inventory.clear();
inventory.setItem(EquipmentSlot.CHEST, ELYTRA);
int offset = 0;
if (AdventsCalendar.active()) {
offset = -1;
}
player.getInventory().setItem(FIREWORK_SLOT + offset, FIREWORK);
player.getInventory().setItem(PARTICLE_SLOT + offset, PARTICLE);
player.getInventory().setItem(NETHER_STAR_SLOT + offset, NETHER_STAR);
}
@EventHandler(priority = EventPriority.HIGH)
public void handlePlayerQuit(PlayerQuitEvent event) {
event.setQuitMessage(null);
}
}
@@ -0,0 +1,70 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.listener;
import de.steamwar.lobby.portal.Portal;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
import java.util.Map;
public class Portals extends BasicListener {
private static final Map<Player, Deque<Portal>> portalStack = new HashMap<>();
public static Deque<Portal> getStack(Player player) {
return portalStack.get(player);
}
@EventHandler
public void onJoin(PlayerJoinEvent e) {
portalStack.put(e.getPlayer(), new ArrayDeque<>());
}
@EventHandler
public void onMove(PlayerMoveEvent e) {
Location from = e.getFrom();
Location to = e.getTo();
assert to != null;
Portal portal = Portal.getPortal(from, to);
if (portal == null)
return;
Player player = e.getPlayer();
Deque<Portal> lastPortals = portalStack.get(player);
if(!lastPortals.isEmpty() && lastPortals.peek() == portal)
return;
portal.handle(player, from, to);
}
@EventHandler
public void onQuit(PlayerQuitEvent e) {
portalStack.remove(e.getPlayer());
}
}
@@ -0,0 +1,71 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.listener;
import de.steamwar.inventory.SWInventory;
import de.steamwar.inventory.SWItem;
import org.bukkit.*;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerInteractEvent;
public class TeleporterListener extends BasicListener {
private static final World world = Bukkit.getWorlds().get(0);
private static final Location spawn = world.getSpawnLocation().clone().add(0.5, 0, 0.5);
private static final Location team = new Location(world,2719.5, 59, 1311.5);
private static final Location map = new Location(world,2336.5,38,1423.5);
private static final Location bau = new Location(world,1951,66.1,1337, -38, -5);
private static final Location arenen = new Location(world,2255.5,21,1450.5);
@EventHandler
public void handlePlayerInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
if (!PlayerSpawn.NETHER_STAR.equals(event.getItem())) return;
SWInventory swInventory = new SWInventory(player, () -> {
return Bukkit.createInventory(null, InventoryType.HOPPER, "§6Teleporter");
});
swInventory.setItem(0, new SWItem(Material.WOODEN_AXE, "§eBaubereich").getItemStack(), clickType -> {
teleport(bau, player);
});
swInventory.setItem(1, new SWItem(Material.MAGMA_CREAM, "§eSpawn").getItemStack(), clickType -> {
teleport(spawn, player);
});
swInventory.setItem(2, new SWItem(Material.BEACON, "§eTeamhalle").getItemStack(), clickType -> {
teleport(team, player);
});
swInventory.setItem(3, new SWItem(Material.MAP, "§eMap").getItemStack(), clickType -> {
teleport(map, player);
});
swInventory.setItem(4, new SWItem(Material.CLOCK, "§eArenen").getItemStack(), clickType -> {
teleport(arenen, player);
});
swInventory.open();
}
private void teleport(Location location, Player player) {
player.teleport(location);
player.playSound(location, Sound.BLOCK_ENCHANTMENT_TABLE_USE, 0.25f, 1.0f);
Portals.getStack(player).clear();
}
}
@@ -0,0 +1,112 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.listener;
import de.steamwar.lobby.command.ModifyCommand;
import org.bukkit.Material;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.hanging.HangingBreakEvent;
import org.bukkit.event.player.PlayerArmorStandManipulateEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.server.MapInitializeEvent;
import org.bukkit.util.Vector;
public class WorldInteraction extends BasicListener {
@EventHandler
public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
if (!(event.getDamager() instanceof Player)) {
return;
}
if(!ModifyCommand.modifying((Player) event.getDamager())) {
event.setCancelled(true);
return;
}
if (!(event.getEntity() instanceof ItemFrame)) {
return;
}
ItemFrame itemFrame = (ItemFrame) event.getEntity();
((Player) event.getDamager()).getInventory().addItem(itemFrame.getItem());
itemFrame.setItem(null);
}
@EventHandler
public void handleEntityDamage(EntityDamageEvent event) {
event.setCancelled(true);
}
@EventHandler
public void handleFoodLevelChange(FoodLevelChangeEvent event) {
event.setCancelled(true);
}
@EventHandler
public void handleBlockBreak(BlockBreakEvent event) {
if(!ModifyCommand.modifying(event.getPlayer()))
event.setCancelled(true);
}
@EventHandler
public void handleBlockPlace(BlockPlaceEvent event) {
if(!ModifyCommand.modifying(event.getPlayer()))
event.setCancelled(true);
}
@EventHandler
public void handleHangingBreak(HangingBreakByEntityEvent event) {
if(!ModifyCommand.modifying((HumanEntity) event.getRemover()))
event.setCancelled(true);
}
@EventHandler
public void handleGoldenPressurePlate(PlayerInteractEvent event) {
if(!ModifyCommand.modifying(event.getPlayer()) && (event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_BLOCK))
event.setCancelled(true);
if(!event.hasBlock() || event.getAction() != Action.PHYSICAL || event.getClickedBlock().getType() != Material.LIGHT_WEIGHTED_PRESSURE_PLATE)
return;
Player player = event.getPlayer();
player.setVelocity(player.getLocation().getDirection().multiply(5).add(new Vector(0, 1, 0)));
}
@EventHandler
public void onBlockPhysics(BlockPhysicsEvent event) {
event.setCancelled(true);
}
@EventHandler
public void onPlayerArmorStandManipulate(PlayerArmorStandManipulateEvent event) {
if(!ModifyCommand.modifying(event.getPlayer()))
event.setCancelled(true);
}
}
@@ -0,0 +1,41 @@
package de.steamwar.lobby.map;
import org.bukkit.map.MapPalette;
import java.awt.*;
import java.io.InputStream;
public class ColorInit {
private static final byte[] colors;
public static int getColor(int r, int g, int b) {
return colors[(r << 16) + (g << 8) + b] & 0xFF;
}
public static byte getColorByte(int r, int g, int b) {
return colors[(r << 16) + (g << 8) + b];
}
static {
long time = System.currentTimeMillis();
InputStream inputStream = ColorInit.class.getResourceAsStream("/colors.nearest");
if (inputStream == null) {
colors = new byte[256 * 256 * 256];
for (int i = 0; i < colors.length; i++) {
colors[i] = MapPalette.matchColor(new Color(i));
}
} else {
try {
byte[] bytes = inputStream.readAllBytes();
if (bytes.length != 256*256*256) {
throw new RuntimeException("Invalid colors.nearest file");
}
colors = bytes;
} catch (Exception e) {
throw new RuntimeException("Failed to read colors.nearest file", e);
}
}
System.out.println("[ColorInit] Initialization took " + (System.currentTimeMillis() - time) + "ms");
}
}
@@ -0,0 +1,362 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.map;
import de.steamwar.lobby.LobbySystem;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.MapMeta;
import org.bukkit.map.MapCanvas;
import org.bukkit.map.MapPalette;
import org.bukkit.map.MapRenderer;
import org.bukkit.map.MapView;
import org.bukkit.util.Vector;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.util.*;
public class CustomMap implements Listener {
public static void init() {
}
private static final CustomMap LEFT = new CustomMap(new File(System.getProperty("user.home") + "/lobbyBanner/left.png"),
new Vector(2346, 48, 1297), new Vector(2345, 48, 1297), new Vector(2344, 48, 1297), new Vector(2343, 48, 1297), new Vector(2342, 48, 1297), new Vector(2341, 48, 1297), new Vector(2340, 48, 1297),
new Vector(2346, 47, 1297), new Vector(2345, 47, 1297), new Vector(2344, 47, 1297), new Vector(2343, 47, 1297), new Vector(2342, 47, 1297), new Vector(2341, 47, 1297), new Vector(2340, 47, 1297),
new Vector(2346, 46, 1297), new Vector(2345, 46, 1297), new Vector(2344, 46, 1297), new Vector(2343, 46, 1297), new Vector(2342, 46, 1297), new Vector(2341, 46, 1297), new Vector(2340, 46, 1297),
new Vector(2346, 45, 1297), new Vector(2345, 45, 1297), new Vector(2344, 45, 1297), new Vector(2343, 45, 1297), new Vector(2342, 45, 1297), new Vector(2341, 45, 1297), new Vector(2340, 45, 1297)
);
private static final CustomMap RIGHT = new CustomMap(new File(System.getProperty("user.home") + "/lobbyBanner/right.png"),
new Vector(2330, 48, 1297), new Vector(2329, 48, 1297), new Vector(2328, 48, 1297), new Vector(2327, 48, 1297), new Vector(2326, 48, 1297), new Vector(2325, 48, 1297), new Vector(2324, 48, 1297),
new Vector(2330, 47, 1297), new Vector(2329, 47, 1297), new Vector(2328, 47, 1297), new Vector(2327, 47, 1297), new Vector(2326, 47, 1297), new Vector(2325, 47, 1297), new Vector(2324, 47, 1297),
new Vector(2330, 46, 1297), new Vector(2329, 46, 1297), new Vector(2328, 46, 1297), new Vector(2327, 46, 1297), new Vector(2326, 46, 1297), new Vector(2325, 46, 1297), new Vector(2324, 46, 1297),
new Vector(2330, 45, 1297), new Vector(2329, 45, 1297), new Vector(2328, 45, 1297), new Vector(2327, 45, 1297), new Vector(2326, 45, 1297), new Vector(2325, 45, 1297), new Vector(2324, 45, 1297)
);
private File mapFile;
private Map<Vector, Integer> itemFrameIndex = new HashMap<>();
private ItemFrame[] itemFrames;
private long lastModified = Long.MAX_VALUE;
public CustomMap(File mapFile, Vector... itemFrames) {
this.mapFile = mapFile;
this.itemFrames = new ItemFrame[itemFrames.length];
for (int i = 0; i < itemFrames.length; i++) {
itemFrameIndex.put(itemFrames[i], i);
}
Bukkit.getScheduler().runTaskTimer(LobbySystem.getPlugin(), () -> {
long modified = mapFile.lastModified();
if (modified > lastModified) {
lastModified = modified;
System.out.println("Updating Banner: " + mapFile.getName());
Bukkit.getScheduler().runTaskAsynchronously(LobbySystem.getPlugin(), () -> {
try {
run();
} catch (IOException e) {
// Ignore
}
});
}
}, 200L, 200L);
Bukkit.getPluginManager().registerEvents(this, LobbySystem.getPlugin());
}
@EventHandler
public void onChunkLoad(ChunkLoadEvent event) {
for (Entity entity : event.getChunk().getEntities()) {
if (!(entity instanceof ItemFrame)) continue;
ItemFrame itemFrame = (ItemFrame) entity;
ItemStack itemStack = itemFrame.getItem();
if (itemStack.getType() != Material.FILLED_MAP) continue;
Vector vector = itemFrame.getLocation().getBlock().getLocation().toVector();
if (itemFrameIndex.containsKey(vector)) {
if (itemFrames[itemFrameIndex.get(vector)] != null) continue;
itemFrames[itemFrameIndex.get(vector)] = itemFrame;
lastModified = 0;
MapView mapView = ((MapMeta) itemFrame.getItem().getItemMeta()).getMapView();
new ArrayList<>(mapView.getRenderers()).forEach(mapView::removeRenderer);
mapView.addRenderer(new MapRenderer() {
@Override
public void render(MapView map, MapCanvas canvas, Player player) {
for (int x = 0; x < 128; x++) {
for (int y = 0; y < 128; y++) {
canvas.setPixel(x, y, (byte) 32);
}
}
}
});
}
}
}
private void run() throws IOException {
BufferedImage bufferedImage = ImageIO.read(mapFile);
Set<Integer>[] patches = new Set[256];
for (int patch = 0; patch < patches.length; patch++) {
patches[patch] = new HashSet<>();
}
for (int y = 0; y < bufferedImage.getHeight(); y++) {
for (int x = 0; x < bufferedImage.getWidth(); x++) {
Color color = new Color(bufferedImage.getRGB(x, y));
double red = color.getRed() / 255.0;
double green = color.getGreen() / 255.0;
double blue = color.getBlue() / 255.0;
double luminance = Math.sqrt(0.299 * red * red + 0.587 * green * green + 0.114 * blue * blue);
luminance *= 255;
patches[(int) luminance].add(x << 16 | y);
}
}
for (int patch = 0; patch < patches.length; patch++) {
Set<Integer> points = patches[patch];
if (points.isEmpty()) continue;
BufferedImage patchImage = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
points.forEach(point -> {
int x = point >>> 16;
int y = point & 0xFFFF;
patchImage.setRGB(x, y, bufferedImage.getRGB(x, y));
});
floodFill(patchImage);
dither(patchImage);
points.forEach(point -> {
int x = point >>> 16;
int y = point & 0xFFFF;
bufferedImage.setRGB(x, y, patchImage.getRGB(x, y));
});
}
for (int y = 0; y < bufferedImage.getHeight(); y += 128) {
for (int x = 0; x < bufferedImage.getWidth(); x += 128) {
ItemFrame itemFrame = itemFrames[y / 128 * 7 + x / 128];
if (itemFrame == null) continue;
int finalX = x;
int finalY = y;
Bukkit.getScheduler().runTaskLater(LobbySystem.getPlugin(), () -> {
ItemStack itemStack = itemFrame.getItem();
MapMeta mapMeta = (MapMeta) itemStack.getItemMeta();
MapView mapView = mapMeta.getMapView();
new ArrayList<>(mapView.getRenderers()).forEach(mapView::removeRenderer);
mapView.addRenderer(new MapRenderer() {
@Override
public void render(MapView map, MapCanvas canvas, Player player) {
for (int dy = 0; dy < 128; dy++) {
for (int dx = 0; dx < 128; dx++) {
int ax = dx + finalX;
int ay = dy + finalY;
Color color = new Color(bufferedImage.getRGB(ax, ay));
canvas.setPixel(dx, dy, ColorInit.getColorByte(color.getRed(), color.getGreen(), color.getBlue()));
}
}
}
});
mapMeta.setMapView(mapView);
itemStack.setItemMeta(mapMeta);
itemFrame.setItem(itemStack);
}, 1);
}
}
}
private static void floodFill(BufferedImage bufferedImage) {
WritableRaster alpha = bufferedImage.getAlphaRaster();
int[] data = alpha.getPixels(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), new int[bufferedImage.getWidth() * bufferedImage.getHeight()]);
for (int i = 0; i < 5; i++) {
Set<Integer> changes = new HashSet<>();
for (int y = 0; y < bufferedImage.getHeight(); y++) {
for (int x = 0; x < bufferedImage.getWidth(); x++) {
if (data[y * bufferedImage.getWidth() + x] == 0) continue;
int color = bufferedImage.getRGB(x, y);
if (x > 0 && data[y * bufferedImage.getWidth() + x - 1] == 0) {
bufferedImage.setRGB(x - 1, y, color);
changes.add((x - 1) << 16 | y);
}
if (x < bufferedImage.getWidth() - 1 && data[y * bufferedImage.getWidth() + x + 1] == 0) {
bufferedImage.setRGB(x + 1, y, color);
changes.add((x + 1) << 16 | y);
}
if (y > 0 && data[(y - 1) * bufferedImage.getWidth() + x] == 0) {
bufferedImage.setRGB(x, y - 1, color);
changes.add(x << 16 | (y - 1));
}
if (y < bufferedImage.getHeight() - 1 && data[(y + 1) * bufferedImage.getWidth() + x] == 0) {
bufferedImage.setRGB(x, y + 1, color);
changes.add(x << 16 | (y + 1));
}
}
}
if (changes.isEmpty()) return;
changes.forEach(point -> {
int x = point >>> 16;
int y = point & 0xFFFF;
data[y * bufferedImage.getWidth() + x] = 255;
});
}
}
private static BufferedImage dither(BufferedImage image) {
final double multiplier1 = 7 / 48.0;
final double multiplier2 = 3 / 48.0;
final double multiplier3 = 5 / 48.0;
final double multiplier4 = 1 / 48.0;
WritableRaster alphaRaster = image.getAlphaRaster();
WritableRaster raster = image.getRaster();
int numBands = raster.getNumBands();
int[] pixels = raster.getPixels(0, 0, image.getWidth(), image.getHeight(), new int[image.getWidth() * image.getHeight() * numBands]);
int width = image.getWidth();
int height = image.getHeight();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (alphaRaster.getPixel(x, y, new int[1])[0] == 0) continue;
int red = pixels[(y * width + x) * numBands];
int i2 = (y * width + x) * numBands + 1;
int green = pixels[i2];
int i3 = (y * width + x) * numBands + 2;
int blue = pixels[i3];
Color nearest = MapPalette.getColor(ColorInit.getColorByte(red, green, blue));
pixels[(y * width + x) * numBands] = nearest.getRed();
pixels[i2] = nearest.getGreen();
pixels[i3] = nearest.getBlue();
int quantErrorRed = red - nearest.getRed();
int quantErrorGreen = green - nearest.getGreen();
int quantErrorBlue = blue - nearest.getBlue();
int mr1 = (int) (quantErrorRed * multiplier1);
int mg1 = (int) (quantErrorGreen * multiplier1);
int mb1 = (int) (quantErrorBlue * multiplier1);
int mr2 = (int) (quantErrorRed * multiplier2);
int mg2 = (int) (quantErrorGreen * multiplier2);
int mb2 = (int) (quantErrorBlue * multiplier2);
int mr3 = (int) (quantErrorRed * multiplier3);
int mg3 = (int) (quantErrorGreen * multiplier3);
int mb3 = (int) (quantErrorBlue * multiplier3);
int mr4 = (int) (quantErrorRed * multiplier4);
int mg4 = (int) (quantErrorGreen * multiplier4);
int mb4 = (int) (quantErrorBlue * multiplier4);
if (x < width - 1) {
int i = (y * width + x + 1) * numBands;
pixels[i] = clamp(pixels[i] + mr1);
pixels[i + 1] = clamp(pixels[i + 1] + mg1);
pixels[i + 2] = clamp(pixels[i + 2] + mb1);
}
if (x < width - 2) {
int i = (y * width + x + 2) * numBands;
pixels[i] = clamp(pixels[i] + mr3);
pixels[i + 1] = clamp(pixels[i + 1] + mg3);
pixels[i + 2] = clamp(pixels[i + 2] + mb3);
}
if (y < height - 1) {
if (x > 1) {
int i = ((y + 1) * width + x - 2) * numBands;
pixels[i] = clamp(pixels[i] + mr2);
pixels[i + 1] = clamp(pixels[i + 1] + mg2);
pixels[i + 2] = clamp(pixels[i + 2] + mb2);
}
if (x > 0) {
int i = ((y + 1) * width + x - 1) * numBands;
pixels[i] = clamp(pixels[i] + mr3);
pixels[i + 1] = clamp(pixels[i + 1] + mg3);
pixels[i + 2] = clamp(pixels[i + 2] + mb3);
}
if (x < width - 1) {
int i = ((y + 1) * width + x + 1) * numBands;
pixels[i] = clamp(pixels[i] + mr3);
pixels[i + 1] = clamp(pixels[i + 1] + mg3);
pixels[i + 2] = clamp(pixels[i + 2] + mb3);
}
if (x < width - 2) {
int i = ((y + 1) * width + x + 2) * numBands;
pixels[i] = clamp(pixels[i] + mr2);
pixels[i + 1] = clamp(pixels[i + 1] + mg2);
pixels[i + 2] = clamp(pixels[i + 2] + mb2);
}
int i = (y * width + x) * numBands;
pixels[i] = clamp(pixels[i] + mr1);
pixels[i + 1] = clamp(pixels[i + 1] + mg1);
pixels[i + 2] = clamp(pixels[i + 2] + mb1);
}
if (y < height - 2) {
if (x > 1) {
int i = ((y + 2) * width + x - 2) * numBands;
pixels[i] = clamp(pixels[i] + mr4);
pixels[i + 1] = clamp(pixels[i + 1] + mg4);
pixels[i + 2] = clamp(pixels[i + 2] + mb4);
}
if (x > 0) {
int i = ((y + 2) * width + x - 1) * numBands;
pixels[i] = clamp(pixels[i] + mr2);
pixels[i + 1] = clamp(pixels[i + 1] + mg2);
pixels[i + 2] = clamp(pixels[i + 2] + mb2);
}
if (x < width - 1) {
int i = ((y + 2) * width + x + 1) * numBands;
pixels[i] = clamp(pixels[i] + mr2);
pixels[i + 1] = clamp(pixels[i + 1] + mg2);
pixels[i + 2] = clamp(pixels[i + 2] + mb2);
}
if (x < width - 2) {
int i = ((y + 2) * width + x + 2) * numBands;
pixels[i] = clamp(pixels[i] + mr4);
pixels[i + 1] = clamp(pixels[i + 1] + mg4);
pixels[i + 2] = clamp(pixels[i + 2] + mb4);
}
int i = (y * width + x) * numBands;
pixels[i] = clamp(pixels[i] + mr3);
pixels[i + 1] = clamp(pixels[i + 1] + mg3);
pixels[i + 2] = clamp(pixels[i + 2] + mb3);
}
}
}
raster.setPixels(0, 0, width, height, pixels);
return image;
}
private static int clamp(int value) {
return Math.max(0, Math.min(value, 255));
}
}
@@ -0,0 +1,76 @@
package de.steamwar.lobby.particle;
import de.steamwar.inventory.SWItem;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.sql.SteamwarUser;
import lombok.Getter;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class ParticleData {
private final Material material;
private final String name;
private final List<String> attributes = new ArrayList<>();
@Getter
private final ParticleRequirement requirement;
@Getter
private final ParticleElement particleElement;
public ParticleData(Material material, String name, ParticleElement particleElement) {
this.material = material;
this.name = name;
this.requirement = ParticleRequirement.NO_REQUIRMENT;
this.particleElement = particleElement;
particleElement.aggregateAttributes(this);
}
public ParticleData(Material material, String name, ParticleRequirement requirement, ParticleElement particleElement) {
this.material = material;
this.name = name;
this.requirement = requirement;
this.particleElement = particleElement;
particleElement.aggregateAttributes(this);
}
public ParticleData add(String attribute) {
attributes.add(attribute);
return this;
}
public SWItem toSWItem(Player player, SteamwarUser user, Set<Integer> eventTeilnahme, String eggHuntConfig) {
String translatedName;
try {
translatedName = LobbySystem.getMessage().parse(name, player);
} catch (Exception e) {
translatedName = name;
}
List<String> lore = new ArrayList<>();
lore.add("");
if (!attributes.isEmpty()) {
lore.add(LobbySystem.getMessage().parse("PARTICLE_ATTRIBUTE", player));
attributes.forEach(attribute -> lore.add(LobbySystem.getMessage().parse(attribute, player)));
lore.add("");
}
String unlockedBy = requirement.getRequirementName(player);
if (unlockedBy != null) {
lore.add(LobbySystem.getMessage().parse("PARTICLE_UNLOCKED_BY", player));
lore.add(unlockedBy);
lore.add("");
}
if (requirement.test(user, eventTeilnahme, eggHuntConfig)) {
lore.add(LobbySystem.getMessage().parse("PARTICLE_SELECT", player));
} else {
lore.add(LobbySystem.getMessage().parse("PARTICLE_LOCKED", player));
}
return new SWItem(material, translatedName, lore, false, clickType -> {});
}
}
@@ -0,0 +1,51 @@
package de.steamwar.lobby.particle;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.entity.Player;
import java.util.Random;
import java.util.function.Consumer;
public interface ParticleElement {
Random RANDOM = new Random();
default Color randomColor() {
return Color.fromRGB(RANDOM.nextInt(255), RANDOM.nextInt(255), RANDOM.nextInt(255));
}
default float randomSize() {
return RANDOM.nextFloat() / 2 + 1;
}
default Particle.DustOptions randomParticleDust() {
return new Particle.DustOptions(randomColor(), randomSize());
}
default void display(Location location, Player root, boolean onlySelf, boolean onlyOther, Consumer<Player> consumer) {
if (onlySelf) {
consumer.accept(root);
return;
}
Bukkit.getOnlinePlayers().forEach(player -> {
if (onlyOther && player == root) {
return;
}
int viewDistance = player.getClientViewDistance() * 16;
if (location.distanceSquared(player.getLocation()) <= viewDistance * viewDistance) {
consumer.accept(player);
}
});
}
default void aggregateAttributes(ParticleData particleData) {
}
default ParticleTickType tickType() {
return ParticleTickType.MOVE;
}
void tick(ParticleTickData particleTickData);
}
@@ -0,0 +1,5 @@
package de.steamwar.lobby.particle;
public interface ParticleEnum {
ParticleData getParticle();
}
@@ -0,0 +1,123 @@
package de.steamwar.lobby.particle;
import de.steamwar.inventory.SWItem;
import de.steamwar.inventory.SWListInv;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.particle.particles.*;
import de.steamwar.lobby.particle.particles.custom.CustomEasterParticle;
import de.steamwar.lobby.particle.particles.custom.CustomPlayerParticle;
import de.steamwar.lobby.particle.particles.custom.CustomTeamParticle;
import de.steamwar.lobby.special.easter.EggHunt;
import de.steamwar.lobby.util.LobbyPlayer;
import de.steamwar.sql.*;
import lombok.experimental.UtilityClass;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
@UtilityClass
public class ParticleInventory {
private final Class<?>[] PARTICLES = {
PlayerParticle.class,
CustomPlayerParticle.class,
TeamParticle.class,
CustomTeamParticle.class,
RainCloudParticle.class,
ServerTeamParticle.class,
EventParticle.class,
EventParticlePlacement.class,
EventParticleParticipation.class,
EasterParticle.class,
CustomEasterParticle.class,
};
public String convertToString(ParticleEnum particleEnum) {
return particleEnum.getClass().getSimpleName() + "@" + ((Enum<?>)particleEnum).name();
}
public ParticleEnum convertFromString(String string) {
String[] split = string.split("@");
Class<?> clazz = null;
for (Class<?> aClass : PARTICLES) {
if (aClass.getSimpleName().equals(split[0])) {
clazz = aClass;
break;
}
}
if (clazz != null) {
try {
return (ParticleEnum) Enum.valueOf((Class<? extends Enum>) clazz, split[1]);
} catch (Exception e) {
return null;
}
}
return null;
}
public void openInventory(Player player, boolean onlyUnlocked) {
LobbyPlayer lobbyPlayer = LobbyPlayer.getLobbyPlayer(player.getUniqueId());
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
Set<Integer> events = user.getTeam() == 0 ? new HashSet<>() : TeamTeilnahme.getEvents(user.getTeam()).stream().map(Event::getEventID).collect(Collectors.toSet());
String eggHuntConfig = UserConfig.getConfig(user.getId(), EggHunt.EGG_HUNT_CONFIG_KEY);
AtomicBoolean hasOneLocked = new AtomicBoolean(false);
List<SWListInv.SWListEntry<ParticleEnum>> particleList = new ArrayList<>();
for (Class<?> clazz : PARTICLES) {
addParticles(particleList, (ParticleEnum[]) clazz.getEnumConstants(), player, onlyUnlocked, hasOneLocked, user, events, eggHuntConfig);
}
for (int i = 0; i < particleList.size() % 45; i++) {
particleList.add(new SWListInv.SWListEntry<>(new SWItem(Material.BLACK_STAINED_GLASS_PANE, " "), null));
}
SWListInv<ParticleEnum> particleSWListInv = new SWListInv<>(player, LobbySystem.getMessage().parse("PARTICLE_INVENTORY", player), false, particleList, (clickType, particle) -> {
if (particle == null) return;
lobbyPlayer.setParticle(particle);
player.closeInventory();
if (ParticleListener.disabled(player)) {
LobbySystem.getMessage().send("PARTICLE_DEACTIVATED", player);
}
});
particleSWListInv.setItem(48, Material.BARRIER, LobbySystem.getMessage().parse("PARTICLE_DESELECT", player), new ArrayList<>(), false, clickType -> {
lobbyPlayer.setParticle(null);
});
if (!hasOneLocked.get()) {
particleSWListInv.setItem(50, Material.GRAY_BANNER, LobbySystem.getMessage().parse("PARTICLE_SHOW_HAS_ALL", player), new ArrayList<>(), false, clickType -> {
});
} else if (onlyUnlocked) {
particleSWListInv.setItem(50, Material.LIME_BANNER, LobbySystem.getMessage().parse("PARTICLE_SHOW_ALL", player), new ArrayList<>(), false, clickType -> {
openInventory(player, false);
});
} else {
particleSWListInv.setItem(50, Material.RED_BANNER, LobbySystem.getMessage().parse("PARTICLE_SHOW_UNLOCKED", player), new ArrayList<>(), false, clickType -> {
openInventory(player, true);
});
}
particleSWListInv.open();
}
private void addParticles(List<SWListInv.SWListEntry<ParticleEnum>> particleList, ParticleEnum[] particleEnums, Player player, boolean onlyUnlocked, AtomicBoolean hasOneLocked, SteamwarUser user, Set<Integer> events, String eggHuntConfig) {
for (ParticleEnum particle : particleEnums) {
ParticleData particleData = particle.getParticle();
SWItem swItem = particleData.toSWItem(player, user, events, eggHuntConfig);
if (particleData.getRequirement().test(user, events, eggHuntConfig)) {
particleList.add(new SWListInv.SWListEntry<>(swItem, particle));
} else {
hasOneLocked.set(true);
if (!onlyUnlocked) {
particleList.add(new SWListInv.SWListEntry<>(swItem, null));
}
}
}
for (int i = 0; i < particleList.size() % 9; i++) {
particleList.add(new SWListInv.SWListEntry<>(new SWItem(Material.BLACK_STAINED_GLASS_PANE, " "), null));
}
}
}
@@ -0,0 +1,117 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.particle;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.jumpandrun.JumpAndRun;
import de.steamwar.lobby.listener.BasicListener;
import de.steamwar.lobby.listener.PlayerSpawn;
import de.steamwar.lobby.util.LobbyPlayer;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.UserPerm;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.HashMap;
import java.util.Map;
public class ParticleListener extends BasicListener {
private static final int PLAYER_MAX_SIZE = 20;
private static final int SERVER_TEAM_MAX_SIZE = 40;
private static double deg = 0;
private static Map<Player, Integer> movingPlayers = new HashMap<>();
public ParticleListener() {
Bukkit.getScheduler().runTaskTimer(LobbySystem.getPlugin(), () -> {
movingPlayers.replaceAll((player, integer) -> integer - 1);
movingPlayers.entrySet().removeIf(entry -> entry.getValue() <= 0);
deg += 0.1;
if (deg > 360) deg = 0;
Bukkit.getOnlinePlayers().forEach(player -> {
if (disabled(player)) return;
if (JumpAndRun.isPlayerInJumpAndRun(player)) return;
LobbyPlayer lobbyPlayer = LobbyPlayer.getLobbyPlayer(player.getUniqueId());
ParticleEnum particle = lobbyPlayer.getParticle();
if (particle == null) return;
ParticleData particleData = particle.getParticle();
ParticleElement particleElement = particleData.getParticleElement();
if (particleElement.tickType() == ParticleTickType.ALWAYS) {
particleElement.tick(new ParticleTickData(player.getWorld(), player, deg, movingPlayers.containsKey(player)));
}
});
}, 0, 1);
}
@EventHandler(priority = EventPriority.NORMAL)
public void handlePlayerInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
if (JumpAndRun.isPlayerInJumpAndRun(player)) return;
if (!PlayerSpawn.PARTICLE.equals(event.getItem())) return;
event.setCancelled(true);
ParticleInventory.openInventory(player, true);
}
@EventHandler
public void handlePlayerMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
if (disabled(player)) return;
if (JumpAndRun.isPlayerInJumpAndRun(player)) return;
LobbyPlayer lobbyPlayer = LobbyPlayer.getLobbyPlayer(player.getUniqueId());
ParticleEnum particle = lobbyPlayer.getParticle();
if (particle == null) return;
ParticleData particleData = particle.getParticle();
ParticleElement particleElement = particleData.getParticleElement();
if (particleElement.tickType() == ParticleTickType.MOVE) {
particleElement.tick(new ParticleTickData(player.getWorld(), player, deg, true));
}
if (event.getFrom().getX() != event.getTo().getX() || event.getFrom().getY() != event.getTo().getY() || event.getFrom().getZ() != event.getTo().getZ()) {
movingPlayers.put(player, 5);
}
}
@EventHandler(ignoreCancelled = true)
public void onPlayerQuit(PlayerQuitEvent event) {
movingPlayers.remove(event.getPlayer());
}
@EventHandler
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
if (PlayerSpawn.PARTICLE.equals(event.getPlayer().getInventory().getItemInMainHand())) {
event.setCancelled(true);
}
}
public static boolean disabled(Player player) {
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
if (Bukkit.getOnlinePlayers().size() > SERVER_TEAM_MAX_SIZE) return true;
return Bukkit.getOnlinePlayers().size() > PLAYER_MAX_SIZE && !user.hasPerm(UserPerm.TEAM);
}
}
@@ -0,0 +1,227 @@
package de.steamwar.lobby.particle;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.special.easter.EggDifficulty;
import de.steamwar.lobby.special.easter.EggHunt;
import de.steamwar.sql.*;
import org.bukkit.entity.Player;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
public interface ParticleRequirement {
String getRequirementName(Player player);
boolean test(SteamwarUser user, Set<Integer> eventTeilname, String eggHuntConfig);
ParticleRequirement SERVER_TEAM = new ParticleRequirement() {
@Override
public String getRequirementName(Player player) {
return LobbySystem.getMessage().parse("PARTICLE_UNLOCKED_BY_SERVER_TEAM", player);
}
@Override
public boolean test(SteamwarUser user, Set<Integer> eventTeilname, String eggHuntConfig) {
return user.hasPerm(UserPerm.TEAM);
}
};
ParticleRequirement NO_REQUIRMENT = new ParticleRequirement() {
@Override
public String getRequirementName(Player player) {
return null;
}
@Override
public boolean test(SteamwarUser user, Set<Integer> eventTeilname, String eggHuntConfig) {
return true;
}
};
ParticleRequirement HAS_TEAM = new ParticleRequirement() {
@Override
public String getRequirementName(Player player) {
return LobbySystem.getMessage().parse("PARTICLE_UNLOCKED_BY_TEAM", player);
}
@Override
public boolean test(SteamwarUser user, Set<Integer> eventTeilname, String eggHuntConfig) {
return user.getTeam() != 0;
}
}.or(SERVER_TEAM);
ParticleRequirement EVENT_PARTICIPATION = new ParticleRequirement() {
@Override
public String getRequirementName(Player player) {
return LobbySystem.getMessage().parse("PARTICLE_UNLOCKED_BY_EVENT", player);
}
@Override
public boolean test(SteamwarUser user, Set<Integer> eventTeilname, String eggHuntConfig) {
return !eventTeilname.isEmpty();
}
}.or(SERVER_TEAM);
ParticleRequirement EGG_HUNT_EASY = _easterEggHuntDifficulty(EggDifficulty.EASY);
ParticleRequirement EGG_HUNT_MEDIUM = _easterEggHuntDifficulty(EggDifficulty.MEDIUM);
ParticleRequirement EGG_HUNT_HARD = _easterEggHuntDifficulty(EggDifficulty.HARD);
ParticleRequirement EGG_HUNT_EXTREME = _easterEggHuntDifficulty(EggDifficulty.EXTREME);
ParticleRequirement EGG_HUNT_ADVANCED = _easterEggHuntDifficulty(EggDifficulty.ADVANCED);
ParticleRequirement EGG_HUNT_FOUND_HALF = new ParticleRequirement() {
@Override
public String getRequirementName(Player player) {
return LobbySystem.getMessage().parse("PARTICLE_UNLOCKED_BY_EASTER_EGG_HUNT_HALF", player);
}
@Override
public boolean test(SteamwarUser user, Set<Integer> eventTeilname, String eggHuntConfig) {
if (eggHuntConfig == null) return false;
int count = 0;
for (int i = 0; i < eggHuntConfig.length(); i++) {
if (eggHuntConfig.charAt(i) == '1') {
count++;
}
}
return count >= EggHunt.getEggList().size() / 2;
}
};
static ParticleRequirement specificTeam(int teamId) {
if (teamId == 0) return NO_REQUIRMENT;
String teamKuerzel = Team.get(teamId).getTeamKuerzel();
return new ParticleRequirement() {
@Override
public String getRequirementName(Player player) {
return LobbySystem.getMessage().parse("PARTICLE_UNLOCKED_BY_SPECIFIC_TEAM", player, teamKuerzel);
}
@Override
public boolean test(SteamwarUser user, Set<Integer> eventTeilname, String eggHuntConfig) {
return user.getTeam() == teamId;
}
}.or(SERVER_TEAM);
}
static ParticleRequirement eventParticipation(int eventId) {
String eventName = Event.get(eventId).getEventName();
return new ParticleRequirement() {
@Override
public String getRequirementName(Player player) {
return LobbySystem.getMessage().parse("PARTICLE_UNLOCKED_BY_EVENT_PARTICIPATION", player, eventName);
}
@Override
public boolean test(SteamwarUser user, Set<Integer> eventTeilname, String eggHuntConfig) {
return eventTeilname.contains(eventId);
}
}.or(SERVER_TEAM);
}
static ParticleRequirement eventPlacement(int eventId, int... placementTeams) {
String eventName = Event.get(eventId).getEventName();
Set<Integer> teams = new HashSet<>();
for (int i : placementTeams) teams.add(i);
return new ParticleRequirement() {
@Override
public String getRequirementName(Player player) {
return LobbySystem.getMessage().parse("PARTICLE_UNLOCKED_BY_EVENT_PLACEMENT", player, eventName);
}
@Override
public boolean test(SteamwarUser user, Set<Integer> eventTeilname, String eggHuntConfig) {
if (!eventTeilname.contains(eventId)) return false;
return teams.contains(user.getTeam());
}
}.or(SERVER_TEAM);
}
static ParticleRequirement _easterEggHuntDifficulty(EggDifficulty difficulty) {
AtomicInteger count = new AtomicInteger();
List<Integer> eggs = EggHunt.getEggList()
.stream()
.map(egg -> {
int id = count.getAndIncrement();
if (egg.getDifficulty() == difficulty) {
return id;
} else {
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
return new ParticleRequirement() {
@Override
public String getRequirementName(Player player) {
return LobbySystem.getMessage().parse("PARTICLE_UNLOCKED_BY_EASTER_EGG_HUNT_DIFFICULTY", player, LobbySystem.getMessage().parse(difficulty.getMessage(), player));
}
@Override
public boolean test(SteamwarUser user, Set<Integer> eventTeilname, String eggHuntConfig) {
if (eggHuntConfig == null) return false;
return eggs.stream().allMatch(id -> eggHuntConfig.length() > id && eggHuntConfig.charAt(id) == '1');
}
};
}
static ParticleRequirement specificPlayer(int userId) {
String userName = SteamwarUser.get(userId).getUserName();
return new ParticleRequirement() {
@Override
public String getRequirementName(Player player) {
return LobbySystem.getMessage().parse("PARTICLE_UNLOCKED_BY_SPECIFIC_USER", player, userName);
}
@Override
public boolean test(SteamwarUser user, Set<Integer> eventTeilname, String eggHuntConfig) {
return user.getId() == userId;
}
}.or(SERVER_TEAM);
}
static ParticleRequirement easterEventSpecificPlayer(int userId) {
String userName = SteamwarUser.get(userId).getUserName();
return new ParticleRequirement() {
@Override
public String getRequirementName(Player player) {
return LobbySystem.getMessage().parse("PARTICLE_UNLOCKED_BY_SPECIFIC_USER_EASTER", player, userName);
}
@Override
public boolean test(SteamwarUser user, Set<Integer> eventTeilname, String eggHuntConfig) {
return user.getId() == userId;
}
}.or(SERVER_TEAM);
}
static ParticleRequirement easterEventSpecificTeam(int teamId) {
if (teamId == 0) return NO_REQUIRMENT;
String teamKuerzel = Team.get(teamId).getTeamKuerzel();
return new ParticleRequirement() {
@Override
public String getRequirementName(Player player) {
return LobbySystem.getMessage().parse("PARTICLE_UNLOCKED_BY_SPECIFIC_TEAM_EASTER", player, teamKuerzel);
}
@Override
public boolean test(SteamwarUser user, Set<Integer> eventTeilname, String eggHuntConfig) {
return user.getTeam() == teamId;
}
}.or(SERVER_TEAM);
}
default ParticleRequirement or(ParticleRequirement particleRequirement) {
return new ParticleRequirement() {
@Override
public String getRequirementName(Player player) {
return ParticleRequirement.this.getRequirementName(player);
}
@Override
public boolean test(SteamwarUser user, Set<Integer> eventTeilname, String eggHuntConfig) {
return ParticleRequirement.this.test(user, eventTeilname, eggHuntConfig) || particleRequirement.test(user, eventTeilname, eggHuntConfig);
}
};
}
}
@@ -0,0 +1,51 @@
package de.steamwar.lobby.particle;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
@RequiredArgsConstructor
@AllArgsConstructor
@Getter
public class ParticleTickData {
private final World world;
private final Player player;
private Location location;
private final double deg;
private final boolean isMoving;
private boolean onlySelf = false;
private boolean onlyOthers = false;
public ParticleTickData withLocation(Location location) {
ParticleTickData particleTickData = copy();
particleTickData.location = location;
return particleTickData;
}
public ParticleTickData onlySelf() {
ParticleTickData particleTickData = copy();
particleTickData.onlySelf = true;
return particleTickData;
}
public ParticleTickData onlyOthers() {
ParticleTickData particleTickData = copy();
particleTickData.onlyOthers = true;
return particleTickData;
}
public Location getLocation() {
if (location == null) {
return player.getLocation();
}
return location;
}
public ParticleTickData copy() {
return new ParticleTickData(world, player, location, deg, isMoving, onlySelf, onlyOthers);
}
}
@@ -0,0 +1,8 @@
package de.steamwar.lobby.particle;
public enum ParticleTickType {
ALWAYS,
MOVE,
;
}
@@ -0,0 +1,56 @@
package de.steamwar.lobby.particle;
import lombok.SneakyThrows;
import org.bukkit.util.Vector;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
public interface WingDesign {
@SneakyThrows
static Vector[] create(String resource) {
List<Vector> vectors = new ArrayList<>();
BufferedImage bufferedImage = ImageIO.read(WingDesign.class.getResourceAsStream(resource));
for (int x = 0; x < bufferedImage.getWidth(); x++) {
for (int y = 0; y < bufferedImage.getHeight(); y++) {
int rgb = bufferedImage.getRGB(x, y);
if (Color.WHITE.getRGB() != rgb) {
vectors.add(new Vector(x - bufferedImage.getWidth() / 2.0, bufferedImage.getHeight() - y - 1.0, 0));
}
}
}
return vectors.toArray(new Vector[0]);
}
class WingDesignImpl implements WingDesign {
private final Vector[] vectors;
public WingDesignImpl(Vector[] vectors) {
this.vectors = vectors;
}
@Override
public Vector[] getVectors() {
return vectors;
}
}
Vector[] getVectors();
WingDesign SIMPLE = new WingDesignImpl(create("/de/steamwar/lobby/particle/decorator/WingSimple4.png"));
WingDesign COMPLEX = new WingDesignImpl(create("/de/steamwar/lobby/particle/decorator/WingSimple2.png"));
WingDesign SWORD = new WingDesignImpl(create("/de/steamwar/lobby/particle/decorator/WingSword.png"));
WingDesign SW = new WingDesignImpl(create("/de/steamwar/lobby/particle/decorator/WingSW.png"));
WingDesign WGS = new WingDesignImpl(create("/de/steamwar/lobby/particle/decorator/WingWGS.png"));
WingDesign SWORD_CROSSED = new WingDesignImpl(create("/de/steamwar/lobby/particle/decorator/WingSwordCrossed.png"));
WingDesign MWGL = new WingDesignImpl(create("/de/steamwar/lobby/particle/decorator/MWGL.png"));
WingDesign ECLIPSE = new WingDesignImpl(create("/de/steamwar/lobby/particle/decorator/ECLIPSE-Logo.png"));
WingDesign PL = new WingDesignImpl(create("/de/steamwar/lobby/particle/decorator/PL-Logo.png"));
WingDesign PlompaEasterWings = new WingDesignImpl(create("/de/steamwar/lobby/particle/decorator/ECAL-Logo.png"));
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 855 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 B

@@ -0,0 +1,27 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
import de.steamwar.lobby.particle.ParticleTickType;
public class Always extends DelegatingParticleElement {
public Always(ParticleElement particleElement) {
super(particleElement);
}
@Override
public String attribute() {
return "PARTICLE_ATTRIBUTE_TICK";
}
@Override
public ParticleTickType tickType() {
return ParticleTickType.ALWAYS;
}
@Override
public void tick(ParticleTickData particleTickData) {
particleElement.tick(particleTickData);
}
}
@@ -0,0 +1,39 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
import org.bukkit.Location;
import org.bukkit.util.Vector;
public class Circle extends DelegatingParticleElement {
private double distance;
private double speed;
public Circle(ParticleElement particleElement) {
super(particleElement);
this.distance = 1;
this.speed = 1;
}
public Circle(ParticleElement particleElement, double distance, double speed) {
super(particleElement);
this.distance = distance;
this.speed = speed;
}
@Override
public String attribute() {
return "PARTICLE_ATTRIBUTE_CIRCLE";
}
@Override
public void tick(ParticleTickData particleTickData) {
Location location = particleTickData.getLocation();
Vector vector = new Vector(distance, 0, 0);
vector.rotateAroundY((particleTickData.getDeg() * speed) % 360);
ParticleTickData nParticleTickData = particleTickData.withLocation(location.clone().add(vector));
particleElement.tick(nParticleTickData);
}
}
@@ -0,0 +1,31 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
import org.bukkit.Material;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
public class Cloud extends DelegatingParticleElement {
public Cloud(ParticleElement particleElement) {
super(particleElement);
}
@Override
public String attribute() {
return "PARTICLE_ATTRIBUTE_CLOUD";
}
@Override
public void tick(ParticleTickData particleTickData) {
if (particleTickData.getWorld().getBlockAt(particleTickData.getPlayer().getLocation().subtract(0, 0.5, 0)).getType() == Material.AIR) {
particleTickData.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.SLOW_FALLING, 5, 2, false, false, false));
} else {
particleTickData.getPlayer().removePotionEffect(PotionEffectType.SLOW_FALLING);
return;
}
ParticleTickData nParticleTickData = particleTickData.withLocation(particleTickData.getLocation().subtract(0, -0.2, 0));
particleElement.tick(nParticleTickData);
}
}
@@ -0,0 +1,52 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.HashMap;
import java.util.Map;
public class Delayed extends DelegatingParticleElement {
private DelayedData delayedData = new DelayedData();
private int interval;
private static class DelayedData implements Listener {
private Map<Player, Integer> data = new HashMap<>();
@EventHandler(ignoreCancelled = true)
public void onPlayerQuit(PlayerQuitEvent event) {
data.remove(event.getPlayer());
}
}
public Delayed(ParticleElement particleElement, int interval) {
super(particleElement);
Bukkit.getPluginManager().registerEvents(delayedData, LobbySystem.getPlugin());
this.interval = interval;
if (interval <= 0) {
throw new IllegalArgumentException("Interval must be greater than 0");
}
}
@Override
public String attribute() {
return null;
}
@Override
public void tick(ParticleTickData particleTickData) {
int currentNumber = delayedData.data.getOrDefault(particleTickData.getPlayer(), 0) % interval;
delayedData.data.put(particleTickData.getPlayer(), currentNumber + 1);
if (currentNumber != 0) {
return;
}
particleElement.tick(particleTickData);
}
}
@@ -0,0 +1,30 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.particle.ParticleData;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickType;
public abstract class DelegatingParticleElement implements ParticleElement {
protected final ParticleElement particleElement;
protected DelegatingParticleElement(ParticleElement particleElement) {
this.particleElement = particleElement;
}
public abstract String attribute();
@Override
public void aggregateAttributes(ParticleData particleData) {
String attribute = attribute();
if (attribute != null) {
particleData.add(attribute);
}
particleElement.aggregateAttributes(particleData);
}
@Override
public ParticleTickType tickType() {
return particleElement.tickType();
}
}
@@ -0,0 +1,58 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
import de.steamwar.lobby.particle.ParticleTickType;
import org.bukkit.Location;
import org.bukkit.util.Vector;
public class DoubleCircle extends Circle {
private ParticleElement second;
private double distance;
private double speed;
public DoubleCircle(ParticleElement first, ParticleElement second) {
super(first);
this.second = second;
this.distance = 1;
this.speed = 1;
}
public DoubleCircle(ParticleElement first, ParticleElement second, double distance, double speed) {
super(first);
this.second = second;
this.distance = distance;
this.speed = speed;
}
@Override
public String attribute() {
return "PARTICLE_ATTRIBUTE_BI_CIRCLE";
}
@Override
public ParticleTickType tickType() {
if (particleElement.tickType() == second.tickType()) {
return particleElement.tickType();
}
return ParticleTickType.MOVE;
}
@Override
public void tick(ParticleTickData particleTickData) {
Location location = particleTickData.getLocation();
Vector vector = new Vector(distance, 0, 0);
vector.rotateAroundY((particleTickData.getDeg() * speed) % 360);
ParticleTickData nParticleTickData = particleTickData.withLocation(location.clone().add(vector));
particleElement.tick(nParticleTickData);
vector.setX(-vector.getX());
vector.setZ(-vector.getZ());
nParticleTickData = particleTickData.withLocation(location.clone().add(vector));
second.tick(nParticleTickData);
}
}
@@ -0,0 +1,44 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
import org.bukkit.Location;
import org.bukkit.Particle;
public class DustParticle implements ParticleElement {
private Particle particle;
private float vx = 0.01f;
private float vy = 0.01f;
private float vz = 0.01f;
private double speed = 0.01;
private int count = 5;
public DustParticle(Particle particle) {
this.particle = particle;
}
public DustParticle(Particle particle, float vx, float vy, float vz) {
this.particle = particle;
this.vx = vx;
this.vy = vy;
this.vz = vz;
}
public DustParticle(Particle particle, float vx, float vy, float vz, double speed, int count) {
this.particle = particle;
this.vx = vx;
this.vy = vy;
this.vz = vz;
this.speed = speed;
this.count = count;
}
@Override
public void tick(ParticleTickData particleTickData) {
Location location = particleTickData.getLocation().add(0.0, 0.2, 0.0);
display(location, particleTickData.getPlayer(), particleTickData.isOnlySelf(), particleTickData.isOnlyOthers(), player -> {
player.spawnParticle(particle, location, count, vx, vy, vz, speed, randomParticleDust());
});
}
}
@@ -0,0 +1,23 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
public class Floor extends DelegatingParticleElement {
public Floor(ParticleElement particleElement) {
super(particleElement);
}
@Override
public String attribute() {
return "PARTICLE_ATTRIBUTE_FLOOR";
}
@Override
public void tick(ParticleTickData particleTickData) {
if (!particleTickData.getWorld().getBlockAt(particleTickData.getPlayer().getLocation().subtract(0, 0.5, 0)).getType().isAir()) {
particleElement.tick(particleTickData);
}
}
}
@@ -0,0 +1,24 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
public class Flying extends DelegatingParticleElement {
public Flying(ParticleElement particleElement) {
super(particleElement);
}
@Override
public String attribute() {
return "PARTICLE_ATTRIBUTE_FLYING";
}
@Override
public void tick(ParticleTickData particleTickData) {
if (!particleTickData.getPlayer().isGliding()) {
return;
}
particleElement.tick(particleTickData);
}
}
@@ -0,0 +1,36 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.particle.ParticleData;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
public class Group extends DelegatingParticleElement {
private final ParticleElement[] rest;
public Group(ParticleElement particleElement, ParticleElement... rest) {
super(particleElement);
this.rest = rest;
}
@Override
public String attribute() {
return null;
}
@Override
public void aggregateAttributes(ParticleData particleData) {
particleElement.aggregateAttributes(particleData);
for (ParticleElement particleElement : rest) {
particleElement.aggregateAttributes(particleData);
}
}
@Override
public void tick(ParticleTickData particleTickData) {
particleElement.tick(particleTickData);
for (ParticleElement particleElement : rest) {
particleElement.tick(particleTickData);
}
}
}
@@ -0,0 +1,32 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
import org.bukkit.Location;
import java.util.function.UnaryOperator;
public class LocationMutator extends DelegatingParticleElement {
private UnaryOperator<Location> mutator;
public LocationMutator(ParticleElement particleElement, UnaryOperator<Location> mutator) {
super(particleElement);
this.mutator = mutator;
}
public LocationMutator(ParticleElement particleElement, double vx, double vy, double vz) {
this(particleElement, location -> location.add(vx, vy, vz));
}
@Override
public String attribute() {
return null;
}
@Override
public void tick(ParticleTickData particleTickData) {
ParticleTickData nParticleTickData = particleTickData.withLocation(mutator.apply(particleTickData.getLocation()));
particleElement.tick(nParticleTickData);
}
}
@@ -0,0 +1,23 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
public class NonFloor extends DelegatingParticleElement {
public NonFloor(ParticleElement particleElement) {
super(particleElement);
}
@Override
public String attribute() {
return "PARTICLE_ATTRIBUTE_NON_FLOOR";
}
@Override
public void tick(ParticleTickData particleTickData) {
if (particleTickData.getWorld().getBlockAt(particleTickData.getPlayer().getLocation().subtract(0, 0.5, 0)).getType().isAir()) {
particleElement.tick(particleTickData);
}
}
}
@@ -0,0 +1,24 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
public class NonFlying extends DelegatingParticleElement {
public NonFlying(ParticleElement particleElement) {
super(particleElement);
}
@Override
public String attribute() {
return "PARTICLE_ATTRIBUTE_NON_FLYING";
}
@Override
public void tick(ParticleTickData particleTickData) {
if (particleTickData.getPlayer().isGliding()) {
return;
}
particleElement.tick(particleTickData);
}
}
@@ -0,0 +1,21 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
public class OnlyOthers extends DelegatingParticleElement {
public OnlyOthers(ParticleElement particleElement) {
super(particleElement);
}
@Override
public String attribute() {
return null;
}
@Override
public void tick(ParticleTickData particleTickData) {
particleElement.tick(particleTickData.onlyOthers());
}
}
@@ -0,0 +1,21 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
public class OnlySelf extends DelegatingParticleElement {
public OnlySelf(ParticleElement particleElement) {
super(particleElement);
}
@Override
public String attribute() {
return null;
}
@Override
public void tick(ParticleTickData particleTickData) {
particleElement.tick(particleTickData.onlySelf());
}
}
@@ -0,0 +1,57 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleEnum;
import de.steamwar.lobby.particle.ParticleTickData;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class RandomParticle implements ParticleElement {
private RandomData randomData;
private ParticleEnum[] particleEnums;
private static class RandomData implements Listener {
private Random random = new Random();
private int max;
private Map<Player, Integer> data = new HashMap<>();
public RandomData(int max) {
this.max = max;
}
@EventHandler(ignoreCancelled = true)
public void onPlayerJoin(PlayerJoinEvent event) {
data.put(event.getPlayer(), random.nextInt(max));
}
@EventHandler(ignoreCancelled = true)
public void onPlayerQuit(PlayerQuitEvent event) {
data.remove(event.getPlayer());
}
}
public RandomParticle(ParticleEnum... particleEnums) {
if (particleEnums.length == 0) {
throw new IllegalArgumentException("ParticleEnums must not be empty");
}
this.randomData = new RandomData(particleEnums.length);
Bukkit.getPluginManager().registerEvents(randomData, LobbySystem.getPlugin());
this.particleEnums = particleEnums;
}
@Override
public void tick(ParticleTickData particleTickData) {
int currentNumber = randomData.data.getOrDefault(particleTickData.getPlayer(), 0);
particleEnums[currentNumber].getParticle().getParticleElement().tick(particleTickData);
}
}
@@ -0,0 +1,18 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.particle.ParticleData;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
public class Separator implements ParticleElement {
@Override
public void aggregateAttributes(ParticleData particleData) {
particleData.add("PARTICLE_ATTRIBUTE_SEPARATOR");
}
@Override
public void tick(ParticleTickData particleTickData) {
// do nothing
}
}
@@ -0,0 +1,66 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
import org.bukkit.Location;
import org.bukkit.Particle;
public class SimpleParticle implements ParticleElement {
private final Particle particle;
private boolean customVelocity = false;
private float vx;
private float vy;
private float vz;
private double time = 1;
private int count = 5;
public SimpleParticle(Particle particle) {
this.particle = particle;
}
public SimpleParticle(Particle particle, float vx, float vy, float vz) {
this.particle = particle;
this.customVelocity = true;
this.vx = vx;
this.vy = vy;
this.vz = vz;
}
public SimpleParticle(Particle particle, float vx, float vy, float vz, double time) {
this.particle = particle;
this.customVelocity = true;
this.vx = vx;
this.vy = vy;
this.vz = vz;
this.time = time;
}
public SimpleParticle(Particle particle, float vx, float vy, float vz, double time, int count) {
this.particle = particle;
this.customVelocity = true;
this.vx = vx;
this.vy = vy;
this.vz = vz;
this.time = time;
this.count = count;
}
public SimpleParticle(Particle particle, double time, int count) {
this.particle = particle;
this.time = time;
this.count = count;
}
@Override
public void tick(ParticleTickData particleTickData) {
Location location = particleTickData.getLocation().add(0.0, 0.2, 0.0);
display(location, particleTickData.getPlayer(), particleTickData.isOnlySelf(), particleTickData.isOnlyOthers(), player -> {
if (customVelocity) {
player.spawnParticle(particle, location, count, vx, vy, vz, time);
} else {
player.spawnParticle(particle, location, count);
}
});
}
}
@@ -0,0 +1,24 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
public class Sneaking extends DelegatingParticleElement {
public Sneaking(ParticleElement particleElement) {
super(particleElement);
}
@Override
public String attribute() {
return "PARTICLE_ATTRIBUTE_SNEAKING";
}
@Override
public void tick(ParticleTickData particleTickData) {
if (!particleTickData.getPlayer().isSneaking()) {
return;
}
particleElement.tick(particleTickData);
}
}
@@ -0,0 +1,37 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
import de.steamwar.lobby.particle.WingDesign;
import org.bukkit.Location;
import org.bukkit.util.Vector;
public class Wing extends DelegatingParticleElement {
private double size;
private WingDesign wingDesign;
public Wing(ParticleElement particleElement, double size, WingDesign wingDesign) {
super(particleElement);
this.size = size;
this.wingDesign = wingDesign;
}
@Override
public String attribute() {
return "PARTICLE_ATTRIBUTE_WING";
}
@Override
public void tick(ParticleTickData particleTickData) {
for (Vector dVector : wingDesign.getVectors()) {
Vector vector = new Vector(dVector.getX() * size, 0.6 + dVector.getY() * size - (particleTickData.getPlayer().isSneaking() ? 0.5 : 0), 0.5);
vector.rotateAroundY(Math.toRadians(particleTickData.getPlayer().getLocation().getYaw() * -1));
vector.setX(-vector.getX());
vector.setZ(-vector.getZ());
Location location = particleTickData.getPlayer().getLocation().clone().add(vector);
ParticleTickData current = particleTickData.withLocation(location);
particleElement.tick(current);
}
}
}
@@ -0,0 +1,44 @@
package de.steamwar.lobby.particle.elements.custom;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
import de.steamwar.lobby.particle.elements.DelegatingParticleElement;
import org.bukkit.Location;
import org.bukkit.util.Vector;
public class HearthBeat extends DelegatingParticleElement {
private double speed;
private double y(double time) {
double d1 = Math.pow(2, -Math.pow(time * 17 - 7.5, 2));
double d2 = Math.pow(2, -Math.pow(time * 20 - 11, 2)) * 0.5;
double d3 = Math.pow(2, -Math.pow(time * 25 - 17, 2)) * 0.1;
return (d1 - d2 + d3) * 0.5;
}
public HearthBeat(ParticleElement particleElement, double speed) {
super(particleElement);
this.speed = speed;
}
@Override
public String attribute() {
return null;
}
@Override
public void tick(ParticleTickData particleTickData) {
double time = ((particleTickData.getDeg() * speed) % 360) / 360.0;
double y = y(time) * 2;
double x = (time - 0.5) * 2;
Vector vector = new Vector(x, 1.1 + y - (particleTickData.getPlayer().isSneaking() ? 0.5 : 0), 0.7);
vector.rotateAroundY(Math.toRadians(particleTickData.getPlayer().getLocation().getYaw() * -1));
vector.setX(-vector.getX());
vector.setZ(-vector.getZ());
Location location = particleTickData.getPlayer().getLocation().clone().add(vector);
ParticleTickData current = particleTickData.withLocation(location);
particleElement.tick(current);
}
}
@@ -0,0 +1,25 @@
package de.steamwar.lobby.particle.elements.custom;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
import de.steamwar.lobby.particle.elements.DelegatingParticleElement;
public class NonMoving extends DelegatingParticleElement {
public NonMoving(ParticleElement particleElement) {
super(particleElement);
}
@Override
public String attribute() {
return "PARTICLE_ATTRIBUTE_NON_MOVING";
}
@Override
public void tick(ParticleTickData particleTickData) {
if (particleTickData.isMoving()) {
return;
}
particleElement.tick(particleTickData);
}
}
@@ -0,0 +1,50 @@
package de.steamwar.lobby.particle.elements.custom;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
import de.steamwar.lobby.particle.elements.DelegatingParticleElement;
import org.bukkit.util.Vector;
public class PulseShimmer extends DelegatingParticleElement {
private int speed;
private int rotationSpeed;
private double x(double time) {
if (time < 0.45) {
return Math.pow(2, -Math.pow((time - 0.45) * 6, 2)) * 0.8;
} else {
return Math.pow(2, -Math.pow((time - 0.45) * 4, 2)) * 0.8;
}
}
private double y(double time) {
return (8 * Math.pow(time, 2.2) - time) / (6.5 / 3.5) -0.1;
}
public PulseShimmer(ParticleElement particleElement, int speed, int rotationSpeed) {
super(particleElement);
this.speed = speed;
this.rotationSpeed = rotationSpeed;
}
@Override
public String attribute() {
return null;
}
@Override
public void tick(ParticleTickData particleTickData) {
double time = ((particleTickData.getDeg() * speed) % 360) / 360.0;
double x = x(time);
double y = y(time);
Vector vector = new Vector(x, y, 0);
vector.rotateAroundY((particleTickData.getDeg() * rotationSpeed) % 360);
particleElement.tick(particleTickData.withLocation(particleTickData.getLocation().clone().add(vector)));
vector.rotateAroundY(90);
particleElement.tick(particleTickData.withLocation(particleTickData.getLocation().clone().add(vector)));
vector.rotateAroundY(90);
particleElement.tick(particleTickData.withLocation(particleTickData.getLocation().clone().add(vector)));
}
}
@@ -0,0 +1,47 @@
package de.steamwar.lobby.particle.elements.custom;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
import de.steamwar.lobby.particle.elements.DelegatingParticleElement;
public class YOffset extends DelegatingParticleElement {
private double multiplication;
private double minY;
private double maxY;
private boolean inverted;
public YOffset(ParticleElement particleElement, double speed, double minY, double maxY, boolean inverted) {
super(particleElement);
this.multiplication = speed;
this.minY = minY;
this.maxY = maxY;
this.inverted = inverted;
}
@Override
public String attribute() {
return null;
}
@Override
public void tick(ParticleTickData particleTickData) {
double value = ((particleTickData.getDeg() * multiplication) % 360) / 180;
double y;
if (inverted) {
if (value <= 1) {
y = maxY - (maxY - minY) * value;
} else {
y = minY + (maxY - minY) * (value - 1);
}
} else {
if (value <= 1) {
y = minY + (maxY - minY) * value;
} else {
y = maxY - (maxY - minY) * (value - 1);
}
}
ParticleTickData current = particleTickData.withLocation(particleTickData.getLocation().clone().add(0, y, 0));
particleElement.tick(current);
}
}
@@ -0,0 +1,51 @@
package de.steamwar.lobby.particle.particles;
import de.steamwar.lobby.particle.ParticleData;
import de.steamwar.lobby.particle.ParticleEnum;
import de.steamwar.lobby.particle.ParticleRequirement;
import de.steamwar.lobby.particle.elements.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
@AllArgsConstructor
public enum EasterParticle implements ParticleEnum {
EGG_HUNT_EASY(new ParticleData(Material.LIME_CONCRETE_POWDER, "PARTICLE_EGG_HUNT_EASY", ParticleRequirement.EGG_HUNT_EASY,
new Always(new LocationMutator(new SimpleParticle(Particle.FALLING_SPORE_BLOSSOM, 0.5F, 0.1f, 0.5F, 1, 1), 0, 2.2, 0)))
),
EGG_HUNT_MEDIUM(new ParticleData(Material.YELLOW_CONCRETE_POWDER, "PARTICLE_EGG_HUNT_MEDIUM", ParticleRequirement.EGG_HUNT_MEDIUM,
new Always(new Floor(new Sneaking(new SimpleParticle(Particle.GLOW_SQUID_INK, 0.4F, 0.9F, 0.4F, 0.01)))))
),
EGG_HUNT_HARD(new ParticleData(Material.RED_CONCRETE_POWDER, "PARTICLE_EGG_HUNT_HARD", ParticleRequirement.EGG_HUNT_HARD,
new Always(new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0.01, 1), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0.01, 1)), 0, 0.5, 0)))
),
EGG_HUNT_EXTREME(new ParticleData(Material.PURPLE_CONCRETE_POWDER, "PARTICLE_EGG_HUNT_EXTREME", ParticleRequirement.EGG_HUNT_EXTREME,
new Always(new LocationMutator(new SimpleParticle(Particle.FALLING_OBSIDIAN_TEAR, 0.5F, 0.1F, 0.5F, 1, 1), 0, 2.2, 0)))
),
EGG_HUNT_ADVANCED(new ParticleData(Material.BLACK_CONCRETE_POWDER, "PARTICLE_EGG_HUNT_ADVANCED", ParticleRequirement.EGG_HUNT_ADVANCED,
new Always(new Sneaking(new LocationMutator(new Group(
new SimpleParticle(Particle.SMOKE_NORMAL, 0.02F, 0, 0.02F, 0.05, 1),
new SimpleParticle(Particle.SMOKE_LARGE, 0.02F, 0, 0.02F, 0.05, 1),
particleTickData -> {
Player player = particleTickData.getPlayer();
player.setVelocity(player.getVelocity().add(new Vector(0, 0.1, 0)));
}
), 0, -0.2, 0))))
),
EGG_HUNT_HALF(new ParticleData(Material.EGG, "PARTICLE_EGG_HUNT_HALF", ParticleRequirement.EGG_HUNT_FOUND_HALF,
new Group(
new Always(new Sneaking(new Floor(new LocationMutator(new SimpleParticle(Particle.HEART, 0, 0, 0, 0.01), 0, 1.7, 0)))),
new Separator(),
new Always(new NonFloor(new NonFlying(new LocationMutator(new Cloud(new Circle(new SimpleParticle(Particle.HEART, 0, 0, 0, 0.01))), 0, 0.5, 0))))
))
),
;
public static ParticleEnum[] particles = values();
@Getter
private ParticleData particle;
}
@@ -0,0 +1,29 @@
package de.steamwar.lobby.particle.particles;
import de.steamwar.lobby.particle.ParticleData;
import de.steamwar.lobby.particle.ParticleEnum;
import de.steamwar.lobby.particle.ParticleRequirement;
import de.steamwar.lobby.particle.elements.Always;
import de.steamwar.lobby.particle.elements.Circle;
import de.steamwar.lobby.particle.elements.LocationMutator;
import de.steamwar.lobby.particle.elements.SimpleParticle;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.Material;
import org.bukkit.Particle;
@AllArgsConstructor
public enum EventParticle implements ParticleEnum {
WATER(new ParticleData(Material.WATER_BUCKET, "PARTICLE_WATER", ParticleRequirement.EVENT_PARTICIPATION,
new Always(new Circle(new LocationMutator(new SimpleParticle(Particle.DRIP_WATER), 0, 1.1, 0))))
),
LAVA(new ParticleData(Material.LAVA_BUCKET, "PARTICLE_FIRE", ParticleRequirement.EVENT_PARTICIPATION,
new Always(new Circle(new LocationMutator(new SimpleParticle(Particle.DRIP_LAVA), 0, 1.1, 0))))
),
;
public static ParticleEnum[] particles = values();
@Getter
private ParticleData particle;
}
@@ -0,0 +1,45 @@
package de.steamwar.lobby.particle.particles;
import de.steamwar.lobby.particle.ParticleData;
import de.steamwar.lobby.particle.ParticleEnum;
import de.steamwar.lobby.particle.ParticleRequirement;
import de.steamwar.lobby.particle.WingDesign;
import de.steamwar.lobby.particle.elements.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.Material;
import org.bukkit.Particle;
@AllArgsConstructor
public enum EventParticleParticipation implements ParticleEnum {
WarGearSeason(new ParticleData(Material.BOOK, "PARTICLE_EVENT_ENCHANTING", ParticleRequirement.eventParticipation(22),
new SimpleParticle(Particle.ENCHANTMENT_TABLE))
),
AirshipEvent(new ParticleData(Material.SNOW_BLOCK, "PARTICLE_EVENT_CLOUD", ParticleRequirement.eventParticipation(26),
new SimpleParticle(Particle.CLOUD))
),
HellsBellsWs(new ParticleData(Material.TNT, "PARTICLE_EVENT_SMOKE", ParticleRequirement.eventParticipation(28),
new Circle(new SimpleParticle(Particle.CAMPFIRE_COSY_SMOKE, 0, 0, 0, 0.01)))
),
Underwater(new ParticleData(Material.PRISMARINE_BRICKS, "PARTICLE_EVENT_WATER", ParticleRequirement.eventParticipation(31),
new SimpleParticle(Particle.DRIP_WATER))
),
AdventWarShip(new ParticleData(Material.PRISMARINE_WALL, "PARTICLE_EVENT_WATER", ParticleRequirement.eventParticipation(32),
new Group(new SimpleParticle(Particle.DRIP_WATER), new SimpleParticle(Particle.WATER_WAKE, 0.2F, 0.2F, 0.2F, 0.01)))
),
MiniWarGearLiga(new ParticleData(Material.PRISMARINE_SLAB, "PARTICLE_EVENT_WATER", ParticleRequirement.eventParticipation(33),
new Circle(new SimpleParticle(Particle.WATER_WAKE, 0, 0, 0, 0)))
),
UnderwaterMWG(new ParticleData(Material.BLUE_CARPET, "PARTICLE_EVENT_RAIN_CLOUD", ParticleRequirement.eventParticipation(35),
new Always(new RandomParticle(RainCloudParticle.values())))
),
WarGearSeason2022(new ParticleData(Material.DIAMOND_SWORD, "PARTICLE_EVENT_WINGS", ParticleRequirement.eventParticipation(37),
new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.DRAGON_BREATH, 0, 0, 0, 0, 1), 0.15, WingDesign.COMPLEX)), 20)))
),
;
public static ParticleEnum[] particles = values();
@Getter
private ParticleData particle;
}
@@ -0,0 +1,51 @@
package de.steamwar.lobby.particle.particles;
import de.steamwar.lobby.particle.ParticleData;
import de.steamwar.lobby.particle.ParticleEnum;
import de.steamwar.lobby.particle.ParticleRequirement;
import de.steamwar.lobby.particle.WingDesign;
import de.steamwar.lobby.particle.elements.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.Material;
import org.bukkit.Particle;
@AllArgsConstructor
public enum EventParticlePlacement implements ParticleEnum {
WarGearSeason(new ParticleData(Material.ENCHANTING_TABLE, "PARTICLE_EVENT_ENCHANTING", ParticleRequirement.eventPlacement(22, 12, 285, 54),
new Cloud(new Circle(new LocationMutator(new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0, 0, 0, 0.01), 0, 1.1, 0)))
)),
AirshipEvent(new ParticleData(Material.SNOWBALL, "PARTICLE_EVENT_CLOUD", ParticleRequirement.eventPlacement(26, 205, 9, 54, 120, 292),
new Circle(new LocationMutator(new SimpleParticle(Particle.CLOUD, 0, 0, 0, 0.01), 0, 2.2, 0))
)),
HellsBellsWs(new ParticleData(Material.TNT_MINECART, "PARTICLE_EVENT_SMOKE", ParticleRequirement.eventPlacement(28, 205, 9, 11),
new Cloud(new Circle(new LocationMutator(new SimpleParticle(Particle.CAMPFIRE_COSY_SMOKE, 0, 0, 0, 0.01), 0, 2.2, 0)))
)),
Underwater(new ParticleData(Material.PRISMARINE_SHARD, "PARTICLE_EVENT_WATER", ParticleRequirement.eventPlacement(31, 9, 210, 520),
new Cloud(new SimpleParticle(Particle.DRIP_WATER)))
),
AdventWarShip(new ParticleData(Material.PRISMARINE_CRYSTALS, "PARTICLE_EVENT_WATER", ParticleRequirement.eventPlacement(32, 9, 205, 210),
new Always(new LocationMutator(new Circle(new Group(new SimpleParticle(Particle.DRIP_WATER), new SimpleParticle(Particle.WATER_WAKE, 0.2F, 0.2F, 0.2F, 0.01))), 0, 1.1, 0)))
),
MiniWarGearLiga(new ParticleData(Material.IRON_SWORD, "PARTICLE_EVENT_WINGS", ParticleRequirement.eventPlacement(33, 9, 34, 205),
new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.WATER_WAKE, 0, 0, 0, 0, 1), 0.15, WingDesign.MWGL)), 20)))
),
Absturz(new ParticleData(Material.FEATHER, "PARTICLE_EVENT_WINGS", ParticleRequirement.eventPlacement(34, 210, 205, 527, 286),
new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0, 1), 0.15, WingDesign.SIMPLE)), 20)))
),
UnderwaterMWG(new ParticleData(Material.CYAN_CARPET, "PARTICLE_EVENT_RAIN_CLOUD", ParticleRequirement.eventPlacement(35, 9, 210),
new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0, 1), 0.15, WingDesign.SW)), 20)))
),
WarGearSeason2022(new ParticleData(Material.DIAMOND_HELMET, "PARTICLE_EVENT_WGS", ParticleRequirement.eventPlacement(37, 285, 210, 122),
new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.FIREWORKS_SPARK, 0, 0, 0, 0, 1), 0.15, WingDesign.WGS)), 20)))
),
WargearClash(new ParticleData(Material.GOLDEN_SWORD, "PARTICLE_EVENT_WARGEARCLASH", ParticleRequirement.eventPlacement(38, 210, 158, 167, 286),
new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0, 1), 0.1, WingDesign.SWORD_CROSSED)), 20)))
),
;
public static ParticleEnum[] particles = values();
@Getter
private ParticleData particle;
}
@@ -0,0 +1,63 @@
package de.steamwar.lobby.particle.particles;
import de.steamwar.lobby.particle.ParticleData;
import de.steamwar.lobby.particle.ParticleEnum;
import de.steamwar.lobby.particle.elements.DustParticle;
import de.steamwar.lobby.particle.elements.LocationMutator;
import de.steamwar.lobby.particle.elements.SimpleParticle;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.Material;
import org.bukkit.Particle;
@AllArgsConstructor
public enum PlayerParticle implements ParticleEnum {
SNEEZE(new ParticleData(Material.SLIME_BLOCK, "PARTICLE_SNEEZE",
new SimpleParticle(Particle.SNEEZE, 0.2F, 0.2F, 0.2F, 0.01))
),
SMOKE(new ParticleData(Material.COBWEB, "PARTICLE_SMOKE",
new SimpleParticle(Particle.SMOKE_NORMAL, 0.2F, 0.2F, 0.2F, 0.01))
),
FIRE(new ParticleData(Material.LAVA_BUCKET, "PARTICLE_FIRE",
new SimpleParticle(Particle.DRIP_LAVA))
),
WATER(new ParticleData(Material.WATER_BUCKET, "PARTICLE_WATER",
new SimpleParticle(Particle.DRIP_WATER))
),
HEARTH(new ParticleData(Material.RED_DYE, "PARTICLE_HEART",
new LocationMutator(new SimpleParticle(Particle.HEART), 0, 2.2, 0))
),
NOTES(new ParticleData(Material.NOTE_BLOCK, "PARTICLE_NOTES",
new LocationMutator(new SimpleParticle(Particle.NOTE), 0, 2.2, 0))
),
NAUTILUS(new ParticleData(Material.NAUTILUS_SHELL, "PARTICLE_NAUTILUS",
new SimpleParticle(Particle.NAUTILUS, 0.2F, 0.2F ,0.2F, 0.01))
),
SNOWBALL(new ParticleData(Material.SNOWBALL, "PARTICLE_SNOWBALL",
new SimpleParticle(Particle.SNOWBALL, 0.2F, 0.2F ,0.2F, 0.01))
),
EFFECT(new ParticleData(Material.GLASS_BOTTLE, "PARTICLE_EFFECT",
new DustParticle(Particle.REDSTONE, 0, 0.2F, 0, 0.01, 5))
),
CAMPFIRE(new ParticleData(Material.CAMPFIRE, "PARTICLE_CAMPFIRE",
new SimpleParticle(Particle.CAMPFIRE_COSY_SMOKE, 0, 0.2F ,0, 0.01))
),
MAGIC(new ParticleData(Material.CAULDRON, "PARTICLE_MAGIC",
new SimpleParticle(Particle.CRIT_MAGIC, 0.2F, 0.2F, 0.2F, 0.01))
),
ANGRY(new ParticleData(Material.REDSTONE_BLOCK, "PARTICLE_ANGRY",
new SimpleParticle(Particle.VILLAGER_ANGRY, 0.2F, 0.2F, 0.2F, 0.01))
),
SLIME(new ParticleData(Material.SLIME_BALL, "PARTICLE_SLIME",
new SimpleParticle(Particle.SLIME))
),
MOB(new ParticleData(Material.ZOMBIE_HEAD, "PARTICLE_MOB",
new SimpleParticle(Particle.SPELL_MOB))
),
;
public static ParticleEnum[] particles = values();
@Getter
private ParticleData particle;
}
@@ -0,0 +1,59 @@
package de.steamwar.lobby.particle.particles;
import de.steamwar.lobby.particle.ParticleData;
import de.steamwar.lobby.particle.ParticleEnum;
import de.steamwar.lobby.particle.ParticleRequirement;
import de.steamwar.lobby.particle.elements.Always;
import de.steamwar.lobby.particle.elements.Group;
import de.steamwar.lobby.particle.elements.LocationMutator;
import de.steamwar.lobby.particle.elements.SimpleParticle;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.Material;
import org.bukkit.Particle;
@AllArgsConstructor
public enum RainCloudParticle implements ParticleEnum {
Raincloud(new ParticleData(Material.BLUE_CARPET, "PARTICLE_RAINCLOUD_NORMAL", ParticleRequirement.HAS_TEAM,
new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new SimpleParticle(Particle.WATER_WAKE, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.DRIP_WATER, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
),
Red_Raincloud(new ParticleData(Material.RED_CARPET, "PARTICLE_RAINCLOUD_RED", ParticleRequirement.HAS_TEAM,
new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.DRIP_LAVA, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
),
Yellow_Raincloud(new ParticleData(Material.YELLOW_CARPET, "PARTICLE_RAINCLOUD_YELLOW", ParticleRequirement.HAS_TEAM,
new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.FALLING_NECTAR, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
),
Orange_Raincloud(new ParticleData(Material.ORANGE_CARPET, "PARTICLE_RAINCLOUD_ORANGE", ParticleRequirement.HAS_TEAM,
new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.FALLING_HONEY, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
),
Green_Raincloud(new ParticleData(Material.LIME_CARPET, "PARTICLE_RAINCLOUD_GREEN", ParticleRequirement.HAS_TEAM,
new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.FALLING_SPORE_BLOSSOM, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
),
Purple_Raincloud(new ParticleData(Material.PURPLE_CARPET, "PARTICLE_RAINCLOUD_PURPLE", ParticleRequirement.HAS_TEAM,
new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.FALLING_OBSIDIAN_TEAR, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
),
Nautilus_Raincloud(new ParticleData(Material.NAUTILUS_SHELL, "PARTICLE_RAINCLOUD_NAUTILUS", ParticleRequirement.HAS_TEAM,
new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.NAUTILUS, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
),
Enchantment_Raincloud(new ParticleData(Material.ENCHANTED_BOOK, "PARTICLE_RAINCLOUD_ENCHANTMENT", ParticleRequirement.HAS_TEAM,
new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
),
Slime_Raincloud(new ParticleData(Material.GREEN_CARPET, "PARTICLE_RAINCLOUD_SLIME", ParticleRequirement.HAS_TEAM,
new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.SLIME, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
),
Hail_Raincloud(new ParticleData(Material.LIGHT_GRAY_CARPET, "PARTICLE_RAINCLOUD_HAIL", ParticleRequirement.HAS_TEAM,
new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.SNOWBALL, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
),
Snow_Raincloud(new ParticleData(Material.WHITE_CARPET, "PARTICLE_RAINCLOUD_SNOW", ParticleRequirement.HAS_TEAM,
new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.SNOWFLAKE, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
),
Totem_Raincloud(new ParticleData(Material.TOTEM_OF_UNDYING, "PARTICLE_RAINCLOUD_TOTEM", ParticleRequirement.HAS_TEAM,
new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.TOTEM, 0.3F, 0.0F, 0.3F, 0.01, 2), 0, -0.3, 0)), 0, 2.4, 0)))
),
;
public static ParticleEnum[] particles = values();
@Getter
private ParticleData particle;
}
@@ -0,0 +1,99 @@
package de.steamwar.lobby.particle.particles;
import de.steamwar.lobby.particle.ParticleData;
import de.steamwar.lobby.particle.ParticleEnum;
import de.steamwar.lobby.particle.ParticleRequirement;
import de.steamwar.lobby.particle.WingDesign;
import de.steamwar.lobby.particle.elements.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.Material;
import org.bukkit.Particle;
@AllArgsConstructor
public enum ServerTeamParticle implements ParticleEnum {
WITCH(new ParticleData(Material.EXPERIENCE_BOTTLE, "PARTICLE_WITCH", ParticleRequirement.SERVER_TEAM,
new SimpleParticle(Particle.SPELL_WITCH))
),
ENCHANTING(new ParticleData(Material.ENCHANTING_TABLE, "PARTICLE_ENCHANTING", ParticleRequirement.SERVER_TEAM,
new SimpleParticle(Particle.ENCHANTMENT_TABLE))
),
HAPPY(new ParticleData(Material.EMERALD_BLOCK, "PARTICLE_HAPPY", ParticleRequirement.SERVER_TEAM,
new SimpleParticle(Particle.HEART, 0.2F, 0.2F, 0.2F, 0.01))
),
FLAME(new ParticleData(Material.FLINT_AND_STEEL, "PARTICLE_FLAME", ParticleRequirement.SERVER_TEAM,
new SimpleParticle(Particle.FLAME, 0, 0.2F, 0, 0.01))
),
END_ROD(new ParticleData(Material.END_ROD, "PARTICLE_END_ROD", ParticleRequirement.SERVER_TEAM,
new SimpleParticle(Particle.END_ROD, 0.2F, 0.2F, 0.2F, 0.01))
),
CLOUD(new ParticleData(Material.WHITE_WOOL, "PARTICLE_CLOUD", ParticleRequirement.SERVER_TEAM,
new Cloud(new SimpleParticle(Particle.CLOUD)))
),
TOTEM(new ParticleData(Material.TOTEM_OF_UNDYING, "PARTICLE_TOTEM", ParticleRequirement.SERVER_TEAM,
new Cloud(new SimpleParticle(Particle.TOTEM, 0.2F, 0.2F, 0.2F, 0.01)))
),
ENCHANTING_CLOUD(new ParticleData(Material.WHITE_DYE, "PARTICLE_ENCHANTING", ParticleRequirement.SERVER_TEAM,
new Cloud(new SimpleParticle(Particle.ENCHANTMENT_TABLE)))
),
FLAME_CLOUD(new ParticleData(Material.FIRE_CORAL_BLOCK, "PARTICLE_FLAME", ParticleRequirement.SERVER_TEAM,
new Cloud(new SimpleParticle(Particle.FLAME)))
),
SNEEZE_CLOUD(new ParticleData(Material.LIME_SHULKER_BOX, "PARTICLE_SNEEZE", ParticleRequirement.SERVER_TEAM,
new Cloud(new SimpleParticle(Particle.SNEEZE)))
),
SLIME_CLOUD(new ParticleData(Material.GREEN_SHULKER_BOX, "PARTICLE_SLIME", ParticleRequirement.SERVER_TEAM,
new Cloud(new SimpleParticle(Particle.SLIME)))
),
SMOKE_CLOUD(new ParticleData(Material.DEAD_BRAIN_CORAL_BLOCK, "PARTICLE_SMOKE", ParticleRequirement.SERVER_TEAM,
new Cloud(new SimpleParticle(Particle.CAMPFIRE_COSY_SMOKE, 0.2F, 0.2F, 0.2F, 0.01)))
),
TOWN_CLOUD(new ParticleData(Material.FIREWORK_STAR, "PARTICLE_TOWN", ParticleRequirement.SERVER_TEAM,
new Cloud(new SimpleParticle(Particle.TOWN_AURA)))
),
FLAME_CIRCLE(new ParticleData(Material.MAGMA_BLOCK, "PARTICLE_FLAME", ParticleRequirement.SERVER_TEAM,
new Circle(new LocationMutator(new SimpleParticle(Particle.FLAME, 0, 0, 0, 0.01), 0, 1.1, 0)))
),
ENCHANTING_CIRCLE(new ParticleData(Material.WHITE_DYE, "PARTICLE_ENCHANTING_CIRCLE", ParticleRequirement.SERVER_TEAM,
new Circle(new LocationMutator(new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0.2F, 0.2F, 0.2F, 0.01), 0, 1.1, 0)))
),
NOTES_CIRCLE(new ParticleData(Material.NOTE_BLOCK, "PARTICLE_NOTES", ParticleRequirement.SERVER_TEAM,
new Circle(new LocationMutator(new SimpleParticle(Particle.NOTE, 0, 0, 0, 0.01), 0, 2.2, 0)))
),
WATER_FIRE(new ParticleData(Material.GUARDIAN_SPAWN_EGG, "PARTICLE_WATER_FIRE", ParticleRequirement.SERVER_TEAM,
new LocationMutator(new DoubleCircle(new SimpleParticle(Particle.DRIP_WATER, 0, 0, 0, 0.01), new SimpleParticle(Particle.DRIP_LAVA, 0, 0, 0, 0.01)), 0, 1.1, 0))
),
WATER_FIRE_ALWAYS(new ParticleData(Material.GUARDIAN_SPAWN_EGG, "PARTICLE_WATER_FIRE", ParticleRequirement.SERVER_TEAM,
new Always(new LocationMutator(new DoubleCircle(new SimpleParticle(Particle.DRIP_WATER, 0, 0, 0, 0.01), new SimpleParticle(Particle.DRIP_LAVA, 0, 0, 0, 0.01)), 0, 1.1, 0)))
),
MAGIC_ENCHANTING(new ParticleData(Material.DIAMOND_SWORD, "PARTICLE_MAGIC_ENCHANTING", ParticleRequirement.SERVER_TEAM,
new LocationMutator(new DoubleCircle(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01), new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0, 0, 0, 0.01)), 0, 1.1, 0))
),
MAGIC_ENCHANTING_ALWAYS(new ParticleData(Material.WOODEN_SWORD, "PARTICLE_MAGIC_ENCHANTING", ParticleRequirement.SERVER_TEAM,
new Always(new LocationMutator(new DoubleCircle(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01), new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0, 0, 0, 0.01)), 0, 1.1, 0)))
),
MAGIC_CLOUD_CIRCLE(new ParticleData(Material.GLOWSTONE_DUST, "PARTICLE_MAGIC", ParticleRequirement.SERVER_TEAM,
new Cloud(new Circle(new LocationMutator(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01), 0, 1.1, 0))))
),
FLAME_CLOUD_CIRCLE(new ParticleData(Material.FIRE_CORAL, "PARTICLE_FLAME", ParticleRequirement.SERVER_TEAM,
new Cloud(new Circle(new LocationMutator(new SimpleParticle(Particle.FLAME, 0, 0, 0, 0.01), 0, 1.1, 0))))
),
FIREWORK_CLOUD_CIRCLE(new ParticleData(Material.FIREWORK_ROCKET, "PARTICLE_FIREWORK", ParticleRequirement.SERVER_TEAM,
new Cloud(new Circle(new LocationMutator(new SimpleParticle(Particle.FIREWORKS_SPARK, 0, 0, 0, 0.01), 0, 1.1, 0))))
),
WATER_CLOUD_CIRCLE(new ParticleData(Material.CYAN_DYE, "PARTICLE_WATER_FIRE", ParticleRequirement.SERVER_TEAM,
new Cloud(new Circle(new LocationMutator(new SimpleParticle(Particle.WATER_WAKE, 0, 0, 0, 0.01), 0, 1.1, 0))))
),
ENCHANTING_DOUBLE_CIRCLE(new ParticleData(Material.BUBBLE_CORAL_BLOCK, "PARTICLE_ENCHANTING", ParticleRequirement.SERVER_TEAM,
new Always(new LocationMutator(new DoubleCircle(new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0, 0, 0, 0.01), new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0, 0, 0, 0.01)), 0, 2.2, 0)))
),
EVIL_WINGS(new ParticleData(Material.PURPUR_SLAB, "PARTICLE_WINGS_EVIL", ParticleRequirement.SERVER_TEAM,
new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.SPELL_WITCH, 0, 0, 0, 0, 1), 0.15, WingDesign.SIMPLE)), 20)))
),
;
public static ParticleEnum[] particles = values();
@Getter
private ParticleData particle;
}
@@ -0,0 +1,50 @@
package de.steamwar.lobby.particle.particles;
import de.steamwar.lobby.particle.ParticleData;
import de.steamwar.lobby.particle.ParticleEnum;
import de.steamwar.lobby.particle.ParticleRequirement;
import de.steamwar.lobby.particle.elements.Circle;
import de.steamwar.lobby.particle.elements.LocationMutator;
import de.steamwar.lobby.particle.elements.NonFloor;
import de.steamwar.lobby.particle.elements.SimpleParticle;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.Material;
import org.bukkit.Particle;
@AllArgsConstructor
public enum TeamParticle implements ParticleEnum {
SQUID(new ParticleData(Material.INK_SAC, "PARTICLE_SQUID", ParticleRequirement.HAS_TEAM,
new SimpleParticle(Particle.SQUID_INK, 0.2F, 0.2F, 0.2F, 0.01))
),
BUBBLE(new ParticleData(Material.TUBE_CORAL, "PARTICLE_BUBBLE", ParticleRequirement.HAS_TEAM,
new SimpleParticle(Particle.BUBBLE_POP, 0.2F, 0.2F, 0.2F, 0.01))
),
HONEY(new ParticleData(Material.HONEY_BOTTLE, "PARTICLE_HONEY", ParticleRequirement.HAS_TEAM,
new SimpleParticle(Particle.DRIPPING_HONEY, 0.2F, 0.2F, 0.2F, 1))
),
NECTAR(new ParticleData(Material.HONEYCOMB, "PARTICLE_NECTAR", ParticleRequirement.HAS_TEAM,
new SimpleParticle(Particle.FALLING_NECTAR, 0.2F, 0.2F, 0.2F, 1))
),
FIREWORK(new ParticleData(Material.FIRE_CHARGE, "PARTICLE_FIREWORK", ParticleRequirement.HAS_TEAM,
new LocationMutator(new NonFloor(new SimpleParticle(Particle.FIREWORKS_SPARK, 0.1F, 0.1F, 0.1F, 0.2, 2)), 0, -0.2, 0))
),
DRAGON_BREATH(new ParticleData(Material.DRAGON_BREATH, "PARTICLE_DRAGON_BREATH", ParticleRequirement.HAS_TEAM,
new SimpleParticle(Particle.DRAGON_BREATH, 1F, 0.2F, 1F, 0.01))
),
DAMAGE(new ParticleData(Material.SPIDER_EYE, "PARTICLE_DAMAGE", ParticleRequirement.HAS_TEAM,
new SimpleParticle(Particle.DAMAGE_INDICATOR, 0.2F, 0, 0.2F, 0.01))
),
DOLPHIN(new ParticleData(Material.BLUE_DYE, "PARTICLE_DOLPHIN", ParticleRequirement.HAS_TEAM,
new SimpleParticle(Particle.DOLPHIN, 0.2F, 0, 0.2F, 0.01))
),
HEART(new ParticleData(Material.RED_CONCRETE, "PARTICLE_HEART", ParticleRequirement.HAS_TEAM,
new Circle(new LocationMutator(new SimpleParticle(Particle.HEART), 0, 2.2, 0)))
),
;
public static ParticleEnum[] particles = values();
@Getter
private ParticleData particle;
}
@@ -0,0 +1,47 @@
package de.steamwar.lobby.particle.particles.custom;
import de.steamwar.lobby.particle.ParticleData;
import de.steamwar.lobby.particle.ParticleEnum;
import de.steamwar.lobby.particle.ParticleRequirement;
import de.steamwar.lobby.particle.WingDesign;
import de.steamwar.lobby.particle.elements.*;
import de.steamwar.lobby.particle.elements.custom.HearthBeat;
import de.steamwar.lobby.particle.elements.custom.NonMoving;
import de.steamwar.lobby.particle.elements.custom.PulseShimmer;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.Material;
import org.bukkit.Particle;
@AllArgsConstructor
public enum CustomEasterParticle implements ParticleEnum {
/*
Lord_Loading(new ParticleData(Material.ENDER_PEARL, "Loading Test", ParticleRequirement.easterEventSpecificPlayer(1063),
new Always(new DoubleCircle(new DoubleCircle(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1),
new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1), 0.5, 4),
new DoubleCircle(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1),
new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1), 0.5, 4), 1.5, 1)))
),
*/
Rongamer99091(new ParticleData(Material.GUNPOWDER, "PARTICLE_PLAYER_RONGAMER99091_AURA", ParticleRequirement.easterEventSpecificPlayer(10697),
new Always(new Sneaking(new Group(
new OnlySelf(new Delayed(new SimpleParticle(Particle.EXPLOSION_HUGE, 0, 0, 0, 0.01, 1), 20)),
new OnlyOthers(new Delayed(new SimpleParticle(Particle.EXPLOSION_HUGE, 0, 0, 0, 0.01, 1), 2))
))))
),
Plompa(new ParticleData(Material.PUFFERFISH_BUCKET, "PARTICLE_PLAYER_PLOMPA", ParticleRequirement.specificPlayer(64),
new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.END_ROD, 0, 0, 0, 0, 1), 0.15, WingDesign.PlompaEasterWings)), 80)))
),
Pulse_EASTER_1(new ParticleData(Material.RED_CANDLE, "PARTICLE_TEAM_PULSE_AURA_1", ParticleRequirement.easterEventSpecificTeam(210),
new Always(new NonMoving(new PulseShimmer(new SimpleParticle(Particle.FLAME, 0, 0, 0, 0, 1), 80, 2))))
),
Pulse_EASTER_3(new ParticleData(Material.APPLE, "PARTICLE_TEAM_PULSE_HEART_BEAT", ParticleRequirement.easterEventSpecificTeam(210),
new Always(new NonFlying(new HearthBeat(new SimpleParticle(Particle.FLAME, 0, 0, 0, 0, 1), 80))))
),
;
public static ParticleEnum[] particles = values();
@Getter
private ParticleData particle;
}
@@ -0,0 +1,28 @@
package de.steamwar.lobby.particle.particles.custom;
import de.steamwar.lobby.particle.ParticleData;
import de.steamwar.lobby.particle.ParticleEnum;
import de.steamwar.lobby.particle.ParticleRequirement;
import de.steamwar.lobby.particle.elements.*;
import de.steamwar.lobby.particle.elements.custom.NonMoving;
import de.steamwar.lobby.particle.elements.custom.YOffset;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.Material;
import org.bukkit.Particle;
@AllArgsConstructor
public enum CustomPlayerParticle implements ParticleEnum {
Haylim_(new ParticleData(Material.WHITE_CANDLE, "PARTICLE_PLAYER_HAYLIM_AURA", ParticleRequirement.specificPlayer(9426),
new Always(new NonMoving(new NonFlying(new Group(
new DoubleCircle(new YOffset(new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0, 0, 0, 0.01, 5), 40, 0, 2, false), new YOffset(new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0, 0, 0, 0.0,5), 40, 0, 2, true)),
new DoubleCircle(new YOffset(new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0, 0, 0, 0.01, 5), 40, 0, 2, true), new YOffset(new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0, 0, 0, 0.0,5), 40, 0, 2, false))
)))))
),
;
public static ParticleEnum[] particles = values();
@Getter
private ParticleData particle;
}
@@ -0,0 +1,35 @@
package de.steamwar.lobby.particle.particles.custom;
import de.steamwar.lobby.particle.ParticleData;
import de.steamwar.lobby.particle.ParticleEnum;
import de.steamwar.lobby.particle.ParticleRequirement;
import de.steamwar.lobby.particle.WingDesign;
import de.steamwar.lobby.particle.elements.*;
import de.steamwar.lobby.particle.elements.custom.NonMoving;
import de.steamwar.lobby.particle.elements.custom.PulseShimmer;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.Material;
import org.bukkit.Particle;
@AllArgsConstructor
public enum CustomTeamParticle implements ParticleEnum {
Eclipse(new ParticleData(Material.ENDER_CHEST, "PARTICLE_EVENT_ENCHANTING", ParticleRequirement.specificTeam(34),
new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.END_ROD, 0, 0, 0, 0, 1), 0.15, WingDesign.ECLIPSE)), 80)))
),
Pulse_1(new ParticleData(Material.GRAY_CANDLE, "PARTICLE_TEAM_PULSE_AURA_2", ParticleRequirement.specificTeam(210),
new Always(new NonMoving(new PulseShimmer(new SimpleParticle(Particle.END_ROD, 0, 0, 0, 0, 1), 80, 2))))
),
Pulse_2(new ParticleData(Material.WHITE_CANDLE, "PARTICLE_TEAM_PULSE_AURA_3", ParticleRequirement.specificTeam(210),
new Always(new NonMoving(new PulseShimmer(new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0, 0, 0, 0, 5), 80, 2))))
),
Pulse_Logo(new ParticleData(Material.ENDER_CHEST, "PARTICLE_TEAM_PULSE_LOGO", ParticleRequirement.specificTeam(210),
new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.END_ROD, 0, 0, 0, 0, 1), 0.15, WingDesign.PL)), 80)))
),
;
public static ParticleEnum[] particles = values();
@Getter
private ParticleData particle;
}
@@ -0,0 +1,109 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.portal;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.command.ModifyCommand;
import de.steamwar.lobby.listener.Portals;
import de.steamwar.network.NetworkSender;
import de.steamwar.network.packets.client.ExecuteCommandPacket;
import de.steamwar.sql.SteamwarUser;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
public class CommandPortal implements PortalHandler {
private final String command;
public CommandPortal(Map<String, Object> section, Portal portal) {
this.command = (String) section.get("command");
}
public CommandPortal(String command) {
this.command = command;
}
@Override
public void handle(Player player, Location loc) {
String[] parts = command.split("\\\\");
int[] stackIds = new int[parts.length-1];
int maxId = 0;
for(int i = 1; i < parts.length; i++) {
stackIds[i-1] = Integer.parseInt(parts[i].substring(0, 1));
if(stackIds[i-1] > maxId)
maxId = stackIds[i-1];
}
Iterator<Portal> stack = Portals.getStack(player).iterator();
String[] pieces = new String[stackIds.length];
while (maxId > 0) {
if(!stack.hasNext()) {
LobbySystem.getPlugin().getLogger().log(Level.WARNING, "Stackportal with missing elements: " + player.getName() + " /" + command);
player.sendMessage("§cEigentlich solltest du gerade gar nicht durch dieses Portal durchgehen können...");
return;
}
Portal portal = stack.next();
if(portal.type() == PortalType.STACK) {
for(int i = 0; i < stackIds.length; i++) {
if(stackIds[i] == maxId) {
pieces[i] = ((StackPortal) portal.getHandler()).getText();
}
}
maxId--;
}
}
StringBuilder cmd = new StringBuilder(parts[0]);
for(int i = 0; i < pieces.length; i++) {
cmd.append(pieces[i]).append(parts[i+1].substring(1));
}
if(ModifyCommand.modifying(player))
player.sendMessage("/" + cmd);
NetworkSender.send(new ExecuteCommandPacket(SteamwarUser.get(player.getUniqueId()).getId(), cmd.toString()));
}
@Override
public void serialize(Map<String, Object> map) {
map.put("command", command);
}
@Override
public PortalType type() {
return PortalType.COMMAND;
}
@Override
public void delete() {
// Nothing to remove
}
@Override
public String toString() {
return "Command: /" + command;
}
}
@@ -0,0 +1,61 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.portal;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.util.Map;
public class DummyPortal implements PortalHandler {
public DummyPortal() {
// Inits nothing
}
public DummyPortal(Map<String, Object> section, Portal portal) {
// Deserializes nothing
}
@Override
public void handle(Player player, Location from) {
// Does nothing
}
@Override
public void serialize(Map<String, Object> map) {
// Serializes nothing
}
@Override
public PortalType type() {
return PortalType.DUMMY;
}
@Override
public void delete() {
// Delets nothing
}
@Override
public String toString() {
return "Dummy";
}
}
@@ -0,0 +1,244 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.portal;
import de.steamwar.lobby.Fightserver;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.display.Hologram;
import de.steamwar.lobby.display.NPC;
import de.steamwar.network.packets.common.FightInfoPacket;
import de.steamwar.sql.SteamwarUser;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import java.util.*;
import java.util.logging.Level;
import java.util.stream.Collectors;
public class FightserverPortal implements PortalHandler, Comparable<FightserverPortal> {
private static final Map<String, List<FightserverPortal>> portals = new HashMap<>();
public static FightserverPortal findFree(String gamemode) {
List<FightserverPortal> list = portals.getOrDefault(gamemode, Collections.emptyList());
for(FightserverPortal portal : list) {
if(portal.server == null)
return portal;
}
return null;
}
private final Portal portal;
private final String gamemode;
private final int order;
private final String target;
private final List<Location> bluePlayers;
private final List<Location> redPlayers;
private Fightserver server = null;
private PortalHandler handler = new DummyPortal();
private final Hologram hologram;
private final List<NPC> blueNPCs = new ArrayList<>();
private final List<NPC> redNPCs = new ArrayList<>();
public FightserverPortal(Map<String, Object> section, Portal portal) {
this(
portal,
(String) section.get("group"),
(int) section.get("order"),
(String) section.get("target"),
(List<Location>) section.getOrDefault("bluePlayers", new ArrayList<>()),
(List<Location>) section.getOrDefault("redPlayers", new ArrayList<>())
);
}
public FightserverPortal(Portal portal, String gamemode, int order, String target, List<Location> bluePlayers, List<Location> redPlayers) {
this.portal = portal;
this.gamemode = gamemode;
this.order = order;
this.target = target;
this.bluePlayers = bluePlayers;
this.redPlayers = redPlayers;
hologram = new Hologram(null, portal.denormalize(new Vector(0.5, 0.5, 0.5)).toLocation(portal.getPos1().getWorld()), "", false);
setServer(null);
List<FightserverPortal> list = portals.computeIfAbsent(gamemode, mode -> new ArrayList<>());
list.add(this);
list.sort(null);
}
public void setServer(Fightserver server) {
this.server = server;
if (server == null) {
setHandler(new TeleportPortal(portal, target));
} else {
setHandler(new CommandPortal("arena " + server.getServerName()));
}
updateText();
updateBluePlayers();
updateRedPlayers();
}
public void updateText() {
if(server == null) {
hologram.updateText("§7Neuen Kampf starten");
return;
}
FightInfoPacket info = server.current();
if (fightStateCountdown(info.getFightState()))
hologram.updateText(String.format("§7%s §e%s §7%d§8:§7%02d", server.getServerName(), fightStateMapper(info.getFightState()), info.getCountdown() / 60, info.getCountdown() % 60));
else
hologram.updateText(String.format("§7%s §e%s", server.getServerName(), fightStateMapper(info.getFightState())));
}
public void updateBluePlayers() {
updateNPCs(bluePlayers, blueNPCs, server != null ? server.current().getBluePlayers() : Collections.emptyList());
}
public void updateRedPlayers() {
updateNPCs(redPlayers, redNPCs, server != null ? server.current().getRedPlayers() : Collections.emptyList());
}
private void updateNPCs(List<Location> locations, List<NPC> npcs, List<Integer> players) {
List<SteamwarUser> remainingPlayers = players.stream().map(SteamwarUser::get).collect(Collectors.toList());
List<Location> remainingLocations = new ArrayList<>(locations);
npcs.removeIf(npc -> {
SteamwarUser user = SteamwarUser.get(npc.getUuid());
if(remainingPlayers.contains(user)) {
remainingPlayers.remove(user);
remainingLocations.remove(npc.getLocation());
return false;
} else {
npc.delete();
return true;
}
});
for(SteamwarUser user : remainingPlayers) {
if(remainingLocations.isEmpty())
break;
npcs.add(new NPC(remainingLocations.remove(0), user.getUUID(), user.getUserName()));
}
}
public void addBlue(Location location) {
bluePlayers.add(location);
LobbySystem.config().save();
}
public void addRed(Location location) {
redPlayers.add(location);
LobbySystem.config().save();
}
public void removeBlue(int i) {
bluePlayers.remove(i);
LobbySystem.config().save();
}
public void removeRed(int i) {
redPlayers.remove(i);
LobbySystem.config().save();
}
private void setHandler(PortalHandler handler) {
handler.delete();
this.handler = handler;
}
@Override
public void handle(Player player, Location from, Location to) {
handler.handle(player, from, to);
}
@Override
public void serialize(Map<String, Object> map) {
map.put("group", gamemode);
map.put("order", order);
map.put("target", target);
map.put("bluePlayers", bluePlayers);
map.put("redPlayers", redPlayers);
}
@Override
public PortalType type() {
return PortalType.FIGHTSERVER;
}
@Override
public void delete() {
portals.get(gamemode).remove(this);
hologram.delete();
blueNPCs.forEach(NPC::delete);
redNPCs.forEach(NPC::delete);
handler.delete();
}
@Override
public int compareTo(FightserverPortal other) {
return order - other.order;
}
private boolean fightStateCountdown(String state) {
switch (state) {
case "waiting":
case "PRE_LEADER_SETUP":
case "end":
case "SPECTATE":
return false;
default:
return true;
}
}
private String fightStateMapper(String state) {
switch (state) {
case "waiting":
case "PRE_LEADER_SETUP":
return "Warten auf Spieler";
case "PRE_SCHEM_SETUP":
return "Schemauswahl";
case "POST_SCHEM_SETUP":
return "Vorbereitung";
case "PRE_RUNNING":
return "Kampfbeginn in";
case "fighting":
case "RUNNING":
return "Kampf läuft";
case "end":
case "SPECTATE":
return "Zuschauerphase";
default:
LobbySystem.getPlugin().getLogger().log(Level.SEVERE, "Unknown FightState " + state + " encountered");
return "Programmierfehler";
}
}
@Override
public String toString() {
return "Fightserver";
}
}
@@ -0,0 +1,273 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.portal;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.display.Hologram;
import de.steamwar.lobby.listener.Portals;
import org.bukkit.Location;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import java.util.*;
import java.util.function.Function;
public class Portal implements PortalHandler, ConfigurationSerializable {
private static final Map<String, Portal> portals = new HashMap<>();
private static final Map<ChunkCoords, List<Portal>> chunkPortals = new HashMap<>();
public static List<Portal> getPortals() {
return new ArrayList<>(portals.values());
}
public static Set<String> getPortalNames() {
return portals.keySet();
}
public static Portal getPortal(Location from, Location to) {
ChunkCoords in = new ChunkCoords(from);
ChunkCoords out = new ChunkCoords(to);
for(ChunkCoords coords : perChunk(Math.min(in.x, out.x), Math.max(in.x, out.x), Math.min(in.z, out.z), Math.max(in.z, out.z))) {
for(Portal portal : chunkPortals.getOrDefault(coords, Collections.emptyList())) {
Vector normalizedFrom = portal.normalize(from);
Vector normalizedTo = portal.normalize(to);
if(portal.depth == 0.0) {
normalizedFrom.setX(normalizedFrom.getX() > 0 ? 2 : -1);
normalizedTo.setX(normalizedTo.getX() > 0 ? 2 : -1);
}
if(inside(normalizedFrom.getX(), normalizedTo.getX()) && inside(normalizedFrom.getY(), normalizedTo.getY()) && inside(normalizedFrom.getZ(), normalizedTo.getZ())) {
return portal;
}
}
}
return null;
}
public static Portal getPortal(String id) {
return portals.get(id);
}
private static boolean inside(double v1, double v2) {
return (v1 >= 0.0 || v2 >= 0.0) && (v1 <= 1.0 || v2 <= 1.0);
}
private final Location pos1;
private final Location pos2;
private final double depth;
private final Vector pos1Vector;
private final double yRotation;
private final Vector rotatedShape;
private final int minChunkX;
private final int minChunkZ;
private final int maxChunkX;
private final int maxChunkZ;
private final String id;
private final PortalType type;
private final PortalHandler handler;
private final Hologram debugPos1;
private final Hologram debugPos2;
private final Hologram debugPos3;
public Portal(Map<String, Object> map) {
this(
(String) map.get("id"),
(Location) map.get("pos1"),
(Location) map.get("pos2"),
(double) map.getOrDefault("depth", 0.0),
portal -> PortalType.valueOf((String) map.get("type")).deserialize(map, portal)
);
}
public Portal(String id, Location pos1, Location pos2, Function<Portal, PortalHandler> handlerConstructor) {
this(id, pos1, pos2, 0.0, handlerConstructor);
LobbySystem.config().save();
}
public Portal(String id, Location pos1, Location pos2, double depth, Function<Portal, PortalHandler> handlerConstructor) {
this.id = id;
this.pos1 = pos1;
this.pos2 = pos2;
this.depth = depth;
this.minChunkX = Math.min(pos1.getBlockX(), pos2.getBlockX()) >> 4;
this.minChunkZ = Math.min(pos1.getBlockZ(), pos2.getBlockZ()) >> 4;
this.maxChunkX = Math.max(pos1.getBlockX(), pos2.getBlockX()) >> 4;
this.maxChunkZ = Math.max(pos1.getBlockZ(), pos2.getBlockZ()) >> 4;
Vector orientation = pos2.toVector().subtract(pos1.toVector());
this.yRotation = Math.atan2(orientation.getX(), orientation.getZ());
this.pos1Vector = pos1.toVector().subtract(new Vector(depth/2, 0, 0).rotateAroundY(yRotation));
this.rotatedShape = new Vector(depth == 0.0 ? 1.0 : depth, orientation.getY(), orientation.clone().setY(0).length());
this.handler = handlerConstructor.apply(this);
this.type = handler.type();
this.debugPos1 = new Hologram(null, pos1, id + " POS1", true);
this.debugPos2 = new Hologram(null, pos2, id + " POS2", true);
this.debugPos3 = new Hologram(null, pos1.clone().add(pos2).toVector().divide(new Vector(2, 2, 2)).toLocation(pos1.getWorld()), handler.toString(), true);
portals.put(id, this);
perChunk(minChunkX, maxChunkX, minChunkZ, maxChunkZ).forEach(coords -> chunkPortals.computeIfAbsent(coords, coords1 -> new ArrayList<>()).add(this));
}
public Vector normalize(Location location) {
return location.toVector().subtract(pos1Vector).rotateAroundY(-yRotation).divide(rotatedShape);
}
public Vector denormalize(Vector vector) {
return vector.multiply(rotatedShape).rotateAroundY(yRotation).add(pos1Vector);
}
public double getYrotation() {
return yRotation;
}
public double getDepth() {
return depth;
}
private static Iterable<ChunkCoords> perChunk(int minChunkX, int maxChunkX, int minChunkZ, int maxChunkZ) {
return () -> new Iterator<ChunkCoords>() {
private int x = minChunkX;
private int z = minChunkZ;
@Override
public boolean hasNext() {
return z <= maxChunkZ;
}
@Override
public ChunkCoords next() {
ChunkCoords coords = new ChunkCoords(x++, z);
if (x > maxChunkX) {
x = minChunkX;
z++;
}
return coords;
}
};
}
@Override
public void handle(Player player, Location from, Location to) {
handler.handle(player, from, to);
Portals.getStack(player).push(this);
}
@Override
public void serialize(Map<String, Object> map) {
map.put("id", id);
map.put("pos1", pos1);
map.put("pos2", pos2);
map.put("depth", depth);
map.put("type", type.name());
handler.serialize(map);
}
@Override
public PortalType type() {
return handler.type();
}
@Override
public void delete() {
debugPos1.delete();
debugPos2.delete();
debugPos3.delete();
handler.delete();
perChunk(minChunkX, maxChunkX, minChunkZ, maxChunkZ).forEach(coords -> chunkPortals.getOrDefault(coords, new ArrayList<>()).remove(this));
portals.remove(id);
LobbySystem.config().save();
}
@Override
public Map<String, Object> serialize() {
Map<String, Object> map = new HashMap<>();
serialize(map);
return map;
}
public Location getPos1() {
return pos1;
}
public Location getPos2() {
return pos2;
}
public String getId() {
return id;
}
public void setDepth(double depth) {
delete();
Map<String, Object> handlerMap = new HashMap<>();
handler.serialize(handlerMap);
new Portal(id, pos1, pos2, depth, portal -> handler.type().deserialize(handlerMap, portal));
LobbySystem.config().save();
}
public PortalHandler getHandler() {
return handler;
}
@Override
public String toString() {
return getId() + " " + type().name();
}
private static class ChunkCoords {
private final int x;
private final int z;
private ChunkCoords(Location location) {
this.x = location.getBlockX() >> 4;
this.z = location.getBlockZ() >> 4;
}
private ChunkCoords(int x, int z) {
this.x = x;
this.z = z;
}
@Override
public int hashCode() {
return x << 16 + z;
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof ChunkCoords))
return false;
ChunkCoords coords = (ChunkCoords) obj;
return x == coords.x && z == coords.z;
}
}
}
@@ -0,0 +1,41 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.portal;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.util.Map;
public interface PortalHandler {
default void handle(Player player, Location to) {
throw new UnsupportedOperationException();
}
default void handle(Player player, Location from, Location to) {
handle(player, to);
}
void serialize(Map<String, Object> map);
PortalType type();
void delete();
}
@@ -0,0 +1,41 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.portal;
import java.util.Map;
import java.util.function.BiFunction;
public enum PortalType {
TELEPORT(TeleportPortal::new),
COMMAND(CommandPortal::new),
FIGHTSERVER(FightserverPortal::new),
DUMMY(DummyPortal::new),
STACK(StackPortal::new);
private final BiFunction<Map<String, Object>, Portal, PortalHandler> deserializer;
PortalType(BiFunction<Map<String, Object>, Portal, PortalHandler> deserializer) {
this.deserializer = deserializer;
}
public PortalHandler deserialize(Map<String, Object> map, Portal portal) {
return deserializer.apply(map, portal);
}
}
@@ -0,0 +1,57 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.portal;
import java.util.Map;
public class StackPortal extends TeleportPortal {
private final String text;
public StackPortal(Map<String, Object> section, Portal portal) {
super(section, portal);
this.text = (String) section.get("text");
}
public StackPortal(Portal portal, String target, String text) {
super(portal, target);
this.text = text;
}
@Override
public void serialize(Map<String, Object> map) {
super.serialize(map);
map.put("text", text);
}
@Override
public PortalType type() {
return PortalType.STACK;
}
public String getText() {
return text;
}
@Override
public String toString() {
return "Stack: " + text;
}
}
@@ -0,0 +1,109 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.portal;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.command.ModifyCommand;
import de.steamwar.lobby.listener.Portals;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.util.Vector;
import java.util.*;
import java.util.logging.Level;
public class TeleportPortal implements PortalHandler {
private static final List<TeleportPortal> portals = new ArrayList<>();
private final Portal portal;
private final String target;
private final Set<TeleportPortal> sources = new HashSet<>();
public TeleportPortal(Map<String, Object> section, Portal portal) {
this.portal = portal;
this.target = (String) section.get("target");
init();
}
public TeleportPortal(Portal portal, String target) {
this.portal = portal;
this.target = target;
init();
}
private void init() {
portals.stream().filter(p -> p.target.equals(portal.getId())).forEach(sources::add);
portals.stream().filter(p -> p.portal.getId().equals(target)).forEach(p -> p.sources.add(this));
portals.add(this);
}
@Override
public void handle(Player player, Location from, Location to) {
Deque<Portal> stack = Portals.getStack(player);
if(!stack.isEmpty() && sources.contains(stack.peek().getHandler())) {
teleport(player, from, to, stack.pop());
} else {
teleport(player, from, to, Portal.getPortal(target));
}
}
private void teleport(Player player, Location from, Location to, Portal target) {
if(target == null) {
LobbySystem.getPlugin().getLogger().log(Level.WARNING, "Portal with unknown target: " + portal.getId());
player.sendMessage("§cAus unbekannten Gründen führt dieses Portal zurzeit in den Limbus");
return;
}
if(ModifyCommand.modifying(player))
player.sendMessage("teleport " + portal.getId() + " -> " + target.getId());
Vector normalized = portal.normalize(to);
if (target.getDepth() != 0.0) {
normalized.setX(1 - portal.normalize(from).getX());
}
Location portalTo = target.denormalize(normalized).toLocation(to.getWorld(), (float) (to.getYaw() - Math.toDegrees(target.getYrotation() - portal.getYrotation())), to.getPitch());
player.teleport(portalTo, PlayerTeleportEvent.TeleportCause.PLUGIN);
player.playSound(portalTo, Sound.BLOCK_ENCHANTMENT_TABLE_USE, 0.25f, 1.0f);
}
@Override
public void serialize(Map<String, Object> map) {
map.put("target", target);
}
@Override
public PortalType type() {
return PortalType.TELEPORT;
}
@Override
public void delete() {
portals.remove(this);
portals.forEach(p -> p.sources.remove(this));
}
@Override
public String toString() {
return "Teleport: " + target;
}
}
@@ -0,0 +1,85 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.special.advent;
import de.steamwar.command.SWCommand;
import de.steamwar.inventory.SWInventory;
import de.steamwar.inventory.SWItem;
import de.steamwar.inventory.SWListInv;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.sql.NodeMember;
import de.steamwar.sql.SteamwarUser;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class AdventCommand extends SWCommand {
public AdventCommand() {
super("advent", "calendar", "adventcalendar");
}
// @Register
/*
public void show(Player player, @Min(intValue = 1) @Max(intValue = 31) int day) {
if (SteamwarUser.get(player.getUniqueId()).getUserGroup() == UserGroup.Member) {
return;
}
AdventsCalendar.getPresentList().forEach(present -> {
present.removePlayer(player);
if (day == present.getDay()) {
present.addPlayer(player);
}
});
}
*/
@Register
public void genericCommand(Player player, String... args) {
if (!AdventsCalendar.active()) {
return;
}
Random random = new Random();
List<SWListInv.SWListEntry<Present>> itemList = new ArrayList<>();
SteamwarUser steamwarUser = SteamwarUser.get(player.getUniqueId());
AdventsCalendar.getPresentList().forEach(present -> {
NodeMember nodeMember = NodeMember.getNodeMember(present.getSchematicId(), steamwarUser.getId());
SWItem item;
if (nodeMember == null) {
item = SWItem.getPlayerSkull(random.nextBoolean() ? "MHF_Present1" : "MHF_Present2");
} else {
item = new SWItem(Material.CHEST, "");
}
item.setName(LobbySystem.getMessage().parse("ADVENT_CALENDAR_DAY", player, present.getDay()));
itemList.add(new SWListInv.SWListEntry<>(item, present));
});
SWInventory swInventory = new SWInventory(player, 27, LobbySystem.getMessage().parse("ADVENT_CALENDAR_TITLE", player));
for (int i = 0; i < itemList.size(); i++) {
swInventory.setItem(i, itemList.get(i).getItem());
}
swInventory.open();
}
}
@@ -0,0 +1,57 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.special.advent;
import de.steamwar.inventory.SWItem;
import de.steamwar.lobby.listener.BasicListener;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.ItemStack;
public class AdventListener extends BasicListener {
public static final int ADVENT_SLOT = 7;
public static final SWItem ADVENT = SWItem.getPlayerSkull("MHF_Present1");
static {
ADVENT.setName("§fAdvent");
}
@EventHandler(priority = EventPriority.LOWEST)
public void handlePlayerInteract(PlayerInteractEvent event) {
ItemStack item = event.getItem();
if(item == null)
return;
if (item.getType() == Material.PLAYER_HEAD && item.getItemMeta() != null && item.getItemMeta().getDisplayName().equals("§fAdvent")) {
event.getPlayer().performCommand("advent");
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onJoin(PlayerJoinEvent e) {
if (!AdventsCalendar.active()) {
return;
}
e.getPlayer().getInventory().setItem(ADVENT_SLOT, ADVENT.getItemStack());
}
}
@@ -0,0 +1,81 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.special.advent;
import de.steamwar.lobby.LobbySystem;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.time.Month;
import java.util.ArrayList;
import java.util.List;
public class AdventsCalendar {
private static List<Present> presentList = new ArrayList<>();
private static File file = new File(LobbySystem.getPlugin().getDataFolder(), "presents.yml");
private static FileConfiguration fileConfiguration = YamlConfiguration.loadConfiguration(file);
public static void init() {
new AdventCommand();
new AdventListener();
new PresentClickListener();
}
static {
for (int i = 1; i <= 31; i++) {
if (i > 24 && i < 31) continue;
ConfigurationSection section = fileConfiguration.getConfigurationSection(i + "");
if (section == null) {
section = fileConfiguration.createSection(i + "");
}
presentList.add(new Present(i, section));
if (i == 24) {
presentList.add(new Present(25, section));
presentList.add(new Present(26, section));
}
}
}
public static List<Present> getPresentList() {
return presentList;
}
public static void save() {
long time = System.currentTimeMillis();
try {
fileConfiguration.save(file);
} catch (IOException e) {
// Ignore
}
System.out.println("Save time: " + (System.currentTimeMillis() - time) + "ms");
}
public static boolean active() {
LocalDate localDate = LocalDate.now();
Month month = localDate.getMonth();
return month == Month.DECEMBER;
}
}
@@ -0,0 +1,149 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.special.advent;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.sql.NodeMember;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser;
import lombok.Data;
import lombok.Getter;
import org.bukkit.*;
import org.bukkit.block.data.BlockData;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import java.util.*;
public class Present {
private static final World WORLD = Bukkit.getWorlds().get(0);
@Data
private static class Point {
private final int x;
private final int y;
private final int z;
public static Point toPoint(Location location) {
return new Point(location.getBlockX(), location.getBlockY(), location.getBlockZ());
}
}
private final List<Map<String, Integer>> blockList;
private final Set<Point> locations = new HashSet<>();
@Getter
private final int day;
@Getter
private final int schematicId;
private Set<Player> players = new HashSet<>();
public Present(int day, ConfigurationSection configurationSection) {
this.day = day;
if (configurationSection.contains("schematicId")) {
schematicId = configurationSection.getInt("schematicId");
} else {
configurationSection.set("schematicId", -1);
schematicId = -1;
}
List<?> blockList = configurationSection.getList("blocks");
if (blockList == null) {
blockList = new ArrayList<>();
configurationSection.set("blocks", blockList);
}
this.blockList = (List<Map<String, Integer>>) blockList;
blockList.forEach(object -> {
if (!(object instanceof Map)) return;
Map<String, ?> map = (Map<String, ?>) object;
locations.add(new Point((int) map.get("x"), (int) map.get("y"), (int) map.get("z")));
});
// generate();
}
public void click(Player player, SteamwarUser user, int day, Location location) {
if (day != this.day) return;
if (!locations.contains(Point.toPoint(location))) return;
if (NodeMember.getNodeMember(schematicId, user.getId()) != null) return;
NodeMember.createNodeMember(schematicId, user.getId());
LobbySystem.getMessage().send("ADVENT_CALENDAR_OPEN", player, SchematicNode.getSchematicNode(schematicId).getName());
player.playSound(location, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1);
}
public void removePlayer(Player player) {
players.remove(player);
locations.forEach(p -> {
Location loc = new Location(WORLD, p.x, p.y, p.z);
BlockData blockData = loc.getBlock().getBlockData();
player.sendBlockChange(loc, blockData);
});
}
public void addPlayer(Player player) {
players.add(player);
locations.forEach(p -> {
Location loc = new Location(WORLD, p.x, p.y, p.z);
player.sendBlockChange(loc, BEDROCK);
});
}
public void edit(Player player, Location location) {
if (!players.contains(player)) return;
Point point = Point.toPoint(location);
if (locations.contains(point)) {
locations.remove(point);
} else {
locations.add(point);
}
generate();
Bukkit.getScheduler().runTaskLater(LobbySystem.getPlugin(), () -> {
BlockData blockData = location.getBlock().getBlockData();
players.forEach(pl -> {
if (pl == player) return;
if (locations.contains(point)) {
pl.sendBlockChange(location, blockData);
} else {
pl.sendBlockChange(location, BEDROCK);
}
});
player.sendBlockChange(location, blockData);
locations.forEach(p -> {
Location loc = new Location(WORLD, p.x, p.y, p.z);
player.sendBlockChange(loc, BEDROCK);
});
}, 4);
}
private static final BlockData BEDROCK = Material.BEDROCK.createBlockData();
private void generate() {
blockList.clear();
locations.forEach(point -> {
Map<String, Integer> pos = new HashMap<>();
pos.put("x", point.x);
pos.put("y", point.y);
pos.put("z", point.z);
blockList.add(pos);
});
AdventsCalendar.save();
}
}
@@ -0,0 +1,75 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.lobby.special.advent;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.listener.BasicListener;
import de.steamwar.sql.NodeMember;
import de.steamwar.sql.SteamwarUser;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import java.time.LocalDate;
public class PresentClickListener extends BasicListener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
LocalDate localDate = LocalDate.now();
int day = localDate.getDayOfMonth();
if (!AdventsCalendar.active()) {
return;
}
AdventsCalendar.getPresentList().forEach(present -> {
if (present.getDay() != day) return;
if (NodeMember.getNodeMember(present.getSchematicId(), SteamwarUser.get(event.getPlayer().getUniqueId()).getId()) != null) return;
LobbySystem.getMessage().send("ADVENT_CALENDAR_MESSAGE", event.getPlayer());
});
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
Block block = event.getClickedBlock();
if (block == null) return;
LocalDate localDate = LocalDate.now();
int day = localDate.getDayOfMonth();
if (!AdventsCalendar.active()) {
return;
}
AdventsCalendar.getPresentList().forEach(present -> {
present.click(event.getPlayer(), SteamwarUser.get(event.getPlayer().getUniqueId()), day, block.getLocation());
});
}
// @EventHandler
public void onPresentSetup(PlayerInteractEvent event) {
Block block = event.getClickedBlock();
if (block == null) return;
AdventsCalendar.getPresentList().forEach(present -> {
present.edit(event.getPlayer(), block.getLocation());
});
}
}
@@ -0,0 +1,102 @@
package de.steamwar.lobby.special.easter;
import de.steamwar.inventory.SWItem;
import de.steamwar.lobby.LobbySystem;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.Skull;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.profile.PlayerProfile;
import org.bukkit.util.Vector;
import java.util.Arrays;
import java.util.Map;
import java.util.Optional;
public class Egg {
private static final World world = Bukkit.getWorlds().get(0);
private final int x;
private final int y;
private final int z;
private final String message;
private final EggDifficulty difficulty;
private Optional<PlayerProfile> playerProfile = null;
public Egg(Map<String, ?> config) {
this.x = (int) config.get("x");
this.y = (int) config.get("y");
this.z = (int) config.get("z");
this.message = (String) config.get("name");
this.difficulty = EggDifficulty.valueOf(((String) config.get("difficulty")).toUpperCase());
}
public Vector getVector() {
return new Vector(x, y, z);
}
public String getMessage() {
return message;
}
public EggDifficulty getDifficulty() {
return difficulty;
}
public Block getBlock() {
Block block = world.getBlockAt(x, y, z);
if (block.getType() != Material.PLAYER_HEAD && block.getType() != Material.PLAYER_WALL_HEAD) {
System.out.println("Block is not a skull: " + block.getType() + " " + x + "," + y + "," + z);
return null;
}
return block;
}
public SWItem getItem(Player player, boolean found) {
if (playerProfile == null) {
Block block = getBlock();
if (block == null) {
playerProfile = Optional.empty();
return null;
}
Skull skull = (Skull) block.getState();
PlayerProfile playerProfile = skull.getOwnerProfile();
if (playerProfile == null) {
this.playerProfile = Optional.empty();
return null;
}
this.playerProfile = Optional.of(playerProfile);
}
if (!playerProfile.isPresent()) {
return null;
}
SWItem swItem;
if (found) {
swItem = new SWItem();
ItemStack itemStack = new ItemStack(Material.PLAYER_HEAD);
SkullMeta skullMeta = (SkullMeta) itemStack.getItemMeta();
skullMeta.setOwnerProfile(playerProfile.get());
itemStack.setItemMeta(skullMeta);
swItem.setItemStack(itemStack);
} else {
swItem = SWItem.getPlayerSkull("MHF_Question");
}
swItem.setLore(Arrays.asList(LobbySystem.getMessage().parse(difficulty.getMessage(), player)));
try {
swItem.setName("§f" + LobbySystem.getMessage().parse(message, player));
} catch (Exception e) {
swItem.setName("§f" + message);
}
return swItem;
}
}
@@ -0,0 +1,64 @@
package de.steamwar.lobby.special.easter;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.listener.BasicListener;
import de.steamwar.sql.UserConfig;
import org.bukkit.Particle;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.util.Vector;
public class EggClickListener extends BasicListener {
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
return;
}
Block block = event.getClickedBlock();
if (block == null) {
return;
}
Vector vector = block.getLocation().toVector();
Egg egg = null;
int index = -1;
for (Egg egg1 : EggHunt.getEggList()) {
index++;
if (egg1.getVector().equals(vector)) {
egg = egg1;
break;
}
}
if (egg == null) {
return;
}
Player player = event.getPlayer();
String found = UserConfig.getConfig(player.getUniqueId(), EggHunt.EGG_HUNT_CONFIG_KEY);
if (found == null) {
found = "";
}
StringBuilder builder = new StringBuilder(found);
while (builder.length() <= index) {
builder.append("0");
}
if (builder.charAt(index) == '1') {
return;
}
try {
player.sendTitle(LobbySystem.getMessage().parse(egg.getDifficulty().getMessage(), player), LobbySystem.getMessage().parse(egg.getMessage(), player), 0, 40, 5);
} catch (Exception e) {
player.sendTitle(LobbySystem.getMessage().parse(egg.getDifficulty().getMessage(), player), egg.getMessage(), 0, 40, 5);
}
player.spawnParticle(Particle.END_ROD, block.getLocation().add(0.5, 0.5, 0.5), 10, 0.5, 0.5, 0.5, 0.1);
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 0.25f, 1.0f);
builder.setCharAt(index, '1');
UserConfig.updatePlayerConfig(player.getUniqueId(), EggHunt.EGG_HUNT_CONFIG_KEY, builder.toString());
}
}

Some files were not shown because too many files have changed in this diff Show More