Explicitly stop metrics, fix stair/slab climbing

This commit is contained in:
fullwall 2012-10-30 21:11:06 +08:00
parent ce0e248867
commit 1f1f2442d4
6 changed files with 139 additions and 36 deletions

View File

@ -64,6 +64,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
private boolean compatible;
private Settings config;
private ClassLoader contextClassLoader;
private Metrics metrics;
private CitizensNPCRegistry npcRegistry;
private NPCDataStore saves;
private NPCSelector selector;
@ -183,6 +184,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
Bukkit.getPluginManager().callEvent(new CitizensDisableEvent());
Editor.leaveAll();
CitizensAPI.shutdown();
metrics.stopTask();
tearDownScripting();
// Don't bother with this part if MC versions are not compatible
@ -340,28 +342,23 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
}
private void startMetrics() {
new Thread() {
@Override
public void run() {
try {
Metrics metrics = new Metrics(Citizens.this);
if (metrics.isOptOut())
return;
metrics.addCustomData(new Metrics.Plotter("Total NPCs") {
@Override
public int getValue() {
return Iterables.size(npcRegistry);
}
});
traitFactory.addPlotters(metrics.createGraph("traits"));
metrics.start();
Messaging.logTr(Messages.METRICS_NOTIFICATION);
} catch (IOException e) {
Messaging.logTr(Messages.METRICS_ERROR_NOTIFICATION, e.getMessage());
try {
metrics = new Metrics(Citizens.this);
if (metrics.isOptOut())
return;
metrics.addCustomData(new Metrics.Plotter("Total NPCs") {
@Override
public int getValue() {
return Iterables.size(npcRegistry);
}
}
}.start();
});
traitFactory.addPlotters(metrics.createGraph("traits"));
metrics.start();
Messaging.logTr(Messages.METRICS_NOTIFICATION);
} catch (IOException e) {
Messaging.logTr(Messages.METRICS_ERROR_NOTIFICATION, e.getMessage());
}
}
public void storeNPCs() {

View File

@ -459,6 +459,15 @@ public class Metrics {
}
}
public void stopTask() {
synchronized (optOutLock) {
if (taskId > 0) {
this.plugin.getServer().getScheduler().cancelTask(taskId);
taskId = -1;
}
}
}
/**
* Represents a custom graph on the website
*/

View File

@ -89,6 +89,17 @@ public abstract class CitizensNPC extends AbstractNPC {
}
public void load(final DataKey root) {
// Spawn the NPC
Spawned spawned = getTrait(Spawned.class);
CurrentLocation spawnLocation = getTrait(CurrentLocation.class);
try {
spawned.load(root.getRelative("spawned"));
spawnLocation.load(root.getRelative("location"));
if (spawned.shouldSpawn() && spawnLocation.getLocation() != null)
spawn(spawnLocation.getLocation());
} catch (NPCLoadException e) {
}
metadata.loadFrom(root.getRelative("metadata"));
// Load traits
@ -123,13 +134,6 @@ public abstract class CitizensNPC extends AbstractNPC {
}
}
// Spawn the NPC
if (getTrait(Spawned.class).shouldSpawn()) {
Location spawnLoc = getTrait(CurrentLocation.class).getLocation();
if (spawnLoc != null)
spawn(spawnLoc);
}
navigator.load(root.getRelative("navigator"));
}

View File

@ -42,6 +42,16 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
initialise(minecraftServer);
}
@Override
public void bf() {
super.bf();
}
@Override
public float by() {
return super.by() * npc.getNavigator().getDefaultParameters().speed();
}
@Override
public void collide(net.minecraft.server.Entity entity) {
// this method is called by both the entities involved - cancelling
@ -141,8 +151,8 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
motY += 0.04;
} else //(handled elsewhere)*/
if (onGround && bW == 0) {
// bf(); // jump commented out as 0.47 works better for stairs
motY = 0.47F;
// bf(); // jump commented to provide block-specific handling
NMS.blockSpecificJump(this);
bW = 10;
}
} else
@ -159,11 +169,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
NMS.setHeadYaw(this, yaw);
}
@Override
public float by() {
return super.by() * npc.getNavigator().getDefaultParameters().speed();
}
public static class PlayerNPC extends CraftPlayer implements NPCHolder {
private final CitizensNPC npc;

View File

@ -4,9 +4,11 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.entity.EntityHumanNPC;
import net.minecraft.server.ControllerLook;
import net.minecraft.server.DamageSource;
import net.minecraft.server.EnchantmentManager;
@ -22,12 +24,18 @@ import net.minecraft.server.PathfinderGoalSelector;
import net.minecraft.server.World;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.material.Stairs;
import org.bukkit.material.Step;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.primitives.Ints;
@SuppressWarnings("unchecked")
public class NMS {
@ -45,7 +53,11 @@ public class NMS {
private static Field NAVIGATION_WORLD_FIELD;
private static Field PATHFINDING_RANGE;
private static Field PERSISTENT_FIELD;
private static Set<Integer> SLAB_MATERIALS = Sets.newHashSet();
private static Field SPEED_FIELD;
private static Set<Integer> STAIR_MATERIALS = Sets.newHashSet();
private static Field THREAD_STOPPER;
public static void addOrRemoveFromPlayerList(LivingEntity bukkitEntity, boolean remove) {
@ -97,6 +109,28 @@ public class NMS {
target.setOnFire(fireAspectLevel * 4);
}
public static void blockSpecificJump(EntityHumanNPC entity) {
int x = MathHelper.floor(entity.locX), y = MathHelper.floor(entity.boundingBox.b - 1), z = MathHelper
.floor(entity.locZ);
int below = entity.world.getTypeId(x, y, z);
BlockFace dir = Util.getFacingDirection(entity.yaw);
int[] typeIds = { below };
if (dir != BlockFace.SELF) {
typeIds = Ints.concat(
typeIds,
new int[] {
entity.world.getTypeId(x + dir.getModX(), y + dir.getModY(), z + dir.getModZ()),
entity.world.getTypeId(x + dir.getModX(), y + dir.getModY() + 1,
z + dir.getModZ()) });
}
if (containsAny(STAIR_MATERIALS, typeIds)) {
entity.motY = 0.47F;
} else if (containsAny(SLAB_MATERIALS, typeIds)) {
entity.motY = 0.52F;
} else
entity.motY = 0.5F;
}
public static void clearGoals(PathfinderGoalSelector... goalSelectors) {
if (GOAL_FIELD == null || goalSelectors == null)
return;
@ -110,6 +144,13 @@ public class NMS {
}
}
private static boolean containsAny(Set<Integer> set, int[] tests) {
for (int test : tests)
if (set.contains(test))
return true;
return false;
}
private static Constructor<? extends Entity> getCustomEntityConstructor(Class<? extends Entity> clazz,
EntityType type) throws SecurityException, NoSuchMethodException {
Constructor<? extends Entity> constructor = ENTITY_CONSTRUCTOR_CACHE.get(clazz);
@ -270,7 +311,6 @@ public class NMS {
Messaging.logTr(Messages.ERROR_UPDATING_PATHFINDING_RANGE, e.getMessage());
}
}
static {
// true field above false and three synchronised lists
THREAD_STOPPER = getField(NetworkManager.class, "m");
@ -304,4 +344,13 @@ public class NMS {
Messaging.logTr(Messages.ERROR_GETTING_ID_MAPPING, e.getMessage());
}
}
static {
for (Material material : Material.values()) {
if (Step.class.isAssignableFrom(material.getData()))
SLAB_MATERIALS.add(material.getId());
else if (Stairs.class.isAssignableFrom(material.getData()))
STAIR_MATERIALS.add(material.getId());
}
}
}

View File

@ -12,6 +12,7 @@ import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.entity.Entity;
@ -65,6 +66,44 @@ public class Util {
NMS.look(handle, (float) yaw - 90, (float) pitch);
}
public static BlockFace getFacingDirection(float degrees) {
return getFacingDirection(degrees, 10);
}
public static BlockFace getFacingDirection(float degrees, double leeway) {
while (degrees < 0D) {
degrees += 360D;
}
while (degrees > 360D) {
degrees -= 360D;
}
if (isFacingNorth(degrees, leeway))
return BlockFace.WEST;
if (isFacingEast(degrees, leeway))
return BlockFace.NORTH;
if (isFacingSouth(degrees, leeway))
return BlockFace.EAST;
if (isFacingWest(degrees, leeway))
return BlockFace.SOUTH;
return BlockFace.SELF;
}
private static boolean isFacingEast(double degrees, double leeway) {
return (45 - leeway <= degrees) && (degrees < 135 + leeway);
}
private static boolean isFacingNorth(double degrees, double leeway) {
return ((0 <= degrees) && (degrees < 45 + leeway)) || ((315 - leeway <= degrees) && (degrees <= 360));
}
private static boolean isFacingSouth(double degrees, double leeway) {
return (135 - leeway <= degrees) && (degrees < 225 + leeway);
}
private static boolean isFacingWest(double degrees, double leeway) {
return (225 - leeway <= degrees) && (degrees < 315 + leeway);
}
public static boolean isSettingFulfilled(Player player, Setting setting) {
String parts = setting.asString();
if (parts.contains("*"))