mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2024-06-22 04:24:57 +02:00
Fix /npc equip for horses on 1.15, add max controllable speed setting
This commit is contained in:
parent
72180ff8ee
commit
3bf5881c4b
|
@ -100,6 +100,7 @@ public class Settings {
|
|||
HIGHLIGHT_COLOUR("general.color-scheme.message-highlight", "<e>"),
|
||||
KEEP_CHUNKS_LOADED("npc.chunks.always-keep-loaded", false),
|
||||
LOCALE("general.translation.locale", ""),
|
||||
MAX_CONTROLLABLE_GROUND_SPEED("npc.controllable.max-ground-speed", 0.5),
|
||||
MAX_NPC_LIMIT_CHECKS("npc.limits.max-permission-checks", 100),
|
||||
MAX_NPC_SKIN_RETRIES("npc.skins.max-retries", -1),
|
||||
MAX_PACKET_ENTRIES("npc.limits.max-packet-entries", 15),
|
||||
|
|
|
@ -34,8 +34,8 @@ import net.citizensnpcs.util.Util;
|
|||
/**
|
||||
* Persists the controllable status for /npc controllable
|
||||
*
|
||||
* A controllable {@link NPC} can be mounted by a {@link Player} using right
|
||||
* click or /npc mount and moved around using e.g. arrow keys.
|
||||
* A controllable {@link NPC} can be mounted by a {@link Player} using right click or /npc mount and moved around using
|
||||
* e.g. arrow keys.
|
||||
*/
|
||||
@TraitName("controllable")
|
||||
public class Controllable extends Trait implements Toggleable, CommandConfigurable {
|
||||
|
@ -134,7 +134,8 @@ public class Controllable extends Trait implements Toggleable, CommandConfigurab
|
|||
/**
|
||||
* Attempts to mount the {@link NPC} onto the supplied {@link Player}.
|
||||
*
|
||||
* @param toMount the player to mount
|
||||
* @param toMount
|
||||
* the player to mount
|
||||
* @return whether the mount was successful
|
||||
*/
|
||||
public boolean mount(Player toMount) {
|
||||
|
@ -159,16 +160,16 @@ public class Controllable extends Trait implements Toggleable, CommandConfigurab
|
|||
if (NMS.getPassengers(npc.getEntity()).contains(npc.getEntity()))
|
||||
return;
|
||||
switch (performed) {
|
||||
case RIGHT_CLICK_BLOCK:
|
||||
case RIGHT_CLICK_AIR:
|
||||
controller.rightClick(event);
|
||||
break;
|
||||
case LEFT_CLICK_BLOCK:
|
||||
case LEFT_CLICK_AIR:
|
||||
controller.leftClick(event);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case RIGHT_CLICK_BLOCK:
|
||||
case RIGHT_CLICK_AIR:
|
||||
controller.rightClick(event);
|
||||
break;
|
||||
case LEFT_CLICK_BLOCK:
|
||||
case LEFT_CLICK_AIR:
|
||||
controller.leftClick(event);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,10 +210,10 @@ public class Controllable extends Trait implements Toggleable, CommandConfigurab
|
|||
}
|
||||
|
||||
/**
|
||||
* Configures the explicit typei.e. whether the NPC should be controlled as if
|
||||
* it was a certain {@link EntityType}.
|
||||
* Configures the explicit typei.e. whether the NPC should be controlled as if it was a certain {@link EntityType}.
|
||||
*
|
||||
* @param type the explicit type
|
||||
* @param type
|
||||
* the explicit type
|
||||
*/
|
||||
public void setExplicitType(EntityType type) {
|
||||
this.explicitType = type;
|
||||
|
@ -238,8 +239,8 @@ public class Controllable extends Trait implements Toggleable, CommandConfigurab
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets whether the {@link Player} attempting to mount the {@link NPC} must
|
||||
* actually own the {@link NPC} to mount it.
|
||||
* Sets whether the {@link Player} attempting to mount the {@link NPC} must actually own the {@link NPC} to mount
|
||||
* it.
|
||||
*
|
||||
* @see Owner#isOwnedBy(org.bukkit.command.CommandSender)
|
||||
*/
|
||||
|
@ -257,6 +258,7 @@ public class Controllable extends Trait implements Toggleable, CommandConfigurab
|
|||
}
|
||||
|
||||
private double updateHorizontalSpeed(Entity handle, Entity passenger, double speed, float speedMod) {
|
||||
double maxSpeed = Setting.MAX_CONTROLLABLE_GROUND_SPEED.asDouble();
|
||||
Vector vel = handle.getVelocity();
|
||||
double oldSpeed = Math.sqrt(vel.getX() * vel.getX() + vel.getZ() * vel.getZ());
|
||||
double horizontal = NMS.getHorizontalMovement(passenger);
|
||||
|
@ -271,17 +273,17 @@ public class Controllable extends Trait implements Toggleable, CommandConfigurab
|
|||
new Vector(passenger.getVelocity().getX() * speedMod, 0D, passenger.getVelocity().getZ() * speedMod));
|
||||
|
||||
double newSpeed = Math.sqrt(vel.getX() * vel.getX() + vel.getZ() * vel.getZ());
|
||||
if (newSpeed > 0.5D) {
|
||||
double movementFactor = 0.5D / newSpeed;
|
||||
if (newSpeed > maxSpeed) {
|
||||
double movementFactor = maxSpeed / newSpeed;
|
||||
vel = vel.multiply(new Vector(movementFactor, 1, movementFactor));
|
||||
newSpeed = 0.5D;
|
||||
newSpeed = maxSpeed;
|
||||
}
|
||||
handle.setVelocity(vel);
|
||||
|
||||
if (newSpeed > oldSpeed && speed < 0.5D) {
|
||||
return (float) Math.min(0.5D, (speed + ((0.5D - speed) / 50.0D)));
|
||||
if (newSpeed > oldSpeed && speed < maxSpeed) {
|
||||
return (float) Math.min(maxSpeed, (speed + ((maxSpeed - speed) / 50.0D)));
|
||||
} else {
|
||||
return (float) Math.max(0.07D, (speed - ((speed - 0.07D) / 50.0D)));
|
||||
return (float) Math.max(0, (speed - ((speed) / 50.0D)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -404,14 +406,15 @@ public class Controllable extends Trait implements Toggleable, CommandConfigurab
|
|||
}
|
||||
|
||||
/**
|
||||
* Register a movement controller for a certain {@link EntityType} to be used
|
||||
* for {@link NPC}s with that type.
|
||||
* Register a movement controller for a certain {@link EntityType} to be used for {@link NPC}s with that type.
|
||||
*
|
||||
* Default controllers are registered for BAT, BLAZE, ENDER_DRAGON, GHAST,
|
||||
* WITHER and PARROT using {@link PlayerInputAirController}.
|
||||
* Default controllers are registered for BAT, BLAZE, ENDER_DRAGON, GHAST, WITHER and PARROT using
|
||||
* {@link PlayerInputAirController}.
|
||||
*
|
||||
* @param type the entity type
|
||||
* @param clazz the controller class
|
||||
* @param type
|
||||
* the entity type
|
||||
* @param clazz
|
||||
* the controller class
|
||||
*/
|
||||
public static void registerControllerType(EntityType type, Class<? extends MovementController> clazz) {
|
||||
try {
|
||||
|
|
|
@ -32,291 +32,291 @@ import net.citizensnpcs.util.Messages;
|
|||
import net.citizensnpcs.util.Util;
|
||||
|
||||
/**
|
||||
* A wandering waypoint provider that wanders between either a box centered at
|
||||
* the current location or inside a region defined by a list of boxes.
|
||||
* A wandering waypoint provider that wanders between either a box centered at the current location or inside a region
|
||||
* defined by a list of boxes.
|
||||
*/
|
||||
public class WanderWaypointProvider
|
||||
implements WaypointProvider, Supplier<PhTreeSolid<Boolean>>, Function<NPC, Location> {
|
||||
private WanderGoal currentGoal;
|
||||
@Persist
|
||||
public int delay = -1;
|
||||
private NPC npc;
|
||||
private volatile boolean paused;
|
||||
@Persist
|
||||
private final List<Location> regionCentres = Lists.newArrayList();
|
||||
private PhTreeSolid<Boolean> tree = PhTreeSolid.create(3);
|
||||
@Persist
|
||||
public int xrange = DEFAULT_XRANGE;
|
||||
@Persist
|
||||
public int yrange = DEFAULT_YRANGE;
|
||||
implements WaypointProvider, Supplier<PhTreeSolid<Boolean>>, Function<NPC, Location> {
|
||||
private WanderGoal currentGoal;
|
||||
@Persist
|
||||
public int delay = -1;
|
||||
private NPC npc;
|
||||
private volatile boolean paused;
|
||||
@Persist
|
||||
private final List<Location> regionCentres = Lists.newArrayList();
|
||||
private PhTreeSolid<Boolean> tree = PhTreeSolid.create(3);
|
||||
@Persist
|
||||
public int xrange = DEFAULT_XRANGE;
|
||||
@Persist
|
||||
public int yrange = DEFAULT_YRANGE;
|
||||
|
||||
public void addRegionCentre(Location centre) {
|
||||
regionCentres.add(centre);
|
||||
recalculateTree();
|
||||
}
|
||||
public void addRegionCentre(Location centre) {
|
||||
regionCentres.add(centre);
|
||||
recalculateTree();
|
||||
}
|
||||
|
||||
public void addRegionCentres(Collection<Location> centre) {
|
||||
regionCentres.addAll(centre);
|
||||
recalculateTree();
|
||||
}
|
||||
public void addRegionCentres(Collection<Location> centre) {
|
||||
regionCentres.addAll(centre);
|
||||
recalculateTree();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location apply(NPC npc) {
|
||||
Location closestCentre = null;
|
||||
double minDist = Double.MAX_VALUE;
|
||||
for (Location centre : regionCentres) {
|
||||
double d = centre.distanceSquared(npc.getStoredLocation());
|
||||
if (d < minDist) {
|
||||
minDist = d;
|
||||
closestCentre = centre;
|
||||
}
|
||||
}
|
||||
if (closestCentre != null) {
|
||||
// TODO: should find closest edge block that is valid
|
||||
return MinecraftBlockExaminer.findValidLocation(closestCentre, xrange, yrange);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Location apply(NPC npc) {
|
||||
Location closestCentre = null;
|
||||
double minDist = Double.MAX_VALUE;
|
||||
for (Location centre : regionCentres) {
|
||||
double d = centre.distanceSquared(npc.getStoredLocation());
|
||||
if (d < minDist) {
|
||||
minDist = d;
|
||||
closestCentre = centre;
|
||||
}
|
||||
}
|
||||
if (closestCentre != null) {
|
||||
// TODO: should find closest edge block that is valid
|
||||
return MinecraftBlockExaminer.findValidLocation(closestCentre, xrange, yrange);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WaypointEditor createEditor(final CommandSender sender, CommandContext args) {
|
||||
return new WaypointEditor() {
|
||||
boolean editingRegions = false;
|
||||
EntityMarkers<Location> markers = new EntityMarkers<Location>();
|
||||
@Override
|
||||
public WaypointEditor createEditor(final CommandSender sender, CommandContext args) {
|
||||
return new WaypointEditor() {
|
||||
boolean editingRegions = false;
|
||||
EntityMarkers<Location> markers = new EntityMarkers<Location>();
|
||||
|
||||
@Override
|
||||
public void begin() {
|
||||
Messaging.sendTr(sender, Messages.WANDER_WAYPOINTS_BEGIN);
|
||||
if (currentGoal != null) {
|
||||
currentGoal.pause();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void begin() {
|
||||
Messaging.sendTr(sender, Messages.WANDER_WAYPOINTS_BEGIN);
|
||||
if (currentGoal != null) {
|
||||
currentGoal.pause();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end() {
|
||||
Messaging.sendTr(sender, Messages.WANDER_WAYPOINTS_END);
|
||||
editingRegions = false;
|
||||
if (currentGoal != null) {
|
||||
currentGoal.unpause();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void end() {
|
||||
Messaging.sendTr(sender, Messages.WANDER_WAYPOINTS_END);
|
||||
editingRegions = false;
|
||||
if (currentGoal != null) {
|
||||
currentGoal.unpause();
|
||||
}
|
||||
}
|
||||
|
||||
private String formatLoc(Location location) {
|
||||
return String.format("[[%d]], [[%d]], [[%d]]", location.getBlockX(), location.getBlockY(),
|
||||
location.getBlockZ());
|
||||
}
|
||||
private String formatLoc(Location location) {
|
||||
return String.format("[[%d]], [[%d]], [[%d]]", location.getBlockX(), location.getBlockY(),
|
||||
location.getBlockZ());
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerChat(AsyncPlayerChatEvent event) {
|
||||
if (!event.getPlayer().equals(sender))
|
||||
return;
|
||||
String message = event.getMessage().toLowerCase();
|
||||
if (message.startsWith("xrange") || message.startsWith("yrange")) {
|
||||
event.setCancelled(true);
|
||||
int range = 0;
|
||||
try {
|
||||
range = Integer.parseInt(message.split(" ", 2)[1]);
|
||||
if (range <= 0) {
|
||||
range = 0;
|
||||
}
|
||||
if (message.startsWith("xrange")) {
|
||||
xrange = range;
|
||||
} else {
|
||||
yrange = range;
|
||||
}
|
||||
if (currentGoal != null) {
|
||||
currentGoal.setXYRange(xrange, yrange);
|
||||
}
|
||||
recalculateTree();
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Messaging.sendTr(sender, Messages.WANDER_WAYPOINTS_RANGE_SET, xrange, yrange);
|
||||
}
|
||||
});
|
||||
} else if (message.startsWith("regions")) {
|
||||
event.setCancelled(true);
|
||||
editingRegions = !editingRegions;
|
||||
if (editingRegions) {
|
||||
for (Location regionCentre : regionCentres) {
|
||||
Entity entity = markers.createMarker(regionCentre, regionCentre);
|
||||
entity.setMetadata("wandermarker",
|
||||
new FixedMetadataValue(CitizensAPI.getPlugin(), regionCentre));
|
||||
}
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Messaging.sendTr(sender, Messages.WANDER_WAYPOINTS_REGION_EDITING_START);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
markers.destroyMarkers();
|
||||
}
|
||||
} else if (message.startsWith("delay")) {
|
||||
event.setCancelled(true);
|
||||
try {
|
||||
delay = Integer.parseInt(message.split(" ")[1]);
|
||||
if (currentGoal != null) {
|
||||
currentGoal.setDelay(delay);
|
||||
}
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerChat(AsyncPlayerChatEvent event) {
|
||||
if (!event.getPlayer().equals(sender))
|
||||
return;
|
||||
String message = event.getMessage().toLowerCase();
|
||||
if (message.startsWith("xrange") || message.startsWith("yrange")) {
|
||||
event.setCancelled(true);
|
||||
int range = 0;
|
||||
try {
|
||||
range = Integer.parseInt(message.split(" ", 2)[1]);
|
||||
if (range <= 0) {
|
||||
range = 0;
|
||||
}
|
||||
if (message.startsWith("xrange")) {
|
||||
xrange = range;
|
||||
} else {
|
||||
yrange = range;
|
||||
}
|
||||
if (currentGoal != null) {
|
||||
currentGoal.setXYRange(xrange, yrange);
|
||||
}
|
||||
recalculateTree();
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Messaging.sendTr(sender, Messages.WANDER_WAYPOINTS_RANGE_SET, xrange, yrange);
|
||||
}
|
||||
});
|
||||
} else if (message.startsWith("regions")) {
|
||||
event.setCancelled(true);
|
||||
editingRegions = !editingRegions;
|
||||
if (editingRegions) {
|
||||
for (Location regionCentre : regionCentres) {
|
||||
Entity entity = markers.createMarker(regionCentre, regionCentre);
|
||||
entity.setMetadata("wandermarker",
|
||||
new FixedMetadataValue(CitizensAPI.getPlugin(), regionCentre));
|
||||
}
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Messaging.sendTr(sender, Messages.WANDER_WAYPOINTS_REGION_EDITING_START);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
markers.destroyMarkers();
|
||||
}
|
||||
} else if (message.startsWith("delay")) {
|
||||
event.setCancelled(true);
|
||||
try {
|
||||
delay = Integer.parseInt(message.split(" ")[1]);
|
||||
if (currentGoal != null) {
|
||||
currentGoal.setDelay(delay);
|
||||
}
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Messaging.sendTr(sender, Messages.WANDER_WAYPOINTS_DELAY_SET, delay);
|
||||
}
|
||||
});
|
||||
} catch (
|
||||
@Override
|
||||
public void run() {
|
||||
Messaging.sendTr(sender, Messages.WANDER_WAYPOINTS_DELAY_SET, delay);
|
||||
}
|
||||
});
|
||||
} catch (
|
||||
|
||||
Exception e) {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Messaging.sendErrorTr(sender, Messages.WANDER_WAYPOINTS_INVALID_DELAY);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Exception e) {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Messaging.sendErrorTr(sender, Messages.WANDER_WAYPOINTS_INVALID_DELAY);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
if (!event.getPlayer().equals(sender) || event.getAction() == Action.PHYSICAL || !npc.isSpawned()
|
||||
|| !editingRegions || event.getPlayer().getWorld() != npc.getEntity().getWorld()
|
||||
|| Util.isOffHand(event))
|
||||
return;
|
||||
if (event.getAction() == Action.LEFT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_AIR) {
|
||||
if (event.getClickedBlock() == null)
|
||||
return;
|
||||
event.setCancelled(true);
|
||||
Location at = event.getClickedBlock().getLocation().add(0, 1, 0);
|
||||
if (!regionCentres.contains(at)) {
|
||||
regionCentres.add(at);
|
||||
Entity entity = markers.createMarker(at, at);
|
||||
entity.setMetadata("wandermarker", new FixedMetadataValue(CitizensAPI.getPlugin(), at));
|
||||
Messaging.sendTr(sender, Messages.WANDER_WAYPOINTS_ADDED_REGION, formatLoc(at),
|
||||
regionCentres.size());
|
||||
recalculateTree();
|
||||
}
|
||||
}
|
||||
}
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
if (!event.getPlayer().equals(sender) || event.getAction() == Action.PHYSICAL || !npc.isSpawned()
|
||||
|| !editingRegions || event.getPlayer().getWorld() != npc.getEntity().getWorld()
|
||||
|| Util.isOffHand(event))
|
||||
return;
|
||||
if (event.getAction() == Action.LEFT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_AIR) {
|
||||
if (event.getClickedBlock() == null)
|
||||
return;
|
||||
event.setCancelled(true);
|
||||
Location at = event.getClickedBlock().getLocation().add(0, 1, 0);
|
||||
if (!regionCentres.contains(at)) {
|
||||
regionCentres.add(at);
|
||||
Entity entity = markers.createMarker(at, at);
|
||||
entity.setMetadata("wandermarker", new FixedMetadataValue(CitizensAPI.getPlugin(), at));
|
||||
Messaging.sendTr(sender, Messages.WANDER_WAYPOINTS_ADDED_REGION, formatLoc(at),
|
||||
regionCentres.size());
|
||||
recalculateTree();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
||||
if (!sender.equals(event.getPlayer()) || !editingRegions || Util.isOffHand(event))
|
||||
return;
|
||||
if (!event.getRightClicked().hasMetadata("wandermarker"))
|
||||
return;
|
||||
regionCentres.remove(event.getRightClicked().getMetadata("wandermarker").get(0).value());
|
||||
markers.removeMarker((Location) event.getRightClicked().getMetadata("wandermarker").get(0).value());
|
||||
Messaging.sendTr(sender, Messages.WANDER_WAYPOINTS_REMOVED_REGION,
|
||||
formatLoc((Location) event.getRightClicked().getMetadata("wandermarker").get(0).value()),
|
||||
regionCentres.size());
|
||||
recalculateTree();
|
||||
}
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
||||
if (!sender.equals(event.getPlayer()) || !editingRegions || Util.isOffHand(event))
|
||||
return;
|
||||
if (!event.getRightClicked().hasMetadata("wandermarker"))
|
||||
return;
|
||||
regionCentres.remove(event.getRightClicked().getMetadata("wandermarker").get(0).value());
|
||||
markers.removeMarker((Location) event.getRightClicked().getMetadata("wandermarker").get(0).value());
|
||||
Messaging.sendTr(sender, Messages.WANDER_WAYPOINTS_REMOVED_REGION,
|
||||
formatLoc((Location) event.getRightClicked().getMetadata("wandermarker").get(0).value()),
|
||||
regionCentres.size());
|
||||
recalculateTree();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhTreeSolid<Boolean> get() {
|
||||
return regionCentres.isEmpty() ? null : tree;
|
||||
}
|
||||
@Override
|
||||
public PhTreeSolid<Boolean> get() {
|
||||
return regionCentres.isEmpty() ? null : tree;
|
||||
}
|
||||
|
||||
public List<Location> getRegionCentres() {
|
||||
return new RecalculateList();
|
||||
}
|
||||
public List<Location> getRegionCentres() {
|
||||
return new RecalculateList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPaused() {
|
||||
return paused;
|
||||
}
|
||||
@Override
|
||||
public boolean isPaused() {
|
||||
return paused;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(DataKey key) {
|
||||
recalculateTree();
|
||||
}
|
||||
@Override
|
||||
public void load(DataKey key) {
|
||||
recalculateTree();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemove() {
|
||||
npc.getDefaultGoalController().removeGoal(currentGoal);
|
||||
}
|
||||
@Override
|
||||
public void onRemove() {
|
||||
npc.getDefaultGoalController().removeGoal(currentGoal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn(NPC npc) {
|
||||
this.npc = npc;
|
||||
if (currentGoal == null) {
|
||||
currentGoal = WanderGoal.createWithNPCAndRangeAndTreeAndFallback(npc, xrange, yrange,
|
||||
WanderWaypointProvider.this, WanderWaypointProvider.this);
|
||||
currentGoal.setDelay(delay);
|
||||
}
|
||||
npc.getDefaultGoalController().addGoal(currentGoal, 1);
|
||||
}
|
||||
@Override
|
||||
public void onSpawn(NPC npc) {
|
||||
this.npc = npc;
|
||||
if (currentGoal == null) {
|
||||
currentGoal = WanderGoal.createWithNPCAndRangeAndTreeAndFallback(npc, xrange, yrange,
|
||||
WanderWaypointProvider.this, WanderWaypointProvider.this);
|
||||
currentGoal.setDelay(delay);
|
||||
}
|
||||
npc.getDefaultGoalController().addGoal(currentGoal, 1);
|
||||
}
|
||||
|
||||
private void recalculateTree() {
|
||||
tree = PhTreeSolid.create(3);
|
||||
for (Location loc : regionCentres) {
|
||||
long[] lower = { loc.getBlockX() - xrange, loc.getBlockY() - yrange, loc.getBlockZ() - xrange };
|
||||
long[] upper = { loc.getBlockX() + xrange, loc.getBlockY() + yrange, loc.getBlockZ() + xrange };
|
||||
tree.put(lower, upper, true);
|
||||
}
|
||||
}
|
||||
private void recalculateTree() {
|
||||
tree = PhTreeSolid.create(3);
|
||||
for (Location loc : regionCentres) {
|
||||
long[] lower = { loc.getBlockX() - xrange, loc.getBlockY() - yrange, loc.getBlockZ() - xrange };
|
||||
long[] upper = { loc.getBlockX() + xrange, loc.getBlockY() + yrange, loc.getBlockZ() + xrange };
|
||||
tree.put(lower, upper, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeRegionCentre(Location centre) {
|
||||
regionCentres.remove(centre);
|
||||
recalculateTree();
|
||||
}
|
||||
public void removeRegionCentre(Location centre) {
|
||||
regionCentres.remove(centre);
|
||||
recalculateTree();
|
||||
}
|
||||
|
||||
public void removeRegionCentres(Collection<Location> centre) {
|
||||
regionCentres.removeAll(centre);
|
||||
recalculateTree();
|
||||
}
|
||||
public void removeRegionCentres(Collection<Location> centre) {
|
||||
regionCentres.removeAll(centre);
|
||||
recalculateTree();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(DataKey key) {
|
||||
}
|
||||
@Override
|
||||
public void save(DataKey key) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPaused(boolean paused) {
|
||||
this.paused = paused;
|
||||
}
|
||||
@Override
|
||||
public void setPaused(boolean paused) {
|
||||
this.paused = paused;
|
||||
}
|
||||
|
||||
private class RecalculateList extends ForwardingList<Location> {
|
||||
@Override
|
||||
public void add(int idx, Location loc) {
|
||||
super.add(idx, loc);
|
||||
recalculateTree();
|
||||
}
|
||||
private class RecalculateList extends ForwardingList<Location> {
|
||||
@Override
|
||||
public void add(int idx, Location loc) {
|
||||
super.add(idx, loc);
|
||||
recalculateTree();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(Location loc) {
|
||||
boolean val = super.add(loc);
|
||||
recalculateTree();
|
||||
return val;
|
||||
}
|
||||
@Override
|
||||
public boolean add(Location loc) {
|
||||
boolean val = super.add(loc);
|
||||
recalculateTree();
|
||||
return val;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Location> delegate() {
|
||||
return regionCentres;
|
||||
}
|
||||
@Override
|
||||
protected List<Location> delegate() {
|
||||
return regionCentres;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location remove(int idx) {
|
||||
Location val = super.remove(idx);
|
||||
recalculateTree();
|
||||
return val;
|
||||
}
|
||||
@Override
|
||||
public Location remove(int idx) {
|
||||
Location val = super.remove(idx);
|
||||
recalculateTree();
|
||||
return val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location set(int idx, Location idx2) {
|
||||
Location val = super.set(idx, idx2);
|
||||
recalculateTree();
|
||||
return val;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Location set(int idx, Location idx2) {
|
||||
Location val = super.set(idx, idx2);
|
||||
recalculateTree();
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
private static final int DEFAULT_XRANGE = 3;
|
||||
private static final int DEFAULT_YRANGE = 25;
|
||||
private static final int DEFAULT_XRANGE = 3;
|
||||
private static final int DEFAULT_YRANGE = 25;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ import net.minecraft.server.v1_15_R1.BlockPosition;
|
|||
import net.minecraft.server.v1_15_R1.DamageSource;
|
||||
import net.minecraft.server.v1_15_R1.DataWatcherObject;
|
||||
import net.minecraft.server.v1_15_R1.EntityHorse;
|
||||
import net.minecraft.server.v1_15_R1.EntityHorseAbstract;
|
||||
import net.minecraft.server.v1_15_R1.EntityTypes;
|
||||
import net.minecraft.server.v1_15_R1.GenericAttributes;
|
||||
import net.minecraft.server.v1_15_R1.IBlockData;
|
||||
|
@ -94,6 +93,13 @@ public class HorseController extends MobEntityController {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkDespawn() {
|
||||
if (npc == null) {
|
||||
super.checkDespawn();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cj() {
|
||||
if (npc != null && riding) {
|
||||
|
@ -102,13 +108,6 @@ public class HorseController extends MobEntityController {
|
|||
return super.cj();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkDespawn() {
|
||||
if (npc == null) {
|
||||
super.checkDespawn();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collide(net.minecraft.server.v1_15_R1.Entity entity) {
|
||||
// this method is called by both the entities involved - cancelling
|
||||
|
@ -146,28 +145,6 @@ public class HorseController extends MobEntityController {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void h(double x, double y, double z) {
|
||||
if (npc == null) {
|
||||
super.h(x, y, z);
|
||||
return;
|
||||
}
|
||||
if (NPCPushEvent.getHandlerList().getRegisteredListeners().length == 0) {
|
||||
if (!npc.data().get(NPC.DEFAULT_PROTECTED_METADATA, true))
|
||||
super.h(x, y, z);
|
||||
return;
|
||||
}
|
||||
Vector vector = new Vector(x, y, z);
|
||||
NPCPushEvent event = Util.callPushEvent(npc, vector);
|
||||
if (!event.isCancelled()) {
|
||||
vector = event.getCollisionVector();
|
||||
super.h(vector.getX(), vector.getY(), vector.getZ());
|
||||
}
|
||||
// when another entity collides, this method is called to push the
|
||||
// NPC so we prevent it from doing anything if the event is
|
||||
// cancelled.
|
||||
}
|
||||
|
||||
@Override
|
||||
public CraftEntity getBukkitEntity() {
|
||||
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
|
||||
|
@ -196,6 +173,28 @@ public class HorseController extends MobEntityController {
|
|||
return NMSImpl.getSoundEffect(npc, super.getSoundHurt(damagesource), NPC.HURT_SOUND_METADATA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void h(double x, double y, double z) {
|
||||
if (npc == null) {
|
||||
super.h(x, y, z);
|
||||
return;
|
||||
}
|
||||
if (NPCPushEvent.getHandlerList().getRegisteredListeners().length == 0) {
|
||||
if (!npc.data().get(NPC.DEFAULT_PROTECTED_METADATA, true))
|
||||
super.h(x, y, z);
|
||||
return;
|
||||
}
|
||||
Vector vector = new Vector(x, y, z);
|
||||
NPCPushEvent event = Util.callPushEvent(npc, vector);
|
||||
if (!event.isCancelled()) {
|
||||
vector = event.getCollisionVector();
|
||||
super.h(vector.getX(), vector.getY(), vector.getZ());
|
||||
}
|
||||
// when another entity collides, this method is called to push the
|
||||
// NPC so we prevent it from doing anything if the event is
|
||||
// cancelled.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClimbing() {
|
||||
if (npc == null || !npc.isFlyable()) {
|
||||
|
@ -232,7 +231,7 @@ public class HorseController extends MobEntityController {
|
|||
if (riding) {
|
||||
d(4, true); // datawatcher method
|
||||
}
|
||||
NMS.setStepHeight(getBukkitEntity(), 1);
|
||||
NMS.setStepHeight(getBukkitEntity(), 2);
|
||||
npc.update();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -872,12 +872,12 @@ public class NMSImpl implements NMSBridge {
|
|||
@Override
|
||||
public void openHorseScreen(Tameable horse, Player equipper) {
|
||||
EntityLiving handle = NMSImpl.getHandle((LivingEntity) horse);
|
||||
EntityLiving equipperHandle = NMSImpl.getHandle(equipper);
|
||||
EntityHuman equipperHandle = (EntityHuman) NMSImpl.getHandle(equipper);
|
||||
if (handle == null || equipperHandle == null)
|
||||
return;
|
||||
boolean wasTamed = horse.isTamed();
|
||||
horse.setTamed(true);
|
||||
((EntityHorseAbstract) handle).c(equipperHandle);
|
||||
((EntityHorseAbstract) handle).e(equipperHandle);
|
||||
horse.setTamed(wasTamed);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user