diff --git a/api-bukkit/src/main/java/dev/aurelium/auraskills/api/event/loot/LootDropEvent.java b/api-bukkit/src/main/java/dev/aurelium/auraskills/api/event/loot/LootDropEvent.java index ee3072e50..f74523aa8 100644 --- a/api-bukkit/src/main/java/dev/aurelium/auraskills/api/event/loot/LootDropEvent.java +++ b/api-bukkit/src/main/java/dev/aurelium/auraskills/api/event/loot/LootDropEvent.java @@ -2,12 +2,15 @@ import dev.aurelium.auraskills.api.user.SkillsUser; import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Called when AuraSkills drops extra loot from mechanics like Fishing, Luck, and custom loot tables. @@ -22,6 +25,7 @@ public class LootDropEvent extends Event implements Cancellable { private Location location; private final Cause cause; private boolean toInventory; + private Entity entity; private boolean cancelled = false; public LootDropEvent(Player player, SkillsUser user, ItemStack item, Location location, Cause cause, boolean toInventory) { @@ -33,6 +37,26 @@ public LootDropEvent(Player player, SkillsUser user, ItemStack item, Location lo this.toInventory = toInventory; } + public LootDropEvent(Player player, SkillsUser user, Entity entity, Location location, Cause cause) { + this.player = player; + this.user = user; + this.location = location; + this.cause = cause; + this.toInventory = false; + this.entity = entity; + // Let's not break things and make the item not nullable still + this.item = new ItemStack(Material.AIR); + } + + /** + * Gets the spawned entity if the loot was an entity. + * + * @return the entity + */ + public @Nullable Entity getEntity() { + return entity; + } + /** * Gets the player that caused the loot drop. * @@ -53,6 +77,7 @@ public SkillsUser getUser() { /** * Gets the item that will be dropped by the event. + * If the drop is an entity, this will be AIR. * * @return the item */ diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/mythicmobs/MythicMobsHook.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/mythicmobs/MythicMobsHook.java index 4664aea98..57bd8937d 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/mythicmobs/MythicMobsHook.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/mythicmobs/MythicMobsHook.java @@ -4,6 +4,7 @@ import dev.aurelium.auraskills.bukkit.AuraSkills; import dev.aurelium.auraskills.bukkit.damage.DamageHandler; import dev.aurelium.auraskills.bukkit.damage.DamageResult; +import dev.aurelium.auraskills.bukkit.hooks.mythicmobs.loot.MythicEntityLootParser; import dev.aurelium.auraskills.common.hooks.Hook; import dev.aurelium.auraskills.api.damage.DamageType; import io.lumine.mythic.api.adapters.AbstractEntity; @@ -30,6 +31,10 @@ public MythicMobsHook(AuraSkills plugin, ConfigurationNode config) { super(plugin, config); this.plugin = plugin; this.damageHandler = new DamageHandler(); + + // Wait for loot manager to be created, but add parser before it is loaded + plugin.getScheduler().executeSync(() -> + plugin.getLootTableManager().getLootManager().registerCustomEntityParser(new MythicEntityLootParser())); } @EventHandler(priority = EventPriority.HIGH) diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/mythicmobs/loot/MythicEntityLootParser.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/mythicmobs/loot/MythicEntityLootParser.java new file mode 100644 index 000000000..cd4e8d20a --- /dev/null +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/mythicmobs/loot/MythicEntityLootParser.java @@ -0,0 +1,19 @@ +package dev.aurelium.auraskills.bukkit.hooks.mythicmobs.loot; + +import dev.aurelium.auraskills.bukkit.loot.entity.EntityProperties; +import dev.aurelium.auraskills.bukkit.loot.entity.EntitySupplier; +import dev.aurelium.auraskills.bukkit.loot.parser.CustomEntityParser; +import org.spongepowered.configurate.ConfigurationNode; + +public class MythicEntityLootParser implements CustomEntityParser { + + @Override + public EntitySupplier getEntitySupplier(ConfigurationNode config) { + return new MythicEntitySupplier(EntityProperties.fromConfig(config)); + } + + @Override + public boolean shouldUseParser(ConfigurationNode config) { + return config.node("entity").getString("").startsWith("mythicmobs:"); + } +} diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/mythicmobs/loot/MythicEntitySupplier.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/mythicmobs/loot/MythicEntitySupplier.java new file mode 100644 index 000000000..934b67b14 --- /dev/null +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/mythicmobs/loot/MythicEntitySupplier.java @@ -0,0 +1,35 @@ +package dev.aurelium.auraskills.bukkit.hooks.mythicmobs.loot; + +import dev.aurelium.auraskills.bukkit.AuraSkills; +import dev.aurelium.auraskills.bukkit.loot.entity.EntityProperties; +import dev.aurelium.auraskills.bukkit.loot.entity.EntitySupplier; +import io.lumine.mythic.bukkit.BukkitAdapter; +import io.lumine.mythic.bukkit.MythicBukkit; +import io.lumine.mythic.core.mobs.ActiveMob; +import org.bukkit.Location; +import org.bukkit.entity.Entity; + +public class MythicEntitySupplier extends EntitySupplier { + + public MythicEntitySupplier(EntityProperties entityProperties) { + super(entityProperties); + } + + @Override + public Entity spawnEntity(AuraSkills plugin, Location location) { + ActiveMob activeMob; + + if (getEntityProperties().level() != null) { + activeMob = MythicBukkit.inst().getMobManager().spawnMob(getEntityProperties().entityId(), location, getEntityProperties().level()); + } else { + activeMob = MythicBukkit.inst().getMobManager().spawnMob(getEntityProperties().entityId(), location); + } + + return BukkitAdapter.adapt(activeMob.getEntity()); + } + + @Override + public void removeEntity(Entity entity) { + MythicBukkit.inst().getMobManager().getActiveMob(entity.getUniqueId()).ifPresent(ActiveMob::remove); + } +} diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/LootLoader.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/LootLoader.java index 3512470bf..75804c441 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/LootLoader.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/LootLoader.java @@ -3,6 +3,7 @@ import dev.aurelium.auraskills.api.loot.*; import dev.aurelium.auraskills.api.registry.NamespacedId; import dev.aurelium.auraskills.bukkit.loot.parser.CommandLootParser; +import dev.aurelium.auraskills.bukkit.loot.parser.EntityLootParser; import dev.aurelium.auraskills.bukkit.loot.parser.ItemLootParser; import dev.aurelium.auraskills.bukkit.loot.parser.LootParsingContextImpl; import dev.aurelium.auraskills.bukkit.util.VersionUtils; @@ -70,6 +71,9 @@ public LootTable loadLootTable(NamespacedId id, File file, ConfigurationNode con // Command loot else if (lootType.equalsIgnoreCase("command")) { loot = new CommandLootParser().parse(context, lootNode); + // Entity loot, mainly for fishing + } else if (lootType.equalsIgnoreCase("entity")) { + loot = new EntityLootParser(manager).parse(context, lootNode); } else { // Parse custom loot registered from API LootParser customParser = manager.getCustomLootParsers().get(lootType); diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/LootManager.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/LootManager.java index d3692c1a2..b4e76da91 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/LootManager.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/LootManager.java @@ -3,6 +3,7 @@ import dev.aurelium.auraskills.api.loot.LootParser; import dev.aurelium.auraskills.bukkit.AuraSkills; import dev.aurelium.auraskills.bukkit.loot.context.ContextProvider; +import dev.aurelium.auraskills.bukkit.loot.parser.CustomEntityParser; import dev.aurelium.auraskills.bukkit.loot.parser.CustomItemParser; import org.jetbrains.annotations.Nullable; @@ -16,6 +17,7 @@ public class LootManager { private final Set lootOptionKeys; private final Set poolOptionKeys; private final List customItemParsers; + private final List customEntityParsers; private final Map customLootParsers; public LootManager(AuraSkills plugin) { @@ -24,6 +26,7 @@ public LootManager(AuraSkills plugin) { this.contextProviders = new HashMap<>(); this.lootOptionKeys = new HashSet<>(); this.poolOptionKeys = new HashSet<>(); + this.customEntityParsers = new ArrayList<>(); this.customItemParsers = new ArrayList<>(); this.customLootParsers = new HashMap<>(); } @@ -77,10 +80,18 @@ public List getCustomItemParsers() { return customItemParsers; } + public List getCustomEntityParsers() { + return customEntityParsers; + } + public void registerCustomItemParser(CustomItemParser customItemParser) { customItemParsers.add(customItemParser); } + public void registerCustomEntityParser(CustomEntityParser customEntityParser) { + customEntityParsers.add(customEntityParser); + } + public Map getCustomLootParsers() { return customLootParsers; } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/LootTableManager.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/LootTableManager.java index 2e0833896..9d1e189fd 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/LootTableManager.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/LootTableManager.java @@ -8,6 +8,7 @@ import dev.aurelium.auraskills.bukkit.AuraSkills; import dev.aurelium.auraskills.bukkit.loot.context.MobContextProvider; import dev.aurelium.auraskills.bukkit.loot.context.SourceContextProvider; +import dev.aurelium.auraskills.bukkit.loot.entity.VanillaEntityParser; import dev.aurelium.auraskills.bukkit.util.ItemUtils; import dev.aurelium.auraskills.common.api.ApiAuraSkills; import dev.aurelium.auraskills.common.config.ConfigurateLoader; @@ -44,6 +45,7 @@ public void initLootManager() { lootManager.registerContextProvider(new SourceContextProvider(plugin)); lootManager.registerContextProvider(new MobContextProvider()); lootManager.registerCustomItemParser(new ItemKeyParser(plugin)); + lootManager.registerCustomEntityParser(new VanillaEntityParser()); lootManager.addLootOptionKeys("xp"); lootManager.addPoolOptionKeys("chance_per_luck", "require_open_water"); } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/entity/EntityProperties.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/entity/EntityProperties.java new file mode 100644 index 000000000..633a1b717 --- /dev/null +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/entity/EntityProperties.java @@ -0,0 +1,26 @@ +package dev.aurelium.auraskills.bukkit.loot.entity; + +import org.spongepowered.configurate.ConfigurationNode; + +public record EntityProperties(String entityId, + String name, + Integer level, + Double health, + Double damage, + Float horizontalVelocity, + Float verticalVelocity) { + + public static EntityProperties fromConfig(ConfigurationNode config) { + String[] id = config.node("entity").getString("").split(":"); + + return new EntityProperties( + id.length > 1 ? id[1] : id[0], + config.node("name").getString(), + config.node("level").empty() ? null : config.node("level").getInt(), + config.node("health").empty() ? null : config.node("health").getDouble(), + config.node("damage").empty() ? null : config.node("damage").getDouble(), + config.node("velocity", "horizontal").empty() ? null : config.node("velocity", "horizontal").getFloat(), + config.node("velocity", "vertical").empty() ? null : config.node("velocity", "vertical").getFloat() + ); + } +} diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/entity/EntitySupplier.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/entity/EntitySupplier.java new file mode 100644 index 000000000..8bd3fe448 --- /dev/null +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/entity/EntitySupplier.java @@ -0,0 +1,22 @@ +package dev.aurelium.auraskills.bukkit.loot.entity; + +import dev.aurelium.auraskills.bukkit.AuraSkills; +import org.bukkit.Location; +import org.bukkit.entity.Entity; + +public abstract class EntitySupplier { + + private final EntityProperties entityProperties; + + public EntitySupplier(EntityProperties entityProperties) { + this.entityProperties = entityProperties; + } + + public abstract Entity spawnEntity(AuraSkills plugin, Location location); + + public abstract void removeEntity(Entity entity); + + public EntityProperties getEntityProperties() { + return entityProperties; + } +} diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/entity/VanillaEntityParser.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/entity/VanillaEntityParser.java new file mode 100644 index 000000000..ac1c8c91e --- /dev/null +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/entity/VanillaEntityParser.java @@ -0,0 +1,23 @@ +package dev.aurelium.auraskills.bukkit.loot.entity; + +import dev.aurelium.auraskills.bukkit.loot.parser.CustomEntityParser; +import org.spongepowered.configurate.ConfigurationNode; + +public class VanillaEntityParser implements CustomEntityParser { + + @Override + public EntitySupplier getEntitySupplier(ConfigurationNode config) { + return new VanillaEntitySupplier(EntityProperties.fromConfig(config)); + } + + @Override + public boolean shouldUseParser(ConfigurationNode config) { + String entity = config.node("entity").getString(); + + if (entity == null) return false; + + // If it has a colon, it's a custom entity + // But if it starts with minecraft:, it's a vanilla entity stated explicitly + return !entity.contains(":") || entity.startsWith("minecraft:"); + } +} diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/entity/VanillaEntitySupplier.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/entity/VanillaEntitySupplier.java new file mode 100644 index 000000000..6580a060b --- /dev/null +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/entity/VanillaEntitySupplier.java @@ -0,0 +1,58 @@ +package dev.aurelium.auraskills.bukkit.loot.entity; + +import dev.aurelium.auraskills.bukkit.AuraSkills; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeInstance; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.metadata.FixedMetadataValue; + +public class VanillaEntitySupplier extends EntitySupplier { + + public VanillaEntitySupplier(EntityProperties entityProperties) { + super(entityProperties); + } + + @Override + public Entity spawnEntity(AuraSkills plugin, Location location) { + World world = location.getWorld(); + if (world == null) return null; + + Entity entity = world.spawnEntity(location, EntityType.valueOf(getEntityProperties().entityId().toUpperCase())); + + if (entity instanceof LivingEntity livingEntity) { + if (getEntityProperties().health() != null) { + AttributeInstance attribute = livingEntity.getAttribute(Attribute.GENERIC_MAX_HEALTH); + if (attribute != null) { + attribute.setBaseValue(getEntityProperties().health()); + livingEntity.setHealth(Math.min(getEntityProperties().health(), attribute.getValue())); + } + } + if (getEntityProperties().damage() != null) { + AttributeInstance attribute = livingEntity.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE); + if (attribute != null) { + attribute.setBaseValue(getEntityProperties().damage()); + } + } + } + + if (getEntityProperties().name() != null) { + entity.setCustomName(plugin.getMessageProvider().applyFormatting(getEntityProperties().name())); + entity.setCustomNameVisible(true); + } + + if (getEntityProperties().level() != null) { + entity.setMetadata("auraskills_level", new FixedMetadataValue(plugin, getEntityProperties().level())); + } + + return entity; + } + + @Override + public void removeEntity(Entity entity) { + entity.remove(); + } +} diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/handler/FishingLootHandler.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/handler/FishingLootHandler.java index a8398bf82..9df92261a 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/handler/FishingLootHandler.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/handler/FishingLootHandler.java @@ -15,6 +15,7 @@ import dev.aurelium.auraskills.api.loot.LootTable; import dev.aurelium.auraskills.bukkit.loot.context.SourceContext; import dev.aurelium.auraskills.bukkit.loot.type.CommandLoot; +import dev.aurelium.auraskills.bukkit.loot.type.EntityLoot; import dev.aurelium.auraskills.bukkit.loot.type.ItemLoot; import dev.aurelium.auraskills.bukkit.source.FishingLeveler; import dev.aurelium.auraskills.bukkit.util.VersionUtils; @@ -103,6 +104,8 @@ public void onFish(PlayerFishEvent event) { giveFishingItemLoot(player, itemLoot, event, source, skill, cause, table); } else if (selectedLoot instanceof CommandLoot commandLoot) { giveCommandLoot(player, commandLoot, source, skill); + } else if (selectedLoot instanceof EntityLoot entityLoot) { + giveFishingEntityLoot(player, entityLoot, event, source, skill, cause); } break; // Stop iterating pools } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/handler/LootHandler.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/handler/LootHandler.java index d34eb5363..3808609d1 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/handler/LootHandler.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/handler/LootHandler.java @@ -15,6 +15,7 @@ import dev.aurelium.auraskills.bukkit.loot.context.MobContext; import dev.aurelium.auraskills.bukkit.loot.context.SourceContext; import dev.aurelium.auraskills.bukkit.loot.type.CommandLoot; +import dev.aurelium.auraskills.bukkit.loot.type.EntityLoot; import dev.aurelium.auraskills.bukkit.loot.type.ItemLoot; import dev.aurelium.auraskills.bukkit.util.ItemUtils; import dev.aurelium.auraskills.common.commands.CommandExecutor; @@ -26,9 +27,12 @@ import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.entity.Entity; import org.bukkit.entity.Item; import org.bukkit.entity.Player; +import org.bukkit.util.Vector; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.player.PlayerFishEvent; import org.bukkit.inventory.ItemStack; @@ -116,6 +120,38 @@ protected void giveFishingItemLoot(Player player, ItemLoot loot, PlayerFishEvent giveXp(player, loot, source, skill); } + protected void giveFishingEntityLoot(Player player, EntityLoot loot, PlayerFishEvent event, @Nullable XpSource source, Skill skill, LootDropEvent.Cause cause) { + if (!(event.getCaught() instanceof Item itemEntity)) return; + + Location location = event.getHook().getLocation(); + Entity entity = loot.getEntity().spawnEntity(plugin, event.getHook().getLocation()); + + if (entity == null) return; + + LootDropEvent dropEvent = new LootDropEvent(player, plugin.getUser(player).toApi(), entity, event.getHook().getLocation(), cause); + Bukkit.getPluginManager().callEvent(dropEvent); + + if (dropEvent.isCancelled()) { + loot.getEntity().removeEntity(entity); + return; + } + + itemEntity.setItemStack(new ItemStack(Material.AIR)); + + Float hVelocity = loot.getEntity().getEntityProperties().horizontalVelocity(); + if (hVelocity == null) hVelocity = 1.2f; + + Float vVelocity = loot.getEntity().getEntityProperties().verticalVelocity(); + if (vVelocity == null) vVelocity = 1.3f; + + Vector vector = player.getLocation().subtract(location).toVector().multiply(hVelocity - 1); + vector.setY((vector.getY() + 0.2) * vVelocity); + entity.setVelocity(vector); + + attemptSendMessage(player, loot); + giveXp(player, loot, source, skill); + } + @Nullable protected Loot selectLoot(LootPool pool, @NotNull LootContext providedContext) { return pool.rollLoot(loot -> { diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/parser/CustomEntityParser.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/parser/CustomEntityParser.java new file mode 100644 index 000000000..e7fdbf58a --- /dev/null +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/parser/CustomEntityParser.java @@ -0,0 +1,10 @@ +package dev.aurelium.auraskills.bukkit.loot.parser; + +import dev.aurelium.auraskills.bukkit.loot.entity.EntitySupplier; +import org.spongepowered.configurate.ConfigurationNode; + +public interface CustomEntityParser extends CustomParser { + + EntitySupplier getEntitySupplier(ConfigurationNode config); + +} diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/parser/CustomItemParser.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/parser/CustomItemParser.java index 392a77f41..b9cb017cc 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/parser/CustomItemParser.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/parser/CustomItemParser.java @@ -3,9 +3,7 @@ import org.bukkit.inventory.ItemStack; import org.spongepowered.configurate.ConfigurationNode; -public interface CustomItemParser { - - boolean shouldUseParser(ConfigurationNode config); +public interface CustomItemParser extends CustomParser { ItemStack parseCustomItem(ConfigurationNode config); diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/parser/CustomParser.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/parser/CustomParser.java new file mode 100644 index 000000000..a11c6fa70 --- /dev/null +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/parser/CustomParser.java @@ -0,0 +1,9 @@ +package dev.aurelium.auraskills.bukkit.loot.parser; + +import org.spongepowered.configurate.ConfigurationNode; + +public interface CustomParser { + + boolean shouldUseParser(ConfigurationNode config); + +} diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/parser/EntityLootParser.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/parser/EntityLootParser.java new file mode 100644 index 000000000..06eadc204 --- /dev/null +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/parser/EntityLootParser.java @@ -0,0 +1,38 @@ +package dev.aurelium.auraskills.bukkit.loot.parser; + +import dev.aurelium.auraskills.api.loot.Loot; +import dev.aurelium.auraskills.api.loot.LootParser; +import dev.aurelium.auraskills.api.loot.LootParsingContext; +import dev.aurelium.auraskills.bukkit.loot.LootManager; +import dev.aurelium.auraskills.bukkit.loot.entity.EntitySupplier; +import dev.aurelium.auraskills.bukkit.loot.type.EntityLoot; +import dev.aurelium.auraskills.common.util.data.Validate; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.serialize.SerializationException; + +public class EntityLootParser implements LootParser { + + protected final LootManager manager; + + public EntityLootParser(LootManager manager) { + this.manager = manager; + } + + @Override + public Loot parse(LootParsingContext context, ConfigurationNode config) throws SerializationException { + String entityType = config.node("entity").getString(); + Validate.notNull(entityType, "Entity loot must specify an entity type"); + + EntitySupplier entity = null; + for (CustomEntityParser parser : manager.getCustomEntityParsers()) { + if (parser.shouldUseParser(config)) { + entity = parser.getEntitySupplier(config); + break; + } + } + + Validate.notNull(entity, "Couldn't parse entity loot with entity type: " + entityType); + + return new EntityLoot(context.parseValues(config), entity); + } +} diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/type/EntityLoot.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/type/EntityLoot.java new file mode 100644 index 000000000..deb3acd16 --- /dev/null +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/loot/type/EntityLoot.java @@ -0,0 +1,19 @@ +package dev.aurelium.auraskills.bukkit.loot.type; + +import dev.aurelium.auraskills.api.loot.Loot; +import dev.aurelium.auraskills.api.loot.LootValues; +import dev.aurelium.auraskills.bukkit.loot.entity.EntitySupplier; + +public class EntityLoot extends Loot { + + private final EntitySupplier entity; + + public EntityLoot(LootValues values, EntitySupplier entity) { + super(values); + this.entity = entity; + } + + public EntitySupplier getEntity() { + return entity; + } +}