Added a custom entity api with initial support for MythicMobs.

This commit is contained in:
Brianna 2020-10-26 12:41:54 -05:00
parent 9264013afc
commit 601dcc1f09
9 changed files with 180 additions and 6 deletions

View File

@ -40,6 +40,7 @@ import com.songoda.ultimatestacker.stackable.block.BlockStack;
import com.songoda.ultimatestacker.stackable.block.BlockStackManager; import com.songoda.ultimatestacker.stackable.block.BlockStackManager;
import com.songoda.ultimatestacker.stackable.entity.EntityStack; import com.songoda.ultimatestacker.stackable.entity.EntityStack;
import com.songoda.ultimatestacker.stackable.entity.EntityStackManager; import com.songoda.ultimatestacker.stackable.entity.EntityStackManager;
import com.songoda.ultimatestacker.stackable.entity.custom.CustomEntityManager;
import com.songoda.ultimatestacker.stackable.spawner.SpawnerStack; import com.songoda.ultimatestacker.stackable.spawner.SpawnerStack;
import com.songoda.ultimatestacker.stackable.spawner.SpawnerStackManager; import com.songoda.ultimatestacker.stackable.spawner.SpawnerStackManager;
import com.songoda.ultimatestacker.tasks.StackingTask; import com.songoda.ultimatestacker.tasks.StackingTask;
@ -77,6 +78,7 @@ public class UltimateStacker extends SongodaPlugin {
private BlockStackManager blockStackManager; private BlockStackManager blockStackManager;
private LootablesManager lootablesManager; private LootablesManager lootablesManager;
private CommandManager commandManager; private CommandManager commandManager;
private CustomEntityManager customEntityManager;
private StackingTask stackingTask; private StackingTask stackingTask;
private DatabaseConnector databaseConnector; private DatabaseConnector databaseConnector;
@ -161,6 +163,7 @@ public class UltimateStacker extends SongodaPlugin {
this.spawnerStackManager = new SpawnerStackManager(); this.spawnerStackManager = new SpawnerStackManager();
this.entityStackManager = new EntityStackManager(this); this.entityStackManager = new EntityStackManager(this);
this.blockStackManager = new BlockStackManager(); this.blockStackManager = new BlockStackManager();
this.customEntityManager = new CustomEntityManager();
guiManager.init(); guiManager.init();
PluginManager pluginManager = Bukkit.getPluginManager(); PluginManager pluginManager = Bukkit.getPluginManager();
@ -343,6 +346,9 @@ public class UltimateStacker extends SongodaPlugin {
return blockStackManager; return blockStackManager;
} }
public CustomEntityManager getCustomEntityManager() {
return customEntityManager;
}
public void updateHologram(Hologramable stack) { public void updateHologram(Hologramable stack) {
// Is this stack invalid? // Is this stack invalid?

View File

@ -152,6 +152,15 @@ public class Settings {
public static final ConfigSetting SHEAR_IN_ONE_CLICK = new ConfigSetting(config, "Entities.Shear In One Click", false, public static final ConfigSetting SHEAR_IN_ONE_CLICK = new ConfigSetting(config, "Entities.Shear In One Click", false,
"Should entities be sheared in a single click?"); "Should entities be sheared in a single click?");
public static final ConfigSetting ENABLED_CUSTOM_ENTITY_PLUGINS = new ConfigSetting(config, "Entities.Enabled Custom Entity Plugins", Collections.singletonList("MythicMobs"),
"Which custom entity plugins should be used?",
"Remove a plugin from this list to disable the stacking of their entities.");
public static final ConfigSetting BLACKLISTED_CUSTOM_ENTITIES = new ConfigSetting(config, "Entities.Blacklisted Custom Entities", Collections.singletonList("mythicmobs_test"),
"Which custom entities should not be stacked?",
"List the entities using their plugin name as a prefix in all lowercase.",
"Example: mythicmobs_test");
public static final ConfigSetting STACK_ITEMS = new ConfigSetting(config, "Items.Enabled", true, public static final ConfigSetting STACK_ITEMS = new ConfigSetting(config, "Items.Enabled", true,
"Should items be stacked?"); "Should items be stacked?");

View File

@ -3,6 +3,7 @@ package com.songoda.ultimatestacker.stackable.entity;
import com.songoda.core.nms.NmsManager; import com.songoda.core.nms.NmsManager;
import com.songoda.core.nms.nbt.NBTEntity; import com.songoda.core.nms.nbt.NBTEntity;
import com.songoda.ultimatestacker.UltimateStacker; import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.stackable.entity.custom.CustomEntity;
import com.songoda.ultimatestacker.utils.Stackable; import com.songoda.ultimatestacker.utils.Stackable;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
@ -71,7 +72,7 @@ public class ColdEntityStack implements Stackable {
public List<StackedEntity> takeEntities(int amount) { public List<StackedEntity> takeEntities(int amount) {
List<StackedEntity> entities = new LinkedList<>(); List<StackedEntity> entities = new LinkedList<>();
for (int i = 0; i < amount; i ++) { for (int i = 0; i < amount; i++) {
StackedEntity entity = stackedEntities.pollFirst(); StackedEntity entity = stackedEntities.pollFirst();
if (entity != null) if (entity != null)
entities.add(entity); entities.add(entity);
@ -90,7 +91,18 @@ public class ColdEntityStack implements Stackable {
if (stackedEntities.isEmpty()) return null; if (stackedEntities.isEmpty()) return null;
NBTEntity nbtEntity = NmsManager.getNbt().newEntity(); NBTEntity nbtEntity = NmsManager.getNbt().newEntity();
nbtEntity.deSerialize(stackedEntities.getFirst().getSerializedEntity()); nbtEntity.deSerialize(stackedEntities.getFirst().getSerializedEntity());
LivingEntity newEntity = (LivingEntity)nbtEntity.spawn(location);
for (CustomEntity customEntity : plugin.getCustomEntityManager().getRegisteredCustomEntities()) {
String identifier = customEntity.getPluginName() + "_UltimateStacker";
if (!nbtEntity.has(identifier)) continue;
LivingEntity entity = customEntity.spawnFromIdentifier(nbtEntity.getString(identifier), location);
if (entity == null) continue;
stackedEntities.removeFirst();
plugin.getDataManager().deleteStackedEntity(entity.getUniqueId());
return entity;
}
LivingEntity newEntity = (LivingEntity) nbtEntity.spawn(location);
stackedEntities.removeFirst(); stackedEntities.removeFirst();
plugin.getDataManager().deleteStackedEntity(newEntity.getUniqueId()); plugin.getDataManager().deleteStackedEntity(newEntity.getUniqueId());
@ -126,6 +138,9 @@ public class ColdEntityStack implements Stackable {
uuid = UUID.randomUUID(); uuid = UUID.randomUUID();
nbtEntity.set("UUID", uuid); nbtEntity.set("UUID", uuid);
} }
CustomEntity customEntity = plugin.getCustomEntityManager().getCustomEntity(entity);
if (customEntity != null)
nbtEntity.set(customEntity.getPluginName() + "_UltimateStacker", customEntity.getNBTIdentifier(entity));
return new StackedEntity(uuid, nbtEntity.serialize("Attributes")); return new StackedEntity(uuid, nbtEntity.serialize("Attributes"));
} }

View File

@ -0,0 +1,27 @@
package com.songoda.ultimatestacker.stackable.entity.custom;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.plugin.Plugin;
public abstract class CustomEntity {
protected final Plugin plugin;
protected CustomEntity(Plugin plugin) {
this.plugin = plugin;
}
public abstract String getPluginName();
public abstract boolean isMatchingType(Entity entity);
public abstract String getDisplayName(Entity entity);
public abstract boolean isSimilar(LivingEntity original, LivingEntity entity);
public abstract String getNBTIdentifier(Entity entity);
public abstract LivingEntity spawnFromIdentifier(String string, Location location);
}

View File

@ -0,0 +1,45 @@
package com.songoda.ultimatestacker.stackable.entity.custom;
import com.songoda.ultimatestacker.settings.Settings;
import com.songoda.ultimatestacker.stackable.entity.custom.entities.MythicMobsCustomEntity;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CustomEntityManager {
public CustomEntityManager() {
load();
}
private final List<CustomEntity> registeredCustomEntities = new ArrayList<>();
public void load() {
if (isEnabled("MythicMobs"))
registeredCustomEntities.add(new MythicMobsCustomEntity());
}
public boolean isEnabled(String plugin) {
return Bukkit.getPluginManager().isPluginEnabled(plugin)
&& Settings.ENABLED_CUSTOM_ENTITY_PLUGINS.getStringList().contains(plugin);
}
public CustomEntity getCustomEntity(Entity entity) {
for (CustomEntity customEntity : registeredCustomEntities) {
if (customEntity.isMatchingType(entity)) {
if (Settings.BLACKLISTED_CUSTOM_ENTITIES.getStringList()
.contains((customEntity.getPluginName() + "_" + customEntity.getNBTIdentifier(entity)).toLowerCase()))
continue;
return customEntity;
}
}
return null;
}
public List<CustomEntity> getRegisteredCustomEntities() {
return Collections.unmodifiableList(registeredCustomEntities);
}
}

View File

@ -0,0 +1,59 @@
package com.songoda.ultimatestacker.stackable.entity.custom.entities;
import com.songoda.ultimatestacker.stackable.entity.custom.CustomEntity;
import io.lumine.xikage.mythicmobs.MythicMobs;
import io.lumine.xikage.mythicmobs.mobs.ActiveMob;
import io.lumine.xikage.mythicmobs.mobs.MobManager;
import io.lumine.xikage.mythicmobs.mobs.MythicMob;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
public class MythicMobsCustomEntity extends CustomEntity {
public MythicMobsCustomEntity() {
super(Bukkit.getPluginManager().getPlugin("MythicMobs"));
}
@Override
public String getPluginName() {
return "MythicMobs";
}
@Override
public boolean isMatchingType(Entity entity) {
return getMobManager().isActiveMob(entity.getUniqueId());
}
@Override
public String getDisplayName(Entity entity) {
return getMobManager().getMythicMobInstance(entity).getType().getDisplayName().toString();
}
@Override
public boolean isSimilar(LivingEntity original, LivingEntity entity) {
if (!isMatchingType(original) || !isMatchingType(entity)) return false;
return getMob(original).getType().equals(getMob(entity).getType());
}
@Override
public String getNBTIdentifier(Entity entity) {
return getMob(entity).getType().getInternalName();
}
@Override
public LivingEntity spawnFromIdentifier(String string, Location location) {
if (getMobManager().getMobTypes().stream().map(MythicMob::getInternalName).noneMatch(t -> t.equals(string)))
return null;
return (LivingEntity)getMobManager().spawnMob(string, location).getEntity().getBukkitEntity();
}
private ActiveMob getMob(Entity entity) {
return getMobManager().getMythicMobInstance(entity);
}
private MobManager getMobManager() {
return ((MythicMobs) plugin).getMobManager();
}
}

View File

@ -9,6 +9,7 @@ import com.songoda.ultimatestacker.stackable.entity.Check;
import com.songoda.ultimatestacker.stackable.entity.EntityStack; import com.songoda.ultimatestacker.stackable.entity.EntityStack;
import com.songoda.ultimatestacker.stackable.entity.EntityStackManager; import com.songoda.ultimatestacker.stackable.entity.EntityStackManager;
import com.songoda.ultimatestacker.stackable.entity.StackedEntity; import com.songoda.ultimatestacker.stackable.entity.StackedEntity;
import com.songoda.ultimatestacker.stackable.entity.custom.CustomEntity;
import com.songoda.ultimatestacker.utils.CachedChunk; import com.songoda.ultimatestacker.utils.CachedChunk;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -167,8 +168,9 @@ public class StackingTask extends BukkitRunnable {
// Attempt to split our stack. If the split is successful then skip this entity. // Attempt to split our stack. If the split is successful then skip this entity.
if (isStack && attemptSplit(stack, livingEntity)) return; if (isStack && attemptSplit(stack, livingEntity)) return;
// If this entity is named or disabled then skip it. // If this entity is named, a custom entity or disabled then skip it.
if (!isStack && livingEntity.getCustomName() != null if (!isStack && (livingEntity.getCustomName() != null
&& plugin.getCustomEntityManager().getCustomEntity(livingEntity) == null)
|| !configurationSection.getBoolean("Mobs." + livingEntity.getType().name() + ".Enabled")) || !configurationSection.getBoolean("Mobs." + livingEntity.getType().name() + ".Enabled"))
return; return;
@ -286,7 +288,8 @@ public class StackingTask extends BukkitRunnable {
&& !this.processed.contains(entity.getUniqueId())).limit(maxEntityStackSize).forEach(entity -> { && !this.processed.contains(entity.getUniqueId())).limit(maxEntityStackSize).forEach(entity -> {
// Make sure we're not naming some poor kids pet. // Make sure we're not naming some poor kids pet.
if (entity.getCustomName() != null) { if (entity.getCustomName() != null
&& plugin.getCustomEntityManager().getCustomEntity(entity) == null) {
processed.add(livingEntity.getUniqueId()); processed.add(livingEntity.getUniqueId());
newStack.destroy(); newStack.destroy();
return; return;
@ -405,6 +408,10 @@ public class StackingTask extends BukkitRunnable {
entityList.add(entity); entityList.add(entity);
} }
CustomEntity customEntity = plugin.getCustomEntityManager().getCustomEntity(initialEntity);
if (customEntity != null)
entityList.removeIf(entity -> !customEntity.isSimilar(initialEntity, entity));
if (stackFlyingDown && canFly(initialEntity)) if (stackFlyingDown && canFly(initialEntity))
entityList.removeIf(entity -> entity.getLocation().getY() > initialEntity.getLocation().getY()); entityList.removeIf(entity -> entity.getLocation().getY() > initialEntity.getLocation().getY());

View File

@ -6,6 +6,8 @@ import com.songoda.core.nms.nbt.NBTItem;
import com.songoda.core.utils.TextUtils; import com.songoda.core.utils.TextUtils;
import com.songoda.ultimatestacker.UltimateStacker; import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.settings.Settings; import com.songoda.ultimatestacker.settings.Settings;
import com.songoda.ultimatestacker.stackable.entity.custom.CustomEntity;
import com.songoda.ultimatestacker.stackable.entity.custom.CustomEntityManager;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.GameMode; import org.bukkit.GameMode;
@ -125,6 +127,10 @@ public class Methods {
String nameFormat = Settings.NAME_FORMAT_ENTITY.getString(); String nameFormat = Settings.NAME_FORMAT_ENTITY.getString();
String displayName = Methods.formatText(UltimateStacker.getInstance().getMobFile().getString("Mobs." + entity.getType().name() + ".Display Name")); String displayName = Methods.formatText(UltimateStacker.getInstance().getMobFile().getString("Mobs." + entity.getType().name() + ".Display Name"));
CustomEntity customEntity = UltimateStacker.getInstance().getCustomEntityManager().getCustomEntity(entity);
if (customEntity != null)
displayName = customEntity.getDisplayName(entity);
nameFormat = nameFormat.replace("{TYPE}", displayName); nameFormat = nameFormat.replace("{TYPE}", displayName);
nameFormat = nameFormat.replace("{AMT}", Integer.toString(amount)); nameFormat = nameFormat.replace("{AMT}", Integer.toString(amount));

View File

@ -1,7 +1,7 @@
name: UltimateStacker name: UltimateStacker
description: UltimateStacker description: UltimateStacker
version: maven-version-number version: maven-version-number
softdepend: [HolographicDisplays, Holograms, CMI, WorldGuard, EpicSpawners, mcMMO, WildStacker, StackMob] softdepend: [MythicMobs, HolographicDisplays, Holograms, CMI, WorldGuard, EpicSpawners, mcMMO, WildStacker, StackMob]
loadbefore: [WorldGuard] loadbefore: [WorldGuard]
main: com.songoda.ultimatestacker.UltimateStacker main: com.songoda.ultimatestacker.UltimateStacker
author: songoda author: songoda