Files
SteamWar/LobbySystem/src/de/steamwar/lobby/particle/elements/touch/TeamLink.java
T
YoyoNow f63390915b Add glyph flight for enchant particles and blend team links
Entries with the enchant particle get a Glyph flight setting: float down as
usual, fly into the player or fly out of them, the latter two unlocked by the
WarGear Season placement and participation. Team link lines now start in the
drawing player's particle and blend into the partner's along the way.
2026-10-26 15:13:39 +01:00

83 lines
3.6 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.particle.elements.touch;
import de.steamwar.lobby.particle.BodyMotion;
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.entity.Player;
import org.bukkit.util.Vector;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
// A line of particles between nearby players who show the same link. It starts in one player's particle and blends
// into the other's towards them. Each pair is drawn by only one of them.
public class TeamLink extends DelegatingParticleElement {
public static final double RANGE = 8;
private static final double CHEST = 1.2;
// Spreads the blend evenly along the line, so it does not flicker from tick to tick
private static final double GOLDEN_RATIO = 0.6180339887;
private record Showing(long tick, ParticleElement particle) {
}
// Per link, who showed it in which tick with which particle
private static final Map<String, Map<Player, Showing>> SHOWING = new HashMap<>();
private final String link;
private final double spacing;
public TeamLink(String link, ParticleElement particleElement, double spacing) {
super(particleElement);
this.link = link;
this.spacing = spacing;
}
@Override
public void tick(ParticleTickData particleTickData) {
Player player = particleTickData.getPlayer();
long now = BodyMotion.currentTick();
Map<Player, Showing> showing = SHOWING.computeIfAbsent(link, key -> new WeakHashMap<>());
showing.put(player, new Showing(now, particleElement));
Location from = player.getLocation().add(0, CHEST, 0);
for (Map.Entry<Player, Showing> other : showing.entrySet()) {
Player partner = other.getKey();
// Still showing it, and drawn by the player with the smaller id only
if (partner == player || other.getValue().tick() < now - 1 || player.getUniqueId().compareTo(partner.getUniqueId()) > 0) continue;
Location to = partner.getLocation().add(0, CHEST, 0);
if (to.getWorld() != from.getWorld() || to.distanceSquared(from) > RANGE * RANGE) continue;
Vector step = to.toVector().subtract(from.toVector());
int points = (int) Math.ceil(step.length() / spacing);
step.multiply(1.0 / points);
for (int i = 1; i < points; i++) {
double towardsPartner = (double) i / points;
ParticleElement particle = (i * GOLDEN_RATIO) % 1 < towardsPartner ? other.getValue().particle() : particleElement;
particle.tick(particleTickData.withLocation(from.clone().add(step.clone().multiply(i))));
}
}
}
}