mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2025-01-08 01:17:41 +01:00
Merge pull request #2576 from BentoBoxWorld/2569_general_display_entitiy_support
2569 general display entitiy support
This commit is contained in:
commit
11bd46e32d
7
pom.xml
7
pom.xml
@ -419,6 +419,13 @@
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- FancyHolograms -->
|
||||
<dependency>
|
||||
<groupId>de.oliver</groupId>
|
||||
<artifactId>FancyHolograms</artifactId>
|
||||
<version>2.4.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
41
src/main/java/world/bentobox/bentobox/api/hooks/NPCHook.java
Normal file
41
src/main/java/world/bentobox/bentobox/api/hooks/NPCHook.java
Normal file
@ -0,0 +1,41 @@
|
||||
package world.bentobox.bentobox.api.hooks;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import de.oliver.fancynpcs.api.Npc;
|
||||
import lol.pyr.znpcsplus.api.npc.NpcEntry;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity;
|
||||
|
||||
/**
|
||||
* NPC Hooks
|
||||
* @author tastybento
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public abstract class NPCHook extends Hook {
|
||||
|
||||
protected NPCHook(@NonNull String pluginName, @NonNull Material icon) {
|
||||
super(pluginName, icon);
|
||||
}
|
||||
|
||||
public abstract boolean spawnNpc(String yaml, Location pos) throws InvalidConfigurationException;
|
||||
|
||||
public abstract Map<? extends Vector, ? extends List<BlueprintEntity>> getNpcsInArea(World world,
|
||||
List<Vector> vectorsToCopy, @Nullable Vector origin);
|
||||
|
||||
/**
|
||||
* Remove all NPCs in chunk
|
||||
* @param chunk chunk
|
||||
*/
|
||||
public abstract void removeNPCsInChunk(Chunk chunk);
|
||||
|
||||
}
|
@ -12,25 +12,20 @@ import java.util.Optional;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Banner;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.CreatureSpawner;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.data.Attachable;
|
||||
import org.bukkit.block.sign.Side;
|
||||
import org.bukkit.entity.AbstractHorse;
|
||||
import org.bukkit.entity.Ageable;
|
||||
import org.bukkit.entity.ChestedHorse;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Horse;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.entity.Villager;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.Attachable;
|
||||
import org.bukkit.material.Colorable;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
import org.bukkit.util.Vector;
|
||||
@ -57,6 +52,10 @@ import world.bentobox.bentobox.hooks.ZNPCsPlusHook;
|
||||
*/
|
||||
public class BlueprintClipboard {
|
||||
|
||||
/**
|
||||
* Used to filter out hidden DisplayEntity armor stands when copying
|
||||
*/
|
||||
private static final NamespacedKey KEY = new NamespacedKey(BentoBox.getInstance(), "associatedDisplayEntity");
|
||||
private @Nullable Blueprint blueprint;
|
||||
private @Nullable Location pos1;
|
||||
private @Nullable Location pos2;
|
||||
@ -74,6 +73,7 @@ public class BlueprintClipboard {
|
||||
private Optional<FancyNpcsHook> npc;
|
||||
private Optional<ZNPCsPlusHook> znpc;
|
||||
|
||||
|
||||
/**
|
||||
* Create a clipboard for blueprint
|
||||
* @param blueprint - the blueprint to load into the clipboard
|
||||
@ -148,6 +148,7 @@ 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));
|
||||
}
|
||||
// ZNPCsPlus NPCs
|
||||
if (znpc.isPresent()) {
|
||||
bpEntities.putAll(znpc.get().getNpcsInArea(world, vectorsToCopy, origin));
|
||||
}
|
||||
@ -162,9 +163,9 @@ public class BlueprintClipboard {
|
||||
List<Entity> ents = world.getEntities().stream()
|
||||
.filter(Objects::nonNull)
|
||||
.filter(e -> !(e instanceof Player))
|
||||
.filter(e -> new Vector(Math.rint(e.getLocation().getX()),
|
||||
Math.rint(e.getLocation().getY()),
|
||||
Math.rint(e.getLocation().getZ())).equals(v))
|
||||
.filter(e -> !e.getPersistentDataContainer().has(KEY, PersistentDataType.STRING)) // Do not copy hidden display entities
|
||||
.filter(e -> new Vector(e.getLocation().getBlockX(), e.getLocation().getBlockY(),
|
||||
e.getLocation().getBlockZ()).equals(v))
|
||||
.toList();
|
||||
if (copyBlock(v.toLocation(world), copyAir, copyBiome, ents)) {
|
||||
count++;
|
||||
@ -230,7 +231,6 @@ public class BlueprintClipboard {
|
||||
if (!copyAir && block.getType().equals(Material.AIR) && !ents.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
BlueprintBlock b = bluePrintBlock(pos, block, copyBiome);
|
||||
if (b != null) {
|
||||
this.bpBlocks.put(pos, b);
|
||||
@ -256,7 +256,7 @@ public class BlueprintClipboard {
|
||||
}
|
||||
}
|
||||
// Set block data
|
||||
if (blockState.getData() instanceof Attachable) {
|
||||
if (blockState.getBlockData() instanceof Attachable) {
|
||||
// Placeholder for attachment
|
||||
bpBlocks.put(pos, new BlueprintBlock("minecraft:air"));
|
||||
bpAttachable.put(pos, b);
|
||||
@ -273,7 +273,6 @@ public class BlueprintClipboard {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Chests
|
||||
if (blockState instanceof InventoryHolder ih) {
|
||||
b.setInventory(new HashMap<>());
|
||||
@ -284,11 +283,9 @@ public class BlueprintClipboard {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (blockState instanceof CreatureSpawner spawner) {
|
||||
b.setCreatureSpawner(getSpawner(spawner));
|
||||
}
|
||||
|
||||
// Banners
|
||||
if (blockState instanceof Banner banner) {
|
||||
b.setBannerPatterns(banner.getPatterns());
|
||||
@ -317,62 +314,15 @@ public class BlueprintClipboard {
|
||||
private List<BlueprintEntity> setEntities(List<Entity> ents) {
|
||||
List<BlueprintEntity> bpEnts = new ArrayList<>();
|
||||
for (Entity entity : ents) {
|
||||
BlueprintEntity bpe = new BlueprintEntity();
|
||||
|
||||
bpe.setType(entity.getType());
|
||||
bpe.setCustomName(entity.getCustomName());
|
||||
if (entity instanceof Villager villager) {
|
||||
setVillager(villager, bpe);
|
||||
}
|
||||
if (entity instanceof Colorable c && c.getColor() != null) {
|
||||
bpe.setColor(c.getColor());
|
||||
}
|
||||
if (entity instanceof Tameable tameable) {
|
||||
bpe.setTamed(tameable.isTamed());
|
||||
}
|
||||
if (entity instanceof ChestedHorse chestedHorse) {
|
||||
bpe.setChest(chestedHorse.isCarryingChest());
|
||||
}
|
||||
// Only set if child. Most animals are adults
|
||||
if (entity instanceof Ageable ageable && !ageable.isAdult()) {
|
||||
bpe.setAdult(false);
|
||||
}
|
||||
if (entity instanceof AbstractHorse horse) {
|
||||
bpe.setDomestication(horse.getDomestication());
|
||||
bpe.setInventory(new HashMap<>());
|
||||
for (int i = 0; i < horse.getInventory().getSize(); i++) {
|
||||
ItemStack item = horse.getInventory().getItem(i);
|
||||
if (item != null) {
|
||||
bpe.getInventory().put(i, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entity instanceof Horse horse) {
|
||||
bpe.setStyle(horse.getStyle());
|
||||
}
|
||||
|
||||
BlueprintEntity bpe = new BlueprintEntity(entity);
|
||||
// Mythic mob check
|
||||
mmh.filter(mm -> mm.isMythicMob(entity)).map(mm -> mm.getMythicMob(entity))
|
||||
.ifPresent(bpe::setMythicMobsRecord);
|
||||
|
||||
bpEnts.add(bpe);
|
||||
}
|
||||
return bpEnts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the villager stats
|
||||
* @param v - villager
|
||||
* @param bpe - Blueprint Entity
|
||||
*/
|
||||
private void setVillager(Villager v, BlueprintEntity bpe) {
|
||||
bpe.setExperience(v.getVillagerExperience());
|
||||
bpe.setLevel(v.getVillagerLevel());
|
||||
bpe.setProfession(v.getProfession());
|
||||
bpe.setVillagerType(v.getVillagerType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the origin
|
||||
*/
|
||||
|
@ -0,0 +1,45 @@
|
||||
package world.bentobox.bentobox.blueprints;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Display;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
|
||||
/**
|
||||
* Provides a listener for the Display Objects pasted when a hologram is interacted with
|
||||
* https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/event/player/PlayerInteractAtEntityEvent.html
|
||||
*/
|
||||
public class DisplayListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerInteractEntity(PlayerInteractAtEntityEvent event) {
|
||||
if (event.getRightClicked() instanceof ArmorStand) {
|
||||
ArmorStand armorStand = (ArmorStand) event.getRightClicked();
|
||||
NamespacedKey key = new NamespacedKey(BentoBox.getInstance(), "associatedDisplayEntity");
|
||||
|
||||
if (armorStand.getPersistentDataContainer().has(key, PersistentDataType.STRING)) {
|
||||
String displayEntityUUID = armorStand.getPersistentDataContainer().get(key, PersistentDataType.STRING);
|
||||
|
||||
// Fetch the associated DisplayEntity by UUID
|
||||
World world = armorStand.getWorld();
|
||||
world.getEntitiesByClass(Display.class).stream()
|
||||
.filter(e -> e.getUniqueId().equals(UUID.fromString(displayEntityUUID))).findFirst()
|
||||
.ifPresent(e -> {
|
||||
event.getPlayer().playSound(event.getPlayer().getLocation(), Sound.BLOCK_GLASS_BREAK, 1F,
|
||||
1F);
|
||||
e.remove();
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,78 +1,234 @@
|
||||
package world.bentobox.bentobox.blueprints.dataobjects;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.AbstractHorse;
|
||||
import org.bukkit.entity.Ageable;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.BlockDisplay;
|
||||
import org.bukkit.entity.ChestedHorse;
|
||||
import org.bukkit.entity.Display;
|
||||
import org.bukkit.entity.Display.Billboard;
|
||||
import org.bukkit.entity.Display.Brightness;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Horse;
|
||||
import org.bukkit.entity.Horse.Style;
|
||||
import org.bukkit.entity.ItemDisplay;
|
||||
import org.bukkit.entity.ItemDisplay.ItemDisplayTransform;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.entity.TextDisplay;
|
||||
import org.bukkit.entity.TextDisplay.TextAlignment;
|
||||
import org.bukkit.entity.Villager;
|
||||
import org.bukkit.entity.Villager.Profession;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.Colorable;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.bukkit.util.Transformation;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public class BlueprintEntity {
|
||||
|
||||
// Npc storage
|
||||
@Expose
|
||||
private String npc;
|
||||
|
||||
// MythicMobs storage
|
||||
public record MythicMobRecord(String type, String displayName, double level, float power, String stance) {
|
||||
}
|
||||
|
||||
// GSON can serialize records, but the record class needs to be know in advance. So this breaks out the record entries
|
||||
@Expose
|
||||
String MMtype;
|
||||
@Expose
|
||||
Double MMLevel;
|
||||
@Expose
|
||||
String MMStance;
|
||||
@Expose
|
||||
Float MMpower;
|
||||
/**
|
||||
* Item Display Entity store
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public record ItemDispRec(@Expose ItemStack item, @Expose ItemDisplayTransform itemDispTrans) {}
|
||||
|
||||
@Expose
|
||||
private DyeColor color;
|
||||
@Expose
|
||||
private EntityType type;
|
||||
@Expose
|
||||
private String customName;
|
||||
@Expose
|
||||
private Boolean tamed;
|
||||
@Expose
|
||||
private Boolean chest;
|
||||
/**
|
||||
* Display Entity store
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public record DisplayRec(@Expose Billboard billboard, @Expose Brightness brightness, @Expose float height,
|
||||
@Expose float width, @Expose Color glowColorOverride, @Expose int interpolationDelay,
|
||||
@Expose int interpolationDuration, @Expose float shadowRadius, @Expose float shadowStrength,
|
||||
@Expose int teleportDuration, @Expose Transformation transformation, @Expose float range) {
|
||||
}
|
||||
|
||||
/**
|
||||
* TextDisplay entity store
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public record TextDisplayRec(@Expose String text, @Expose TextAlignment alignment, @Expose Color bgColor,
|
||||
@Expose BlockFace face, @Expose int lWidth, @Expose byte opacity, @Expose boolean isShadowed,
|
||||
@Expose boolean isSeeThrough, @Expose boolean isDefaultBg) {
|
||||
}
|
||||
@Expose
|
||||
private Boolean adult;
|
||||
@Expose
|
||||
public BlueprintBlock blockDisp;
|
||||
|
||||
@Expose
|
||||
private Boolean chest;
|
||||
@Expose
|
||||
private DyeColor color;
|
||||
@Expose
|
||||
private String customName;
|
||||
@Expose
|
||||
public DisplayRec displayRec;
|
||||
@Expose
|
||||
private Integer domestication;
|
||||
@Expose
|
||||
private Map<Integer, ItemStack> inventory;
|
||||
@Expose
|
||||
private Style style;
|
||||
@Expose
|
||||
private Integer level;
|
||||
@Expose
|
||||
private Profession profession;
|
||||
@Expose
|
||||
private Integer experience;
|
||||
@Expose
|
||||
private Map<Integer, ItemStack> inventory;
|
||||
@Expose
|
||||
public ItemDispRec itemDisp;
|
||||
@Expose
|
||||
private Integer level;
|
||||
@Expose
|
||||
Double MMLevel;
|
||||
@Expose
|
||||
Float MMpower;
|
||||
@Expose
|
||||
String MMStance;
|
||||
// GSON can serialize records, but the record class needs to be know in advance. So this breaks out the record entries
|
||||
@Expose
|
||||
String MMtype;
|
||||
// Npc storage
|
||||
@Expose
|
||||
private String npc;
|
||||
@Expose
|
||||
private Profession profession;
|
||||
@Expose
|
||||
private Style style;
|
||||
|
||||
@Expose
|
||||
private Boolean tamed;
|
||||
|
||||
@Expose
|
||||
public TextDisplayRec textDisp;
|
||||
|
||||
@Expose
|
||||
private EntityType type;
|
||||
@Expose
|
||||
private Villager.Type villagerType;
|
||||
// Position within the block
|
||||
@Expose
|
||||
private double x;
|
||||
@Expose
|
||||
private double y;
|
||||
@Expose
|
||||
private double z;
|
||||
@Expose
|
||||
private boolean glowing;
|
||||
@Expose
|
||||
private boolean gravity;
|
||||
@Expose
|
||||
private boolean visualFire;
|
||||
@Expose
|
||||
private boolean silent;
|
||||
@Expose
|
||||
private boolean invulnerable;
|
||||
@Expose
|
||||
private int fireTicks;
|
||||
|
||||
/**
|
||||
* Serializes an entity to a Blueprint Entity
|
||||
* @param entity entity to serialize
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public BlueprintEntity(Entity entity) {
|
||||
this.setType(entity.getType());
|
||||
this.setCustomName(entity.getCustomName());
|
||||
this.setGlowing(entity.isGlowing());
|
||||
this.setGravity(entity.hasGravity());
|
||||
this.setVisualFire(entity.isVisualFire());
|
||||
this.setSilent(entity.isSilent());
|
||||
this.setInvulnerable(entity.isInvulnerable());
|
||||
this.setFireTicks(entity.getFireTicks());
|
||||
|
||||
if (entity instanceof Villager villager) {
|
||||
configVillager(villager);
|
||||
}
|
||||
if (entity instanceof Colorable c && c.getColor() != null) {
|
||||
this.setColor(c.getColor());
|
||||
}
|
||||
if (entity instanceof Tameable tameable) {
|
||||
this.setTamed(tameable.isTamed());
|
||||
}
|
||||
if (entity instanceof ChestedHorse chestedHorse) {
|
||||
this.setChest(chestedHorse.isCarryingChest());
|
||||
}
|
||||
// Only set if child. Most animals are adults
|
||||
if (entity instanceof Ageable ageable && !ageable.isAdult()) {
|
||||
this.setAdult(false);
|
||||
}
|
||||
if (entity instanceof AbstractHorse horse) {
|
||||
this.setDomestication(horse.getDomestication());
|
||||
this.setInventory(new HashMap<>());
|
||||
for (int i = 0; i < horse.getInventory().getSize(); i++) {
|
||||
ItemStack item = horse.getInventory().getItem(i);
|
||||
if (item != null) {
|
||||
this.getInventory().put(i, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entity instanceof Horse horse) {
|
||||
this.setStyle(horse.getStyle());
|
||||
}
|
||||
|
||||
// Display entities
|
||||
if (entity instanceof Display disp) {
|
||||
this.storeDisplay(disp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a blank BlueprintEntity
|
||||
*/
|
||||
public BlueprintEntity() {
|
||||
// Blank constructor
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the villager stats
|
||||
* @param v - villager
|
||||
* @param bpe - Blueprint Entity
|
||||
*/
|
||||
private void configVillager(Villager v) {
|
||||
this.setExperience(v.getVillagerExperience());
|
||||
this.setLevel(v.getVillagerLevel());
|
||||
this.setProfession(v.getProfession());
|
||||
this.setVillagerType(v.getVillagerType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the entity according to how it was stored
|
||||
* @since 1.8.0
|
||||
*/
|
||||
public void configureEntity(Entity e) {
|
||||
// Set the general states
|
||||
e.setGlowing(glowing);
|
||||
e.setGravity(gravity);
|
||||
e.setVisualFire(visualFire);
|
||||
e.setSilent(silent);
|
||||
e.setInvulnerable(invulnerable);
|
||||
e.setFireTicks(fireTicks);
|
||||
|
||||
if (e instanceof Villager villager) {
|
||||
setVillager(villager);
|
||||
}
|
||||
@ -102,78 +258,8 @@ public class BlueprintEntity {
|
||||
if (style != null && e instanceof Horse horse) {
|
||||
horse.setStyle(style);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param v - villager
|
||||
* @since 1.16.0
|
||||
*/
|
||||
private void setVillager(Villager v) {
|
||||
v.setProfession(profession == null ? Profession.NONE : profession);
|
||||
v.setVillagerExperience(experience == null ? 0 : experience);
|
||||
v.setVillagerLevel(level == null ? 0 : level);
|
||||
v.setVillagerType(villagerType == null ? Villager.Type.PLAINS : villagerType);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the color
|
||||
*/
|
||||
public DyeColor getColor() {
|
||||
return color;
|
||||
}
|
||||
/**
|
||||
* @param color the color to set
|
||||
*/
|
||||
public void setColor(DyeColor color) {
|
||||
this.color = color;
|
||||
}
|
||||
/**
|
||||
* @return the type
|
||||
*/
|
||||
public EntityType getType() {
|
||||
return type;
|
||||
}
|
||||
/**
|
||||
* @param type the type to set
|
||||
*/
|
||||
public void setType(EntityType type) {
|
||||
this.type = type;
|
||||
}
|
||||
/**
|
||||
* @return the customName
|
||||
*/
|
||||
public String getCustomName() {
|
||||
return customName;
|
||||
}
|
||||
/**
|
||||
* @param customName the customName to set
|
||||
*/
|
||||
public void setCustomName(String customName) {
|
||||
this.customName = customName;
|
||||
}
|
||||
/**
|
||||
* @return the tamed
|
||||
*/
|
||||
public Boolean getTamed() {
|
||||
return tamed;
|
||||
}
|
||||
/**
|
||||
* @param tamed the tamed to set
|
||||
*/
|
||||
public void setTamed(Boolean tamed) {
|
||||
this.tamed = tamed;
|
||||
}
|
||||
/**
|
||||
* @return the chest
|
||||
*/
|
||||
public Boolean getChest() {
|
||||
return chest;
|
||||
}
|
||||
/**
|
||||
* @param chest the chest to set
|
||||
*/
|
||||
public void setChest(Boolean chest) {
|
||||
this.chest = chest;
|
||||
// Shift to the in-block location (remove the 0.5 that the location serializer used)
|
||||
e.getLocation().add(new Vector(x - 0.5D, y, z - 0.5D));
|
||||
}
|
||||
/**
|
||||
* @return the adult
|
||||
@ -182,10 +268,22 @@ public class BlueprintEntity {
|
||||
return adult;
|
||||
}
|
||||
/**
|
||||
* @param adult the adult to set
|
||||
* @return the chest
|
||||
*/
|
||||
public void setAdult(Boolean adult) {
|
||||
this.adult = adult;
|
||||
public Boolean getChest() {
|
||||
return chest;
|
||||
}
|
||||
/**
|
||||
* @return the color
|
||||
*/
|
||||
public DyeColor getColor() {
|
||||
return color;
|
||||
}
|
||||
/**
|
||||
* @return the customName
|
||||
*/
|
||||
public String getCustomName() {
|
||||
return customName;
|
||||
}
|
||||
/**
|
||||
* @return the domestication
|
||||
@ -194,10 +292,10 @@ public class BlueprintEntity {
|
||||
return domestication;
|
||||
}
|
||||
/**
|
||||
* @param domestication the domestication to set
|
||||
* @return the experience
|
||||
*/
|
||||
public void setDomestication(int domestication) {
|
||||
this.domestication = domestication;
|
||||
public Integer getExperience() {
|
||||
return experience;
|
||||
}
|
||||
/**
|
||||
* @return the inventory
|
||||
@ -206,10 +304,31 @@ public class BlueprintEntity {
|
||||
return inventory;
|
||||
}
|
||||
/**
|
||||
* @param inventory the inventory to set
|
||||
* @return the level
|
||||
*/
|
||||
public void setInventory(Map<Integer, ItemStack> inventory) {
|
||||
this.inventory = inventory;
|
||||
public Integer getLevel() {
|
||||
return level;
|
||||
}
|
||||
/**
|
||||
* @return the mythicMobsRecord
|
||||
*/
|
||||
public MythicMobRecord getMythicMobsRecord() {
|
||||
if (this.MMtype == null || this.MMLevel == null || this.MMpower == null || this.MMStance == null) {
|
||||
return null;
|
||||
}
|
||||
return new MythicMobRecord(this.MMtype, this.getCustomName(), this.MMLevel, this.MMpower, this.MMStance);
|
||||
}
|
||||
/**
|
||||
* @return the npc
|
||||
*/
|
||||
public String getNpc() {
|
||||
return npc;
|
||||
}
|
||||
/**
|
||||
* @return the profession
|
||||
*/
|
||||
public Profession getProfession() {
|
||||
return profession;
|
||||
}
|
||||
/**
|
||||
* @return the style
|
||||
@ -217,53 +336,19 @@ public class BlueprintEntity {
|
||||
public Style getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param style the style to set
|
||||
* @return the tamed
|
||||
*/
|
||||
public void setStyle(Style style) {
|
||||
this.style = style;
|
||||
public Boolean getTamed() {
|
||||
return tamed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the level
|
||||
* @return the type
|
||||
*/
|
||||
public Integer getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param level the level to set
|
||||
*/
|
||||
public void setLevel(Integer level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the profession
|
||||
*/
|
||||
public Profession getProfession() {
|
||||
return profession;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param profession the profession to set
|
||||
*/
|
||||
public void setProfession(Profession profession) {
|
||||
this.profession = profession;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the experience
|
||||
*/
|
||||
public Integer getExperience() {
|
||||
return experience;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param experience the experience to set
|
||||
*/
|
||||
public void setExperience(Integer experience) {
|
||||
this.experience = experience;
|
||||
public EntityType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -274,10 +359,93 @@ public class BlueprintEntity {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param villagerType the villagerType to set
|
||||
* @param adult the adult to set
|
||||
*/
|
||||
public void setVillagerType(Villager.Type villagerType) {
|
||||
this.villagerType = villagerType;
|
||||
public void setAdult(Boolean adult) {
|
||||
this.adult = adult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param chest the chest to set
|
||||
*/
|
||||
public void setChest(Boolean chest) {
|
||||
this.chest = chest;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param color the color to set
|
||||
*/
|
||||
public void setColor(DyeColor color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param customName the customName to set
|
||||
*/
|
||||
public void setCustomName(String customName) {
|
||||
this.customName = customName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets any display entity properties to the location, e.g. holograms
|
||||
* @param pos location
|
||||
*/
|
||||
public void setDisplay(Location pos) {
|
||||
World world = pos.getWorld();
|
||||
Location newPos = pos.clone().add(new Vector(x - 0.5D, y, z - 0.5D));
|
||||
Display d = null;
|
||||
if (this.blockDisp != null) {
|
||||
// Block Display
|
||||
d = world.spawn(newPos, BlockDisplay.class);
|
||||
BlockData bd = Bukkit.createBlockData(this.blockDisp.getBlockData());
|
||||
((BlockDisplay) d).setBlock(bd);
|
||||
} else if (this.itemDisp != null) {
|
||||
// Item Display
|
||||
d = world.spawn(newPos, ItemDisplay.class);
|
||||
((ItemDisplay) d).setItemStack(itemDisp.item());
|
||||
((ItemDisplay) d).setItemDisplayTransform(itemDisp.itemDispTrans());
|
||||
} else if (this.textDisp != null) {
|
||||
// Text Display
|
||||
d = world.spawn(newPos, TextDisplay.class);
|
||||
((TextDisplay) d).setText(textDisp.text());
|
||||
((TextDisplay) d).setAlignment(textDisp.alignment());
|
||||
((TextDisplay) d).setBackgroundColor(textDisp.bgColor());
|
||||
((TextDisplay) d).setLineWidth(textDisp.lWidth());
|
||||
((TextDisplay) d).setTextOpacity(textDisp.opacity());
|
||||
((TextDisplay) d).setShadowed(textDisp.isShadowed());
|
||||
((TextDisplay) d).setSeeThrough(textDisp.isSeeThrough());
|
||||
((TextDisplay) d).setBackgroundColor(textDisp.bgColor());
|
||||
}
|
||||
if (d != null && this.displayRec != null) {
|
||||
d.setCustomName(getCustomName());
|
||||
d.setBillboard(displayRec.billboard());
|
||||
d.setBrightness(displayRec.brightness());
|
||||
d.setDisplayHeight(displayRec.height());
|
||||
d.setDisplayWidth(displayRec.width());
|
||||
d.setGlowColorOverride(displayRec.glowColorOverride());
|
||||
d.setInterpolationDelay(displayRec.interpolationDelay());
|
||||
d.setInterpolationDuration(displayRec.interpolationDuration());
|
||||
d.setShadowRadius(displayRec.shadowRadius());
|
||||
d.setShadowStrength(displayRec.shadowStrength());
|
||||
d.setTeleportDuration(displayRec.teleportDuration());
|
||||
d.setTransformation(displayRec.transformation());
|
||||
d.setViewRange(displayRec.range());
|
||||
|
||||
// Spawn an armor stand here so that we have a way to detect if a player interacts with the item
|
||||
ArmorStand armorStand = (ArmorStand) world.spawnEntity(newPos, EntityType.ARMOR_STAND);
|
||||
armorStand.setSmall(true); // Reduces size
|
||||
armorStand.setGravity(false); // Prevents falling
|
||||
armorStand.setInvisible(true);
|
||||
NamespacedKey key = new NamespacedKey(BentoBox.getInstance(), "associatedDisplayEntity");
|
||||
armorStand.getPersistentDataContainer().set(key, PersistentDataType.STRING, d.getUniqueId().toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param domestication the domestication to set
|
||||
*/
|
||||
public void setDomestication(int domestication) {
|
||||
this.domestication = domestication;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -288,13 +456,24 @@ public class BlueprintEntity {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the mythicMobsRecord
|
||||
* @param experience the experience to set
|
||||
*/
|
||||
public MythicMobRecord getMythicMobsRecord() {
|
||||
if (this.MMtype == null || this.MMLevel == null || this.MMpower == null || this.MMStance == null) {
|
||||
return null;
|
||||
}
|
||||
return new MythicMobRecord(this.MMtype, this.getCustomName(), this.MMLevel, this.MMpower, this.MMStance);
|
||||
public void setExperience(Integer experience) {
|
||||
this.experience = experience;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param inventory the inventory to set
|
||||
*/
|
||||
public void setInventory(Map<Integer, ItemStack> inventory) {
|
||||
this.inventory = inventory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param level the level to set
|
||||
*/
|
||||
public void setLevel(Integer level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -308,38 +487,164 @@ public class BlueprintEntity {
|
||||
this.MMStance = mmr.stance();
|
||||
this.MMpower = mmr.power();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the npc
|
||||
* @param npc the citizen to set
|
||||
*/
|
||||
public String getNpc() {
|
||||
return npc;
|
||||
public void setNpc(String npc) {
|
||||
this.npc = npc;
|
||||
}
|
||||
/**
|
||||
* @param profession the profession to set
|
||||
*/
|
||||
public void setProfession(Profession profession) {
|
||||
this.profession = profession;
|
||||
}
|
||||
/**
|
||||
* @param style the style to set
|
||||
*/
|
||||
public void setStyle(Style style) {
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param citizen the citizen to set
|
||||
* @param tamed the tamed to set
|
||||
*/
|
||||
public void setNpc(String citizen) {
|
||||
this.npc = citizen;
|
||||
public void setTamed(Boolean tamed) {
|
||||
this.tamed = tamed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BlueprintEntity [" + (npc != null ? "npc=" + npc + ", " : "")
|
||||
+ (MMtype != null ? "MMtype=" + MMtype + ", " : "")
|
||||
+ (MMLevel != null ? "MMLevel=" + MMLevel + ", " : "")
|
||||
+ (MMStance != null ? "MMStance=" + MMStance + ", " : "")
|
||||
+ (MMpower != null ? "MMpower=" + MMpower + ", " : "") + (color != null ? "color=" + color + ", " : "")
|
||||
+ (type != null ? "type=" + type + ", " : "")
|
||||
+ (customName != null ? "customName=" + customName + ", " : "")
|
||||
+ (tamed != null ? "tamed=" + tamed + ", " : "") + (chest != null ? "chest=" + chest + ", " : "")
|
||||
+ (adult != null ? "adult=" + adult + ", " : "")
|
||||
+ (domestication != null ? "domestication=" + domestication + ", " : "")
|
||||
+ (inventory != null ? "inventory=" + inventory + ", " : "")
|
||||
+ (style != null ? "style=" + style + ", " : "") + (level != null ? "level=" + level + ", " : "")
|
||||
+ (profession != null ? "profession=" + profession + ", " : "")
|
||||
+ (experience != null ? "experience=" + experience + ", " : "")
|
||||
+ (villagerType != null ? "villagerType=" + villagerType : "") + "]";
|
||||
/**
|
||||
* @param type the type to set
|
||||
*/
|
||||
public void setType(EntityType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param v - villager
|
||||
* @since 1.16.0
|
||||
*/
|
||||
private void setVillager(Villager v) {
|
||||
v.setProfession(profession == null ? Profession.NONE : profession);
|
||||
v.setVillagerExperience(experience == null ? 0 : experience);
|
||||
v.setVillagerLevel(level == null ? 0 : level);
|
||||
v.setVillagerType(villagerType == null ? Villager.Type.PLAINS : villagerType);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param villagerType the villagerType to set
|
||||
*/
|
||||
public void setVillagerType(Villager.Type villagerType) {
|
||||
this.villagerType = villagerType;
|
||||
}
|
||||
|
||||
/**
|
||||
* BlockDisplay, ItemDisplay, TextDisplay
|
||||
* @param disp display entity
|
||||
*/
|
||||
public void storeDisplay(Display disp) {
|
||||
// Generic items
|
||||
displayRec = new DisplayRec(disp.getBillboard(), disp.getBrightness(), disp.getDisplayHeight(),
|
||||
disp.getDisplayWidth(), disp.getGlowColorOverride(), disp.getInterpolationDelay(),
|
||||
disp.getInterpolationDuration(), disp.getShadowRadius(), disp.getShadowStrength(),
|
||||
disp.getTeleportDuration(), disp.getTransformation(), disp.getViewRange());
|
||||
// Class specific items
|
||||
if (disp instanceof BlockDisplay bd) {
|
||||
this.blockDisp = new BlueprintBlock(bd.getBlock().getAsString());
|
||||
} else if (disp instanceof ItemDisplay id) {
|
||||
itemDisp = new ItemDispRec(id.getItemStack(), id.getItemDisplayTransform());
|
||||
} else if (disp instanceof TextDisplay td) {
|
||||
textDisp = new TextDisplayRec(td.getText(), td.getAlignment(), td.getBackgroundColor(),
|
||||
td.getFacing(), td.getLineWidth(), td.getTextOpacity(), td.isShadowed(), td.isSeeThrough(),
|
||||
td.isDefaultBackground());
|
||||
}
|
||||
// Store location within block
|
||||
x = disp.getLocation().getX() - disp.getLocation().getBlockX();
|
||||
y = disp.getLocation().getY() - disp.getLocation().getBlockY();
|
||||
z = disp.getLocation().getZ() - disp.getLocation().getBlockZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the glowing
|
||||
*/
|
||||
public boolean isGlowing() {
|
||||
return glowing;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param glowing the glowing to set
|
||||
*/
|
||||
public void setGlowing(boolean glowing) {
|
||||
this.glowing = glowing;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the gravity
|
||||
*/
|
||||
public boolean isGravity() {
|
||||
return gravity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param gravity the gravity to set
|
||||
*/
|
||||
public void setGravity(boolean gravity) {
|
||||
this.gravity = gravity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the visualFire
|
||||
*/
|
||||
public boolean isVisualFire() {
|
||||
return visualFire;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param visualFire the visualFire to set
|
||||
*/
|
||||
public void setVisualFire(boolean visualFire) {
|
||||
this.visualFire = visualFire;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the silent
|
||||
*/
|
||||
public boolean isSilent() {
|
||||
return silent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param silent the silent to set
|
||||
*/
|
||||
public void setSilent(boolean silent) {
|
||||
this.silent = silent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the invulnerable
|
||||
*/
|
||||
public boolean isInvulnerable() {
|
||||
return invulnerable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param invulnerable the invulnerable to set
|
||||
*/
|
||||
public void setInvulnerable(boolean invulnerable) {
|
||||
this.invulnerable = invulnerable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the fireTicks
|
||||
*/
|
||||
public int getFireTicks() {
|
||||
return fireTicks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fireTicks the fireTicks to set
|
||||
*/
|
||||
public void setFireTicks(int fireTicks) {
|
||||
this.fireTicks = fireTicks;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import com.google.gson.stream.JsonWriter;
|
||||
|
||||
/**
|
||||
* Minecraft 1.20 changed GRASS to SHORT_GRASS. This class provides and backwards compatibility when loading
|
||||
* databased files stored with previous versions. It can be extended in the future if further enum changes are made.
|
||||
* database files stored with previous versions. It can be extended in the future if further enum changes are made.
|
||||
* @author tastybento
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
@ -10,6 +10,7 @@ import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
@ -29,9 +30,10 @@ import de.oliver.fancynpcs.api.actions.ActionTrigger;
|
||||
import de.oliver.fancynpcs.api.actions.NpcAction;
|
||||
import de.oliver.fancynpcs.api.utils.NpcEquipmentSlot;
|
||||
import de.oliver.fancynpcs.api.utils.SkinFetcher;
|
||||
import lol.pyr.znpcsplus.api.npc.NpcEntry;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.hooks.Hook;
|
||||
import world.bentobox.bentobox.api.hooks.NPCHook;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity;
|
||||
|
||||
/**
|
||||
@ -40,13 +42,13 @@ import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity;
|
||||
* @author tastybento
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public class FancyNpcsHook extends Hook {
|
||||
public class FancyNpcsHook extends NPCHook {
|
||||
|
||||
public FancyNpcsHook() {
|
||||
super("FancyNpcs", Material.PLAYER_HEAD);
|
||||
}
|
||||
|
||||
public String serializeNPC(Npc npc, Vector origin) {
|
||||
String serializeNPC(Npc npc, Vector origin) {
|
||||
if (npc == null) {
|
||||
throw new IllegalArgumentException("NPC cannot be null.");
|
||||
}
|
||||
@ -265,6 +267,26 @@ public class FancyNpcsHook extends Hook {
|
||||
return null; // The hook process shouldn't fail
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all NPCs in the chunk
|
||||
* @param chunk chunk
|
||||
* @return list of NPCs
|
||||
*/
|
||||
public List<Npc> getNPCsInChunk(Chunk chunk) {
|
||||
return FancyNpcsPlugin.get().getNpcManager().getAllNpcs().stream()
|
||||
.filter(npc -> npc.getData().getLocation().getChunk().equals(chunk)).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all NPCs in chunk
|
||||
* @param chunk chunk
|
||||
*/
|
||||
@Override
|
||||
public void removeNPCsInChunk(Chunk chunk) {
|
||||
getNPCsInChunk(chunk).forEach(npc -> npc.removeForAll());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<? extends Vector, ? extends List<BlueprintEntity>> getNpcsInArea(World world, List<Vector> vectorsToCopy,
|
||||
@Nullable Vector origin) {
|
||||
Map<Vector, List<BlueprintEntity>> bpEntities = new HashMap<>();
|
||||
@ -290,4 +312,5 @@ public class FancyNpcsHook extends Hook {
|
||||
}
|
||||
return bpEntities;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
@ -17,7 +18,7 @@ import lol.pyr.znpcsplus.api.NpcApiProvider;
|
||||
import lol.pyr.znpcsplus.api.npc.NpcEntry;
|
||||
import lol.pyr.znpcsplus.util.NpcLocation;
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.hooks.Hook;
|
||||
import world.bentobox.bentobox.api.hooks.NPCHook;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
|
||||
@ -27,7 +28,7 @@ import world.bentobox.bentobox.util.Util;
|
||||
* @author tastybento
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public class ZNPCsPlusHook extends Hook {
|
||||
public class ZNPCsPlusHook extends NPCHook {
|
||||
|
||||
private static final String VERSION = "2.0.0-SNAPSHOT"; // Minimum version required
|
||||
|
||||
@ -35,13 +36,20 @@ public class ZNPCsPlusHook extends Hook {
|
||||
super("ZNPCsPlus", Material.PLAYER_HEAD);
|
||||
}
|
||||
|
||||
public String serializeNPC(NpcEntry entry, Vector origin) {
|
||||
/**
|
||||
* Serialize a NpcEntry
|
||||
* @param entry NPC entry
|
||||
* @param origin origin point of blueprint
|
||||
* @return string serializing the NPC Entry
|
||||
*/
|
||||
String serializeNPC(NpcEntry entry, Vector origin) {
|
||||
String result = NpcApiProvider.get().getNpcSerializerRegistry().getSerializer(YamlConfiguration.class)
|
||||
.serialize(entry)
|
||||
.saveToString();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean spawnNpc(String yaml, Location pos) throws InvalidConfigurationException {
|
||||
YamlConfiguration yaml2 = new YamlConfiguration();
|
||||
yaml2.loadFromString(yaml);
|
||||
@ -75,6 +83,7 @@ public class ZNPCsPlusHook extends Hook {
|
||||
+ this.getPlugin().getDescription().getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<? extends Vector, ? extends List<BlueprintEntity>> getNpcsInArea(World world, List<Vector> vectorsToCopy,
|
||||
@Nullable Vector origin) {
|
||||
Map<Vector, List<BlueprintEntity>> bpEntities = new HashMap<>();
|
||||
@ -101,4 +110,23 @@ public class ZNPCsPlusHook extends Hook {
|
||||
}
|
||||
return bpEntities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all the NPC IDs in this chunk
|
||||
* @param chunk chunk
|
||||
* @return list of NPC IDs
|
||||
*/
|
||||
public List<String> getNPCsInChunk(Chunk chunk) {
|
||||
return NpcApiProvider.get().getNpcRegistry().getAll().stream()
|
||||
.filter(npc -> npc.getNpc().getWorld().equals(chunk.getWorld())) // Only NPCs in this world
|
||||
.filter(npc -> npc.getNpc().getLocation().toBukkitLocation(chunk.getWorld()).getChunk().equals(chunk)) // Only in this chunk
|
||||
.map(npc -> npc.getId()) // IDs
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNPCsInChunk(Chunk chunk) {
|
||||
getNPCsInChunk(chunk).forEach(NpcApiProvider.get().getNpcRegistry()::delete);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ import world.bentobox.bentobox.api.metadata.MetaDataValue;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.Blueprint;
|
||||
import world.bentobox.bentobox.blueprints.BlueprintPaster;
|
||||
import world.bentobox.bentobox.blueprints.DisplayListener;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBlock;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle;
|
||||
import world.bentobox.bentobox.database.json.BentoboxTypeAdapterFactory;
|
||||
@ -113,6 +114,8 @@ public class BlueprintsManager {
|
||||
gson = builder.create();
|
||||
// Loaded tracker
|
||||
blueprintsLoaded = new HashSet<>();
|
||||
// Register Display listeners
|
||||
Bukkit.getPluginManager().registerEvents(new DisplayListener(), plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,8 +43,10 @@ import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.addons.GameModeAddon;
|
||||
import world.bentobox.bentobox.api.hooks.Hook;
|
||||
import world.bentobox.bentobox.database.objects.IslandDeletion;
|
||||
import world.bentobox.bentobox.hooks.FancyNpcsHook;
|
||||
import world.bentobox.bentobox.hooks.ItemsAdderHook;
|
||||
import world.bentobox.bentobox.hooks.SlimefunHook;
|
||||
import world.bentobox.bentobox.hooks.ZNPCsPlusHook;
|
||||
import world.bentobox.bentobox.util.MyBiomeGrid;
|
||||
|
||||
/**
|
||||
@ -56,9 +58,18 @@ import world.bentobox.bentobox.util.MyBiomeGrid;
|
||||
public abstract class CopyWorldRegenerator implements WorldRegenerator {
|
||||
|
||||
private final BentoBox plugin;
|
||||
private Optional<FancyNpcsHook> npc;
|
||||
private Optional<ZNPCsPlusHook> znpc;
|
||||
|
||||
protected CopyWorldRegenerator() {
|
||||
this.plugin = BentoBox.getInstance();
|
||||
// Fancy NPCs Hook
|
||||
npc = plugin.getHooks().getHook("FancyNpcs").filter(FancyNpcsHook.class::isInstance)
|
||||
.map(FancyNpcsHook.class::cast);
|
||||
// ZNPCs Plus Hook
|
||||
znpc = plugin.getHooks().getHook("ZNPCsPlus").filter(ZNPCsPlusHook.class::isInstance)
|
||||
.map(ZNPCsPlusHook.class::cast);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -179,11 +190,20 @@ public abstract class CopyWorldRegenerator implements WorldRegenerator {
|
||||
);
|
||||
|
||||
// Similarly, when the chunk is loaded, remove all the entities in the chunk apart from players
|
||||
CompletableFuture<Void> entitiesFuture = chunkFuture.thenAccept(chunk ->
|
||||
// Remove all entities in chunk, including any dropped items as a result of clearing the blocks above
|
||||
Arrays.stream(chunk.getEntities())
|
||||
.filter(e -> !(e instanceof Player) && di.inBounds(e.getLocation().getBlockX(), e.getLocation().getBlockZ()))
|
||||
.forEach(Entity::remove));
|
||||
CompletableFuture<Void> entitiesFuture = chunkFuture.thenAccept(chunk -> {
|
||||
// Remove all entities in chunk, including any dropped items as a result of clearing the blocks above
|
||||
Arrays.stream(chunk.getEntities())
|
||||
.filter(e -> !(e instanceof Player)
|
||||
&& di.inBounds(e.getLocation().getBlockX(), e.getLocation().getBlockZ()))
|
||||
.forEach(Entity::remove);
|
||||
// Remove any NPCs
|
||||
// Fancy NPCs Hook
|
||||
npc.ifPresent(hook -> hook.removeNPCsInChunk(chunk));
|
||||
// ZNPCs Plus Hook
|
||||
znpc.ifPresent(hook -> hook.removeNPCsInChunk(chunk));
|
||||
|
||||
});
|
||||
|
||||
return CompletableFuture.allOf(invFuture, entitiesFuture);
|
||||
}
|
||||
|
||||
@ -310,6 +330,10 @@ public abstract class CopyWorldRegenerator implements WorldRegenerator {
|
||||
|
||||
public CompletableFuture<Void> regenerateSimple(GameModeAddon gm, IslandDeletion di, World world) {
|
||||
CompletableFuture<Void> bigFuture = new CompletableFuture<>();
|
||||
if (world == null) {
|
||||
bigFuture.complete(null);
|
||||
return bigFuture;
|
||||
}
|
||||
new BukkitRunnable() {
|
||||
private int chunkX = di.getMinXChunk();
|
||||
private int chunkZ = di.getMinZChunk();
|
||||
|
@ -189,6 +189,8 @@ public class DefaultPasteUtil {
|
||||
* @return true if Bukkit entity spawned, false another plugin entity spawned
|
||||
*/
|
||||
static boolean spawnBlueprintEntity(BlueprintEntity k, Location location, Island island) {
|
||||
// Display Entity (holograms, etc.)
|
||||
k.setDisplay(location);
|
||||
// FancyNpc entity
|
||||
if (k.getNpc() != null
|
||||
&& plugin.getHooks().getHook("FancyNpcs").filter(mmh -> mmh instanceof FancyNpcsHook).map(mmh -> {
|
||||
|
@ -25,6 +25,8 @@ softdepend:
|
||||
- EconomyPlus
|
||||
- MythicMobs
|
||||
- ZNPCsPlus
|
||||
- FancyNpcs
|
||||
- FancyHolograms
|
||||
|
||||
libraries:
|
||||
- mysql:mysql-connector-java:${mysql.version}
|
||||
|
@ -47,13 +47,15 @@ import world.bentobox.bentobox.managers.LocalesManager;
|
||||
@PrepareForTest({Bukkit.class, BentoBox.class, User.class })
|
||||
public class AdminBlueprintCopyCommandTest {
|
||||
|
||||
@Mock
|
||||
private BentoBox plugin;
|
||||
@Mock
|
||||
private AdminBlueprintCommand ac;
|
||||
@Mock
|
||||
private GameModeAddon addon;
|
||||
@Mock
|
||||
private User user;
|
||||
@Mock
|
||||
|
||||
private BlueprintClipboard clip;
|
||||
private UUID uuid = UUID.randomUUID();
|
||||
@Mock
|
||||
@ -64,10 +66,12 @@ public class AdminBlueprintCopyCommandTest {
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
// Set up plugin
|
||||
BentoBox plugin = mock(BentoBox.class);
|
||||
// Set up plugin // Set up plugin
|
||||
// Required for NamespacedKey
|
||||
when(plugin.getName()).thenReturn("BentoBox");
|
||||
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
|
||||
|
||||
clip = mock(BlueprintClipboard.class);
|
||||
// Blueprints Manager
|
||||
when(plugin.getBlueprintsManager()).thenReturn(bm);
|
||||
|
||||
|
@ -76,6 +76,8 @@ public class AdminBlueprintLoadCommandTest {
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
// Required for NamespacedKey
|
||||
when(plugin.getName()).thenReturn("BentoBox");
|
||||
// Set up plugin
|
||||
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
|
||||
|
||||
|
@ -55,6 +55,8 @@ import world.bentobox.bentobox.mocks.ServerMocks;
|
||||
@PrepareForTest({Bukkit.class, BentoBox.class, User.class })
|
||||
public class AdminBlueprintSaveCommandTest {
|
||||
|
||||
@Mock
|
||||
private BentoBox plugin;
|
||||
private AdminBlueprintSaveCommand absc;
|
||||
@Mock
|
||||
private AdminBlueprintCommand ac;
|
||||
@ -76,8 +78,8 @@ public class AdminBlueprintSaveCommandTest {
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
// Set up plugin
|
||||
BentoBox plugin = mock(BentoBox.class);
|
||||
// Required for NamespacedKey
|
||||
when(plugin.getName()).thenReturn("BentoBox");
|
||||
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
|
||||
// Hooks
|
||||
HooksManager hooksManager = mock(HooksManager.class);
|
||||
|
@ -58,6 +58,8 @@ public class BlueprintClipboardTest {
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
// Required for NamespacedKey
|
||||
when(plugin.getName()).thenReturn("BentoBox");
|
||||
// Set up plugin
|
||||
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
|
||||
// Hooks
|
||||
|
@ -57,7 +57,7 @@ public class BlueprintClipboardManagerTest {
|
||||
|
||||
@Mock
|
||||
private BentoBox plugin;
|
||||
@Mock
|
||||
|
||||
private BlueprintClipboard clipboard;
|
||||
|
||||
private File blueprintFolder;
|
||||
@ -129,15 +129,19 @@ public class BlueprintClipboardManagerTest {
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
// Set up plugin
|
||||
// Required for NamespacedKey
|
||||
when(plugin.getName()).thenReturn("BentoBox");
|
||||
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
|
||||
|
||||
clipboard = mock(BlueprintClipboard.class);
|
||||
|
||||
server = ServerMocks.newServer();
|
||||
PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
|
||||
|
||||
blueprintFolder = new File("blueprints");
|
||||
// Clear any residual files
|
||||
tearDown();
|
||||
// Set up plugin
|
||||
BentoBox plugin = mock(BentoBox.class);
|
||||
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
|
||||
// Hooks
|
||||
HooksManager hooksManager = mock(HooksManager.class);
|
||||
when(hooksManager.getHook(anyString())).thenReturn(Optional.empty());
|
||||
|
Loading…
Reference in New Issue
Block a user