Skip to content

Commit

Permalink
Make door opening work more consistently
Browse files Browse the repository at this point in the history
  • Loading branch information
fullwall committed May 28, 2022
1 parent c4351f8 commit 4a9f254
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 27 deletions.
Expand Up @@ -3,6 +3,7 @@
import java.util.ListIterator;

import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
Expand All @@ -13,7 +14,9 @@
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.material.MaterialData;
import org.bukkit.scheduler.BukkitRunnable;

import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.astar.pathfinder.PathPoint.PathCallback;
import net.citizensnpcs.api.event.NPCOpenDoorEvent;
import net.citizensnpcs.api.event.NPCOpenGateEvent;
Expand All @@ -37,7 +40,7 @@ public PassableState isPassable(BlockSource source, PathPoint point) {
}

static class DoorOpener implements PathCallback {
boolean opened = false;
private boolean opened;

private void close(NPC npc, Block point) {
if (SpigotUtil.isUsing1_13API()) {
Expand All @@ -47,6 +50,7 @@ private void close(NPC npc, Block point) {
}
open.setOpen(false);
point.setBlockData(open);
point.getState().update();
} else {
point = getCorrectDoor(point);
BlockState state = point.getState();
Expand All @@ -66,6 +70,7 @@ private void close(NPC npc, Block point) {
: Sound.BLOCK_FENCE_GATE_CLOSE;
point.getWorld().playSound(point.getLocation(), sound, 10, 1);
} catch (Exception ex) {
ex.printStackTrace();
SUPPORTS_SOUNDS = false;
}
}
Expand All @@ -83,6 +88,26 @@ private Block getCorrectDoor(Block point) {
return bottom ? point : point.getRelative(BlockFace.DOWN);
}

@Override
public void onReached(NPC npc, Block point) {
Location centreDoor = point.getLocation().add(0.5, 0, 0.5);
new BukkitRunnable() {
@Override
public void run() {
if (!npc.getNavigator().isNavigating()) {
cancel();
return;
}

double dist = npc.getStoredLocation().distance(centreDoor);
if (dist > 1.8) {
close(npc, point);
cancel();
}
}
}.runTaskTimer(CitizensAPI.getPlugin(), 5, 1);
}

private void open(NPC npc, Block point) {
if (SpigotUtil.isUsing1_13API()) {
Openable open = (Openable) point.getBlockData();
Expand All @@ -97,7 +122,7 @@ private void open(NPC npc, Block point) {
}
open.setOpen(true);
point.setBlockData(open);
opened = true;
point.getState().update();
} else {
point = getCorrectDoor(point);
BlockState state = point.getState();
Expand All @@ -114,7 +139,6 @@ private void open(NPC npc, Block point) {
open.setOpen(true);
state.setData((MaterialData) open);
state.update();
opened = true;
}
if (SUPPORTS_SOUNDS) {
try {
Expand All @@ -124,6 +148,7 @@ private void open(NPC npc, Block point) {
: Sound.BLOCK_FENCE_GATE_OPEN;
point.getWorld().playSound(point.getLocation(), sound, 10, 1);
} catch (Exception ex) {
ex.printStackTrace();
SUPPORTS_SOUNDS = false;
}
}
Expand All @@ -134,30 +159,10 @@ private void open(NPC npc, Block point) {
public void run(NPC npc, Block point, ListIterator<Block> path) {
if (!MinecraftBlockExaminer.isDoor(point.getType()) || opened)
return;
double dist = npc.getStoredLocation().distance(point.getLocation().add(0.5, 0, 0.5));
if (dist > 2)
if (npc.getStoredLocation().distance(point.getLocation().add(0.5, 0, 0.5)) > 2.5)
return;

open(npc, point);

if (!opened)
return;

// TODO: a more block-focused API for these things would be better (see LadderClimber)
npc.getNavigator().getLocalParameters().addRunCallback(new Runnable() {
boolean closed = false;

@Override
public void run() {
if (closed)
return;
double dist = npc.getStoredLocation().distance(point.getLocation().add(0.5, 0, 0.5));
if (dist > 1.8) {
close(npc, point);
closed = true;
}
}
});
opened = true;
}

private void tryArmSwing(NPC npc) {
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/net/citizensnpcs/api/astar/pathfinder/Path.java
Expand Up @@ -108,6 +108,7 @@ public void update(Agent agent) {
if (isComplete()) {
return;
}
path[index].onComplete((NPC) agent);
++index;
}

Expand All @@ -120,6 +121,16 @@ private PathEntry(Vector vector, List<PathCallback> callbacks) {
this.callbacks = callbacks;
}

public void onComplete(NPC npc) {
if (callbacks == null)
return;
Block current = npc.getEntity().getWorld().getBlockAt(vector.getBlockX(), vector.getBlockY(),
vector.getBlockZ());
for (PathCallback callback : callbacks) {
callback.onReached(npc, current);
}
}

public void run(final NPC npc) {
if (callbacks == null)
return;
Expand Down
16 changes: 14 additions & 2 deletions src/main/java/net/citizensnpcs/api/astar/pathfinder/PathPoint.java
Expand Up @@ -54,11 +54,23 @@ public interface PathPoint {

public static interface PathCallback {
/**
* A callback that is run every tick while the path is being executed.
* Run once the specificed point is reached.
*
* @param npc
* The NPC
* @param point
* The current target path
* The point that was reached
*/
default void onReached(NPC npc, Block point) {
};

/**
* Run every tick when moving towards a specific block.
*
* @param npc
* The NPC
* @param point
* The point
* @param path
* The future path destinations as blocks
*/
Expand Down

0 comments on commit 4a9f254

Please sign in to comment.