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.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class MoveCommand implements CommandHandler {
|
public class MoveCommand implements CommandHandler {
|
||||||
private final NpcRegistryImpl npcRegistry;
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
@ -27,7 +28,7 @@ public class MoveCommand implements CommandHandler {
|
||||||
Player player = context.ensureSenderIsPlayer();
|
Player player = context.ensureSenderIsPlayer();
|
||||||
NpcImpl npc = context.parse(NpcEntryImpl.class).getNpc();
|
NpcImpl npc = context.parse(NpcEntryImpl.class).getNpc();
|
||||||
npc.setLocation(new NpcLocation(player.getLocation()));
|
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));
|
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.Component;
|
||||||
import net.kyori.adventure.text.event.ClickEvent;
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -32,7 +33,10 @@ public class NearCommand implements CommandHandler {
|
||||||
|
|
||||||
List<NpcEntryImpl> entries = npcRegistry.getAllModifiable().stream()
|
List<NpcEntryImpl> entries = npcRegistry.getAllModifiable().stream()
|
||||||
.filter(entry -> Objects.equals(entry.getNpc().getWorld(), player.getWorld()))
|
.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());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
if (entries.isEmpty()) context.halt(Component.text("There are no npcs within " + raw + " blocks around you.", NamedTextColor.RED));
|
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.World;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -75,8 +76,10 @@ public class NpcImpl extends Viewable implements Npc {
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Location getBukkitLocation() {
|
public @Nullable Location getBukkitLocation() {
|
||||||
return location.toBukkitLocation(getWorld());
|
World world = getWorld();
|
||||||
|
if (world == null) return null;
|
||||||
|
return location.toBukkitLocation(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLocation(NpcLocation location) {
|
public void setLocation(NpcLocation location) {
|
||||||
|
@ -112,7 +115,7 @@ public class NpcImpl extends Viewable implements Npc {
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public World getWorld() {
|
public @Nullable World getWorld() {
|
||||||
return Bukkit.getWorld(worldName);
|
return Bukkit.getWorld(worldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,6 +185,11 @@ public class NpcImpl extends Viewable implements Npc {
|
||||||
setProperty((EntityPropertyImpl<T>) property, (T) value);
|
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() {
|
public Set<EntityProperty<?>> getAllProperties() {
|
||||||
return Collections.unmodifiableSet(propertyMap.keySet());
|
return Collections.unmodifiableSet(propertyMap.keySet());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
package lol.pyr.znpcsplus.npc;
|
package lol.pyr.znpcsplus.npc;
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
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.NpcEntry;
|
||||||
import lol.pyr.znpcsplus.api.npc.NpcRegistry;
|
import lol.pyr.znpcsplus.api.npc.NpcRegistry;
|
||||||
import lol.pyr.znpcsplus.api.npc.NpcType;
|
import lol.pyr.znpcsplus.api.npc.NpcType;
|
||||||
import lol.pyr.znpcsplus.config.ConfigManager;
|
import lol.pyr.znpcsplus.config.ConfigManager;
|
||||||
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
|
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.ActionRegistry;
|
||||||
|
import lol.pyr.znpcsplus.interaction.InteractionActionImpl;
|
||||||
import lol.pyr.znpcsplus.packets.PacketFactory;
|
import lol.pyr.znpcsplus.packets.PacketFactory;
|
||||||
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||||
import lol.pyr.znpcsplus.storage.NpcStorage;
|
import lol.pyr.znpcsplus.storage.NpcStorage;
|
||||||
|
@ -153,6 +158,35 @@ public class NpcRegistryImpl implements NpcRegistry {
|
||||||
return entry;
|
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
|
@Override
|
||||||
public void delete(String id) {
|
public void delete(String id) {
|
||||||
NpcEntryImpl entry = npcIdLookupMap.get(id.toLowerCase());
|
NpcEntryImpl entry = npcIdLookupMap.get(id.toLowerCase());
|
||||||
|
|
Loading…
Reference in a new issue