From 64ce5138e1877b7f9e0814dabaa297e1f8d78b39 Mon Sep 17 00:00:00 2001 From: StrangeOne101 Date: Fri, 6 Aug 2021 02:52:48 +1200 Subject: [PATCH] Re-added MythicMob support - Re-added Mythic Mob support via everyone's favourite friend: Reflection - Added room for Citizens to be supported using the same system - MythicMobs can be spawned by adding `"specialType": "MythicMobs:"` to your entity file. In future, Citizens could also be used here --- src/main/java/com/volmit/iris/Iris.java | 3 + .../volmit/iris/core/link/MythicMobsLink.java | 93 +++++++++++++++++++ .../iris/core/project/SchemaBuilder.java | 17 ++++ .../RegistryListSpecialEntity.java | 33 +++++++ .../iris/engine/object/entity/IrisEntity.java | 18 ++++ 5 files changed, 164 insertions(+) create mode 100644 src/main/java/com/volmit/iris/core/link/MythicMobsLink.java create mode 100644 src/main/java/com/volmit/iris/engine/object/annotations/RegistryListSpecialEntity.java diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index 7da305f6e..f5ff4df3b 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -25,6 +25,7 @@ import com.volmit.iris.core.command.studio.CommandIrisStudio; import com.volmit.iris.core.command.world.CommandLocate; import com.volmit.iris.core.link.IrisPapiExpansion; import com.volmit.iris.core.link.MultiverseCoreLink; +import com.volmit.iris.core.link.MythicMobsLink; import com.volmit.iris.core.link.OraxenLink; import com.volmit.iris.core.nms.INMS; import com.volmit.iris.core.project.loader.IrisData; @@ -81,6 +82,7 @@ public class Iris extends VolmitPlugin implements Listener { public static IrisBoardManager board; public static MultiverseCoreLink linkMultiverseCore; public static OraxenLink linkOraxen; + public static MythicMobsLink linkMythicMobs; public static TreeManager saplingManager; private static final Queue syncJobs = new ShurikenQueue<>(); public static IrisCompat compat; @@ -132,6 +134,7 @@ public class Iris extends VolmitPlugin implements Listener { board = new IrisBoardManager(); linkMultiverseCore = new MultiverseCoreLink(); linkOraxen = new OraxenLink(); + linkMythicMobs = new MythicMobsLink(); saplingManager = new TreeManager(); edit = new EditManager(); configWatcher = new FileWatcher(getDataFile("settings.json")); diff --git a/src/main/java/com/volmit/iris/core/link/MythicMobsLink.java b/src/main/java/com/volmit/iris/core/link/MythicMobsLink.java new file mode 100644 index 000000000..255138372 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/link/MythicMobsLink.java @@ -0,0 +1,93 @@ +package com.volmit.iris.core.link; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.plugin.Plugin; + +import javax.annotation.Nullable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.function.BiFunction; + +public class MythicMobsLink { + + private Collection mobs; + private BiFunction spawnMobFunction; + + public MythicMobsLink() { + + } + + public boolean isEnabled() { + return getPlugin() != null; + } + + public Plugin getPlugin() { + return Bukkit.getPluginManager().getPlugin("MythicMobs"); + } + + /** + * Spawn a mythic mob at this location + * @param mob The mob + * @param location The location + * @return The mob, or null if it can't be spawned + */ + public @Nullable Entity spawnMob(String mob, Location location) { + if (!isEnabled()) return null; + + if (spawnMobFunction != null) { + return spawnMobFunction.apply(mob, location); + } + + try { + Class mythicMobClass = Class.forName("io.lumine.xikage.mythicmobs.MythicMobs"); + Method getInst = mythicMobClass.getDeclaredMethod("inst"); + Object inst = getInst.invoke(null); + Method getAPIHelper = mythicMobClass.getDeclaredMethod("getAPIHelper"); + Object apiHelper = getAPIHelper.invoke(inst); + Method spawnMobMethod = apiHelper.getClass().getDeclaredMethod("spawnMythicMob", String.class, Location.class); + + spawnMobFunction = (str, loc) -> { + try { + return (Entity) spawnMobMethod.invoke(apiHelper, str, loc); + } catch (InvocationTargetException | IllegalAccessException e) { + e.printStackTrace(); + } + return null; + }; + + return spawnMobFunction.apply(mob, location); + } catch (Exception e) { + e.printStackTrace(); + + } + return null; + } + + public Collection getMythicMobTypes() { + if (mobs != null) { + return mobs; + } + + if(isEnabled()) { + + try { + Class mythicMobClass = Class.forName("io.lumine.xikage.mythicmobs.MythicMobs"); + Method getInst = mythicMobClass.getDeclaredMethod("inst"); + Object inst = getInst.invoke(null); + Method getMobManager = mythicMobClass.getDeclaredMethod("getMobManager"); + Object mobManager = getMobManager.invoke(inst); + Method getMobNames = mobManager.getClass().getDeclaredMethod("getMobNames"); + mobs = (Collection) getMobNames.invoke(mobManager); + return mobs; + } catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + e.printStackTrace(); + } + } + + return new ArrayList<>(); + } +} diff --git a/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java b/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java index a2abcf944..b279ed987 100644 --- a/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java +++ b/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java @@ -35,6 +35,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; public class SchemaBuilder { private static final String SYMBOL_LIMIT__N = "*"; @@ -221,6 +222,22 @@ public class SchemaBuilder { prop.put("$ref", "#/definitions/" + key); description.add(SYMBOL_TYPE__N + " Must be a valid Item Type (use ctrl+space for auto complete!)"); + } else if(k.isAnnotationPresent(RegistryListSpecialEntity.class)) { + String key = "enum-reg-specialentity"; + + if(!definitions.containsKey(key)) + { + JSONObject j = new JSONObject(); + KList list = new KList<>(); + list.addAll(Iris.linkMythicMobs.getMythicMobTypes().stream().map(s -> "MythicMobs:" + s).collect(Collectors.toList())); + //TODO add Citizens stuff here too + j.put("enum", list.toJSONStringArray()); + definitions.put(key, j); + } + + fancyType = "Mythic Mob Type"; + prop.put("$ref", "#/definitions/" + key); + description.add(SYMBOL_TYPE__N + " Must be a valid Mythic Mob Type (use ctrl+space for auto complete!) Define mythic mobs with the mythic mobs plugin configuration files."); } else if (k.isAnnotationPresent(RegistryListFont.class)) { String key = "enum-font"; diff --git a/src/main/java/com/volmit/iris/engine/object/annotations/RegistryListSpecialEntity.java b/src/main/java/com/volmit/iris/engine/object/annotations/RegistryListSpecialEntity.java new file mode 100644 index 000000000..39374f94d --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/annotations/RegistryListSpecialEntity.java @@ -0,0 +1,33 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.object.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Retention(RUNTIME) +@Target({PARAMETER, TYPE, FIELD}) +public @interface RegistryListSpecialEntity { + +} diff --git a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java index 56887612f..6c34aeb91 100644 --- a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java +++ b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java @@ -23,6 +23,7 @@ import com.volmit.iris.core.project.loader.IrisRegistrant; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.annotations.ArrayType; import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.engine.object.annotations.RegistryListSpecialEntity; import com.volmit.iris.engine.object.annotations.Required; import com.volmit.iris.engine.object.loot.IrisLoot; import com.volmit.iris.engine.object.loot.IrisLootReference; @@ -150,6 +151,10 @@ public class IrisEntity extends IrisRegistrant { @Desc("The surface type to spawn this mob on") private IrisSurface surface = IrisSurface.LAND; + @RegistryListSpecialEntity + @Desc("Create a mob from another plugin, such as Mythic Mobs. Should be in the format of a namespace of PluginName:MobName") + private String specialType = ""; + public Entity spawn(Engine gen, Location at) { return spawn(gen, at, new RNG(at.hashCode())); } @@ -308,6 +313,15 @@ public class IrisEntity extends IrisRegistrant { return ae.get(); } + if (isSpecialType()) { + if (specialType.toLowerCase().startsWith("mythicmobs:")) { + return Iris.linkMythicMobs.spawnMob(specialType.substring(11), at); + } else { + Iris.warn("Invalid mob type to spawn: '" + specialType + "'!"); + return null; + } + } + return at.getWorld().spawnEntity(at, getType()); } @@ -318,6 +332,10 @@ public class IrisEntity extends IrisRegistrant { // TODO: return Iris.linkCitizens.supported() && someType is not empty; } + public boolean isSpecialType() { + return specialType != null && !specialType.equals(""); + } + @Override public String getFolderName() { return "entities";