New features requested by mcmonkey

This commit is contained in:
fullwall 2016-03-30 01:57:14 +08:00
parent ec87419554
commit 145a362264
11 changed files with 110 additions and 24 deletions

View File

@ -227,6 +227,11 @@ public class EventListen implements Listener {
if (npc == null) { if (npc == null) {
return; return;
} }
if (!npc.data().get(NPC.DROPS_ITEMS_METADATA, false)) {
event.getDrops().clear();
}
final Location location = npc.getEntity().getLocation(); final Location location = npc.getEntity().getLocation();
Bukkit.getPluginManager().callEvent(new NPCDeathEvent(npc, event)); Bukkit.getPluginManager().callEvent(new NPCDeathEvent(npc, event));
npc.despawn(DespawnReason.DEATH); npc.despawn(DespawnReason.DEATH);

View File

@ -116,7 +116,8 @@ public class Settings {
TALK_CLOSE_MINIMUM_COOLDOWN("npc.text.min-talk-cooldown", 10), TALK_CLOSE_MINIMUM_COOLDOWN("npc.text.min-talk-cooldown", 10),
TALK_ITEM("npc.text.talk-item", "340"), TALK_ITEM("npc.text.talk-item", "340"),
USE_BOAT_CONTROLS("npc.controllable.use-boat-controls", true), USE_BOAT_CONTROLS("npc.controllable.use-boat-controls", true),
USE_NEW_PATHFINDER("npc.pathfinding.use-new-finder", false); USE_NEW_PATHFINDER("npc.pathfinding.use-new-finder", false),
USE_SCOREBOARD_TEAMS("npc.player-scoreboard-teams.enable", true);
protected String path; protected String path;
protected Object value; protected Object value;

View File

@ -53,6 +53,7 @@ import net.citizensnpcs.api.event.PlayerCreateNPCEvent;
import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.npc.NPCRegistry; import net.citizensnpcs.api.npc.NPCRegistry;
import net.citizensnpcs.api.trait.Trait; import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.trait.Inventory;
import net.citizensnpcs.api.trait.trait.MobType; import net.citizensnpcs.api.trait.trait.MobType;
import net.citizensnpcs.api.trait.trait.Owner; import net.citizensnpcs.api.trait.trait.Owner;
import net.citizensnpcs.api.trait.trait.Spawned; import net.citizensnpcs.api.trait.trait.Spawned;
@ -675,6 +676,18 @@ public class NPCCommands {
Messaging.send(sender, npc.getId()); Messaging.send(sender, npc.getId());
} }
@Command(
aliases = { "npc" },
usage = "inventory",
desc = "Toggles gravity",
modifiers = { "gravity" },
min = 1,
max = 1,
permission = "citizens.npc.inventory")
public void inventory(CommandContext args, CommandSender sender, NPC npc) {
((Player) sender).openInventory(npc.getTrait(Inventory.class).getInventoryView());
}
@Command( @Command(
aliases = { "npc" }, aliases = { "npc" },
usage = "item [item] (data)", usage = "item [item] (data)",

View File

@ -61,7 +61,7 @@ public class GenericEquipper implements Equipper {
break; break;
case AIR: case AIR:
if (equipper.isSneaking()) { if (equipper.isSneaking()) {
for (int i = 0; i < 5; i++) { for (int i = 0; i < 6; i++) {
if (trait.get(i) != null && trait.get(i).getType() != Material.AIR) { if (trait.get(i) != null && trait.get(i).getType() != Material.AIR) {
equipper.getWorld().dropItemNaturally(toEquip.getEntity().getLocation(), trait.get(i)); equipper.getWorld().dropItemNaturally(toEquip.getEntity().getLocation(), trait.get(i));
trait.set(i, null); trait.set(i, null);

View File

@ -30,6 +30,7 @@ import net.citizensnpcs.trait.CurrentLocation;
import net.citizensnpcs.trait.Gravity; import net.citizensnpcs.trait.Gravity;
import net.citizensnpcs.trait.HorseModifiers; import net.citizensnpcs.trait.HorseModifiers;
import net.citizensnpcs.trait.LookClose; import net.citizensnpcs.trait.LookClose;
import net.citizensnpcs.trait.MountTrait;
import net.citizensnpcs.trait.NPCSkeletonType; import net.citizensnpcs.trait.NPCSkeletonType;
import net.citizensnpcs.trait.OcelotModifiers; import net.citizensnpcs.trait.OcelotModifiers;
import net.citizensnpcs.trait.Poses; import net.citizensnpcs.trait.Poses;
@ -72,6 +73,7 @@ public class CitizensTraitFactory implements TraitFactory {
registerTrait(TraitInfo.create(ScriptTrait.class)); registerTrait(TraitInfo.create(ScriptTrait.class));
registerTrait(TraitInfo.create(SheepTrait.class)); registerTrait(TraitInfo.create(SheepTrait.class));
registerTrait(TraitInfo.create(SkinLayers.class)); registerTrait(TraitInfo.create(SkinLayers.class));
registerTrait(TraitInfo.create(MountTrait.class));
registerTrait(TraitInfo.create(NPCSkeletonType.class)); registerTrait(TraitInfo.create(NPCSkeletonType.class));
registerTrait(TraitInfo.create(SlimeSize.class)); registerTrait(TraitInfo.create(SlimeSize.class));
registerTrait(TraitInfo.create(Spawned.class)); registerTrait(TraitInfo.create(Spawned.class));

View File

@ -98,22 +98,25 @@ public class HumanController extends AbstractEntityController {
Setting.REMOVE_PLAYERS_FROM_PLAYER_LIST.asBoolean()); Setting.REMOVE_PLAYERS_FROM_PLAYER_LIST.asBoolean());
NMS.addOrRemoveFromPlayerList(getBukkitEntity(), NMS.addOrRemoveFromPlayerList(getBukkitEntity(),
npc.data().get("removefromplayerlist", removeFromPlayerList)); npc.data().get("removefromplayerlist", removeFromPlayerList));
Scoreboard scoreboard = Bukkit.getScoreboardManager().getMainScoreboard();
String teamName = UUID.randomUUID().toString().substring(0, 16);
Team team = scoreboard.getTeam(teamName); if (Setting.USE_SCOREBOARD_TEAMS.asBoolean()) {
if (team == null) { Scoreboard scoreboard = Bukkit.getScoreboardManager().getMainScoreboard();
team = scoreboard.registerNewTeam(teamName); String teamName = UUID.randomUUID().toString().substring(0, 16);
if (prefixCapture != null) {
team.setPrefix(prefixCapture); Team team = scoreboard.getTeam(teamName);
} if (team == null) {
if (suffixCapture != null) { team = scoreboard.registerNewTeam(teamName);
team.setSuffix(suffixCapture); if (prefixCapture != null) {
team.setPrefix(prefixCapture);
}
if (suffixCapture != null) {
team.setSuffix(suffixCapture);
}
} }
team.addPlayer(handle.getBukkitEntity());
handle.getNPC().data().set(NPC.SCOREBOARD_FAKE_TEAM_NAME_METADATA, teamName);
} }
team.addPlayer(handle.getBukkitEntity());
handle.getNPC().data().set(NPC.SCOREBOARD_FAKE_TEAM_NAME_METADATA, teamName);
} }
}, 20); }, 20);

View File

@ -0,0 +1,37 @@
package net.citizensnpcs.trait;
import java.util.UUID;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitName;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
@TraitName("mounttrait")
public class MountTrait extends Trait {
@Persist("mountedon")
private UUID mountedOn;
public MountTrait() {
super("mounttrait");
}
@Override
public void run() {
if (!npc.isSpawned())
return;
if (mountedOn != null) {
NPC other = CitizensAPI.getNPCRegistry().getByUniqueId(mountedOn);
if (other != null && other.isSpawned()) {
NMS.mount(other.getEntity(), npc.getEntity());
}
}
if (NMS.getVehicle(npc.getEntity()) instanceof NPCHolder) {
mountedOn = ((NPCHolder) NMS.getVehicle(npc.getEntity())).getNPC().getUniqueId();
}
}
}

View File

@ -40,10 +40,11 @@ import net.citizensnpcs.api.util.prtree.DistanceResult;
import net.citizensnpcs.api.util.prtree.PRTree; import net.citizensnpcs.api.util.prtree.PRTree;
import net.citizensnpcs.api.util.prtree.Region3D; import net.citizensnpcs.api.util.prtree.Region3D;
import net.citizensnpcs.api.util.prtree.SimplePointND; import net.citizensnpcs.api.util.prtree.SimplePointND;
import net.citizensnpcs.trait.waypoint.WaypointProvider.EnumerableWaypointProvider;
import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.Messages;
import net.citizensnpcs.util.Util; import net.citizensnpcs.util.Util;
public class GuidedWaypointProvider implements WaypointProvider { public class GuidedWaypointProvider implements EnumerableWaypointProvider {
private final List<Waypoint> available = Lists.newArrayList(); private final List<Waypoint> available = Lists.newArrayList();
private GuidedAIGoal currentGoal; private GuidedAIGoal currentGoal;
private final List<Waypoint> helpers = Lists.newArrayList(); private final List<Waypoint> helpers = Lists.newArrayList();
@ -234,6 +235,11 @@ public class GuidedWaypointProvider implements WaypointProvider {
this.paused = paused; this.paused = paused;
} }
@Override
public Iterable<Waypoint> waypoints() {
return Iterables.concat(available, helpers);
}
private class GuidedAIGoal implements Goal { private class GuidedAIGoal implements Goal {
private GuidedPlan plan; private GuidedPlan plan;

View File

@ -36,11 +36,12 @@ import net.citizensnpcs.api.persistence.PersistenceLoader;
import net.citizensnpcs.api.util.DataKey; import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.api.util.Messaging; import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.editor.Editor; import net.citizensnpcs.editor.Editor;
import net.citizensnpcs.trait.waypoint.WaypointProvider.EnumerableWaypointProvider;
import net.citizensnpcs.trait.waypoint.triggers.TriggerEditPrompt; import net.citizensnpcs.trait.waypoint.triggers.TriggerEditPrompt;
import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.Messages;
import net.citizensnpcs.util.Util; import net.citizensnpcs.util.Util;
public class LinearWaypointProvider implements WaypointProvider { public class LinearWaypointProvider implements EnumerableWaypointProvider {
private LinearWaypointGoal currentGoal; private LinearWaypointGoal currentGoal;
private NPC npc; private NPC npc;
private final List<Waypoint> waypoints = Lists.newArrayList(); private final List<Waypoint> waypoints = Lists.newArrayList();
@ -84,6 +85,13 @@ public class LinearWaypointProvider implements WaypointProvider {
return new LinearWaypointEditor((Player) sender); return new LinearWaypointEditor((Player) sender);
} }
public Waypoint getCurrentWaypoint() {
if (currentGoal != null && currentGoal.currentDestination != null) {
return currentGoal.currentDestination;
}
return null;
}
@Override @Override
public boolean isPaused() { public boolean isPaused() {
return currentGoal.isPaused(); return currentGoal.isPaused();
@ -127,6 +135,11 @@ public class LinearWaypointProvider implements WaypointProvider {
currentGoal.setPaused(paused); currentGoal.setPaused(paused);
} }
@Override
public Iterable<Waypoint> waypoints() {
return waypoints;
}
private final class LinearWaypointEditor extends WaypointEditor { private final class LinearWaypointEditor extends WaypointEditor {
Conversation conversation; Conversation conversation;
boolean editing = true; boolean editing = true;

View File

@ -1,11 +1,11 @@
package net.citizensnpcs.trait.waypoint; package net.citizensnpcs.trait.waypoint;
import org.bukkit.command.CommandSender;
import net.citizensnpcs.api.command.CommandContext; import net.citizensnpcs.api.command.CommandContext;
import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.persistence.Persistable; import net.citizensnpcs.api.persistence.Persistable;
import org.bukkit.command.CommandSender;
public interface WaypointProvider extends Persistable { public interface WaypointProvider extends Persistable {
/** /**
* Creates an {@link WaypointEditor} with the given {@link CommandSender}. * Creates an {@link WaypointEditor} with the given {@link CommandSender}.
@ -44,4 +44,8 @@ public interface WaypointProvider extends Persistable {
* Whether to pause waypoint execution. * Whether to pause waypoint execution.
*/ */
public void setPaused(boolean paused); public void setPaused(boolean paused);
public static interface EnumerableWaypointProvider extends WaypointProvider {
public Iterable<Waypoint> waypoints();
}
} }

View File

@ -18,7 +18,6 @@ import javax.annotation.Nullable;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
@ -36,7 +35,6 @@ import org.bukkit.entity.Tameable;
import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.plugin.PluginLoadOrder; import org.bukkit.plugin.PluginLoadOrder;
import org.bukkit.scoreboard.Team;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
@ -78,7 +76,6 @@ import net.minecraft.server.v1_9_R1.EntityTameableAnimal;
import net.minecraft.server.v1_9_R1.EntityTracker; import net.minecraft.server.v1_9_R1.EntityTracker;
import net.minecraft.server.v1_9_R1.EntityTrackerEntry; import net.minecraft.server.v1_9_R1.EntityTrackerEntry;
import net.minecraft.server.v1_9_R1.EntityTypes; import net.minecraft.server.v1_9_R1.EntityTypes;
import net.minecraft.server.v1_9_R1.EnumChatFormat;
import net.minecraft.server.v1_9_R1.GenericAttributes; import net.minecraft.server.v1_9_R1.GenericAttributes;
import net.minecraft.server.v1_9_R1.MathHelper; import net.minecraft.server.v1_9_R1.MathHelper;
import net.minecraft.server.v1_9_R1.MobEffects; import net.minecraft.server.v1_9_R1.MobEffects;
@ -87,7 +84,6 @@ import net.minecraft.server.v1_9_R1.NetworkManager;
import net.minecraft.server.v1_9_R1.Packet; import net.minecraft.server.v1_9_R1.Packet;
import net.minecraft.server.v1_9_R1.PacketPlayOutPlayerInfo; import net.minecraft.server.v1_9_R1.PacketPlayOutPlayerInfo;
import net.minecraft.server.v1_9_R1.PathfinderGoalSelector; import net.minecraft.server.v1_9_R1.PathfinderGoalSelector;
import net.minecraft.server.v1_9_R1.ScoreboardTeam;
import net.minecraft.server.v1_9_R1.Vec3D; import net.minecraft.server.v1_9_R1.Vec3D;
import net.minecraft.server.v1_9_R1.World; import net.minecraft.server.v1_9_R1.World;
import net.minecraft.server.v1_9_R1.WorldServer; import net.minecraft.server.v1_9_R1.WorldServer;
@ -484,6 +480,10 @@ public class NMS {
return NMS.getHandle(entity).P; return NMS.getHandle(entity).P;
} }
public static Entity getVehicle(org.bukkit.entity.Entity entity) {
return getHandle(entity).getVehicle();
}
public static void initNetworkManager(NetworkManager network) { public static void initNetworkManager(NetworkManager network) {
if (NETWORK_ADDRESS == null) if (NETWORK_ADDRESS == null)
return; return;
@ -724,7 +724,8 @@ public class NMS {
} else if (handle instanceof EntityHumanNPC) { } else if (handle instanceof EntityHumanNPC) {
((EntityHumanNPC) handle).setMoveDestination(x, y, z, speed); ((EntityHumanNPC) handle).setMoveDestination(x, y, z, speed);
} }
} }
public static void setHeadYaw(Entity en, float yaw) { public static void setHeadYaw(Entity en, float yaw) {
if (!(en instanceof EntityLiving)) if (!(en instanceof EntityLiving))
return; return;
@ -908,6 +909,7 @@ public class NMS {
private static final Field RABBIT_FIELD = getField(EntityRabbit.class, "bv"); private static final Field RABBIT_FIELD = getField(EntityRabbit.class, "bv");
private static final Random RANDOM = Util.getFastRandom(); private static final Random RANDOM = Util.getFastRandom();
private static Field SKULL_PROFILE_FIELD; private static Field SKULL_PROFILE_FIELD;
private static Field TRACKED_ENTITY_SET = NMS.getField(EntityTracker.class, "c"); private static Field TRACKED_ENTITY_SET = NMS.getField(EntityTracker.class, "c");
static { static {