diff --git a/pom.xml b/pom.xml
index 997ff27cc..6169abb16 100644
--- a/pom.xml
+++ b/pom.xml
@@ -189,6 +189,12 @@
MG-Dev Jenkins CI Maven Repository
https://ci.mg-dev.eu/plugin/repository/everything
+
+
+ nexus
+ Lumine Releases
+ https://mvn.lumine.io/repository/maven-public/
+
@@ -297,6 +303,12 @@
${myworlds.version}
provided
+
+ io.lumine
+ Mythic-Dist
+ 5.3.5
+ provided
+
com.github.TheBusyBiscuit
diff --git a/src/main/java/world/bentobox/bentobox/BentoBox.java b/src/main/java/world/bentobox/bentobox/BentoBox.java
index 1ee3cfb1e..235d37ef6 100644
--- a/src/main/java/world/bentobox/bentobox/BentoBox.java
+++ b/src/main/java/world/bentobox/bentobox/BentoBox.java
@@ -27,6 +27,7 @@ import world.bentobox.bentobox.database.DatabaseSetup;
import world.bentobox.bentobox.hooks.ItemsAdderHook;
import world.bentobox.bentobox.hooks.MultiverseCoreHook;
import world.bentobox.bentobox.hooks.MyWorldsHook;
+import world.bentobox.bentobox.hooks.MythicMobsHook;
import world.bentobox.bentobox.hooks.SlimefunHook;
import world.bentobox.bentobox.hooks.VaultHook;
import world.bentobox.bentobox.hooks.placeholders.PlaceholderAPIHook;
@@ -185,6 +186,9 @@ public class BentoBox extends JavaPlugin implements Listener {
final long enableStart = System.currentTimeMillis();
hooksManager.registerHook(new VaultHook());
+ // MythicMobs
+ hooksManager.registerHook(new MythicMobsHook());
+
hooksManager.registerHook(new PlaceholderAPIHook());
// Setup the Placeholders manager
placeholdersManager = new PlaceholdersManager(this);
diff --git a/src/main/java/world/bentobox/bentobox/blueprints/BlueprintClipboard.java b/src/main/java/world/bentobox/bentobox/blueprints/BlueprintClipboard.java
index a47f79571..048bfeec4 100644
--- a/src/main/java/world/bentobox/bentobox/blueprints/BlueprintClipboard.java
+++ b/src/main/java/world/bentobox/bentobox/blueprints/BlueprintClipboard.java
@@ -8,6 +8,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@@ -43,6 +44,7 @@ import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBlock;
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintCreatureSpawner;
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity;
+import world.bentobox.bentobox.hooks.MythicMobsHook;
/**
* The clipboard provides the holding spot for an active blueprint that is being
@@ -67,6 +69,7 @@ public class BlueprintClipboard {
private final Map bpAttachable = new LinkedHashMap<>();
private final Map bpBlocks = new LinkedHashMap<>();
private final BentoBox plugin = BentoBox.getInstance();
+ private Optional mmh;
/**
* Create a clipboard for blueprint
@@ -74,9 +77,16 @@ public class BlueprintClipboard {
*/
public BlueprintClipboard(@NonNull Blueprint blueprint) {
this.blueprint = blueprint;
+ // MythicMobs
+ mmh = plugin.getHooks().getHook("MythicMobs").filter(hook -> hook instanceof MythicMobsHook)
+ .map(h -> (MythicMobsHook) h);
}
- public BlueprintClipboard() { }
+ public BlueprintClipboard() {
+ // MythicMobs
+ mmh = plugin.getHooks().getHook("MythicMobs").filter(hook -> hook instanceof MythicMobsHook)
+ .map(h -> (MythicMobsHook) h);
+ }
/**
* Copy the blocks between pos1 and pos2 into the clipboard for a user.
@@ -285,6 +295,7 @@ public class BlueprintClipboard {
List bpEnts = new ArrayList<>();
for (LivingEntity entity: entities) {
BlueprintEntity bpe = new BlueprintEntity();
+
bpe.setType(entity.getType());
bpe.setCustomName(entity.getCustomName());
if (entity instanceof Villager villager) {
@@ -317,6 +328,10 @@ public class BlueprintClipboard {
if (entity instanceof Horse horse) {
bpe.setStyle(horse.getStyle());
}
+
+ mmh.filter(mm -> mm.isMythicMob(entity)).map(mm -> mm.getMythicMob(entity))
+ .ifPresent(mmr -> bpe.setMythicMobsRecord(mmr));
+
bpEnts.add(bpe);
}
return bpEnts;
diff --git a/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintEntity.java b/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintEntity.java
index a06c11932..bc8f72ae3 100644
--- a/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintEntity.java
+++ b/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintEntity.java
@@ -24,6 +24,19 @@ import com.google.gson.annotations.Expose;
*/
public class BlueprintEntity {
+ 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;
+
@Expose
private DyeColor color;
@Expose
@@ -50,7 +63,6 @@ public class BlueprintEntity {
private Integer experience;
@Expose
private Villager.Type villagerType;
-
/**
* @since 1.8.0
@@ -85,7 +97,6 @@ public class BlueprintEntity {
if (style != null && e instanceof Horse horse) {
horse.setStyle(style);
}
-
}
/**
@@ -270,5 +281,24 @@ public class BlueprintEntity {
public void setDomestication(Integer domestication) {
this.domestication = domestication;
}
+
+ /**
+ * @return the mythicMobsRecord
+ */
+ public MythicMobRecord getMythicMobsRecord() {
+ return new MythicMobRecord(this.MMtype, this.getCustomName(), this.MMLevel, this.MMpower, this.MMStance);
+ }
+
+ /**
+ * @param mythicMobsRecord the mythicMobsRecord to set
+ * @since 2.1.0
+ */
+ public void setMythicMobsRecord(MythicMobRecord mmr) {
+ this.setCustomName(mmr.displayName());
+ this.MMtype = mmr.type();
+ this.MMLevel = mmr.level();
+ this.MMStance = mmr.stance();
+ this.MMpower = mmr.power();
+ }
}
diff --git a/src/main/java/world/bentobox/bentobox/hooks/MythicMobsHook.java b/src/main/java/world/bentobox/bentobox/hooks/MythicMobsHook.java
new file mode 100644
index 000000000..5db726a27
--- /dev/null
+++ b/src/main/java/world/bentobox/bentobox/hooks/MythicMobsHook.java
@@ -0,0 +1,70 @@
+package world.bentobox.bentobox.hooks;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.entity.Entity;
+
+import io.lumine.mythic.bukkit.BukkitAdapter;
+import io.lumine.mythic.bukkit.MythicBukkit;
+import io.lumine.mythic.core.mobs.ActiveMob;
+import world.bentobox.bentobox.api.hooks.Hook;
+import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity.MythicMobRecord;
+
+/**
+ * Provides implementation and interfacing to interact with MythicMobs.
+ *
+ * @author tastybento
+ * @since 2.2.0
+ */
+public class MythicMobsHook extends Hook {
+
+ public MythicMobsHook() {
+ super("MythicMobs", Material.CREEPER_HEAD);
+ }
+
+ public boolean isMythicMob(Entity bukkitEntity) {
+ return MythicBukkit.inst().getMobManager().isMythicMob(bukkitEntity);
+ }
+
+ public MythicMobRecord getMythicMob(Entity bukkitEntity) {
+ ActiveMob mm = MythicBukkit.inst().getMobManager().getActiveMob(bukkitEntity.getUniqueId()).orElse(null);
+ if (mm != null) {
+ return new MythicMobRecord(mm.getMobType(), mm.getDisplayName(), mm.getLevel(),
+ mm.getPower(),
+ mm.getStance());
+ }
+ return null;
+ }
+
+
+ @Override
+ public boolean hook() {
+ return true; // The hook process shouldn't fail
+ }
+
+ @Override
+ public String getFailureCause() {
+ return null; // The hook process shouldn't fail
+ }
+
+ /**
+ * Spawn a MythicMob
+ * @param mmr MythicMobRecord
+ * @param spawnLocation location
+ * @return true if spawn is successful
+ */
+ public boolean spawnMythicMob(MythicMobRecord mmr, Location spawnLocation) {
+ return MythicBukkit.inst().getMobManager().getMythicMob(mmr.type()).map(mob -> {
+ // A delay is required before spawning, I assume because the blocks are pasted using NMS
+ Bukkit.getScheduler().runTaskLater(getPlugin(), () -> {
+ // spawns mob
+ ActiveMob activeMob = mob.spawn(BukkitAdapter.adapt(spawnLocation), mmr.level());
+ activeMob.setDisplayName(mmr.displayName());
+ activeMob.setPower(mmr.power());
+ activeMob.setStance(mmr.stance());
+ }, 40L);
+ return true;
+ }).orElse(false);
+ }
+}
diff --git a/src/main/java/world/bentobox/bentobox/util/DefaultPasteUtil.java b/src/main/java/world/bentobox/bentobox/util/DefaultPasteUtil.java
index e616e35a3..76fb68be9 100644
--- a/src/main/java/world/bentobox/bentobox/util/DefaultPasteUtil.java
+++ b/src/main/java/world/bentobox/bentobox/util/DefaultPasteUtil.java
@@ -33,6 +33,7 @@ import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBlock;
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintCreatureSpawner;
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity;
import world.bentobox.bentobox.database.objects.Island;
+import world.bentobox.bentobox.hooks.MythicMobsHook;
import world.bentobox.bentobox.nms.PasteHandler;
/**
@@ -172,29 +173,46 @@ public class DefaultPasteUtil {
public static CompletableFuture setEntity(Island island, Location location, List list) {
World world = location.getWorld();
assert world != null;
- return Util.getChunkAtAsync(location).thenRun(() -> list.stream().filter(k -> k.getType() != null).forEach(k -> {
- LivingEntity e = (LivingEntity) location.getWorld().spawnEntity(location, k.getType());
- if (k.getCustomName() != null) {
- String customName = k.getCustomName();
+ return Util.getChunkAtAsync(location).thenRun(() -> list.stream().filter(k -> k.getType() != null)
+ .forEach(k -> spawnBlueprintEntity(k, location, island)));
+ }
- if (island != null) {
- // Parse any placeholders in the entity's name, if the owner's connected (he should)
- Optional owner = Optional.ofNullable(island.getOwner())
- .map(User::getInstance)
- .map(User::getPlayer);
- if (owner.isPresent()) {
- // Parse for the player's name first (in case placeholders might need it)
- customName = customName.replace(TextVariables.NAME, owner.get().getName());
- // Now parse the placeholders
- customName = plugin.getPlaceholdersManager().replacePlaceholders(owner.get(), customName);
- }
+ /**
+ * Spawn an entity
+ * @param k the blueprint entity definition
+ * @param location location
+ * @param island island
+ * @return true if Bukkit entity spawned, false if MythicMob entity spawned
+ */
+ static boolean spawnBlueprintEntity(BlueprintEntity k, Location location, Island island) {
+ if (k.getMythicMobsRecord() != null && plugin.getHooks().getHook("MythicMobs")
+ .filter(mmh -> mmh instanceof MythicMobsHook)
+ .map(mmh -> ((MythicMobsHook) mmh).spawnMythicMob(k.getMythicMobsRecord(), location))
+ .orElse(false)) {
+ // MythicMob has spawned.
+ return false;
+ }
+ LivingEntity e = (LivingEntity) location.getWorld().spawnEntity(location, k.getType());
+ if (k.getCustomName() != null) {
+ String customName = k.getCustomName();
+
+ if (island != null) {
+ // Parse any placeholders in the entity's name, if the owner's connected (he should)
+ Optional owner = Optional.ofNullable(island.getOwner()).map(User::getInstance)
+ .map(User::getPlayer);
+ if (owner.isPresent()) {
+ // Parse for the player's name first (in case placeholders might need it)
+ customName = customName.replace(TextVariables.NAME, owner.get().getName());
+ // Now parse the placeholders
+ customName = plugin.getPlaceholdersManager().replacePlaceholders(owner.get(), customName);
}
-
- // Actually set the custom name
- e.setCustomName(customName);
}
- k.configureEntity(e);
- }));
+
+ // Actually set the custom name
+ e.setCustomName(customName);
+ }
+ k.configureEntity(e);
+ return true;
}
/**
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index ac15aa754..0ca09ce7d 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -1,7 +1,7 @@
name: BentoBox
main: world.bentobox.bentobox.BentoBox
version: ${project.version}${build.number}
-api-version: "1.18"
+api-version: "1.20"
authors: [tastybento, Poslovitch]
contributors: ["The BentoBoxWorld Community"]
@@ -17,15 +17,13 @@ softdepend:
- Vault
- PlaceholderAPI
- dynmap
- - WorldBorderAPI
- BsbMongo
- - WorldGeneratorApi
- AdvancedChests
- LangUtils
- WildStacker
- LuckPerms
- - HolographicDisplays
- EconomyPlus
+ - MythicMobs
libraries:
- mysql:mysql-connector-java:${mysql.version}
diff --git a/src/test/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintLoadCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintLoadCommandTest.java
index 428b702b7..97e7f2d53 100644
--- a/src/test/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintLoadCommandTest.java
+++ b/src/test/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintLoadCommandTest.java
@@ -40,6 +40,7 @@ import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.blueprints.Blueprint;
import world.bentobox.bentobox.managers.BlueprintsManager;
import world.bentobox.bentobox.managers.CommandsManager;
+import world.bentobox.bentobox.managers.HooksManager;
import world.bentobox.bentobox.managers.LocalesManager;
/**
@@ -73,6 +74,11 @@ public class AdminBlueprintLoadCommandTest {
// Set up plugin
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
+ // Hooks
+ HooksManager hooksManager = mock(HooksManager.class);
+ when(hooksManager.getHook(anyString())).thenReturn(Optional.empty());
+ when(plugin.getHooks()).thenReturn(hooksManager);
+
// Blueprints Manager
when(plugin.getBlueprintsManager()).thenReturn(bm);
diff --git a/src/test/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintSaveCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintSaveCommandTest.java
index af71e869f..1ab109bc5 100644
--- a/src/test/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintSaveCommandTest.java
+++ b/src/test/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintSaveCommandTest.java
@@ -18,6 +18,7 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.UUID;
import org.bukkit.Bukkit;
@@ -41,6 +42,7 @@ import world.bentobox.bentobox.blueprints.Blueprint;
import world.bentobox.bentobox.blueprints.BlueprintClipboard;
import world.bentobox.bentobox.managers.BlueprintsManager;
import world.bentobox.bentobox.managers.CommandsManager;
+import world.bentobox.bentobox.managers.HooksManager;
import world.bentobox.bentobox.managers.LocalesManager;
/**
@@ -58,7 +60,7 @@ public class AdminBlueprintSaveCommandTest {
private GameModeAddon addon;
@Mock
private User user;
- private BlueprintClipboard clip = new BlueprintClipboard();
+ private BlueprintClipboard clip;
private UUID uuid = UUID.randomUUID();
private File blueprintsFolder;
@Mock
@@ -72,6 +74,12 @@ public class AdminBlueprintSaveCommandTest {
// 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());
+ when(plugin.getHooks()).thenReturn(hooksManager);
+
+ clip = new BlueprintClipboard();
// Blueprints Manager
when(plugin.getBlueprintsManager()).thenReturn(bm);
@@ -109,7 +117,6 @@ public class AdminBlueprintSaveCommandTest {
PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
-
absc = new AdminBlueprintSaveCommand(ac);
}
diff --git a/src/test/java/world/bentobox/bentobox/blueprints/BlueprintClipboardTest.java b/src/test/java/world/bentobox/bentobox/blueprints/BlueprintClipboardTest.java
index dbe08cd9c..861b0f8be 100644
--- a/src/test/java/world/bentobox/bentobox/blueprints/BlueprintClipboardTest.java
+++ b/src/test/java/world/bentobox/bentobox/blueprints/BlueprintClipboardTest.java
@@ -4,11 +4,14 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.List;
+import java.util.Optional;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@@ -29,6 +32,7 @@ import org.powermock.reflect.Whitebox;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.user.User;
+import world.bentobox.bentobox.managers.HooksManager;
/**
* @author tastybento
@@ -56,6 +60,10 @@ public class BlueprintClipboardTest {
public void setUp() throws Exception {
// Set up plugin
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
+ // Hooks
+ HooksManager hooksManager = mock(HooksManager.class);
+ when(hooksManager.getHook(anyString())).thenReturn(Optional.empty());
+ when(plugin.getHooks()).thenReturn(hooksManager);
// User
when(user.getTranslation(Mockito.anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class));
diff --git a/src/test/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintEntityTest.java b/src/test/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintEntityTest.java
index bb5dec831..ed2bb7e9d 100644
--- a/src/test/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintEntityTest.java
+++ b/src/test/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintEntityTest.java
@@ -1,5 +1,6 @@
package world.bentobox.bentobox.blueprints.dataobjects;
+import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
import java.util.HashMap;
@@ -26,6 +27,8 @@ import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.modules.junit4.PowerMockRunner;
+import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity.MythicMobRecord;
+
/**
* @author tastybento
*
@@ -84,10 +87,10 @@ public class BlueprintEntityTest {
blueprint.configureEntity(villager);
- Assert.assertEquals(Profession.LIBRARIAN, villager.getProfession());
- Assert.assertEquals(100, villager.getVillagerExperience());
- Assert.assertEquals(2, villager.getVillagerLevel());
- Assert.assertEquals(Villager.Type.PLAINS, villager.getVillagerType());
+ assertEquals(Profession.LIBRARIAN, villager.getProfession());
+ assertEquals(100, villager.getVillagerExperience());
+ assertEquals(2, villager.getVillagerLevel());
+ assertEquals(Villager.Type.PLAINS, villager.getVillagerType());
}
@Test
@@ -99,7 +102,7 @@ public class BlueprintEntityTest {
blueprint.configureEntity(sheep);
- Assert.assertEquals(DyeColor.BLUE, sheep.getColor());
+ assertEquals(DyeColor.BLUE, sheep.getColor());
}
@Test
@@ -147,7 +150,7 @@ public class BlueprintEntityTest {
blueprint.configureEntity(horse);
- Assert.assertEquals(50, horse.getDomestication());
+ assertEquals(50, horse.getDomestication());
}
@Test
@@ -159,7 +162,7 @@ public class BlueprintEntityTest {
blueprint.configureEntity(horse);
- Assert.assertEquals(Style.WHITE_DOTS, horse.getStyle());
+ assertEquals(Style.WHITE_DOTS, horse.getStyle());
}
@Test
@@ -167,13 +170,13 @@ public class BlueprintEntityTest {
BlueprintEntity blueprint = new BlueprintEntity();
blueprint.setColor(DyeColor.RED);
- Assert.assertEquals(DyeColor.RED, blueprint.getColor());
+ assertEquals(DyeColor.RED, blueprint.getColor());
blueprint.setType(EntityType.CREEPER);
- Assert.assertEquals(EntityType.CREEPER, blueprint.getType());
+ assertEquals(EntityType.CREEPER, blueprint.getType());
blueprint.setCustomName("My Entity");
- Assert.assertEquals("My Entity", blueprint.getCustomName());
+ assertEquals("My Entity", blueprint.getCustomName());
blueprint.setTamed(true);
Assert.assertTrue(blueprint.getTamed());
@@ -185,27 +188,35 @@ public class BlueprintEntityTest {
Assert.assertFalse(blueprint.getAdult());
blueprint.setDomestication(75);
- Assert.assertEquals(75, blueprint.getDomestication().intValue());
+ assertEquals(75, blueprint.getDomestication().intValue());
Map inventory = new HashMap<>();
inventory.put(1, new ItemStack(Material.DIAMOND));
blueprint.setInventory(inventory);
- Assert.assertEquals(inventory, blueprint.getInventory());
+ assertEquals(inventory, blueprint.getInventory());
blueprint.setStyle(Style.WHITE);
- Assert.assertEquals(Style.WHITE, blueprint.getStyle());
+ assertEquals(Style.WHITE, blueprint.getStyle());
blueprint.setLevel(5);
- Assert.assertEquals(5, blueprint.getLevel().intValue());
+ assertEquals(5, blueprint.getLevel().intValue());
blueprint.setProfession(Profession.FARMER);
- Assert.assertEquals(Profession.FARMER, blueprint.getProfession());
+ assertEquals(Profession.FARMER, blueprint.getProfession());
blueprint.setExperience(500);
- Assert.assertEquals(500, blueprint.getExperience().intValue());
+ assertEquals(500, blueprint.getExperience().intValue());
blueprint.setVillagerType(Villager.Type.TAIGA);
- Assert.assertEquals(Villager.Type.TAIGA, blueprint.getVillagerType());
+ assertEquals(Villager.Type.TAIGA, blueprint.getVillagerType());
+ }
+
+ @Test
+ public void testMythicMobs() {
+ BlueprintEntity blueprint = new BlueprintEntity();
+ MythicMobRecord mmr = new MythicMobRecord("string", "string2", 10D, 1F, "string3");
+ blueprint.setMythicMobsRecord(mmr);
+ assertEquals(mmr, blueprint.getMythicMobsRecord());
}
}
diff --git a/src/test/java/world/bentobox/bentobox/hooks/MythicMobsHookTest.java b/src/test/java/world/bentobox/bentobox/hooks/MythicMobsHookTest.java
new file mode 100644
index 000000000..360befc6f
--- /dev/null
+++ b/src/test/java/world/bentobox/bentobox/hooks/MythicMobsHookTest.java
@@ -0,0 +1,165 @@
+package world.bentobox.bentobox.hooks;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Optional;
+import java.util.UUID;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.World;
+import org.bukkit.entity.Entity;
+import org.bukkit.plugin.Plugin;
+import org.bukkit.plugin.PluginManager;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.reflect.Whitebox;
+
+import io.lumine.mythic.api.mobs.MythicMob;
+import io.lumine.mythic.bukkit.MythicBukkit;
+import io.lumine.mythic.core.mobs.ActiveMob;
+import io.lumine.mythic.core.mobs.MobExecutor;
+import world.bentobox.bentobox.BentoBox;
+import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity.MythicMobRecord;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({ BentoBox.class, Bukkit.class, MythicBukkit.class })
+public class MythicMobsHookTest {
+
+ @Mock
+ private BentoBox plugin;
+ @Mock
+ private PluginManager pim;
+ @Mock
+ private Plugin mythicMobs;
+ @Mock
+ private Location location;
+ @Mock
+ private World world;
+ // DUT
+ MythicMobsHook hook;
+ @Mock
+ private MythicBukkit mythicBukkit;
+ @Mock
+ private MobExecutor mm;
+ @Mock
+ private MythicMob mythicMob;
+ @Mock
+ private ActiveMob activeMob;
+ @Mock
+ private Entity entity;
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Before
+ public void setUp() throws Exception {
+ // Set up plugin
+ plugin = mock(BentoBox.class);
+ Whitebox.setInternalState(BentoBox.class, "instance", plugin);
+ // Bukkit
+ PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
+ when(Bukkit.getPluginManager()).thenReturn(pim);
+ when(pim.getPlugin("MythicMobs")).thenReturn(mythicMobs);
+ // Location
+ when(world.getName()).thenReturn("bskyblock");
+ when(location.getWorld()).thenReturn(world);
+ // Entity
+ when(entity.getUniqueId()).thenReturn(UUID.randomUUID());
+ // MythicMobs
+ PowerMockito.mockStatic(MythicBukkit.class, Mockito.RETURNS_MOCKS);
+ when(MythicBukkit.inst()).thenReturn(mythicBukkit);
+ when(mythicBukkit.getMobManager()).thenReturn(mm);
+ when(mm.getMythicMob(anyString())).thenReturn(Optional.of(mythicMob));
+ when(activeMob.getDisplayName()).thenReturn("Minion");
+ when(activeMob.getMobType()).thenReturn("GIANT");
+ when(activeMob.getStance()).thenReturn("default");
+ when(activeMob.getLevel()).thenReturn(2.5D);
+ when(activeMob.getPower()).thenReturn(33.2F);
+ when(mm.getActiveMob(any())).thenReturn(Optional.of(activeMob));
+
+ hook = new MythicMobsHook();
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ /**
+ * Test method for {@link world.bentobox.bentobox.hooks.MythicMobsHook#hook()}.
+ */
+ @Test
+ public void testHook() {
+ assertTrue(hook.hook());
+ }
+
+ /**
+ * Test method for {@link world.bentobox.bentobox.hooks.MythicMobsHook#getFailureCause()}.
+ */
+ @Test
+ public void testGetFailureCause() {
+ assertNull(hook.getFailureCause());
+ }
+
+ /**
+ * Test method for {@link world.bentobox.bentobox.hooks.MythicMobsHook#MythicMobsHook()}.
+ */
+ @Test
+ public void testMythicMobsHook() {
+ assertNotNull(hook);
+ assertEquals(Material.CREEPER_HEAD, hook.getIcon());
+
+ }
+
+ /**
+ * Test method for {@link world.bentobox.bentobox.hooks.MythicMobsHook#isMythicMob(org.bukkit.entity.Entity)}.
+ */
+ @Test
+ public void testIsMythicMob() {
+ assertFalse(hook.isMythicMob(entity));
+ }
+
+ /**
+ * Test method for {@link world.bentobox.bentobox.hooks.MythicMobsHook#getMythicMob(org.bukkit.entity.Entity)}.
+ */
+ @Test
+ public void testGetMythicMob() {
+ MythicMobRecord mmr = hook.getMythicMob(entity);
+ assertEquals("GIANT", mmr.type());
+ assertEquals("Minion", mmr.displayName());
+ assertEquals("default", mmr.stance());
+ assertEquals(2.5D, mmr.level(), 0D);
+ assertEquals(33.2F, mmr.power(), 0F);
+ }
+
+ /**
+ * Test method for {@link world.bentobox.bentobox.hooks.MythicMobsHook#spawnMythicMob(world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity.MythicMobRecord, org.bukkit.Location)}.
+ */
+ @Test
+ public void testSpawnMythicMob() {
+ MythicMobRecord mmr = hook.getMythicMob(entity);
+ assertTrue(hook.spawnMythicMob(mmr, location));
+ verify(mm).getMythicMob("GIANT");
+ }
+
+}
diff --git a/src/test/java/world/bentobox/bentobox/managers/BlueprintClipboardManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/BlueprintClipboardManagerTest.java
index 30e24cb16..53804ab00 100644
--- a/src/test/java/world/bentobox/bentobox/managers/BlueprintClipboardManagerTest.java
+++ b/src/test/java/world/bentobox/bentobox/managers/BlueprintClipboardManagerTest.java
@@ -4,6 +4,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -16,6 +17,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Comparator;
+import java.util.Optional;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@@ -33,6 +35,7 @@ import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.reflect.Whitebox;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.user.User;
@@ -128,13 +131,20 @@ public class BlueprintClipboardManagerTest {
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());
+ when(plugin.getHooks()).thenReturn(hooksManager);
+
PowerMockito.mockStatic(Bukkit.class);
BlockData blockData = mock(BlockData.class);
when(Bukkit.createBlockData(any(Material.class))).thenReturn(blockData);
when(blockData.getAsString()).thenReturn("test123");
when(server.getBukkitVersion()).thenReturn("version");
when(Bukkit.getServer()).thenReturn(server);
-
}
/**
diff --git a/src/test/java/world/bentobox/bentobox/util/DefaultPasteUtilTest.java b/src/test/java/world/bentobox/bentobox/util/DefaultPasteUtilTest.java
index f383c7f7d..75cc62b8b 100644
--- a/src/test/java/world/bentobox/bentobox/util/DefaultPasteUtilTest.java
+++ b/src/test/java/world/bentobox/bentobox/util/DefaultPasteUtilTest.java
@@ -1,9 +1,12 @@
package world.bentobox.bentobox.util;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -25,10 +28,13 @@ import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.WallSign;
import org.bukkit.block.sign.Side;
import org.bukkit.block.sign.SignSide;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -43,7 +49,11 @@ import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBlock;
+import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity;
+import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity.MythicMobRecord;
import world.bentobox.bentobox.database.objects.Island;
+import world.bentobox.bentobox.hooks.MythicMobsHook;
+import world.bentobox.bentobox.managers.HooksManager;
import world.bentobox.bentobox.managers.IslandWorldManager;
import world.bentobox.bentobox.managers.LocalesManager;
import world.bentobox.bentobox.managers.PlayersManager;
@@ -79,10 +89,20 @@ public class DefaultPasteUtilTest {
@Mock(extraInterfaces = {org.bukkit.block.Sign.class})
BlockState sign;
+ @Mock
+ private PlayersManager pm;
+ @Mock
+ private MythicMobsHook mythicMobsHook;
+ @Mock
+ private BlueprintEntity blueprintEntity;
+ @Mock
+ private Location location;
+ @Mock
+ private LivingEntity livingEntity;
@Mock
private World world;
@Mock
- private PlayersManager pm;
+ private HooksManager hooksManager;
/**
@@ -110,6 +130,11 @@ public class DefaultPasteUtilTest {
when(plugin.getLocalesManager()).thenReturn(localesManager);
when(localesManager.getOrDefault(any(), anyString(), anyString())).thenReturn("translated");
+ when(location.getWorld()).thenReturn(world);
+ // Hooks
+ when(hooksManager.getHook("MythicMobs")).thenReturn(Optional.of(mythicMobsHook));
+ when(plugin.getHooks()).thenReturn(hooksManager);
+
when(plugin.getPlayers()).thenReturn(pm);
}
@@ -188,4 +213,32 @@ public class DefaultPasteUtilTest {
List capturedLines = lineCaptor.getAllValues();
Assert.assertEquals(linesTranslated, capturedLines);
}
+
+ @Ignore
+ @Test
+ public void testSpawnBlueprintEntity_WithMythicMobs() {
+ // Set up conditions to satisfy the mythic mobs spawning logic
+ MythicMobRecord mmr = new MythicMobRecord("string", "string2", 10D, 1F, "string3");
+ when(blueprintEntity.getMythicMobsRecord()).thenReturn(mmr);
+ when(mythicMobsHook.spawnMythicMob(mmr, location)).thenReturn(true);
+ // This test works fine if there is a System.out.println() in the code. I assume some optimization is being done in compilation
+
+ assertFalse(DefaultPasteUtil.spawnBlueprintEntity(blueprintEntity, location, island));
+
+ // Verify the mythic mob was spawned, and the method returned early
+ verify(mythicMobsHook).spawnMythicMob(mmr, location);
+ verify(world, never()).spawnEntity(any(Location.class), any(EntityType.class));
+ }
+
+ @Test
+ public void testSpawnBlueprintEntity_WithoutMythicMobs() {
+ // Set up conditions where MythicMobs should not be spawned
+ when(hooksManager.getHook("MythicMobs")).thenReturn(Optional.empty());
+
+ assertTrue(DefaultPasteUtil.spawnBlueprintEntity(blueprintEntity, location, island));
+
+ // Verify a regular entity was spawned instead
+ verify(world).spawnEntity(location, blueprintEntity.getType());
+ }
+
}