mirror of
https://github.com/filoghost/HolographicDisplays.git
synced 2025-02-22 06:51:20 +01:00
Add item pickup functionality
This commit is contained in:
parent
089d1eaa7c
commit
54d089bf04
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) filoghost and contributors
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
package me.filoghost.holographicdisplays.plugin.hologram.tracking;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
public class CollisionHelper {
|
||||||
|
|
||||||
|
private static final double PLAYER_WIDTH_RADIUS = 0.6 / 2;
|
||||||
|
private static final double PLAYER_HEIGHT_RADIUS = 1.8 / 2;
|
||||||
|
|
||||||
|
private static final double ITEM_WIDTH_RADIUS = 0.25 / 2;
|
||||||
|
private static final double ITEM_HEIGHT_RADIUS = 0.25 / 2;
|
||||||
|
|
||||||
|
// The server increases the player's bounding box in all directions before checking if it intersects with an item
|
||||||
|
private static final double PLAYER_GROW_WIDTH = 1;
|
||||||
|
private static final double PLAYER_GROW_HEIGHT = 0.5;
|
||||||
|
|
||||||
|
private static final double REQUIRED_DISTANCE_X = PLAYER_WIDTH_RADIUS + PLAYER_GROW_WIDTH + ITEM_WIDTH_RADIUS;
|
||||||
|
private static final double REQUIRED_DISTANCE_Z = REQUIRED_DISTANCE_X;
|
||||||
|
private static final double REQUIRED_DISTANCE_Y = PLAYER_HEIGHT_RADIUS + PLAYER_GROW_HEIGHT + ITEM_HEIGHT_RADIUS;
|
||||||
|
|
||||||
|
public static boolean isInPickupRange(Player player, double itemX, double itemY, double itemZ) {
|
||||||
|
/*
|
||||||
|
* Normally, the server determines if a player is picking up a dropped item
|
||||||
|
* by checking if the bounding boxes of the player and the item intersect.
|
||||||
|
*
|
||||||
|
* This can be simplified: for each direction (X, Y, Z), check if the distance between the centers of the bounding boxes
|
||||||
|
* is lower than the sum of the radius (half the length) of each box.
|
||||||
|
*
|
||||||
|
* If the condition is satisfied for all directions, the bounding boxes intersect. Visual example:
|
||||||
|
*
|
||||||
|
* Box #1
|
||||||
|
* ._____________.
|
||||||
|
* | |
|
||||||
|
* | | Box #2
|
||||||
|
* | * .___|_______________.
|
||||||
|
* | | | |
|
||||||
|
* |_________|___| * |
|
||||||
|
* | |
|
||||||
|
* |___________________|
|
||||||
|
*
|
||||||
|
* *------>
|
||||||
|
* Radius #1
|
||||||
|
*
|
||||||
|
* <---------*
|
||||||
|
* Radius #2
|
||||||
|
*
|
||||||
|
* *------------*
|
||||||
|
* Distance between centers
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* In the example above, the distance between the centers is lower than the sum of the two radii,
|
||||||
|
* so the boxes collide in that direction.
|
||||||
|
*/
|
||||||
|
Location playerLocation = player.getLocation();
|
||||||
|
|
||||||
|
// The Y position is on lowest point of the bounding box, not in the center
|
||||||
|
double playerCenterY = playerLocation.getY() + PLAYER_HEIGHT_RADIUS;
|
||||||
|
double itemCenterY = itemY + ITEM_HEIGHT_RADIUS;
|
||||||
|
|
||||||
|
double xDiff = Math.abs(playerLocation.getX() - itemX);
|
||||||
|
double zDiff = Math.abs(playerLocation.getZ() - itemZ);
|
||||||
|
double yDiff = Math.abs(playerCenterY - itemCenterY);
|
||||||
|
|
||||||
|
return xDiff <= REQUIRED_DISTANCE_X
|
||||||
|
&& yDiff <= REQUIRED_DISTANCE_Y
|
||||||
|
&& zDiff <= REQUIRED_DISTANCE_Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -9,9 +9,11 @@ import me.filoghost.holographicdisplays.common.nms.EntityID;
|
|||||||
import me.filoghost.holographicdisplays.common.nms.NMSManager;
|
import me.filoghost.holographicdisplays.common.nms.NMSManager;
|
||||||
import me.filoghost.holographicdisplays.common.nms.NMSPacketList;
|
import me.filoghost.holographicdisplays.common.nms.NMSPacketList;
|
||||||
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseItemLine;
|
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseItemLine;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.MustBeInvokedByOverriders;
|
import org.jetbrains.annotations.MustBeInvokedByOverriders;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class ItemLineTracker extends ClickableLineTracker<BaseItemLine> {
|
public class ItemLineTracker extends ClickableLineTracker<BaseItemLine> {
|
||||||
@ -31,6 +33,20 @@ public class ItemLineTracker extends ClickableLineTracker<BaseItemLine> {
|
|||||||
this.itemEntityID = nmsManager.newEntityID();
|
this.itemEntityID = nmsManager.newEntityID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@MustBeInvokedByOverriders
|
||||||
|
@Override
|
||||||
|
protected void update(Collection<? extends Player> onlinePlayers) {
|
||||||
|
super.update(onlinePlayers);
|
||||||
|
|
||||||
|
if (spawnItemEntities && hasTrackedPlayers()) {
|
||||||
|
for (Player trackedPlayer : getTrackedPlayers()) {
|
||||||
|
if (CollisionHelper.isInPickupRange(trackedPlayer, locationX, locationY, locationZ)) {
|
||||||
|
line.onPickup(trackedPlayer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean updatePlaceholders() {
|
protected boolean updatePlaceholders() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -46,7 +46,8 @@ public abstract class LineTracker<T extends BaseHologramLine> {
|
|||||||
lineChanged = true;
|
lineChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final void update(Collection<? extends Player> onlinePlayers) {
|
@MustBeInvokedByOverriders
|
||||||
|
protected void update(Collection<? extends Player> onlinePlayers) {
|
||||||
boolean sendChangesPackets = false;
|
boolean sendChangesPackets = false;
|
||||||
|
|
||||||
// First, detect the changes if the flag is on and set it off
|
// First, detect the changes if the flag is on and set it off
|
||||||
@ -115,10 +116,14 @@ public abstract class LineTracker<T extends BaseHologramLine> {
|
|||||||
|
|
||||||
protected abstract boolean shouldTrackPlayer(Player player);
|
protected abstract boolean shouldTrackPlayer(Player player);
|
||||||
|
|
||||||
private boolean hasTrackedPlayers() {
|
protected final boolean hasTrackedPlayers() {
|
||||||
return !trackedPlayers.isEmpty();
|
return !trackedPlayers.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected final Set<Player> getTrackedPlayers() {
|
||||||
|
return trackedPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
public final boolean isTrackedPlayer(Player player) {
|
public final boolean isTrackedPlayer(Player player) {
|
||||||
return trackedPlayers.contains(player);
|
return trackedPlayers.contains(player);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user