Workaround for horse pathfinding in minecraft - assume that it fits on a single block

This commit is contained in:
fullwall 2016-07-03 01:10:34 +08:00
parent 9972c71c99
commit 6b3a453927
4 changed files with 45 additions and 25 deletions

View File

@ -26,6 +26,7 @@ import net.citizensnpcs.api.command.CommandManager.CommandInfo;
import net.citizensnpcs.api.command.Injector;
import net.citizensnpcs.api.event.CitizensDisableEvent;
import net.citizensnpcs.api.event.CitizensEnableEvent;
import net.citizensnpcs.api.event.CitizensPreReloadEvent;
import net.citizensnpcs.api.event.CitizensReloadEvent;
import net.citizensnpcs.api.event.DespawnReason;
import net.citizensnpcs.api.exception.NPCLoadException;
@ -344,6 +345,8 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
despawnNPCs();
ProfileFetcher.reset();
Skin.clearCache();
getServer().getPluginManager().callEvent(new CitizensPreReloadEvent());
saves = createStorage(getDataFolder());
saves.loadInto(npcRegistry);

View File

@ -59,7 +59,7 @@ import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.ai.event.NavigationBeginEvent;
import net.citizensnpcs.api.ai.event.NavigationCompleteEvent;
import net.citizensnpcs.api.event.CitizensDeserialiseMetaEvent;
import net.citizensnpcs.api.event.CitizensReloadEvent;
import net.citizensnpcs.api.event.CitizensPreReloadEvent;
import net.citizensnpcs.api.event.CitizensSerialiseMetaEvent;
import net.citizensnpcs.api.event.CommandSenderCreateNPCEvent;
import net.citizensnpcs.api.event.DespawnReason;
@ -164,7 +164,7 @@ public class EventListen implements Listener {
}
@EventHandler(priority = EventPriority.MONITOR)
public void onCitizensReload(CitizensReloadEvent event) {
public void onCitizensReload(CitizensPreReloadEvent event) {
skinUpdateTracker.reset();
toRespawn.clear();
}
@ -306,29 +306,29 @@ public class EventListen implements Listener {
@EventHandler
public void onMetaSerialise(CitizensSerialiseMetaEvent event) {
if (event.getMeta() instanceof SkullMeta) {
SkullMeta meta = (SkullMeta) event.getMeta();
GameProfile profile = NMS.getProfile(meta);
if (profile == null)
return;
if (profile.getName() != null) {
event.getKey().setString("skull.owner", profile.getName());
}
if (profile.getId() != null) {
event.getKey().setString("skull.uuid", profile.getId().toString());
}
if (profile.getProperties() != null) {
for (Entry<String, Collection<Property>> entry : profile.getProperties().asMap().entrySet()) {
DataKey relative = event.getKey().getRelative("skull.properties." + entry.getKey());
int i = 0;
for (Property value : entry.getValue()) {
relative.getRelative(i).setString("name", value.getName());
if (value.getSignature() != null) {
relative.getRelative(i).setString("signature", value.getSignature());
}
relative.getRelative(i).setString("value", value.getValue());
i++;
if (!(event.getMeta() instanceof SkullMeta))
return;
SkullMeta meta = (SkullMeta) event.getMeta();
GameProfile profile = NMS.getProfile(meta);
if (profile == null)
return;
if (profile.getName() != null) {
event.getKey().setString("skull.owner", profile.getName());
}
if (profile.getId() != null) {
event.getKey().setString("skull.uuid", profile.getId().toString());
}
if (profile.getProperties() != null) {
for (Entry<String, Collection<Property>> entry : profile.getProperties().asMap().entrySet()) {
DataKey relative = event.getKey().getRelative("skull.properties." + entry.getKey());
int i = 0;
for (Property value : entry.getValue()) {
relative.getRelative(i).setString("name", value.getName());
if (value.getSignature() != null) {
relative.getRelative(i).setString("signature", value.getSignature());
}
relative.getRelative(i).setString("value", value.getValue());
i++;
}
}
}
@ -349,6 +349,7 @@ public class EventListen implements Listener {
ChunkCoord coord = toCoord(event.getSpawnLocation());
if (toRespawn.containsEntry(coord, event.getNPC()))
return;
Messaging.debug("Stored", event.getNPC().getId(), "for respawn from NPCNeedsRespawnEvent");
toRespawn.put(coord, event.getNPC());
}
@ -516,6 +517,7 @@ public class EventListen implements Listener {
respawnAllFromCoord(coord);
}
}
event.setCancelled(true);
return;
}
if (npc.isSpawned()) {

View File

@ -79,7 +79,8 @@ public class CitizensNPC extends AbstractNPC {
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
getEntity().getLocation().getChunk();
Messaging.debug("Couldn't despawn", getId(), "due to despawn event cancellation. Force loaded chunk.");
Messaging.debug("Couldn't despawn", getId(), "due to despawn event cancellation. Force loaded chunk.",
getEntity().isValid());
return false;
}
boolean keepSelected = getTrait(Spawned.class).shouldSpawn();
@ -93,6 +94,7 @@ public class CitizensNPC extends AbstractNPC {
for (Trait trait : new ArrayList<Trait>(traits.values())) {
trait.onDespawn();
}
Messaging.debug("Despawned", getId(), "DespawnReason.", reason);
entityController.remove();
return true;
@ -140,6 +142,9 @@ public class CitizensNPC extends AbstractNPC {
if (getTrait(Spawned.class).shouldSpawn() && spawnLocation.getLocation() != null) {
spawn(spawnLocation.getLocation());
}
if (getTrait(Spawned.class).shouldSpawn() && spawnLocation.getLocation() == null) {
Messaging.debug("Tried to spawn", getId(), "on load but world was null");
}
navigator.load(root.getRelative("navigator"));
}
@ -261,6 +266,7 @@ public class CitizensNPC extends AbstractNPC {
NMS.replaceTrackerEntry(player);
}
}
Messaging.debug("Spawned", getId(), at, mcEntity.valid);
return true;
}

View File

@ -7,7 +7,9 @@ import net.citizensnpcs.api.ai.NavigatorParameters;
import net.citizensnpcs.api.ai.TargetType;
import net.citizensnpcs.api.ai.event.CancelReason;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.util.NMS;
import net.minecraft.server.v1_10_R1.EntityHorse;
import net.minecraft.server.v1_10_R1.EntityLiving;
import net.minecraft.server.v1_10_R1.NavigationAbstract;
@ -29,7 +31,13 @@ public class MCNavigationStrategy extends AbstractPathStrategy {
// navigation won't execute, and calling entity.move doesn't
// entirely fix the problem.
navigation = NMS.getNavigation(handle);
float oldWidth = handle.width;
if (handle instanceof EntityHorse) {
handle.width = Math.min(0.99f, oldWidth);
}
navigation.a(dest.getX(), dest.getY(), dest.getZ(), parameters.speed());
handle.width = oldWidth; // minecraft requires that an entity fit onto both blocks if width >= 1f, but we'd
// prefer to make it just fit on 1 so hack around it a bit.
if (NMS.isNavigationFinished(navigation)) {
setCancelReason(CancelReason.STUCK);
}
@ -64,6 +72,7 @@ public class MCNavigationStrategy extends AbstractPathStrategy {
if (getCancelReason() != null)
return true;
if (parameters.speed() != lastSpeed) {
Messaging.debug("Repathfinding " + ((NPCHolder) handle).getNPC().getId() + " due to speed change");
navigation.a(target.getX(), target.getY(), target.getZ(), parameters.speed());
lastSpeed = parameters.speed();
}