forked from SteamWar/SteamWar
The repeating timers that linked classes and the plugin main classes started once for the whole runtime now use @LinkedTimer, on Spigot (BauSystem, SpigotCore, LobbySystem, MissileWars, TowerRun, Teamserver) and Velocity. The FightInfoPacketSenders of MissileWars and TowerRun are linked themselves instead of being started by the main class.
204 lines
8.7 KiB
Java
204 lines
8.7 KiB
Java
/*
|
|
* This file is a part of the SteamWar software.
|
|
*
|
|
* Copyright (C) 2025 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.jumpandrun;
|
|
|
|
import de.steamwar.linkage.Linked;
|
|
import de.steamwar.linkage.LinkedTimer;
|
|
import de.steamwar.lobby.LobbySystem;
|
|
import de.steamwar.lobby.listener.PlayerSpawn;
|
|
import de.steamwar.lobby.util.LeaderboardManager;
|
|
import de.steamwar.sql.SteamwarUser;
|
|
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.Listener;
|
|
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.*;
|
|
|
|
@Linked
|
|
public class JumpAndRun implements Listener {
|
|
|
|
public static final String JUMP_AND_RUN_CONFIG = "jump_and_run@winter25";
|
|
|
|
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 LeaderboardManager LEADERBOARD = new LeaderboardManager(LobbySystem.getEntityServer(false), JUMP_AND_RUN_CONFIG, new Location(Bukkit.getWorlds().get(0), 2338.5, 42.5, 1231.5));
|
|
|
|
@LinkedTimer(delay = 1, period = 1)
|
|
private void updatePlayers() {
|
|
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 > 20) {
|
|
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));
|
|
});
|
|
}
|
|
|
|
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()) index = -2;
|
|
if (location.toVector().distanceSquared(point) >= 17) index = -2;
|
|
if (index > 0 && index < points.size() - 1) {
|
|
Vector nextPoint = points.get(index + 1);
|
|
if (location.getY() >= nextPoint.getY() && location.toVector().distanceSquared(nextPoint) < 17) {
|
|
index = index + 1;
|
|
}
|
|
}
|
|
if (index == -2) {
|
|
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) {
|
|
long best = LEADERBOARD.getPlayerTime(SteamwarUser.get(player.getUniqueId()));
|
|
if (time < best) {
|
|
if (best != Long.MAX_VALUE) {
|
|
SimpleDateFormat format = new SimpleDateFormat(LobbySystem.getMessage().parse("JUMP_AND_RUN_TIME", player), Locale.ROOT);
|
|
String parsed = format.format(new Date(best - time));
|
|
LobbySystem.getMessage().sendPrefixless("JUMP_AND_RUN_PERSONAL_BEST", player, parsed);
|
|
}
|
|
LEADERBOARD.updateBestTime(SteamwarUser.get(player.getUniqueId()), time);
|
|
}
|
|
}
|
|
|
|
@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);
|
|
}
|
|
}
|