Add a super simple follow trait

This commit is contained in:
fullwall 2018-10-06 17:11:57 +08:00
parent 92121c11e2
commit 787e114faa
5 changed files with 95 additions and 1 deletions

View File

@ -73,6 +73,7 @@ import net.citizensnpcs.trait.Anchors;
import net.citizensnpcs.trait.ArmorStandTrait;
import net.citizensnpcs.trait.Controllable;
import net.citizensnpcs.trait.CurrentLocation;
import net.citizensnpcs.trait.FollowTrait;
import net.citizensnpcs.trait.Gravity;
import net.citizensnpcs.trait.HorseModifiers;
import net.citizensnpcs.trait.LookClose;
@ -509,6 +510,24 @@ public class NPCCommands {
Messaging.sendTr(sender, flyable ? Messages.FLYABLE_SET : Messages.FLYABLE_UNSET, npc.getName());
}
@Command(
aliases = { "npc" },
usage = "follow (player name) (-p[rotect])",
desc = "Toggles NPC following you",
modifiers = { "follow" },
min = 1,
max = 1,
permission = "citizens.npc.follow")
public void follow(CommandContext args, Player sender, NPC npc) throws CommandException {
boolean protect = args.hasFlag('p');
String name = sender.getName();
if (args.argsLength() > 1) {
name = args.getString(1);
}
boolean following = npc.getTrait(FollowTrait.class).toggle(name, protect);
Messaging.sendTr(sender, following ? Messages.FOLLOW_SET : Messages.FOLLOW_UNSET, npc.getName(), name);
}
@Command(
aliases = { "npc" },
usage = "gamemode [gamemode]",

View File

@ -24,6 +24,7 @@ import net.citizensnpcs.trait.Anchors;
import net.citizensnpcs.trait.ArmorStandTrait;
import net.citizensnpcs.trait.Controllable;
import net.citizensnpcs.trait.CurrentLocation;
import net.citizensnpcs.trait.FollowTrait;
import net.citizensnpcs.trait.Gravity;
import net.citizensnpcs.trait.HorseModifiers;
import net.citizensnpcs.trait.LookClose;
@ -53,11 +54,12 @@ public class CitizensTraitFactory implements TraitFactory {
registerTrait(TraitInfo.create(ArmorStandTrait.class));
registerTrait(TraitInfo.create(Anchors.class));
registerTrait(TraitInfo.create(Controllable.class));
registerTrait(TraitInfo.create(CurrentLocation.class));
registerTrait(TraitInfo.create(Equipment.class));
registerTrait(TraitInfo.create(FollowTrait.class));
registerTrait(TraitInfo.create(Gravity.class));
registerTrait(TraitInfo.create(HorseModifiers.class));
registerTrait(TraitInfo.create(Inventory.class));
registerTrait(TraitInfo.create(CurrentLocation.class));
registerTrait(TraitInfo.create(LookClose.class));
registerTrait(TraitInfo.create(OcelotModifiers.class));
registerTrait(TraitInfo.create(Owner.class));

View File

@ -0,0 +1,68 @@
package net.citizensnpcs.trait;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitName;
@TraitName("followtrait")
public class FollowTrait extends Trait {
@Persist
private boolean active = false;
@Persist
private String followingName;
private Player player;
@Persist("protect")
private boolean protect;
public FollowTrait() {
super("followtrait");
}
private boolean isActive() {
return active && npc.isSpawned() && player != null && npc.getEntity().getWorld().equals(player.getWorld());
}
@EventHandler
public void onEntityDamage(EntityDamageByEntityEvent event) {
if (isActive() && event.getEntity().equals(player)) {
npc.getNavigator().setTarget(event.getDamager(), true);
}
}
@Override
public void run() {
if (player == null || !player.isValid()) {
if (followingName == null)
return;
player = Bukkit.getPlayerExact(followingName);
if (player == null) {
return;
}
}
if (!isActive()) {
return;
}
if (!npc.getNavigator().isNavigating()) {
npc.getNavigator().setTarget(player, false);
}
}
public boolean toggle(String name, boolean protect) {
this.protect = protect;
if (name.equalsIgnoreCase(this.followingName) || this.followingName == null) {
this.active = !active;
}
this.followingName = name;
if (npc.getNavigator().isNavigating() && player != null
&& player == npc.getNavigator().getEntityTarget().getTarget()) {
npc.getNavigator().cancelNavigation();
}
this.player = null;
return this.active;
}
}

View File

@ -80,6 +80,9 @@ public class Messages {
public static final String FAILED_TO_REMOVE = "citizens.commands.trait.failed-to-remove";
public static final String FLYABLE_SET = "citizens.commands.npc.flyable.set";
public static final String FLYABLE_UNSET = "citizens.commands.npc.flyable.unset";
public static final String FOLLOW_PLAYER_NOT_INGAME = "citizens.commands.npc.follow.player-not-ingame";
public static final String FOLLOW_SET = "citizens.commands.npc.follow.set";
public static final String FOLLOW_UNSET = "citizens.commands.npc.follow.unset";
public static final String FROM_ENTITY_NOT_FOUND = "citizens.commands.npc.tpto.from-not-found";
public static final String GAMEMODE_DESCRIBE = "citizens.commands.npc.gamemode.describe";
public static final String GAMEMODE_INVALID = "citizens.commands.npc.gamemode.invalid";

View File

@ -39,6 +39,8 @@ citizens.commands.npc.create.no-player-for-spawn=No player could be found by tha
citizens.commands.npc.despawn.despawned=You despawned [[{0}]].
citizens.commands.npc.flyable.set=[[{0}]] is now flyable.
citizens.commands.npc.flyable.unset=[[{0}]] is no longer flyable.
citizens.commands.npc.follow.set=[[{0}]] is now following [[{1}]].
citizens.commands.npc.follow.unset=[[{0}]] is no longer following anyone.
citizens.commands.npc.gamemode.describe={0}''s gamemode is [[{1}]].
citizens.commands.npc.gamemode.invalid={0} is not a valid gamemode.
citizens.commands.npc.gamemode.set=Gamemode set to [[{0}]].