fix multiple null errors with unloaded worlds
This commit is contained in:
parent
95ba3347b2
commit
1e80b0b217
5 changed files with 100 additions and 5 deletions
|
@ -0,0 +1,48 @@
|
|||
package lol.pyr.znpcsplus.commands;
|
||||
|
||||
import lol.pyr.director.adventure.command.CommandContext;
|
||||
import lol.pyr.director.adventure.command.CommandHandler;
|
||||
import lol.pyr.director.common.command.CommandExecutionException;
|
||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||
import lol.pyr.znpcsplus.npc.NpcTypeImpl;
|
||||
import lol.pyr.znpcsplus.npc.NpcTypeRegistryImpl;
|
||||
import lol.pyr.znpcsplus.util.NpcLocation;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class CloneCommand implements CommandHandler {
|
||||
private final NpcRegistryImpl npcRegistry;
|
||||
private final NpcTypeRegistryImpl typeRegistry;
|
||||
|
||||
public CloneCommand(NpcRegistryImpl npcRegistry, NpcTypeRegistryImpl typeRegistry) {
|
||||
this.npcRegistry = npcRegistry;
|
||||
this.typeRegistry = typeRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CommandContext context) throws CommandExecutionException {
|
||||
context.setUsage(context.getLabel() + " create <id> <type>");
|
||||
Player player = context.ensureSenderIsPlayer();
|
||||
|
||||
String id = context.popString();
|
||||
if (npcRegistry.getById(id) != null) context.halt(Component.text("NPC with that ID already exists.", NamedTextColor.RED));
|
||||
NpcTypeImpl type = context.parse(NpcTypeImpl.class);
|
||||
|
||||
NpcEntryImpl entry = npcRegistry.create(id, player.getWorld(), type, new NpcLocation(player.getLocation()));
|
||||
entry.enableEverything();
|
||||
|
||||
context.send(Component.text("Created a " + type.getName() + " NPC with ID " + id + ".", NamedTextColor.GREEN));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
||||
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
|
||||
if (context.argSize() == 2) return context.suggestStream(typeRegistry.getAllImpl().stream().map(NpcTypeImpl::getName));
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ import org.bukkit.entity.Player;
|
|||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class MoveCommand implements CommandHandler {
|
||||
private final NpcRegistryImpl npcRegistry;
|
||||
|
@ -27,7 +28,7 @@ public class MoveCommand implements CommandHandler {
|
|||
Player player = context.ensureSenderIsPlayer();
|
||||
NpcImpl npc = context.parse(NpcEntryImpl.class).getNpc();
|
||||
npc.setLocation(new NpcLocation(player.getLocation()));
|
||||
if (!npc.getWorld().equals(player.getWorld())) npc.setWorld(player.getWorld());
|
||||
if (!Objects.equals(npc.getWorld(), player.getWorld())) npc.setWorld(player.getWorld());
|
||||
context.send(Component.text("NPC moved to your current location.", NamedTextColor.GREEN));
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import lol.pyr.znpcsplus.util.NpcLocation;
|
|||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -32,7 +33,10 @@ public class NearCommand implements CommandHandler {
|
|||
|
||||
List<NpcEntryImpl> entries = npcRegistry.getAllModifiable().stream()
|
||||
.filter(entry -> Objects.equals(entry.getNpc().getWorld(), player.getWorld()))
|
||||
.filter(entry -> entry.getNpc().getBukkitLocation().distanceSquared(player.getLocation()) < radius)
|
||||
.filter(entry -> {
|
||||
Location loc = entry.getNpc().getBukkitLocation();
|
||||
return loc != null && loc.distanceSquared(player.getLocation()) < radius;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (entries.isEmpty()) context.halt(Component.text("There are no npcs within " + raw + " blocks around you.", NamedTextColor.RED));
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.bukkit.Location;
|
|||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -75,8 +76,10 @@ public class NpcImpl extends Viewable implements Npc {
|
|||
return location;
|
||||
}
|
||||
|
||||
public Location getBukkitLocation() {
|
||||
return location.toBukkitLocation(getWorld());
|
||||
public @Nullable Location getBukkitLocation() {
|
||||
World world = getWorld();
|
||||
if (world == null) return null;
|
||||
return location.toBukkitLocation(world);
|
||||
}
|
||||
|
||||
public void setLocation(NpcLocation location) {
|
||||
|
@ -112,7 +115,7 @@ public class NpcImpl extends Viewable implements Npc {
|
|||
return uuid;
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
public @Nullable World getWorld() {
|
||||
return Bukkit.getWorld(worldName);
|
||||
}
|
||||
|
||||
|
@ -182,6 +185,11 @@ public class NpcImpl extends Viewable implements Npc {
|
|||
setProperty((EntityPropertyImpl<T>) property, (T) value);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> void UNSAFE_setProperty(EntityProperty<?> property, Object value) {
|
||||
setProperty((EntityPropertyImpl<T>) property, (T) value);
|
||||
}
|
||||
|
||||
public Set<EntityProperty<?>> getAllProperties() {
|
||||
return Collections.unmodifiableSet(propertyMap.keySet());
|
||||
}
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
package lol.pyr.znpcsplus.npc;
|
||||
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import lol.pyr.znpcsplus.api.entity.EntityProperty;
|
||||
import lol.pyr.znpcsplus.api.npc.NpcEntry;
|
||||
import lol.pyr.znpcsplus.api.npc.NpcRegistry;
|
||||
import lol.pyr.znpcsplus.api.npc.NpcType;
|
||||
import lol.pyr.znpcsplus.config.ConfigManager;
|
||||
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
|
||||
import lol.pyr.znpcsplus.hologram.HologramItem;
|
||||
import lol.pyr.znpcsplus.hologram.HologramLine;
|
||||
import lol.pyr.znpcsplus.hologram.HologramText;
|
||||
import lol.pyr.znpcsplus.interaction.ActionRegistry;
|
||||
import lol.pyr.znpcsplus.interaction.InteractionActionImpl;
|
||||
import lol.pyr.znpcsplus.packets.PacketFactory;
|
||||
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||
import lol.pyr.znpcsplus.storage.NpcStorage;
|
||||
|
@ -153,6 +158,35 @@ public class NpcRegistryImpl implements NpcRegistry {
|
|||
return entry;
|
||||
}
|
||||
|
||||
public NpcEntryImpl clone(String id, String newId, World newWorld, NpcLocation newLocation) {
|
||||
NpcEntryImpl oldNpc = getById(id);
|
||||
if (oldNpc == null) return null;
|
||||
NpcEntryImpl newNpc = create(newId, newWorld, oldNpc.getNpc().getType(), newLocation);
|
||||
newNpc.enableEverything();
|
||||
|
||||
for (EntityProperty<?> property : oldNpc.getNpc().getAllProperties()) {
|
||||
newNpc.getNpc().UNSAFE_setProperty(property, oldNpc.getNpc().getProperty(property));
|
||||
}
|
||||
|
||||
for (InteractionActionImpl action : oldNpc.getNpc().getActions()) {
|
||||
newNpc.getNpc().addAction(action);
|
||||
}
|
||||
|
||||
for (HologramLine<?> line : oldNpc.getNpc().getHologram().getLines()) {
|
||||
if (line instanceof HologramText) {
|
||||
HologramText text = (HologramText) line;
|
||||
newNpc.getNpc().getHologram().addTextLineComponent(text.getValue());
|
||||
}
|
||||
else if (line instanceof HologramItem) {
|
||||
HologramItem item = (HologramItem) line;
|
||||
newNpc.getNpc().getHologram().addItemLinePEStack(item.getValue());
|
||||
}
|
||||
else throw new IllegalArgumentException("Unknown hologram line type during clone");
|
||||
}
|
||||
|
||||
return newNpc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String id) {
|
||||
NpcEntryImpl entry = npcIdLookupMap.get(id.toLowerCase());
|
||||
|
|
Loading…
Reference in a new issue