mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2025-01-04 07:27:59 +01:00
Fix traits/lookclose, use less memory in MCTargetStrategy, improve Behaviour (ie. scripts don't need to implement hashCode() any more)
This commit is contained in:
parent
358cf996b1
commit
eacf70202d
@ -96,15 +96,20 @@ public class NPCCommands {
|
|||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = { "npc" },
|
aliases = { "npc" },
|
||||||
usage = "behaviour [scripts]",
|
usage = "behaviour [scripts] (-r)",
|
||||||
desc = "Sets the behaviour of a NPC",
|
desc = "Sets the behaviour of a NPC",
|
||||||
modifiers = { "behaviour", "ai" },
|
modifiers = { "behaviour", "ai" },
|
||||||
min = 2,
|
flags = "r",
|
||||||
max = -1)
|
min = 2)
|
||||||
public void behaviour(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
public void behaviour(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||||
Iterable<String> files = Splitter.on(',').split(args.getJoinedStrings(1, ','));
|
Iterable<String> files = Splitter.on(',').split(args.getJoinedStrings(1, ','));
|
||||||
npc.getTrait(Behaviour.class).addScripts(files);
|
if (args.hasFlag('r')) {
|
||||||
sender.sendMessage(ChatColor.GREEN + "Behaviours added.");
|
npc.getTrait(Behaviour.class).addScripts(files);
|
||||||
|
sender.sendMessage(ChatColor.GREEN + "Behaviours added.");
|
||||||
|
} else {
|
||||||
|
npc.getTrait(Behaviour.class).removeScripts(files);
|
||||||
|
sender.sendMessage(ChatColor.GREEN + "Behaviours removed.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
|
@ -40,7 +40,7 @@ public class ScriptCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onScriptCompiled(ScriptFactory script) {
|
public void onScriptCompiled(File file, ScriptFactory script) {
|
||||||
Script s = script.newInstance();
|
Script s = script.newInstance();
|
||||||
if (args.hasValueFlag("methods")) {
|
if (args.hasValueFlag("methods")) {
|
||||||
for (String m : Splitter.on(',').split(args.getFlag("methods"))) {
|
for (String m : Splitter.on(',').split(args.getFlag("methods"))) {
|
||||||
|
@ -26,7 +26,7 @@ public class TraitCommands {
|
|||||||
flags = "r",
|
flags = "r",
|
||||||
permission = "npc.trait")
|
permission = "npc.trait")
|
||||||
public void add(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
public void add(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||||
String traitName = args.getString(1);
|
String traitName = args.getString(0);
|
||||||
if (!sender.hasPermission("citizens.npc.trait." + traitName))
|
if (!sender.hasPermission("citizens.npc.trait." + traitName))
|
||||||
throw new NoPermissionsException();
|
throw new NoPermissionsException();
|
||||||
if (args.hasFlag('r')) {
|
if (args.hasFlag('r')) {
|
||||||
@ -57,7 +57,7 @@ public class TraitCommands {
|
|||||||
flags = "*",
|
flags = "*",
|
||||||
permission = "npc.trait-configure")
|
permission = "npc.trait-configure")
|
||||||
public void configure(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
public void configure(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||||
String traitName = args.getString(1);
|
String traitName = args.getString(0);
|
||||||
if (!sender.hasPermission("citizens.npc.trait-configure." + traitName))
|
if (!sender.hasPermission("citizens.npc.trait-configure." + traitName))
|
||||||
throw new NoPermissionsException();
|
throw new NoPermissionsException();
|
||||||
Class<? extends Trait> clazz = CitizensAPI.getTraitFactory().getTraitClass(args.getString(1));
|
Class<? extends Trait> clazz = CitizensAPI.getTraitFactory().getTraitClass(args.getString(1));
|
||||||
|
@ -15,12 +15,6 @@ public class MCNavigationStrategy implements PathStrategy {
|
|||||||
MCNavigationStrategy(final CitizensNPC npc, Location dest, float speed) {
|
MCNavigationStrategy(final CitizensNPC npc, Location dest, float speed) {
|
||||||
this(npc.getHandle(), dest);
|
this(npc.getHandle(), dest);
|
||||||
navigation.a(dest.getX(), dest.getY(), dest.getZ(), speed);
|
navigation.a(dest.getX(), dest.getY(), dest.getZ(), speed);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
MCNavigationStrategy(EntityLiving entity, EntityLiving target, float speed) {
|
|
||||||
this(entity, target.getBukkitEntity().getLocation());
|
|
||||||
navigation.a(target, speed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private MCNavigationStrategy(EntityLiving entity, Location target) {
|
private MCNavigationStrategy(EntityLiving entity, Location target) {
|
||||||
|
@ -7,6 +7,7 @@ import net.citizensnpcs.util.Util;
|
|||||||
import net.minecraft.server.EntityLiving;
|
import net.minecraft.server.EntityLiving;
|
||||||
import net.minecraft.server.EntityMonster;
|
import net.minecraft.server.EntityMonster;
|
||||||
import net.minecraft.server.EntityPlayer;
|
import net.minecraft.server.EntityPlayer;
|
||||||
|
import net.minecraft.server.Navigation;
|
||||||
import net.minecraft.server.Packet18ArmAnimation;
|
import net.minecraft.server.Packet18ArmAnimation;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -18,10 +19,12 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
|
|||||||
private int attackTicks;
|
private int attackTicks;
|
||||||
private final EntityLiving handle, target;
|
private final EntityLiving handle, target;
|
||||||
private final float speed;
|
private final float speed;
|
||||||
|
private final Navigation navigation;
|
||||||
|
|
||||||
public MCTargetStrategy(CitizensNPC handle, LivingEntity target, boolean aggro, float speed) {
|
public MCTargetStrategy(CitizensNPC handle, LivingEntity target, boolean aggro, float speed) {
|
||||||
this.handle = handle.getHandle();
|
this.handle = handle.getHandle();
|
||||||
this.target = ((CraftLivingEntity) target).getHandle();
|
this.target = ((CraftLivingEntity) target).getHandle();
|
||||||
|
this.navigation = this.handle.getNavigation();
|
||||||
this.aggro = aggro;
|
this.aggro = aggro;
|
||||||
this.speed = speed;
|
this.speed = speed;
|
||||||
}
|
}
|
||||||
@ -60,7 +63,7 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
|
|||||||
public boolean update() {
|
public boolean update() {
|
||||||
if (target == null || target.dead)
|
if (target == null || target.dead)
|
||||||
return true;
|
return true;
|
||||||
new MCNavigationStrategy(handle, target, speed).update();
|
navigation.a(target, speed);
|
||||||
handle.getControllerLook().a(target, 10.0F, handle.bf());
|
handle.getControllerLook().a(target, 10.0F, handle.bf());
|
||||||
if (aggro && canAttack()) {
|
if (aggro && canAttack()) {
|
||||||
if (handle instanceof EntityMonster) {
|
if (handle instanceof EntityMonster) {
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
package net.citizensnpcs.trait;
|
package net.citizensnpcs.trait;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import net.citizensnpcs.api.CitizensAPI;
|
import net.citizensnpcs.api.CitizensAPI;
|
||||||
import net.citizensnpcs.api.ai.Goal;
|
import net.citizensnpcs.api.ai.Goal;
|
||||||
|
import net.citizensnpcs.api.ai.GoalController.GoalEntry;
|
||||||
|
import net.citizensnpcs.api.ai.SimpleGoalEntry;
|
||||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||||
import net.citizensnpcs.api.scripting.CompileCallback;
|
import net.citizensnpcs.api.scripting.CompileCallback;
|
||||||
import net.citizensnpcs.api.scripting.ScriptFactory;
|
import net.citizensnpcs.api.scripting.ScriptFactory;
|
||||||
@ -20,10 +21,9 @@ import com.google.common.base.Joiner;
|
|||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
|
|
||||||
public class Behaviour extends Trait {
|
public class Behaviour extends Trait {
|
||||||
private final Map<Goal, Integer> addedGoals = Maps.newHashMap();
|
private final List<BehaviourGoalEntry> addedGoals = Lists.newArrayList();
|
||||||
private final Function<String, File> fileConverterFunction = new Function<String, File>() {
|
private final Function<String, File> fileConverterFunction = new Function<String, File>() {
|
||||||
@Override
|
@Override
|
||||||
public File apply(String arg0) {
|
public File apply(String arg0) {
|
||||||
@ -63,14 +63,14 @@ public class Behaviour extends Trait {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSpawn() {
|
public void onSpawn() {
|
||||||
for (Entry<Goal, Integer> entry : addedGoals.entrySet()) {
|
for (GoalEntry entry : addedGoals) {
|
||||||
npc.getDefaultGoalController().addGoal(entry.getKey(), entry.getValue());
|
npc.getDefaultGoalController().addGoal(entry.getGoal(), entry.getPriority());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeGoals() {
|
private void removeGoals() {
|
||||||
for (Goal entry : addedGoals.keySet()) {
|
for (GoalEntry entry : addedGoals) {
|
||||||
npc.getDefaultGoalController().removeGoal(entry);
|
npc.getDefaultGoalController().removeGoal(entry.getGoal());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,27 +85,60 @@ public class Behaviour extends Trait {
|
|||||||
key.setString("scripts", Joiner.on(",").join(scripts));
|
key.setString("scripts", Joiner.on(",").join(scripts));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class BehaviourGoalEntry extends SimpleGoalEntry {
|
||||||
|
private final File file;
|
||||||
|
|
||||||
|
private BehaviourGoalEntry(Goal goal, int priority, File file) {
|
||||||
|
super(goal, priority);
|
||||||
|
this.file = file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class BehaviourCallback implements CompileCallback {
|
public class BehaviourCallback implements CompileCallback {
|
||||||
private final Map<Goal, Integer> goals = Maps.newHashMap();
|
private final List<BehaviourGoalEntry> goals = Lists.newArrayList();
|
||||||
|
private File fileInUse;
|
||||||
|
|
||||||
public void addGoal(int priority, Goal goal) {
|
public void addGoal(int priority, Goal goal) {
|
||||||
Validate.notNull(goal);
|
Validate.notNull(goal);
|
||||||
goals.put(goal, priority);
|
goals.add(new BehaviourGoalEntry(goal, priority, fileInUse));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCompileTaskFinished() {
|
public void onCompileTaskFinished() {
|
||||||
addedGoals.putAll(goals);
|
addedGoals.addAll(goals);
|
||||||
if (!npc.isSpawned())
|
if (!npc.isSpawned())
|
||||||
return;
|
return;
|
||||||
for (Entry<Goal, Integer> entry : goals.entrySet()) {
|
for (GoalEntry entry : goals) {
|
||||||
npc.getDefaultGoalController().addGoal(entry.getKey(), entry.getValue());
|
npc.getDefaultGoalController().addGoal(entry.getGoal(), entry.getPriority());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onScriptCompiled(ScriptFactory script) {
|
public void onScriptCompiled(File file, ScriptFactory script) {
|
||||||
script.newInstance().invoke("addGoals", this, npc);
|
synchronized (goals) {
|
||||||
|
fileInUse = file;
|
||||||
|
script.newInstance().invoke("addGoals", this, npc);
|
||||||
|
scripts.add(file);
|
||||||
|
fileInUse = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeScripts(Iterable<String> files) {
|
||||||
|
Iterable<File> transformed = Iterables.transform(files, fileConverterFunction);
|
||||||
|
boolean isSpawned = npc.isSpawned();
|
||||||
|
for (File file : transformed) {
|
||||||
|
if (isSpawned) {
|
||||||
|
Iterator<BehaviourGoalEntry> itr = addedGoals.iterator();
|
||||||
|
while (itr.hasNext()) {
|
||||||
|
BehaviourGoalEntry entry = itr.next();
|
||||||
|
if (file.equals(entry.file)) {
|
||||||
|
itr.remove();
|
||||||
|
npc.getDefaultGoalController().removeGoal(entry.getGoal());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scripts.remove(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,8 @@ public class LookClose extends Trait implements Toggleable, CommandConfigurable
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(DataKey key) throws NPCLoadException {
|
public void load(DataKey key) throws NPCLoadException {
|
||||||
enabled = key.getBoolean("");
|
enabled = key.getBoolean("enabled", key.getBoolean(""));
|
||||||
|
// TODO: remove key.getBoolean("") ^ after a few updates
|
||||||
range = key.getDouble("range", range);
|
range = key.getDouble("range", range);
|
||||||
realisticLooking = key.getBoolean("realistic-looking", false);
|
realisticLooking = key.getBoolean("realistic-looking", false);
|
||||||
}
|
}
|
||||||
@ -90,7 +91,11 @@ public class LookClose extends Trait implements Toggleable, CommandConfigurable
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save(DataKey key) {
|
public void save(DataKey key) {
|
||||||
key.setBoolean("", enabled);
|
if (key.keyExists("")) {
|
||||||
|
// TODO: remove after a few updates
|
||||||
|
key.removeKey("");
|
||||||
|
}
|
||||||
|
key.setBoolean("enabled", enabled);
|
||||||
key.setDouble("range", range);
|
key.setDouble("range", range);
|
||||||
key.setBoolean("realistic-looking", realisticLooking);
|
key.setBoolean("realistic-looking", realisticLooking);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user