Fix navigation bug with duplicate examiners, add change detection to scoreboard to avoid sending as many packets

This commit is contained in:
fullwall 2021-01-27 22:38:50 +08:00
parent 66a3855aa8
commit 0499839115
5 changed files with 76 additions and 61 deletions

View File

@ -4,6 +4,8 @@ import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.google.common.collect.Maps;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.command.Command;
import net.citizensnpcs.api.command.CommandContext;
@ -42,7 +44,7 @@ public class EditorCommands {
permission = "citizens.npc.edit.equip")
public void equip(CommandContext args, Player player, NPC npc) {
if (Messaging.isDebugging() && false) {
InventoryMenu create = InventoryMenu.create(EquipmentGUI.class);
InventoryMenu create = InventoryMenu.createWithContext(EquipmentGUI.class, Maps.newHashMap());
Bukkit.getPluginManager().registerEvents(create, CitizensAPI.getPlugin());
create.present(player);
return;

View File

@ -8,7 +8,6 @@ import org.bukkit.event.inventory.InventoryType;
import net.citizensnpcs.api.gui.ClickHandler;
import net.citizensnpcs.api.gui.InventoryMenuPage;
import net.citizensnpcs.api.gui.InventoryMenuPattern;
import net.citizensnpcs.api.gui.InventoryMenuSlot;
import net.citizensnpcs.api.gui.Menu;
import net.citizensnpcs.api.gui.MenuContext;
@ -23,23 +22,8 @@ import net.citizensnpcs.api.util.Messaging;
@MenuSlot(value = { 0, 3 }, material = Material.DIAMOND_CHESTPLATE, amount = 1, filter = ClickType.UNKNOWN)
@MenuSlot(value = { 0, 4 }, material = Material.DIAMOND_LEGGINGS, amount = 1, filter = ClickType.UNKNOWN)
@MenuSlot(value = { 0, 5 }, material = Material.DIAMOND_BOOTS, amount = 1, filter = ClickType.UNKNOWN)
@MenuPattern(offset = { 0, 6 }, slots = { @MenuSlot(filter = ClickType.UNKNOWN, pat = 'x') }, value = "xxx\nxxx")
public class EquipmentGUI extends InventoryMenuPage {
@MenuPattern(offset = { 0, 5 }, value = "xxx\nxxx")
@MenuSlot(filter = ClickType.UNKNOWN, pat = 'x')
private InventoryMenuPattern block;
@MenuSlot({ 1, 5 })
private InventoryMenuSlot boots;
@MenuSlot({ 1, 3 })
private InventoryMenuSlot chest;
@MenuSlot({ 1, 0 })
private InventoryMenuSlot hand;
@MenuSlot({ 1, 2 })
private InventoryMenuSlot helmet;
@MenuSlot({ 1, 4 })
private InventoryMenuSlot leggings;
@MenuSlot({ 1, 1 })
private InventoryMenuSlot offhand;
@Override
public void create(MenuContext ctx) {
}
@ -56,7 +40,6 @@ public class EquipmentGUI extends InventoryMenuPage {
@ClickHandler(slot = { 1, 5 })
public void setBoots(InventoryMenuSlot slot, InventoryClickEvent event) {
Messaging.log("BOOTS", event);
}
@ClickHandler(slot = { 1, 3 })
@ -65,7 +48,6 @@ public class EquipmentGUI extends InventoryMenuPage {
@ClickHandler(slot = { 1, 0 })
public void setHand(InventoryMenuSlot slot, InventoryClickEvent event) {
Messaging.log("HAND", event);
}
@ClickHandler(slot = { 1, 2 })

View File

@ -135,7 +135,7 @@ public class AStarNavigationStrategy extends AbstractPathStrategy {
Location currLoc = npc.getEntity().getLocation(NPC_LOCATION);
Vector destVector = new Vector(vector.getX() + 0.5, vector.getY(), vector.getZ() + 0.5);
/* Proper door movement - gets stuck on corners at times
Block block = currLoc.getWorld().getBlockAt(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
if (MinecraftBlockExaminer.isDoor(block.getType())) {
Door door = (Door) block.getState().getData();

View File

@ -3,6 +3,7 @@ package net.citizensnpcs.npc.ai;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.function.Function;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -219,11 +220,16 @@ public class CitizensNavigator implements Navigator, Runnable {
@Override
public void setTarget(Entity target, boolean aggressive) {
setTarget(target, aggressive, new MCTargetStrategy(npc, target, aggressive, localParams));
setTarget(target, aggressive, new Function<NavigatorParameters, PathStrategy>() {
@Override
public PathStrategy apply(NavigatorParameters params) {
return new MCTargetStrategy(npc, target, aggressive, params);
}
});
}
@Override
public void setTarget(Entity target, boolean aggressive, PathStrategy strategy) {
public void setTarget(Entity target, boolean aggressive, Function<NavigatorParameters, PathStrategy> strategy) {
if (!npc.isSpawned())
throw new IllegalStateException("npc is not spawned");
if (target == null) {
@ -231,28 +237,30 @@ public class CitizensNavigator implements Navigator, Runnable {
return;
}
switchParams();
updatePathfindingRange();
switchStrategyTo(strategy);
switchStrategyTo(strategy.apply(localParams));
}
@Override
public void setTarget(Iterable<Vector> path) {
if (!npc.isSpawned())
throw new IllegalStateException("npc is not spawned");
PathStrategy newStrategy;
if (npc.isFlyable()) {
newStrategy = new FlyingAStarNavigationStrategy(npc, path, localParams);
} else if (localParams.useNewPathfinder() || !(npc.getEntity() instanceof LivingEntity)
|| npc.getEntity() instanceof ArmorStand) {
newStrategy = new AStarNavigationStrategy(npc, path, localParams);
} else {
newStrategy = new MCNavigationStrategy(npc, path, localParams);
}
setTarget(path, newStrategy);
setTarget(path, new Function<NavigatorParameters, PathStrategy>() {
@Override
public PathStrategy apply(NavigatorParameters params) {
if (npc.isFlyable()) {
return new FlyingAStarNavigationStrategy(npc, path, params);
} else if (params.useNewPathfinder() || !(npc.getEntity() instanceof LivingEntity)
|| npc.getEntity() instanceof ArmorStand) {
return new AStarNavigationStrategy(npc, path, params);
} else {
return new MCNavigationStrategy(npc, path, params);
}
}
});
}
@Override
public void setTarget(Iterable<Vector> path, PathStrategy strategy) {
public void setTarget(Iterable<Vector> path, Function<NavigatorParameters, PathStrategy> strategy) {
if (!npc.isSpawned())
throw new IllegalStateException("npc is not spawned");
if (path == null || Iterables.size(path) == 0) {
@ -260,28 +268,31 @@ public class CitizensNavigator implements Navigator, Runnable {
return;
}
switchParams();
updatePathfindingRange();
switchStrategyTo(strategy);
switchStrategyTo(strategy.apply(localParams));
}
@Override
public void setTarget(Location target) {
public void setTarget(Location targetIn) {
if (!npc.isSpawned())
throw new IllegalStateException("npc is not spawned");
PathStrategy newStrategy;
if (npc.isFlyable()) {
newStrategy = new FlyingAStarNavigationStrategy(npc, target, localParams);
} else if (localParams.useNewPathfinder() || !(npc.getEntity() instanceof LivingEntity)
|| npc.getEntity() instanceof ArmorStand) {
newStrategy = new AStarNavigationStrategy(npc, target, localParams);
} else {
newStrategy = new MCNavigationStrategy(npc, target, localParams);
}
setTarget(target, newStrategy);
final Location target = targetIn.clone();
setTarget(target, new Function<NavigatorParameters, PathStrategy>() {
@Override
public PathStrategy apply(NavigatorParameters params) {
if (npc.isFlyable()) {
return new FlyingAStarNavigationStrategy(npc, target, params);
} else if (params.useNewPathfinder() || !(npc.getEntity() instanceof LivingEntity)
|| npc.getEntity() instanceof ArmorStand) {
return new AStarNavigationStrategy(npc, target, params);
} else {
return new MCNavigationStrategy(npc, target, params);
}
}
});
}
@Override
public void setTarget(Location target, PathStrategy strategy) {
public void setTarget(Location target, Function<NavigatorParameters, PathStrategy> strategy) {
if (!npc.isSpawned())
throw new IllegalStateException("npc is not spawned");
if (target == null) {
@ -290,8 +301,7 @@ public class CitizensNavigator implements Navigator, Runnable {
}
target = target.clone();
switchParams();
updatePathfindingRange();
switchStrategyTo(strategy);
switchStrategyTo(strategy.apply(localParams));
}
private void stopNavigating() {
@ -359,6 +369,7 @@ public class CitizensNavigator implements Navigator, Runnable {
}
private void switchStrategyTo(PathStrategy newStrategy) {
updatePathfindingRange();
if (executing != null) {
Bukkit.getPluginManager().callEvent(new NavigationReplaceEvent(this));
}

View File

@ -20,6 +20,7 @@ import net.citizensnpcs.util.Util;
public class ScoreboardTrait extends Trait {
@Persist
private ChatColor color;
private boolean justSpawned;
private ChatColor previousGlowingColor;
@Persist
private final Set<String> tags = new HashSet<String>();
@ -33,17 +34,22 @@ public class ScoreboardTrait extends Trait {
}
public void apply(Team team, boolean nameVisibility) {
boolean changed = false;
Set<String> newTags = new HashSet<String>(tags);
if (SUPPORT_TAGS) {
try {
for (Iterator<String> iterator = npc.getEntity().getScoreboardTags().iterator(); iterator.hasNext();) {
String oldTag = iterator.next();
if (!newTags.remove(oldTag)) {
iterator.remove();
if (!npc.getEntity().getScoreboardTags().equals(tags)) {
changed = true;
for (Iterator<String> iterator = npc.getEntity().getScoreboardTags().iterator(); iterator
.hasNext();) {
String oldTag = iterator.next();
if (!newTags.remove(oldTag)) {
iterator.remove();
}
}
for (String tag : newTags) {
npc.getEntity().addScoreboardTag(tag);
}
}
for (String tag : newTags) {
npc.getEntity().addScoreboardTag(tag);
}
} catch (NoSuchMethodError e) {
SUPPORT_TAGS = false;
@ -52,7 +58,11 @@ public class ScoreboardTrait extends Trait {
if (SUPPORT_TEAM_SETOPTION) {
try {
team.setOption(Option.NAME_TAG_VISIBILITY, nameVisibility ? OptionStatus.ALWAYS : OptionStatus.NEVER);
OptionStatus visibility = nameVisibility ? OptionStatus.ALWAYS : OptionStatus.NEVER;
if (visibility != team.getOption(Option.NAME_TAG_VISIBILITY)) {
changed = true;
}
team.setOption(Option.NAME_TAG_VISIBILITY, visibility);
} catch (NoSuchMethodError e) {
SUPPORT_TEAM_SETOPTION = false;
} catch (NoClassDefFoundError e) {
@ -77,6 +87,7 @@ public class ScoreboardTrait extends Trait {
|| (previousGlowingColor != null && color != previousGlowingColor)) {
team.setColor(color);
previousGlowingColor = color;
changed = true;
}
} catch (NoSuchMethodError err) {
SUPPORT_GLOWING_COLOR = false;
@ -87,10 +98,14 @@ public class ScoreboardTrait extends Trait {
&& !team.getPrefix().equals(previousGlowingColor.toString()))) {
team.setPrefix(color.toString());
previousGlowingColor = color;
changed = true;
}
}
}
Util.sendTeamPacketToOnlinePlayers(team, 2);
if (changed || justSpawned) {
Util.sendTeamPacketToOnlinePlayers(team, 2);
justSpawned = false;
}
}
public ChatColor getColor() {
@ -101,6 +116,11 @@ public class ScoreboardTrait extends Trait {
return tags;
}
@Override
public void onSpawn() {
justSpawned = true;
}
public void removeTag(String tag) {
tags.remove(tag);
}