mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2025-02-27 09:42:37 +01:00
Use EntitiesLoadEvent instead of ChunkLoadEvent, other minor fixes
This commit is contained in:
parent
3409b06b93
commit
0afeb4792d
@ -47,8 +47,10 @@ import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.event.vehicle.VehicleDamageEvent;
|
||||
import org.bukkit.event.vehicle.VehicleDestroyEvent;
|
||||
import org.bukkit.event.vehicle.VehicleEnterEvent;
|
||||
import org.bukkit.event.world.ChunkEvent;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||
import org.bukkit.event.world.EntitiesLoadEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.event.world.WorldUnloadEvent;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
@ -151,8 +153,7 @@ public class EventListen implements Listener {
|
||||
Predicates.notNull());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onChunkLoad(ChunkLoadEvent event) {
|
||||
private void loadNPCs(ChunkEvent event) {
|
||||
ChunkCoord coord = new ChunkCoord(event.getChunk());
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
@ -170,6 +171,14 @@ public class EventListen implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onChunkLoad(ChunkLoadEvent event) {
|
||||
if (usingEntitiesLoadEvents())
|
||||
return;
|
||||
|
||||
loadNPCs(event);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onChunkUnload(final ChunkUnloadEvent event) {
|
||||
final List<NPC> toDespawn = Lists.newArrayList();
|
||||
@ -232,6 +241,11 @@ public class EventListen implements Listener {
|
||||
checkCreationEvent(event);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onEntitiesLoad(EntitiesLoadEvent event) {
|
||||
loadNPCs(event);
|
||||
}
|
||||
|
||||
/*
|
||||
* Entity events
|
||||
*/
|
||||
@ -732,4 +746,18 @@ public class EventListen implements Listener {
|
||||
}
|
||||
return npc.spawn(spawn, SpawnReason.CHUNK_LOAD);
|
||||
}
|
||||
|
||||
private static boolean usingEntitiesLoadEvents() {
|
||||
if (USING_ENTITIES_LOAD == null) {
|
||||
try {
|
||||
Class.forName("org.bukkit.event.world.EntitiesLoadEvent");
|
||||
USING_ENTITIES_LOAD = true;
|
||||
} catch (ClassNotFoundException swallow) {
|
||||
USING_ENTITIES_LOAD = false;
|
||||
}
|
||||
}
|
||||
return USING_ENTITIES_LOAD;
|
||||
}
|
||||
|
||||
private static Boolean USING_ENTITIES_LOAD;
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ public class Settings {
|
||||
DISABLE_LOOKCLOSE_WHILE_NAVIGATING("npc.default.look-close.disable-while-navigating", true),
|
||||
DISABLE_MC_NAVIGATION_FALLBACK("npc.pathfinding.disable-mc-fallback-navigation", true),
|
||||
DISABLE_TABLIST("npc.tablist.disable", true),
|
||||
ENTITY_SPAWN_WAIT_TICKS("general.entity-spawn-wait-ticks", 10),
|
||||
ENTITY_SPAWN_WAIT_TICKS("general.entity-spawn-wait-ticks", 20),
|
||||
ERROR_COLOUR("general.color-scheme.message-error", "<c>"),
|
||||
FOLLOW_ACROSS_WORLDS("npc.follow.teleport-across-worlds", true),
|
||||
HIGHLIGHT_COLOUR("general.color-scheme.message-highlight", "<e>"),
|
||||
|
@ -62,9 +62,12 @@ public class EditorCommands {
|
||||
desc = "Toggle the text editor",
|
||||
modifiers = { "text" },
|
||||
min = 1,
|
||||
max = 1,
|
||||
permission = "citizens.npc.edit.text")
|
||||
public void text(CommandContext args, Player player, NPC npc) {
|
||||
if (player.isConversing() && Editor.hasEditor(player) && args.argsLength() > 1) {
|
||||
player.acceptConversationInput(args.getJoinedStrings(1));
|
||||
return;
|
||||
}
|
||||
Editor.enterOrLeave(player, npc.getOrAddTrait(Text.class).getEditor(player));
|
||||
}
|
||||
}
|
||||
|
@ -1580,8 +1580,8 @@ public class NPCCommands {
|
||||
permission = "citizens.npc.passive")
|
||||
public void passive(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
boolean passive = args.hasValueFlag("set") ? Boolean.parseBoolean(args.getFlag("set"))
|
||||
: npc.data().get(NPC.DAMAGE_OTHERS_METADATA, true);
|
||||
npc.data().setPersistent(NPC.DAMAGE_OTHERS_METADATA, !passive);
|
||||
: !npc.data().get(NPC.DAMAGE_OTHERS_METADATA, true);
|
||||
npc.data().setPersistent(NPC.DAMAGE_OTHERS_METADATA, passive);
|
||||
Messaging.sendTr(sender, passive ? Messages.PASSIVE_SET : Messages.PASSIVE_UNSET, npc.getName());
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package net.citizensnpcs.npc;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
@ -19,6 +20,7 @@ import org.bukkit.scheduler.BukkitRunnable;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
|
||||
import net.citizensnpcs.NPCNeedsRespawnEvent;
|
||||
@ -292,22 +294,23 @@ public class CitizensNPC extends AbstractNPC {
|
||||
NMS.setBodyYaw(getEntity(), at.getYaw());
|
||||
|
||||
final Location to = at;
|
||||
BukkitRunnable postSpawn = new BukkitRunnable() {
|
||||
Consumer<Runnable> postSpawn = new Consumer<Runnable>() {
|
||||
private int timer;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (timer++ > Setting.ENTITY_SPAWN_WAIT_TICKS.asInt()) {
|
||||
Messaging.debug("Couldn't spawn", CitizensNPC.this, "entity not added to world");
|
||||
entityController.remove();
|
||||
cancel();
|
||||
Bukkit.getPluginManager().callEvent(new NPCNeedsRespawnEvent(CitizensNPC.this, to));
|
||||
public void accept(Runnable cancel) {
|
||||
if (getEntity() == null || !getEntity().isValid()) {
|
||||
if (timer++ > Setting.ENTITY_SPAWN_WAIT_TICKS.asInt()) {
|
||||
Messaging.debug("Couldn't spawn ", CitizensNPC.this, "waited", timer,
|
||||
"ticks but entity not added to world");
|
||||
entityController.remove();
|
||||
cancel.run();
|
||||
Bukkit.getPluginManager().callEvent(new NPCNeedsRespawnEvent(CitizensNPC.this, to));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (getEntity() == null || !getEntity().isValid())
|
||||
return;
|
||||
|
||||
// Set the spawned state
|
||||
getOrAddTrait(CurrentLocation.class).setLocation(to);
|
||||
getOrAddTrait(Spawned.class).setSpawned(true);
|
||||
@ -319,14 +322,13 @@ public class CitizensNPC extends AbstractNPC {
|
||||
Messaging.debug("Couldn't spawn", CitizensNPC.this, "SpawnReason." + reason,
|
||||
"due to event cancellation.");
|
||||
entityController.remove();
|
||||
cancel();
|
||||
cancel.run();
|
||||
return;
|
||||
}
|
||||
|
||||
navigator.onSpawn();
|
||||
|
||||
Collection<Trait> onSpawn = traits.values();
|
||||
for (Trait trait : onSpawn.toArray(new Trait[onSpawn.size()])) {
|
||||
for (Trait trait : Iterables.toArray(traits.values(), Trait.class)) {
|
||||
try {
|
||||
trait.onSpawn();
|
||||
} catch (Throwable ex) {
|
||||
@ -335,17 +337,20 @@ public class CitizensNPC extends AbstractNPC {
|
||||
}
|
||||
}
|
||||
|
||||
if (getEntity() instanceof LivingEntity) {
|
||||
EntityType type = getEntity().getType();
|
||||
if (type.isAlive()) {
|
||||
LivingEntity entity = (LivingEntity) getEntity();
|
||||
entity.setRemoveWhenFarAway(false);
|
||||
|
||||
if (NMS.getStepHeight(entity) < 1) {
|
||||
NMS.setStepHeight(entity, 1);
|
||||
}
|
||||
if (getEntity() instanceof Player) {
|
||||
|
||||
if (type == EntityType.PLAYER) {
|
||||
NMS.replaceTrackerEntry((Player) getEntity());
|
||||
PlayerUpdateTask.registerPlayer(getEntity());
|
||||
}
|
||||
|
||||
if (SUPPORT_NODAMAGE_TICKS && (Setting.DEFAULT_SPAWN_NODAMAGE_TICKS.asInt() != 20
|
||||
|| data().has(NPC.Metadata.SPAWN_NODAMAGE_TICKS))) {
|
||||
try {
|
||||
@ -366,13 +371,19 @@ public class CitizensNPC extends AbstractNPC {
|
||||
updateCustomName();
|
||||
|
||||
Messaging.debug("Spawned", CitizensNPC.this, "SpawnReason." + reason);
|
||||
cancel();
|
||||
cancel.run();
|
||||
}
|
||||
};
|
||||
if (isSpawned()) {
|
||||
postSpawn.runTask(CitizensAPI.getPlugin());
|
||||
if (getEntity() != null && getEntity().isValid()) {
|
||||
postSpawn.accept(() -> {
|
||||
});
|
||||
} else {
|
||||
postSpawn.runTaskTimer(CitizensAPI.getPlugin(), 0, 1);
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
postSpawn.accept(() -> cancel());
|
||||
}
|
||||
}.runTaskTimer(CitizensAPI.getPlugin(), 0, 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -171,8 +171,6 @@ public class SkinPacketTracker {
|
||||
* The radius.
|
||||
*/
|
||||
public void updateNearbyViewers(double radius) {
|
||||
radius *= radius;
|
||||
|
||||
org.bukkit.World world = entity.getBukkitEntity().getWorld();
|
||||
Player from = entity.getBukkitEntity();
|
||||
Location location = from.getLocation();
|
||||
@ -181,12 +179,12 @@ public class SkinPacketTracker {
|
||||
if (player == null || player.hasMetadata("NPC"))
|
||||
continue;
|
||||
|
||||
player.getLocation(CACHE_LOCATION);
|
||||
if (!player.canSee(from) || !location.getWorld().equals(CACHE_LOCATION.getWorld()))
|
||||
if (!location.getWorld().equals(player.getLocation(CACHE_LOCATION).getWorld()) || !player.canSee(from))
|
||||
continue;
|
||||
|
||||
if (location.distanceSquared(CACHE_LOCATION) > radius)
|
||||
if (location.distance(CACHE_LOCATION) > radius)
|
||||
continue;
|
||||
|
||||
updateViewer(player);
|
||||
}
|
||||
}
|
||||
|
@ -74,10 +74,7 @@ public class SkinUpdateTracker {
|
||||
Location playerLoc = player.getLocation(CACHE_LOCATION);
|
||||
Location skinLoc = entity.getLocation(NPC_LOCATION);
|
||||
|
||||
double viewDistance = Setting.NPC_SKIN_VIEW_DISTANCE.asDouble();
|
||||
viewDistance *= viewDistance;
|
||||
|
||||
if (playerLoc.distanceSquared(skinLoc) > viewDistance)
|
||||
if (playerLoc.distance(skinLoc) > Setting.NPC_SKIN_VIEW_DISTANCE.asDouble())
|
||||
return false;
|
||||
|
||||
// see if the NPC is within the players field of view
|
||||
|
@ -66,7 +66,7 @@ public class SmoothRotationTrait extends Trait {
|
||||
* The target location to face
|
||||
*/
|
||||
public void rotateToFace(Location target) {
|
||||
this.globalSession.setTarget(target);
|
||||
globalSession.setTarget(target);
|
||||
}
|
||||
|
||||
public void rotateToHave(float yaw, float pitch) {
|
||||
@ -119,13 +119,22 @@ public class SmoothRotationTrait extends Trait {
|
||||
}
|
||||
}
|
||||
|
||||
public static class RotationParams implements Persistable {
|
||||
public static class RotationParams implements Persistable, Cloneable {
|
||||
private boolean headOnly = false;
|
||||
private boolean immediate = false;
|
||||
private float maxPitchPerTick = 10;
|
||||
private float maxYawPerTick = 40;
|
||||
private final float[] pitchRange = { 0, 0 };
|
||||
private final float[] yawRange = { 0, 0 };
|
||||
private float[] pitchRange = { -180, 180 };
|
||||
private float[] yawRange = { -180, 180 };
|
||||
|
||||
@Override
|
||||
public RotationParams clone() {
|
||||
try {
|
||||
return (RotationParams) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public RotationParams headOnly(boolean headOnly) {
|
||||
this.headOnly = headOnly;
|
||||
@ -151,6 +160,14 @@ public class SmoothRotationTrait extends Trait {
|
||||
if (key.keyExists("maxYawPerTick")) {
|
||||
maxYawPerTick = (float) key.getDouble("maxYawPerTick");
|
||||
}
|
||||
if (key.keyExists("yawRange")) {
|
||||
String[] parts = key.getString("yawRange").split(",");
|
||||
yawRange = new float[] { Float.parseFloat(parts[0]), Float.parseFloat(parts[1]) };
|
||||
}
|
||||
if (key.keyExists("pitchRange")) {
|
||||
String[] parts = key.getString("pitchRange").split(",");
|
||||
pitchRange = new float[] { Float.parseFloat(parts[0]), Float.parseFloat(parts[1]) };
|
||||
}
|
||||
}
|
||||
|
||||
public RotationParams maxPitchPerTick(float val) {
|
||||
@ -163,13 +180,22 @@ public class SmoothRotationTrait extends Trait {
|
||||
return this;
|
||||
}
|
||||
|
||||
public RotationParams pitchRange(float[] val) {
|
||||
this.pitchRange = val;
|
||||
return this;
|
||||
}
|
||||
|
||||
public float rotateHeadYawTowards(int t, float yaw, float targetYaw) {
|
||||
return rotateTowards(yaw, targetYaw, maxYawPerTick);
|
||||
float out = rotateTowards(yaw, targetYaw, maxYawPerTick);
|
||||
return clamp(out, yawRange[0], yawRange[1]);
|
||||
}
|
||||
|
||||
public float rotatePitchTowards(int t, float pitch, float targetPitch) {
|
||||
return rotateTowards(pitch, targetPitch, maxPitchPerTick);
|
||||
}/*
|
||||
float out = rotateTowards(pitch, targetPitch, maxPitchPerTick);
|
||||
return clamp(out, pitchRange[0], pitchRange[1]);
|
||||
}
|
||||
|
||||
/*
|
||||
* public Vector3 SuperSmoothVector3Lerp( Vector3 pastPosition, Vector3 pastTargetPosition, Vector3 targetPosition, float time, float speed ){
|
||||
Vector3 f = pastPosition - pastTargetPosition + (targetPosition - pastTargetPosition) / (speed * time);
|
||||
return targetPosition - (targetPosition - pastTargetPosition) / (speed*time) + f * Mathf.Exp(-speed*time);
|
||||
@ -189,12 +215,35 @@ public class SmoothRotationTrait extends Trait {
|
||||
if (immediate) {
|
||||
key.setBoolean("immediate", immediate);
|
||||
}
|
||||
|
||||
if (maxPitchPerTick != 10) {
|
||||
key.setDouble("maxPitchPerTick", maxPitchPerTick);
|
||||
} else {
|
||||
key.removeKey("maxPitchPerTick");
|
||||
}
|
||||
|
||||
if (maxYawPerTick != 40) {
|
||||
key.setDouble("maxYawPerTick", maxYawPerTick);
|
||||
} else {
|
||||
key.removeKey("maxYawPerTick");
|
||||
}
|
||||
|
||||
if (pitchRange[0] != -180 || pitchRange[1] != 180) {
|
||||
key.setString("pitchRange", pitchRange[0] + "," + pitchRange[1]);
|
||||
} else {
|
||||
key.removeKey("pitchRange");
|
||||
}
|
||||
|
||||
if (yawRange[0] != -180 || yawRange[1] != 180) {
|
||||
key.setString("yawRange", yawRange[0] + "," + yawRange[1]);
|
||||
} else {
|
||||
key.removeKey("yawRange");
|
||||
}
|
||||
}
|
||||
|
||||
public RotationParams yawRange(float[] val) {
|
||||
this.yawRange = val;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,7 +256,7 @@ public class SmoothRotationTrait extends Trait {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
private float getTargetPitch() {
|
||||
public float getTargetPitch() {
|
||||
double dx = tx - getX();
|
||||
double dy = ty - (getY() + getEyeY());
|
||||
double dz = tz - getZ();
|
||||
@ -215,10 +264,22 @@ public class SmoothRotationTrait extends Trait {
|
||||
return (float) -Math.toDegrees(Math.atan2(dy, diag));
|
||||
}
|
||||
|
||||
private float getTargetYaw() {
|
||||
public double getTargetX() {
|
||||
return tx;
|
||||
}
|
||||
|
||||
public double getTargetY() {
|
||||
return ty;
|
||||
}
|
||||
|
||||
public float getTargetYaw() {
|
||||
return (float) Math.toDegrees(Math.atan2(tz - getZ(), tx - getX())) - 90.0F;
|
||||
}
|
||||
|
||||
public double getTargetZ() {
|
||||
return tz;
|
||||
}
|
||||
|
||||
public boolean hasTarget() {
|
||||
return t >= 0;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ public class TextBasePrompt extends StringPrompt {
|
||||
public Prompt acceptInput(ConversationContext context, String original) {
|
||||
String[] parts = ChatColor.stripColor(original.trim()).split(" ");
|
||||
String input = parts[0];
|
||||
|
||||
CommandSender sender = (CommandSender) context.getForWhom();
|
||||
if (input.equalsIgnoreCase("add")) {
|
||||
text.add(Joiner.on(' ').join(Arrays.copyOfRange(parts, 1, parts.length)));
|
||||
|
@ -26,7 +26,9 @@ import org.bukkit.util.Vector;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import io.netty.util.Version;
|
||||
import net.citizensnpcs.api.event.NPCCollisionEvent;
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
@ -326,6 +328,27 @@ public class Util {
|
||||
to.getBlockZ(), (int) to.getYaw(), (int) to.getPitch());
|
||||
}
|
||||
|
||||
public static boolean requiresNettyChannelMetadata() {
|
||||
if (REQUIRES_CHANNEL_METADATA != null)
|
||||
return REQUIRES_CHANNEL_METADATA;
|
||||
|
||||
Version version = Version.identify().get("netty-common");
|
||||
if (version == null) {
|
||||
version = Version.identify().get("netty-all");
|
||||
}
|
||||
if (version == null)
|
||||
return REQUIRES_CHANNEL_METADATA = false;
|
||||
try {
|
||||
Integer[] parts = Iterables.toArray(
|
||||
Iterables.transform(Splitter.on('.').split(version.artifactVersion()), s -> Integer.parseInt(s)),
|
||||
int.class);
|
||||
return REQUIRES_CHANNEL_METADATA = parts[0] > 4 || (parts[0] == 4 && parts[1] > 1);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
return REQUIRES_CHANNEL_METADATA = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the entity's yaw and pitch directly including head yaw.
|
||||
*/
|
||||
@ -334,6 +357,8 @@ public class Util {
|
||||
}
|
||||
|
||||
private static final Location AT_LOCATION = new Location(null, 0, 0, 0);
|
||||
|
||||
private static final Scoreboard DUMMY_SCOREBOARD = Bukkit.getScoreboardManager().getNewScoreboard();
|
||||
private static String MINECRAFT_REVISION;
|
||||
private static Boolean REQUIRES_CHANNEL_METADATA;
|
||||
}
|
||||
|
@ -339,14 +339,14 @@ citizens.editors.text.range-set=[[Range]] set to [[{0}]].
|
||||
citizens.editors.text.delay-set=[[Delay]] set to [[{0}]] seconds.
|
||||
citizens.editors.text.realistic-looking-set=[[Realistic looking]] set to [[{0}]].
|
||||
citizens.editors.text.speech-bubbles-set=[[Speech bubbles]] set to [[{0}]].
|
||||
citizens.editors.text.start-prompt=<<[[add:command(add ):Add text>> | <<[[item:suggest(item ):Set the talk item in hand pattern (set to ''default'' to clear)>> | <<[[range:suggest(range ):Set the talking range in blocks>> | <<[[delay:suggest(delay ):Set the talking delay in seconds>><br><<{0}talk close:command(close):Toggle sending messages when players get close>> | <<{1}random:command(random):Toggle random talking>> | <<{2}speech bubbles:command(speech bubbles):Toggle showing text as holograms instead of messages>> | <<{3}realistic:command(realistic looking):Toggle requiring line of sight before speaking>>
|
||||
citizens.editors.text.start-prompt=<<[[add:suggest(add ):Add text>> | <<[[item:suggest(item ):Set the talk item in hand pattern (set to ''default'' to clear)>> | <<[[range:suggest(range ):Set the talking range in blocks>> | <<[[delay:suggest(delay ):Set the talking delay in seconds>><br><<{0}talk close:command(/npc text close):Toggle sending messages when players get close>> | <<{1}random:command(/npc text random):Toggle random talking>> | <<{2}speech bubbles:command(/npc text speech bubbles):Toggle showing text as holograms instead of messages>> | <<{3}realistic:command(/npc text realistic looking):Toggle requiring line of sight before speaking>>
|
||||
citizens.editors.text.talk-item-set=[[Talk item pattern]] set to [[{0}]].
|
||||
citizens.editors.text.text-list-header=Current text:
|
||||
citizens.editors.waypoints.wander.editing-regions-stop=Exited the region editor.
|
||||
citizens.editors.waypoints.wander.worldguard-region-not-found=WorldGuard region not found.
|
||||
citizens.editors.waypoints.wander.worldguard-region-set=WorldGuard region set to [[{0}]].
|
||||
citizens.editors.waypoints.wander.range-set=Wander range set to xrange [[{0}]] and yrange [[{1}]].
|
||||
citizens.editors.waypoints.wander.begin=<b>Entered the wander waypoint editor.<br><<x range:suggest(xrange ):Set the x range in blocks>> | <<y range:suggest(yrange ):Set the y range in blocks>> | <<delay:suggest(delay ):Ticks to wait in between wanders>><br><<Enter the region editor:command(regions)>> | <<Restrict wandering to WorldGuard regions:suggest(worldguardregion )>>
|
||||
citizens.editors.waypoints.wander.begin=<b>Entered the wander waypoint editor.<br><<x range:suggest(xrange ):Set the x range in blocks>> | <<y range:suggest(yrange ):Set the y range in blocks>> | <<delay:suggest(delay ):Ticks to wait in between wanders>><br><<Enter the region editor:suggest(regions)>> | <<Restrict wandering to WorldGuard regions:suggest(worldguardregion )>>
|
||||
citizens.editors.waypoints.wander.end=Exited the wander waypoint editor.
|
||||
citizens.editors.waypoints.wander.delay-set=Delay between wanders set to [[{0}]] ticks.
|
||||
citizens.editors.waypoints.wander.invalid-delay=Invalid delay specified.
|
||||
|
@ -953,6 +953,7 @@ public class NMSImpl implements NMSBridge {
|
||||
@Override
|
||||
public void look(org.bukkit.entity.Entity entity, Location to, boolean headOnly, boolean immediate) {
|
||||
Entity handle = NMSImpl.getHandle(entity);
|
||||
|
||||
if (immediate || headOnly || BAD_CONTROLLER_LOOK.contains(handle.getBukkitEntity().getType())
|
||||
|| (!(handle instanceof Mob) && !(handle instanceof EntityHumanNPC))) {
|
||||
Location fromLocation = entity.getLocation(FROM_LOCATION);
|
||||
|
Loading…
Reference in New Issue
Block a user