mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2025-01-08 01:17:41 +01:00
Tidied up and working
This commit is contained in:
parent
ce84d66b91
commit
180ccd9f5e
@ -45,6 +45,7 @@ import world.bentobox.bentobox.blueprints.dataobjects.BlueprintCreatureSpawner;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity;
|
||||
import world.bentobox.bentobox.hooks.FancyNpcsHook;
|
||||
import world.bentobox.bentobox.hooks.MythicMobsHook;
|
||||
import world.bentobox.bentobox.hooks.ZNPCsPlusHook;
|
||||
|
||||
/**
|
||||
* The clipboard provides the holding spot for an active blueprint that is being
|
||||
@ -71,6 +72,7 @@ public class BlueprintClipboard {
|
||||
private final BentoBox plugin = BentoBox.getInstance();
|
||||
private Optional<MythicMobsHook> mmh;
|
||||
private Optional<FancyNpcsHook> npc;
|
||||
private Optional<ZNPCsPlusHook> znpc;
|
||||
|
||||
/**
|
||||
* Create a clipboard for blueprint
|
||||
@ -82,12 +84,15 @@ public class BlueprintClipboard {
|
||||
}
|
||||
|
||||
public BlueprintClipboard() {
|
||||
// Citizens Hook
|
||||
// Fancy NPCs Hook
|
||||
npc = plugin.getHooks().getHook("FancyNpcs").filter(FancyNpcsHook.class::isInstance)
|
||||
.map(FancyNpcsHook.class::cast);
|
||||
// MythicMobs Hook
|
||||
mmh = plugin.getHooks().getHook("MythicMobs").filter(MythicMobsHook.class::isInstance)
|
||||
.map(MythicMobsHook.class::cast);
|
||||
// ZNPCs Plus Hook
|
||||
znpc = plugin.getHooks().getHook("ZNPCsPlus").filter(ZNPCsPlusHook.class::isInstance)
|
||||
.map(ZNPCsPlusHook.class::cast);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -143,6 +148,9 @@ public class BlueprintClipboard {
|
||||
// Add all the citizens for the area in one go. This is pretty fast.
|
||||
bpEntities.putAll(npc.get().getNpcsInArea(world, vectorsToCopy, origin));
|
||||
}
|
||||
if (znpc.isPresent()) {
|
||||
bpEntities.putAll(znpc.get().getNpcsInArea(world, vectorsToCopy, origin));
|
||||
}
|
||||
|
||||
// Repeating copy task
|
||||
copyTask = Bukkit.getScheduler().runTaskTimer(plugin, () -> {
|
||||
|
@ -240,7 +240,7 @@ public class BlueprintPaster {
|
||||
int x = location.getBlockX() + entry.getKey().getBlockX();
|
||||
int y = location.getBlockY() + entry.getKey().getBlockY();
|
||||
int z = location.getBlockZ() + entry.getKey().getBlockZ();
|
||||
Location center = new Location(world, x, y, z).add(new Vector(0.5, 0.5, 0.5));
|
||||
Location center = new Location(world, x, y, z).add(new Vector(0.5, 0D, 0.5));
|
||||
List<BlueprintEntity> entities = entry.getValue();
|
||||
entityMap.put(center, entities);
|
||||
count++;
|
||||
|
@ -3,13 +3,17 @@ package world.bentobox.bentobox.hooks;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
@ -19,6 +23,7 @@ import lol.pyr.znpcsplus.util.NpcLocation;
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.hooks.Hook;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
|
||||
/**
|
||||
* Provides copy and pasting of ZNPCS Plus in blueprints https://github.com/Pyrbu/ZNPCsPlus
|
||||
@ -28,6 +33,8 @@ import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity;
|
||||
*/
|
||||
public class ZNPCsPlusHook extends Hook {
|
||||
|
||||
private static final String VERSION = "2.0.0-SNAPSHOT"; // Minimum version required
|
||||
|
||||
public ZNPCsPlusHook() {
|
||||
super("ZNPCsPlus", Material.PLAYER_HEAD);
|
||||
}
|
||||
@ -36,7 +43,6 @@ public class ZNPCsPlusHook extends Hook {
|
||||
String result = NpcApiProvider.get().getNpcSerializerRegistry().getSerializer(YamlConfiguration.class)
|
||||
.serialize(entry)
|
||||
.saveToString();
|
||||
BentoBox.getInstance().logDebug(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -48,6 +54,7 @@ public class ZNPCsPlusHook extends Hook {
|
||||
NpcLocation loc = new NpcLocation(pos);
|
||||
entry.getNpc().setLocation(loc);
|
||||
NpcApiProvider.get().getNpcRegistry().register(entry);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -56,7 +63,9 @@ public class ZNPCsPlusHook extends Hook {
|
||||
boolean hooked = this.isPluginAvailable();
|
||||
// Check version
|
||||
String version = this.getPlugin().getDescription().getVersion();
|
||||
BentoBox.getInstance().logDebug("ZNPCsPlus version = " + version);
|
||||
if (!Util.isVersionCompatible(version, VERSION)) {
|
||||
return false;
|
||||
}
|
||||
if (!hooked) {
|
||||
BentoBox.getInstance().logError("Could not hook into FancyNpcs");
|
||||
}
|
||||
@ -65,28 +74,30 @@ public class ZNPCsPlusHook extends Hook {
|
||||
|
||||
@Override
|
||||
public String getFailureCause() {
|
||||
return null; // The hook process shouldn't fail
|
||||
// The only failure is wrong version
|
||||
return "ZNPCsPlus version " + VERSION + " required or later. You are running "
|
||||
+ this.getPlugin().getDescription().getVersion();
|
||||
}
|
||||
|
||||
public Map<? extends Vector, ? extends List<BlueprintEntity>> getNpcsInArea(World world, List<Vector> vectorsToCopy,
|
||||
@Nullable Vector origin) {
|
||||
Map<Vector, List<BlueprintEntity>> bpEntities = new HashMap<>();
|
||||
|
||||
for (NpcEntry npc : NpcApiProvider.get().getNpcRegistry().getAll()) {
|
||||
NpcLocation npcLocation = npc.getNpc().getLocation();
|
||||
Vector spot = new Vector(npcLocation.getBlockX(), npcLocation.getBlockY(), npcLocation.getBlockZ());
|
||||
if (npc.getNpc().getWorld().equals(world) && vectorsToCopy.contains(spot)) {
|
||||
for (NpcEntry npcEntry : NpcApiProvider.get().getNpcRegistry().getAll()) {
|
||||
NpcLocation npcLocation = npcEntry.getNpc().getLocation();
|
||||
Vector loc = new Vector(npcLocation.getBlockX(), npcLocation.getBlockY(), npcLocation.getBlockZ());
|
||||
if (npcEntry.getNpc().getWorld().equals(world) && vectorsToCopy.contains(loc)) {
|
||||
// Put the NPC into a BlueprintEntity - serialize it
|
||||
BlueprintEntity cit = new BlueprintEntity();
|
||||
//cit.setType(npc.getNpc().getType());
|
||||
cit.setNpc(this.serializeNPC(npc, origin));
|
||||
// Retrieve or create the list, then add the entity
|
||||
List<BlueprintEntity> entities = bpEntities.getOrDefault(spot, new ArrayList<>());
|
||||
cit.setNpc(this.serializeNPC(npcEntry, origin));
|
||||
// Retrieve or create the list of entities and add this one
|
||||
List<BlueprintEntity> entities = bpEntities.getOrDefault(loc, new ArrayList<>());
|
||||
entities.add(cit);
|
||||
// Create position
|
||||
// Create the position where this entity will be pasted relative to the location
|
||||
Vector origin2 = origin == null ? new Vector(0, 0, 0) : origin;
|
||||
int x = spot.getBlockX() - origin2.getBlockX();
|
||||
int y = spot.getBlockY() - origin2.getBlockY();
|
||||
int z = spot.getBlockZ() - origin2.getBlockZ();
|
||||
int x = loc.getBlockX() - origin2.getBlockX();
|
||||
int y = loc.getBlockY() - origin2.getBlockY();
|
||||
int z = loc.getBlockZ() - origin2.getBlockZ();
|
||||
Vector pos = new Vector(x, y, z);
|
||||
// Store
|
||||
bpEntities.put(pos, entities); // Update the map
|
||||
|
@ -36,6 +36,7 @@ import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity;
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.bentobox.hooks.FancyNpcsHook;
|
||||
import world.bentobox.bentobox.hooks.MythicMobsHook;
|
||||
import world.bentobox.bentobox.hooks.ZNPCsPlusHook;
|
||||
import world.bentobox.bentobox.nms.PasteHandler;
|
||||
|
||||
/**
|
||||
@ -176,8 +177,8 @@ public class DefaultPasteUtil {
|
||||
public static CompletableFuture<Void> setEntity(Island island, Location location, List<BlueprintEntity> list) {
|
||||
World world = location.getWorld();
|
||||
assert world != null;
|
||||
return Util.getChunkAtAsync(location).thenRun(() -> list.stream().filter(k -> k.getType() != null)
|
||||
.forEach(k -> spawnBlueprintEntity(k, location, island)));
|
||||
return Util.getChunkAtAsync(location)
|
||||
.thenRun(() -> list.stream().forEach(k -> spawnBlueprintEntity(k, location, island)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -188,7 +189,7 @@ public class DefaultPasteUtil {
|
||||
* @return true if Bukkit entity spawned, false another plugin entity spawned
|
||||
*/
|
||||
static boolean spawnBlueprintEntity(BlueprintEntity k, Location location, Island island) {
|
||||
// Npc entity
|
||||
// FancyNpc entity
|
||||
if (k.getNpc() != null
|
||||
&& plugin.getHooks().getHook("FancyNpcs").filter(mmh -> mmh instanceof FancyNpcsHook).map(mmh -> {
|
||||
try {
|
||||
@ -201,6 +202,19 @@ public class DefaultPasteUtil {
|
||||
// Npc has spawned.
|
||||
return false;
|
||||
}
|
||||
// ZNPCsPlus
|
||||
if (k.getNpc() != null
|
||||
&& plugin.getHooks().getHook("ZNPCsPlus").filter(mmh -> mmh instanceof ZNPCsPlusHook).map(znpch -> {
|
||||
try {
|
||||
return ((ZNPCsPlusHook) znpch).spawnNpc(k.getNpc(), location);
|
||||
} catch (InvalidConfigurationException e) {
|
||||
plugin.logError("ZNPCsPlus loading failed in blueprint.");
|
||||
return false;
|
||||
}
|
||||
}).orElse(false)) {
|
||||
// Npc has spawned.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Mythic Mobs entity
|
||||
if (k.getMythicMobsRecord() != null && plugin.getHooks().getHook("MythicMobs")
|
||||
@ -210,6 +224,10 @@ public class DefaultPasteUtil {
|
||||
// MythicMob has spawned.
|
||||
return false;
|
||||
}
|
||||
if (k.getType() == null) {
|
||||
// Nothing
|
||||
return false;
|
||||
}
|
||||
LivingEntity e = (LivingEntity) location.getWorld().spawnEntity(location, k.getType());
|
||||
if (k.getCustomName() != null) {
|
||||
String customName = k.getCustomName();
|
||||
|
@ -514,6 +514,54 @@ public class Util {
|
||||
return PaperLib.getMinecraftPatchVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given version is compatible with the required version.
|
||||
*
|
||||
* <p>
|
||||
* A version is considered compatible if:
|
||||
* <ul>
|
||||
* <li>The major, minor, and patch components of the given version are greater than or equal to those of the required version.</li>
|
||||
* <li>If the numeric components are equal, the absence of "-SNAPSHOT" in the given version takes precedence (i.e., release versions are considered more compatible than SNAPSHOT versions).</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* @param version the version to check, in the format "major.minor.patch[-SNAPSHOT]".
|
||||
* @param requiredVersion the required version, in the format "major.minor.patch[-SNAPSHOT]".
|
||||
* @return {@code true} if the given version is compatible with the required version; {@code false} otherwise.
|
||||
*
|
||||
* <p>
|
||||
* Examples:
|
||||
* <ul>
|
||||
* <li>{@code isVersionCompatible("2.1.0", "2.0.0-SNAPSHOT")} returns {@code true}</li>
|
||||
* <li>{@code isVersionCompatible("2.0.0", "2.0.0-SNAPSHOT")} returns {@code true}</li>
|
||||
* <li>{@code isVersionCompatible("2.0.0-SNAPSHOT", "2.0.0")} returns {@code false}</li>
|
||||
* <li>{@code isVersionCompatible("1.9.9", "2.0.0-SNAPSHOT")} returns {@code false}</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public static boolean isVersionCompatible(String version, String requiredVersion) {
|
||||
String[] versionParts = version.replace("-SNAPSHOT", "").split("\\.");
|
||||
String[] requiredVersionParts = requiredVersion.replace("-SNAPSHOT", "").split("\\.");
|
||||
|
||||
for (int i = 0; i < Math.max(versionParts.length, requiredVersionParts.length); i++) {
|
||||
int vPart = i < versionParts.length ? Integer.parseInt(versionParts[i]) : 0;
|
||||
int rPart = i < requiredVersionParts.length ? Integer.parseInt(requiredVersionParts[i]) : 0;
|
||||
|
||||
if (vPart > rPart) {
|
||||
return true;
|
||||
} else if (vPart < rPart) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If numeric parts are equal, prioritize SNAPSHOT as lower precedence
|
||||
boolean isVersionSnapshot = version.contains("-SNAPSHOT");
|
||||
boolean isRequiredSnapshot = requiredVersion.contains("-SNAPSHOT");
|
||||
|
||||
// If required version is a full release but current version is SNAPSHOT, it's incompatible
|
||||
return !(!isRequiredSnapshot && isVersionSnapshot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the server has access to the Spigot API
|
||||
* @return True for Spigot <em>and</em> Paper environments
|
||||
|
@ -24,6 +24,7 @@ softdepend:
|
||||
- LuckPerms
|
||||
- EconomyPlus
|
||||
- MythicMobs
|
||||
- ZNPCsPlus
|
||||
|
||||
libraries:
|
||||
- mysql:mysql-connector-java:${mysql.version}
|
||||
|
Loading…
Reference in New Issue
Block a user