001/*
002 * PlotSquared, a land and world management plugin for Minecraft.
003 * Copyright (C) IntellectualSites <https://intellectualsites.com>
004 * Copyright (C) IntellectualSites team and contributors
005 *
006 * This program is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * This program is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
018 */
019package com.plotsquared.bukkit.listener;
020
021import com.plotsquared.bukkit.player.BukkitPlayer;
022import com.plotsquared.bukkit.util.BukkitUtil;
023import com.plotsquared.core.location.Location;
024import com.plotsquared.core.permissions.Permission;
025import com.plotsquared.core.player.PlotPlayer;
026import com.plotsquared.core.plot.Plot;
027import com.plotsquared.core.plot.flag.implementations.ForcefieldFlag;
028import org.bukkit.entity.Player;
029import org.bukkit.util.Vector;
030
031import java.util.HashSet;
032import java.util.Set;
033import java.util.UUID;
034
035@SuppressWarnings("unused")
036public class ForceFieldListener {
037
038    private static Set<PlotPlayer<?>> getNearbyPlayers(Player player, Plot plot) {
039        Set<PlotPlayer<?>> players = new HashSet<>();
040        for (Player nearPlayer : player.getNearbyEntities(5d, 5d, 5d).stream()
041                .filter(entity -> entity instanceof Player)
042                .map(entity -> (Player) entity)
043                .toList()
044        ) {
045            PlotPlayer<?> plotPlayer;
046            if ((plotPlayer = BukkitUtil.adapt(nearPlayer)) == null || !plot
047                    .equals(plotPlayer.getCurrentPlot())) {
048                continue;
049            }
050            if (!plot.isAdded(plotPlayer.getUUID())) {
051                players.add(plotPlayer);
052            }
053        }
054        return players;
055    }
056
057    private static PlotPlayer<?> hasNearbyPermitted(Player player, Plot plot) {
058        for (Player nearPlayer : player.getNearbyEntities(5d, 5d, 5d).stream()
059                .filter(entity -> entity instanceof Player)
060                .map(entity -> (Player) entity)
061                .toList()
062        ) {
063            PlotPlayer<?> plotPlayer;
064            if ((plotPlayer = BukkitUtil.adapt(nearPlayer)) == null || !plot
065                    .equals(plotPlayer.getCurrentPlot())) {
066                continue;
067            }
068            if (plot.isAdded(plotPlayer.getUUID())) {
069                return plotPlayer;
070            }
071        }
072        return null;
073    }
074
075    private static Vector calculateVelocity(PlotPlayer<?> player, PlotPlayer<?> e) {
076        Location playerLocation = player.getLocationFull();
077        Location oPlayerLocation = e.getLocation();
078        double playerX = playerLocation.getX();
079        double playerY = playerLocation.getY();
080        double playerZ = playerLocation.getZ();
081        double oPlayerX = oPlayerLocation.getX();
082        double oPlayerY = oPlayerLocation.getY();
083        double oPlayerZ = oPlayerLocation.getZ();
084        double x = 0d;
085        if (playerX < oPlayerX) {
086            x = 1.0d;
087        } else if (playerX > oPlayerX) {
088            x = -1.0d;
089        }
090        double y = 0d;
091        if (playerY < oPlayerY) {
092            y = 0.5d;
093        } else if (playerY > oPlayerY) {
094            y = -0.5d;
095        }
096        double z = 0d;
097        if (playerZ < oPlayerZ) {
098            z = 1.0d;
099        } else if (playerZ > oPlayerZ) {
100            z = -1.0d;
101        }
102        return new Vector(x, y, z);
103    }
104
105    public static void handleForcefield(Player player, PlotPlayer<?> plotPlayer, Plot plot) {
106        if (plot.getFlag(ForcefieldFlag.class)) {
107            UUID uuid = plotPlayer.getUUID();
108            if (plot.isAdded(uuid)) {
109                Set<PlotPlayer<?>> players = getNearbyPlayers(player, plot);
110                for (PlotPlayer<?> oPlayer : players) {
111                    if (!oPlayer.hasPermission(Permission.PERMISSION_ADMIN_ENTRY_FORCEFIELD)) {
112                        ((BukkitPlayer) oPlayer).player
113                                .setVelocity(calculateVelocity(plotPlayer, oPlayer));
114                    }
115                }
116            } else {
117                PlotPlayer<?> oPlayer = hasNearbyPermitted(player, plot);
118                if (oPlayer == null) {
119                    return;
120                }
121                if (!plotPlayer.hasPermission(Permission.PERMISSION_ADMIN_ENTRY_FORCEFIELD)) {
122                    player.setVelocity(calculateVelocity(oPlayer, plotPlayer));
123                }
124            }
125        }
126    }
127
128}