diff --git a/api/src/main/kotlin/com/artillexstudios/axminions/api/AxMinionsAPI.kt b/api/src/main/kotlin/com/artillexstudios/axminions/api/AxMinionsAPI.kt index 9e5e8ec..13fc07f 100644 --- a/api/src/main/kotlin/com/artillexstudios/axminions/api/AxMinionsAPI.kt +++ b/api/src/main/kotlin/com/artillexstudios/axminions/api/AxMinionsAPI.kt @@ -1,8 +1,11 @@ package com.artillexstudios.axminions.api +import com.artillexstudios.axapi.AxPlugin import com.artillexstudios.axminions.api.config.Config import com.artillexstudios.axminions.api.config.Messages import com.artillexstudios.axminions.api.data.DataHandler +import com.artillexstudios.axminions.api.minions.Minion +import org.bukkit.entity.Player import java.io.File interface AxMinionsAPI { @@ -15,6 +18,12 @@ interface AxMinionsAPI { fun getDataHandler(): DataHandler + fun getMinions(): List + + fun getAxMinionsInstance(): AxPlugin + + fun getMinionLimit(player: Player): Int + companion object { @JvmStatic lateinit var INSTANCE: AxMinionsAPI diff --git a/api/src/main/kotlin/com/artillexstudios/axminions/api/config/Config.kt b/api/src/main/kotlin/com/artillexstudios/axminions/api/config/Config.kt index 87de3d2..cff66fa 100644 --- a/api/src/main/kotlin/com/artillexstudios/axminions/api/config/Config.kt +++ b/api/src/main/kotlin/com/artillexstudios/axminions/api/config/Config.kt @@ -12,30 +12,30 @@ import java.io.InputStream class Config(file: File, stream: InputStream) { companion object { - @JvmField - val AUTO_SAVE_MINUTES = AxMinionsAPI.INSTANCE.getConfig().get("autosave-minutes", 3L) - @JvmField - val MAX_LINKING_DISTANCE = AxMinionsAPI.INSTANCE.getConfig().get("max-linking-distance", 30) - @JvmField - val DEFAULT_MINION_LIMIT = AxMinionsAPI.INSTANCE.getConfig().get("default-minion-limit", 5) - @JvmField - val ALLOW_FLOATING_MINIONS = AxMinionsAPI.INSTANCE.getConfig().get("allow-floating-minions", false) - @JvmField - val ONLY_OWNER_BREAK = AxMinionsAPI.INSTANCE.getConfig().get("only-owner-break", true) - @JvmField - val DISPLAY_WARNINGS = AxMinionsAPI.INSTANCE.getConfig().get("display-warnings", true) - @JvmField - val CAN_BREAK_TOOLS = AxMinionsAPI.INSTANCE.getConfig().get("can-break-tools", true) - @JvmField - val USE_DURABILITY = AxMinionsAPI.INSTANCE.getConfig().get("use-durability", true) - @JvmField - val DATABASE_TYPE = AxMinionsAPI.INSTANCE.getConfig().get("database.type", "H2") - @JvmField - val STACKER_HOOK = AxMinionsAPI.INSTANCE.getConfig().get("hooks.stacker", "none") - @JvmField - val ECONOMY_HOOK = AxMinionsAPI.INSTANCE.getConfig().get("hooks.economy", "Vault") - @JvmField - val PRICES_HOOK = AxMinionsAPI.INSTANCE.getConfig().get("hooks.prices", "ShopGUIPlus") + @JvmStatic + fun AUTO_SAVE_MINUTES() = AxMinionsAPI.INSTANCE.getConfig().get("autosave-minutes", 3L) + @JvmStatic + fun MAX_LINKING_DISTANCE() = AxMinionsAPI.INSTANCE.getConfig().get("max-linking-distance", 30) + @JvmStatic + fun DEFAULT_MINION_LIMIT() = AxMinionsAPI.INSTANCE.getConfig().get("default-minion-limit", 5) + @JvmStatic + fun ALLOW_FLOATING_MINIONS() = AxMinionsAPI.INSTANCE.getConfig().get("allow-floating-minions", false) + @JvmStatic + fun ONLY_OWNER_BREAK() = AxMinionsAPI.INSTANCE.getConfig().get("only-owner-break", true) + @JvmStatic + fun DISPLAY_WARNINGS() = AxMinionsAPI.INSTANCE.getConfig().get("display-warnings", true) + @JvmStatic + fun CAN_BREAK_TOOLS() = AxMinionsAPI.INSTANCE.getConfig().get("can-break-tools", true) + @JvmStatic + fun USE_DURABILITY() = AxMinionsAPI.INSTANCE.getConfig().get("use-durability", true) + @JvmStatic + fun DATABASE_TYPE() = AxMinionsAPI.INSTANCE.getConfig().get("database.type", "H2") + @JvmStatic + fun STACKER_HOOK() = AxMinionsAPI.INSTANCE.getConfig().get("hooks.stacker", "none") + @JvmStatic + fun ECONOMY_HOOK() = AxMinionsAPI.INSTANCE.getConfig().get("hooks.economy", "Vault") + @JvmStatic + fun PRICES_HOOK() = AxMinionsAPI.INSTANCE.getConfig().get("hooks.prices", "ShopGUIPlus") } private val config = Config( diff --git a/api/src/main/kotlin/com/artillexstudios/axminions/api/config/Messages.kt b/api/src/main/kotlin/com/artillexstudios/axminions/api/config/Messages.kt index dec167d..7a6e0eb 100644 --- a/api/src/main/kotlin/com/artillexstudios/axminions/api/config/Messages.kt +++ b/api/src/main/kotlin/com/artillexstudios/axminions/api/config/Messages.kt @@ -13,16 +13,16 @@ import java.io.InputStream class Messages(file: File, stream: InputStream) { companion object { - @JvmField - var PREFIX = AxMinionsAPI.INSTANCE.getMessages().get("prefix") - @JvmField - var NO_CONTAINER_WARNING = AxMinionsAPI.INSTANCE.getMessages().get("warnings.no-container") - @JvmField - var NO_TOOL_WARNING = AxMinionsAPI.INSTANCE.getMessages().get("warnings.no-tool") - @JvmField - var NO_WATER_NEARBY_WARNING = AxMinionsAPI.INSTANCE.getMessages().get("warnings.no-water-nearby") - @JvmField - var CONTAINER_FULL_WARNING = AxMinionsAPI.INSTANCE.getMessages().get("warnings.container-full") + @JvmStatic + fun PREFIX() = AxMinionsAPI.INSTANCE.getMessages().get("prefix") + @JvmStatic + fun NO_CONTAINER_WARNING() = AxMinionsAPI.INSTANCE.getMessages().get("warnings.no-container") + @JvmStatic + fun NO_TOOL_WARNING() = AxMinionsAPI.INSTANCE.getMessages().get("warnings.no-tool") + @JvmStatic + fun NO_WATER_NEARBY_WARNING() = AxMinionsAPI.INSTANCE.getMessages().get("warnings.no-water-nearby") + @JvmStatic + fun CONTAINER_FULL_WARNING() = AxMinionsAPI.INSTANCE.getMessages().get("warnings.container-full") } private val config = Config( diff --git a/api/src/main/kotlin/com/artillexstudios/axminions/api/minions/Minion.kt b/api/src/main/kotlin/com/artillexstudios/axminions/api/minions/Minion.kt index 7028c79..44171c3 100644 --- a/api/src/main/kotlin/com/artillexstudios/axminions/api/minions/Minion.kt +++ b/api/src/main/kotlin/com/artillexstudios/axminions/api/minions/Minion.kt @@ -72,4 +72,12 @@ interface Minion { fun setDirection(direction: Direction) fun getDirection(): Direction + + fun remove() + + fun getLinkedInventory(): Inventory? + + fun addToContainerOrDrop(itemStack: ItemStack) + + fun addToContainerOrDrop(itemStack: Iterable) } \ No newline at end of file diff --git a/api/src/main/kotlin/com/artillexstudios/axminions/api/minions/miniontype/MinionType.kt b/api/src/main/kotlin/com/artillexstudios/axminions/api/minions/miniontype/MinionType.kt index 8f12c84..f311ab3 100644 --- a/api/src/main/kotlin/com/artillexstudios/axminions/api/minions/miniontype/MinionType.kt +++ b/api/src/main/kotlin/com/artillexstudios/axminions/api/minions/miniontype/MinionType.kt @@ -1,9 +1,13 @@ package com.artillexstudios.axminions.api.minions.miniontype import com.artillexstudios.axapi.config.Config +import com.artillexstudios.axapi.utils.ItemBuilder import com.artillexstudios.axminions.api.AxMinionsAPI import com.artillexstudios.axminions.api.minions.Minion +import dev.dejvokep.boostedyaml.block.implementation.Section import org.bukkit.Location +import org.bukkit.inventory.ItemStack +import org.bukkit.persistence.PersistentDataType import java.io.File import java.io.InputStream @@ -11,7 +15,7 @@ abstract class MinionType(private val name: String, private val defaults: InputS private lateinit var config: Config fun load() { - config = Config(File(AxMinionsAPI.INSTANCE.getAxMinionsDataFolder(), "$name.yml"), defaults) + config = Config(File(AxMinionsAPI.INSTANCE.getAxMinionsDataFolder(), "/minions/$name.yml"), defaults) AxMinionsAPI.INSTANCE.getDataHandler().loadMinionsOfType(this) } @@ -34,9 +38,50 @@ abstract class MinionType(private val name: String, private val defaults: InputS run(minion) } + fun getItem(): ItemStack { + val builder = ItemBuilder(config.getSection("item")) + val itemStack = builder.clonedGet() + val itemMeta = itemStack.itemMeta ?: return itemStack + + itemMeta.persistentDataContainer.set(MinionTypes.getMinionKey(), PersistentDataType.STRING, name) + itemStack.setItemMeta(itemMeta) + + return itemStack + } + fun getConfig(): Config { return this.config } + fun getString(key: String, level: Int): String { + return get(key, level, "---", String::class.java)!! + } + + fun getDouble(key: String, level: Int): Double { + return get(key, level, -1.0, Double::class.java)!! + } + + fun getLong(key: String, level: Int): Long { + return get(key, level, -1, Long::class.java)!! + } + + fun getSection(key: String, level: Int): Section? { + return get(key, level, null, Section::class.java) + } + + private fun get(key: String, level: Int, defaultValue: T?, clazz: Class): T? { + var n = defaultValue + + config.getSection("upgrades").getRoutesAsStrings(false).forEach { + if (it.toInt() > level) return n + + if (config.backingDocument.getAsOptional("upgrades.$it.$key", clazz).isEmpty) return@forEach + + n = config.get("upgrades.$it.$key") + } + + return n + } + abstract fun run(minion: Minion) } \ No newline at end of file diff --git a/api/src/main/kotlin/com/artillexstudios/axminions/api/minions/miniontype/MinionTypes.kt b/api/src/main/kotlin/com/artillexstudios/axminions/api/minions/miniontype/MinionTypes.kt index 40ebcfc..c9f1446 100644 --- a/api/src/main/kotlin/com/artillexstudios/axminions/api/minions/miniontype/MinionTypes.kt +++ b/api/src/main/kotlin/com/artillexstudios/axminions/api/minions/miniontype/MinionTypes.kt @@ -1,11 +1,15 @@ package com.artillexstudios.axminions.api.minions.miniontype +import com.artillexstudios.axminions.api.AxMinionsAPI import com.artillexstudios.axminions.api.exception.MinionTypeAlreadyRegisteredException +import org.bukkit.NamespacedKey import java.util.Collections object MinionTypes { private val TYPES = hashMapOf() + private val MINION_KEY = NamespacedKey(AxMinionsAPI.INSTANCE.getAxMinionsInstance(), "minion_type") + @JvmStatic fun register(type: MinionType): MinionType { if (TYPES.containsKey(type.getName())) { throw MinionTypeAlreadyRegisteredException("A minion with type ${type.getName()} has already been registered!") @@ -16,10 +20,22 @@ object MinionTypes { return type } + @JvmStatic fun unregister(key: String) { TYPES.remove(key) } + @JvmStatic + fun valueOf(name: String): MinionType? { + return TYPES[name] + } + + @JvmStatic + fun getMinionKey(): NamespacedKey { + return MINION_KEY + } + + @JvmStatic fun getMinionTypes(): Map { return Collections.unmodifiableMap(TYPES) } diff --git a/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/impl/WarningContainerFull.kt b/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/impl/WarningContainerFull.kt index 410cddd..0dd5271 100644 --- a/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/impl/WarningContainerFull.kt +++ b/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/impl/WarningContainerFull.kt @@ -8,6 +8,6 @@ import net.kyori.adventure.text.Component class WarningContainerFull : Warning("container_full") { override fun getContent(): Component { - return StringUtils.format(Messages.CONTAINER_FULL_WARNING) + return StringUtils.format(Messages.CONTAINER_FULL_WARNING()) } } \ No newline at end of file diff --git a/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/impl/WarningNoContainer.kt b/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/impl/WarningNoContainer.kt index 5dbd02a..3760a5a 100644 --- a/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/impl/WarningNoContainer.kt +++ b/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/impl/WarningNoContainer.kt @@ -8,6 +8,6 @@ import net.kyori.adventure.text.Component class WarningNoContainer : Warning("no_container") { override fun getContent(): Component { - return StringUtils.format(Messages.NO_CONTAINER_WARNING) + return StringUtils.format(Messages.NO_CONTAINER_WARNING()) } } \ No newline at end of file diff --git a/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/impl/WarningNoTool.kt b/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/impl/WarningNoTool.kt index 9c62877..9a3b559 100644 --- a/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/impl/WarningNoTool.kt +++ b/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/impl/WarningNoTool.kt @@ -8,6 +8,6 @@ import net.kyori.adventure.text.Component class WarningNoTool : Warning("no_tool") { override fun getContent(): Component { - return StringUtils.format(Messages.NO_TOOL_WARNING) + return StringUtils.format(Messages.NO_TOOL_WARNING()) } } \ No newline at end of file diff --git a/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/impl/WarningNoWaterNearby.kt b/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/impl/WarningNoWaterNearby.kt index 7997c49..0f42c4a 100644 --- a/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/impl/WarningNoWaterNearby.kt +++ b/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/impl/WarningNoWaterNearby.kt @@ -8,6 +8,6 @@ import net.kyori.adventure.text.Component class WarningNoWaterNearby : Warning("no_water_nearby") { override fun getContent(): Component { - return StringUtils.format(Messages.NO_WATER_NEARBY_WARNING) + return StringUtils.format(Messages.NO_WATER_NEARBY_WARNING()) } } \ No newline at end of file diff --git a/build.gradle b/build.gradle index 25493dd..42babbb 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,7 @@ repositories { dependencies { implementation project(path: ":api") + implementation project(path: ":common") } allprojects { @@ -61,11 +62,9 @@ allprojects { compileOnly 'dev.rosewood:rosestacker:1.5.11' compileOnly 'com.bgsoftware:WildStackerAPI:2023.2' compileOnly 'com.github.MilkBowl:VaultAPI:1.7' - compileOnly 'com.h2database:h2:2.2.220' - compileOnly 'com.github.NEZNAMY:YamlAssist:1.0.5' compileOnly 'com.github.brcdev-minecraft:shopgui-api:3.0.0' compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.9.0' - implementation 'com.github.Carleslc.Simple-YAML:Simple-Yaml:1.8.4' + compileOnly 'com.h2database:h2:2.2.220' implementation files('../libs/AxAPI-1.0-SNAPSHOT.jar') } diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/AxMinionsPlugin.kt b/common/src/main/kotlin/com/artillexstudios/axminions/AxMinionsPlugin.kt index 1ddcb90..7d37666 100644 --- a/common/src/main/kotlin/com/artillexstudios/axminions/AxMinionsPlugin.kt +++ b/common/src/main/kotlin/com/artillexstudios/axminions/AxMinionsPlugin.kt @@ -1,12 +1,39 @@ package com.artillexstudios.axminions import com.artillexstudios.axapi.AxPlugin +import com.artillexstudios.axapi.data.ThreadedQueue import com.artillexstudios.axminions.api.AxMinionsAPI import com.artillexstudios.axminions.api.AxMinionsAPIImpl +import com.artillexstudios.axminions.api.config.Config +import com.artillexstudios.axminions.api.config.Messages +import com.artillexstudios.axminions.api.data.DataHandler +import com.artillexstudios.axminions.api.minions.miniontype.MinionType +import com.artillexstudios.axminions.api.minions.miniontype.MinionTypes +import com.artillexstudios.axminions.commands.AxMinionsCommand +import com.artillexstudios.axminions.data.H2DataHandler +import com.artillexstudios.axminions.minions.miniontype.CollectorMinionType +import com.artillexstudios.axminions.minions.miniontype.FarmerMinionType +import net.byteflux.libby.BukkitLibraryManager +import net.byteflux.libby.Library +import revxrsal.commands.bukkit.BukkitCommandHandler +import java.io.File class AxMinionsPlugin : AxPlugin() { companion object { lateinit var INSTANCE: AxMinionsPlugin + lateinit var messages: Messages + lateinit var config: Config + lateinit var dataHandler: DataHandler + lateinit var dataQueue: ThreadedQueue + } + + init { + val manager = BukkitLibraryManager(this) + val stdLib = Library.builder().groupId("org.jetbrains.kotlin").artifactId("kotlin-stdlib").relocate("org.jetbrains.kotlin", "com.artillexstudios.axminions.libs.kotlin").version("1.9.0").build() + val h2 = Library.builder().groupId("com.h2database").artifactId("h2").version("2.2.220").relocate("org.h2", "com.artillexstudios.axminions.libs.h2").build() + manager.addMavenCentral() + manager.loadLibrary(stdLib) + manager.loadLibrary(h2) } override fun load() { @@ -15,6 +42,43 @@ class AxMinionsPlugin : AxPlugin() { } override fun enable() { + AxMinionsPlugin.config = Config(File(dataFolder, "config.yml"), getResource("config.yml")!!) + messages = Messages(File(dataFolder, "messages.yml"), getResource("messages.yml")!!) + loadDataHandler() + dataQueue = ThreadedQueue("AxMinions-Database-Queue") + + MinionTypes.also { + it.register(CollectorMinionType()) + it.register(FarmerMinionType()) + } + + val handler = BukkitCommandHandler.create(this) + + handler.registerValueResolver(MinionType::class.java) { c -> + val type = c.popForParameter() + + val minionType = MinionTypes.valueOf(type) ?: return@registerValueResolver MinionTypes.valueOf("collector") + + + return@registerValueResolver minionType + } + + handler.autoCompleter.registerSuggestion("minionTypes") { _, _, _ -> + return@registerSuggestion MinionTypes.getMinionTypes().values.map { it.getName() } + } + + handler.register(AxMinionsCommand()) + + handler.registerBrigadier() + } + + private fun loadDataHandler() { + if (Config.DATABASE_TYPE().equals("H2", true)) { + dataHandler = H2DataHandler() + dataHandler.setup() + } else { + + } } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/api/AxMinionsAPIImpl.kt b/common/src/main/kotlin/com/artillexstudios/axminions/api/AxMinionsAPIImpl.kt index ba95dea..a651787 100644 --- a/common/src/main/kotlin/com/artillexstudios/axminions/api/AxMinionsAPIImpl.kt +++ b/common/src/main/kotlin/com/artillexstudios/axminions/api/AxMinionsAPIImpl.kt @@ -1,28 +1,58 @@ package com.artillexstudios.axminions.api +import com.artillexstudios.axapi.AxPlugin import com.artillexstudios.axminions.AxMinionsPlugin import com.artillexstudios.axminions.api.config.Config import com.artillexstudios.axminions.api.config.Messages import com.artillexstudios.axminions.api.data.DataHandler +import com.artillexstudios.axminions.api.minions.Minion +import com.artillexstudios.axminions.minions.Minions +import org.bukkit.entity.Player import java.io.File class AxMinionsAPIImpl(private val plugin: AxMinionsPlugin) : AxMinionsAPI { - private val messages = Messages(File(getAxMinionsDataFolder(), "messages.yml"), plugin.getResource("messages.yml")!!) - private val config = Config(File(getAxMinionsDataFolder(), "config.yml"), plugin.getResource("config.yml")!!) override fun getAxMinionsDataFolder(): File { return plugin.dataFolder } override fun getMessages(): Messages { - return messages + return AxMinionsPlugin.messages } override fun getConfig(): Config { - return config + return AxMinionsPlugin.config } override fun getDataHandler(): DataHandler { - TODO("Not yet implemented") + return AxMinionsPlugin.dataHandler + } + + override fun getMinions(): List { + return Minions.getMinions() + } + + override fun getAxMinionsInstance(): AxPlugin { + return plugin + } + + override fun getMinionLimit(player: Player): Int { + var limit = Config.DEFAULT_MINION_LIMIT() + + player.effectivePermissions.forEach { + val permission = it.permission + if (!permission.startsWith("axminions.limit.")) return@forEach + if (permission.contains("*")) { + return Int.MAX_VALUE + } + + val value = permission.substring(permission.lastIndexOf('.') + 1).toInt() + + if (value > limit) { + limit = value + } + } + + return limit } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/commands/AxMinionsCommand.kt b/common/src/main/kotlin/com/artillexstudios/axminions/commands/AxMinionsCommand.kt new file mode 100644 index 0000000..772268d --- /dev/null +++ b/common/src/main/kotlin/com/artillexstudios/axminions/commands/AxMinionsCommand.kt @@ -0,0 +1,32 @@ +package com.artillexstudios.axminions.commands + +import com.artillexstudios.axminions.api.minions.miniontype.MinionType +import org.bukkit.command.CommandSender +import org.bukkit.entity.Player +import revxrsal.commands.annotation.AutoComplete +import revxrsal.commands.annotation.Command +import revxrsal.commands.annotation.Default +import revxrsal.commands.annotation.Description +import revxrsal.commands.annotation.Range +import revxrsal.commands.annotation.Subcommand +import revxrsal.commands.bukkit.annotation.CommandPermission + +@Command("axminions", "minion", "minions") +class AxMinionsCommand { + + @Subcommand("give") + @CommandPermission("axminions.command.give") + @Description("Give a minion to a player") + @AutoComplete("* @minionTypes * *") + fun give(sender: CommandSender, @Default("me") receiver: Player, @Default("collector") minionType: MinionType, @Default("1") level: Int, @Default("1") @Range(min = 1.0, max = 64.0) amount: Int) { + receiver.inventory.addItem(minionType.getItem()) + } + + + @Subcommand("reload") + @CommandPermission("axminions.command.reload") + @Description("Reload the configurations of the plugin") + fun reload(sender: CommandSender) { + + } +} \ No newline at end of file diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/data/H2DataHandler.kt b/common/src/main/kotlin/com/artillexstudios/axminions/data/H2DataHandler.kt index ef2a483..6db9072 100644 --- a/common/src/main/kotlin/com/artillexstudios/axminions/data/H2DataHandler.kt +++ b/common/src/main/kotlin/com/artillexstudios/axminions/data/H2DataHandler.kt @@ -3,10 +3,8 @@ package com.artillexstudios.axminions.data import com.artillexstudios.axapi.serializers.Serializers import com.artillexstudios.axminions.AxMinionsPlugin import com.artillexstudios.axminions.api.minions.Direction -import com.artillexstudios.axminions.api.minions.Minion import com.artillexstudios.axminions.api.minions.miniontype.MinionType import com.artillexstudios.axminions.api.data.DataHandler -import com.artillexstudios.axminions.minions.MinionImpl import org.bukkit.Bukkit import org.bukkit.Location import org.bukkit.Material @@ -58,7 +56,7 @@ class H2DataHandler : DataHandler { itemStack = Serializers.ITEM_STACK.deserialize(tool) } - MinionImpl( + com.artillexstudios.axminions.minions.Minion( Serializers.LOCATION.deserialize(location), uuid, ownerPlayer, @@ -74,7 +72,7 @@ class H2DataHandler : DataHandler { } } - override fun saveMinion(minion: Minion) { + override fun saveMinion(minion: com.artillexstudios.axminions.api.minions.Minion) { connection.prepareStatement("MERGE INTO `axminions_data`(`location`, `owner`, `linked-chest-location`, `extra_data`, `direction`, `type`, `level`, `tool`) KEY(`location`) VALUES(?,?,?,?,?,?,?,?);") .use { preparedStatement -> preparedStatement.setString(1, Serializers.LOCATION.serialize(minion.getLocation())) @@ -96,7 +94,7 @@ class H2DataHandler : DataHandler { } } - override fun deleteMinion(minion: Minion) { + override fun deleteMinion(minion: com.artillexstudios.axminions.api.minions.Minion) { connection.prepareStatement("DELETE FROM `axminions_data` WHERE `location` = ?;").use { preparedStatement -> preparedStatement.setString(1, Serializers.LOCATION.serialize(minion.getLocation())) preparedStatement.executeUpdate() diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/minions/MinionImpl.kt b/common/src/main/kotlin/com/artillexstudios/axminions/minions/Minion.kt similarity index 79% rename from common/src/main/kotlin/com/artillexstudios/axminions/minions/MinionImpl.kt rename to common/src/main/kotlin/com/artillexstudios/axminions/minions/Minion.kt index 9851d75..251d3fe 100644 --- a/common/src/main/kotlin/com/artillexstudios/axminions/minions/MinionImpl.kt +++ b/common/src/main/kotlin/com/artillexstudios/axminions/minions/Minion.kt @@ -9,9 +9,12 @@ import com.artillexstudios.axminions.api.minions.Direction import com.artillexstudios.axminions.api.minions.Minion import com.artillexstudios.axminions.api.minions.miniontype.MinionType import com.artillexstudios.axminions.api.warnings.Warning +import com.artillexstudios.axminions.api.warnings.Warnings import com.artillexstudios.axminions.utils.fastFor import org.bukkit.Location +import org.bukkit.Material import org.bukkit.OfflinePlayer +import org.bukkit.block.Container import org.bukkit.enchantments.Enchantment import org.bukkit.entity.EntityType import org.bukkit.entity.Player @@ -21,7 +24,7 @@ import org.bukkit.util.EulerAngle import java.util.UUID import kotlin.math.roundToInt -class MinionImpl( +class Minion( private val location: Location, private val ownerUUID: UUID, private val owner: OfflinePlayer, @@ -40,10 +43,13 @@ class MinionImpl( private var warning: Warning? = null private var hologram: Hologram? = null private val extraData = hashMapOf() + private var linkedInventory: Inventory? = null init { spawn() loadExtraData(savedExtraData) + Minions.load(this) + linkedInventory = (linkedChest?.block?.blockData as? Container)?.inventory } override fun getType(): MinionType { @@ -54,14 +60,21 @@ class MinionImpl( entity = PacketEntityFactory.get().spawnEntity(location, EntityType.ARMOR_STAND) as PacketArmorStand entity.setHasBasePlate(false) entity.setSmall(true) + entity.onClick { event -> + if (event.isAttack) { + println("LEFT CLICKED!") + } else { + println("RIGHT CLICKED!") + } + } } override fun tick() { if (dirty) { dirty = false - range = type.getConfig().get("range", 0.0) + range = type.getDouble("range", level) val efficiency = 1.0 - (getTool()?.getEnchantmentLevel(Enchantment.DIG_SPEED)?.div(10.0) ?: 0.1) - nextAction = (type.getConfig().get("speed", 0L) * efficiency).roundToInt() + nextAction = (type.getLong("speed", level) * efficiency).roundToInt() } type.tick(this) @@ -73,15 +86,15 @@ class MinionImpl( } override fun updateInventory(inventory: Inventory) { - TODO("Not yet implemented") + } override fun openInventory(player: Player) { - TODO("Not yet implemented") + } override fun getAsItem(): ItemStack { - TODO("Not yet implemented") + return ItemStack(Material.STONE) } override fun getLevel(): Int { @@ -166,6 +179,7 @@ class MinionImpl( override fun setLinkedChest(location: Location?) { this.linkedChest = location?.clone() + linkedInventory = (linkedChest?.block?.blockData as? Container)?.inventory } override fun getLinkedChest(): Location? { @@ -194,6 +208,30 @@ class MinionImpl( return this.direction } + override fun remove() { + Warnings.remove(this) + Minions.remove(this) + entity.remove() + } + + override fun getLinkedInventory(): Inventory? { + return linkedInventory + } + + override fun addToContainerOrDrop(itemStack: ItemStack) { + val remaining = linkedInventory?.addItem(itemStack) + + remaining?.forEach { (_, u) -> + location.world?.dropItem(location, u) + } + } + + override fun addToContainerOrDrop(itemStack: Iterable) { + itemStack.forEach { + addToContainerOrDrop(it) + } + } + private fun loadExtraData(data: String) { data.split("|").fastFor { split -> val secondSplit = split.split("=") diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/minions/MinionTicker.kt b/common/src/main/kotlin/com/artillexstudios/axminions/minions/MinionTicker.kt index 3dbb8a1..427b856 100644 --- a/common/src/main/kotlin/com/artillexstudios/axminions/minions/MinionTicker.kt +++ b/common/src/main/kotlin/com/artillexstudios/axminions/minions/MinionTicker.kt @@ -1,5 +1,7 @@ package com.artillexstudios.axminions.minions +import com.artillexstudios.axapi.scheduler.Scheduler + object MinionTicker { private var tick = 0L @@ -9,6 +11,12 @@ object MinionTicker { tick++ } + fun startTicking() { + Scheduler.get().runTimer({ task -> + + }, 0, 0) + } + fun getTick(): Long { return this.tick } diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/minions/Minions.kt b/common/src/main/kotlin/com/artillexstudios/axminions/minions/Minions.kt new file mode 100644 index 0000000..14396ce --- /dev/null +++ b/common/src/main/kotlin/com/artillexstudios/axminions/minions/Minions.kt @@ -0,0 +1,20 @@ +package com.artillexstudios.axminions.minions + +import com.artillexstudios.axminions.api.minions.Minion +import java.util.Collections + +object Minions { + private val entities = mutableListOf() + + fun load(minion: Minion) { + entities.add(minion) + } + + fun remove(minion: Minion) { + entities.remove(minion) + } + + fun getMinions(): List { + return Collections.unmodifiableList(entities) + } +} \ No newline at end of file diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/CollectorMinionType.kt b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/CollectorMinionType.kt index 3031af3..b38148d 100644 --- a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/CollectorMinionType.kt +++ b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/CollectorMinionType.kt @@ -5,7 +5,7 @@ import com.artillexstudios.axminions.api.minions.Minion import com.artillexstudios.axminions.api.minions.miniontype.MinionType import com.artillexstudios.axminions.api.warnings.Warnings import com.artillexstudios.axminions.minions.MinionTicker -import org.bukkit.block.Container +import org.bukkit.Material import org.bukkit.entity.Item class CollectorMinionType : MinionType("collector", AxMinionsPlugin.INSTANCE.getResource("minions/collector.yml")!!) { @@ -21,8 +21,14 @@ class CollectorMinionType : MinionType("collector", AxMinionsPlugin.INSTANCE.get return } - val state = minion.getLinkedChest()?.block?.state - if (state !is Container) { + val type = minion.getLinkedChest()!!.block.type + if (type != Material.CHEST && type != Material.TRAPPED_CHEST && type != Material.BARREL && !type.name.lowercase().contains("shulker_box")) { + Warnings.NO_CONTAINER.display(minion) + minion.setLinkedChest(null) + return + } + + if (minion.getLinkedInventory() == null) { Warnings.NO_CONTAINER.display(minion) minion.setLinkedChest(null) return @@ -38,7 +44,7 @@ class CollectorMinionType : MinionType("collector", AxMinionsPlugin.INSTANCE.get ) entities?.filterIsInstance()?.forEach { item -> - if (state.inventory.firstEmpty() == -1) { + if (minion.getLinkedInventory()?.firstEmpty() == -1) { Warnings.CONTAINER_FULL.display(minion) return } diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/FarmerMinionType.kt b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/FarmerMinionType.kt index f0f8b66..7f6750c 100644 --- a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/FarmerMinionType.kt +++ b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/FarmerMinionType.kt @@ -3,10 +3,42 @@ package com.artillexstudios.axminions.minions.miniontype import com.artillexstudios.axminions.AxMinionsPlugin import com.artillexstudios.axminions.api.minions.Minion import com.artillexstudios.axminions.api.minions.miniontype.MinionType +import com.artillexstudios.axminions.utils.LocationUtils +import com.artillexstudios.axminions.utils.fastFor +import org.bukkit.Material +import org.bukkit.block.data.Ageable +import org.bukkit.inventory.ItemStack class FarmerMinionType : MinionType("farmer", AxMinionsPlugin.INSTANCE.getResource("minions/farmer.yml")!!) { override fun run(minion: Minion) { - TODO("Not yet implemented") + LocationUtils.getAllBlocksInRadius(minion.getLocation(), minion.getRange(), false).fastFor { location -> + val block = location.block + val drops = arrayListOf() + + when (block.type) { + Material.CACTUS, Material.SUGAR_CANE, Material.BAMBOO, Material.MELON, Material.PUMPKIN -> { + drops.addAll(block.getDrops(minion.getTool())) + block.type = Material.AIR + } + Material.COCOA_BEANS, Material.COCOA, Material.NETHER_WART, Material.WHEAT, Material.CARROTS, Material.BEETROOTS, Material.POTATOES -> { + val ageable = block.blockData as Ageable + if (ageable.age != ageable.maximumAge) return@fastFor + drops.addAll(block.getDrops(minion.getTool())) + ageable.age = 0 + block.blockData = ageable + } + Material.SWEET_BERRY_BUSH -> { + val ageable = block.blockData as Ageable + if (ageable.age != ageable.maximumAge) return@fastFor + drops.addAll(block.getDrops(minion.getTool())) + ageable.age = 1 + block.blockData = ageable + } + else -> return@fastFor + } + + minion.addToContainerOrDrop(drops) + } } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/FisherMinionType.kt b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/FisherMinionType.kt index 2674dae..fccee2b 100644 --- a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/FisherMinionType.kt +++ b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/FisherMinionType.kt @@ -3,10 +3,11 @@ package com.artillexstudios.axminions.minions.miniontype import com.artillexstudios.axminions.AxMinionsPlugin import com.artillexstudios.axminions.api.minions.Minion import com.artillexstudios.axminions.api.minions.miniontype.MinionType +import org.bukkit.loot.LootTables class FisherMinionType : MinionType("fisher", AxMinionsPlugin.INSTANCE.getResource("minions/fisher.yml")!!) { override fun run(minion: Minion) { - TODO("Not yet implemented") + } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/LumberMinionType.kt b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/LumberMinionType.kt index 35b968c..dca29bb 100644 --- a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/LumberMinionType.kt +++ b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/LumberMinionType.kt @@ -7,6 +7,6 @@ import com.artillexstudios.axminions.api.minions.miniontype.MinionType class LumberMinionType : MinionType("lumber", AxMinionsPlugin.INSTANCE.getResource("minions/lumber.yml")!!) { override fun run(minion: Minion) { - TODO("Not yet implemented") + } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/MinerMinionType.kt b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/MinerMinionType.kt index c104232..b007796 100644 --- a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/MinerMinionType.kt +++ b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/MinerMinionType.kt @@ -7,6 +7,6 @@ import com.artillexstudios.axminions.api.minions.miniontype.MinionType class MinerMinionType : MinionType("miner", AxMinionsPlugin.INSTANCE.getResource("minions/miner.yml")!!) { override fun run(minion: Minion) { - TODO("Not yet implemented") + } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/SellerMinionType.kt b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/SellerMinionType.kt index b0a880e..ab6189b 100644 --- a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/SellerMinionType.kt +++ b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/SellerMinionType.kt @@ -7,6 +7,6 @@ import com.artillexstudios.axminions.api.minions.miniontype.MinionType class SellerMinionType : MinionType("seller", AxMinionsPlugin.INSTANCE.getResource("minions/seller.yml")!!) { override fun run(minion: Minion) { - TODO("Not yet implemented") + } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/SlayerMinionType.kt b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/SlayerMinionType.kt index 384f317..d1486a0 100644 --- a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/SlayerMinionType.kt +++ b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/SlayerMinionType.kt @@ -7,6 +7,6 @@ import com.artillexstudios.axminions.api.minions.miniontype.MinionType class SlayerMinionType : MinionType("slayer", AxMinionsPlugin.INSTANCE.getResource("minions/slayer.yml")!!) { override fun run(minion: Minion) { - TODO("Not yet implemented") + } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/utils/LocationUtils.kt b/common/src/main/kotlin/com/artillexstudios/axminions/utils/LocationUtils.kt new file mode 100644 index 0000000..303b251 --- /dev/null +++ b/common/src/main/kotlin/com/artillexstudios/axminions/utils/LocationUtils.kt @@ -0,0 +1,36 @@ +package com.artillexstudios.axminions.utils + +import org.bukkit.Location +object LocationUtils { + + @JvmStatic + fun getAllBlocksInRadius(location: Location, radius: Double, filterEmpty: Boolean): ArrayList { + // Approximate the volume of the sphere + val blocks = ArrayList((2 * radius * radius * radius).toInt()) + + val blockX = location.blockX + val blockY = location.blockY + val blockZ = location.blockZ + + val rangeX = (blockX - radius).rangeTo((blockX + radius)).step(1.0) + val rangeY = (blockY - radius).rangeTo((blockY + radius)).step(1.0) + val rangeZ = (blockZ - radius).rangeTo((blockZ + radius)).step(1.0) + + val radiusSquared = radius * radius + val smallRadiusSquared = (radius - 1) * (radius -1) + + for (x in rangeX) { + for (y in rangeY) { + for (z in rangeZ) { + val distance = ((blockX - x) * (blockX - x) + ((blockZ - z) * (blockZ - z)) + ((blockY - y) * (blockY - y))) + + if (distance < radiusSquared && !(filterEmpty && distance < smallRadiusSquared)) { + blocks.add(Location(location.world, x, y, z)) + } + } + } + } + + return blocks + } +} \ No newline at end of file diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/utils/Ranges.kt b/common/src/main/kotlin/com/artillexstudios/axminions/utils/Ranges.kt new file mode 100644 index 0000000..7c99421 --- /dev/null +++ b/common/src/main/kotlin/com/artillexstudios/axminions/utils/Ranges.kt @@ -0,0 +1,16 @@ +package com.artillexstudios.axminions.utils + +// Thanks a lot to this hero! https://stackoverflow.com/a/44332139 +infix fun ClosedRange.step(step: Double): Iterable { + require(start.isFinite()) + require(endInclusive.isFinite()) + require(step > 0.0) { "Step must be positive, was: $step." } + + val sequence = generateSequence(start) { previous -> + if (previous == Double.POSITIVE_INFINITY) return@generateSequence null + val next = previous + step + if (next > endInclusive) null else next + } + + return sequence.asIterable() +} \ No newline at end of file diff --git a/common/src/main/resources/minions/collector.yml b/common/src/main/resources/minions/collector.yml index fca6e9e..51e9477 100644 --- a/common/src/main/resources/minions/collector.yml +++ b/common/src/main/resources/minions/collector.yml @@ -10,7 +10,7 @@ tool: - "NETHERITE_SHOVEL" item: - material: "player_head" + type: "player_head" texture: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvN2UzZDM2MzVjZTQxMWFiZjFlNGYzNzNkMTYxZDA3YjhjNDdlMzU5YjZjNTZmNzRiNDEzY2I0OTRhYzc0NmUyZCJ9fX0=" name: "<#FFEE00>Collector Minion" lore: @@ -25,7 +25,7 @@ item: gui: upgrade: - material: "gold_ingot" + type: "gold_ingot" name: "<#00CCFF>Upgrade minion" lore: - "" @@ -39,7 +39,7 @@ gui: - "" - "<#00CCFF>(!) Click here to upgrade your minion!" statistics: - material: "paper" + type: "paper" name: "<#FFEE00>Statistics" lore: - "" @@ -52,18 +52,18 @@ upgrades: speed: 160 items: helmet: - material: "player_head" + type: "player_head" texture: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvN2UzZDM2MzVjZTQxMWFiZjFlNGYzNzNkMTYxZDA3YjhjNDdlMzU5YjZjNTZmNzRiNDEzY2I0OTRhYzc0NmUyZCJ9fX0=" chestplate: - material: "leather_chestplate" + type: "leather_chestplate" color: "255, 230, 0" glow: false leggings: - material: "leather_leggings" + type: "leather_leggings" color: "255, 230, 0" glow: false boots: - material: "leather_boots" + type: "leather_boots" color: "255, 230, 0" glow: false 2: @@ -118,14 +118,14 @@ upgrades: actions: 50000 items: chestplate: - material: LEATHER_CHESTPLATE + type: LEATHER_CHESTPLATE color: "255, 200, 0" glow: true leggings: - material: LEATHER_LEGGINGS + type: LEATHER_LEGGINGS color: "255, 200, 0" glow: true boots: - material: LEATHER_BOOTS + type: LEATHER_BOOTS color: "255, 200, 0" glow: true \ No newline at end of file diff --git a/common/src/main/resources/minions/farmer.yml b/common/src/main/resources/minions/farmer.yml new file mode 100644 index 0000000..37a9481 --- /dev/null +++ b/common/src/main/resources/minions/farmer.yml @@ -0,0 +1,135 @@ +name: "[] <#33FF33>Farmer Minion []" + +tool: + material: + - "WOODEN_HOE" + - "STONE_HOE" + - "GOLDEN_HOE" + - "IRON_HOE" + - "DIAMOND_HOE" + - "NETHERITE_HOE" + +item: + type: "player_head" + texture: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDAxZTAzNWEzZDhkNjEyNjA3MmJjYmU1MmE5NzkxM2FjZTkzNTUyYTk5OTk1YjVkNDA3MGQ2NzgzYTMxZTkwOSJ9fX0=" + name: "<#33FF33>Collector Minion" + lore: + - "" + - " - Harvests and replants nearby crops." + - "" + - "<#33FF33>Statistics" + - " <#33FF33>❙ Level: <#AAFFAA>" + - " <#33FF33>❙ Harvested crops: <#AAFFAA>" + - "" + - "<#33FF33>(!) Place the minion and give it a hoe!" + +gui: + upgrade: + type: "gold_ingot" + name: "<#00CCFF>Upgrade minion" + lore: + - "" + - " - Level: » " + - " - Range: » " + - " - Speed: » " + - "" + - "<#00CCFF>Requirements:" + - " - Money: <#33FF33>$" + - " - Crops harvested: <#33FF33>" + - "" + - "<#00CCFF>(!) Click here to upgrade your minion!" + statistics: + type: "paper" + name: "<#33FF33>Statistics" + lore: + - "" + - " - Crops harvested: <#33FF33>" + - "" + +upgrades: + 1: + range: 2 + speed: 200 + items: + helmet: + type: "player_head" + texture: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDAxZTAzNWEzZDhkNjEyNjA3MmJjYmU1MmE5NzkxM2FjZTkzNTUyYTk5OTk1YjVkNDA3MGQ2NzgzYTMxZTkwOSJ9fX0=" + chestplate: + type: "leather_chestplate" + color: "50, 255, 50" + glow: false + leggings: + type: "leather_leggings" + color: "50, 255, 50" + glow: false + boots: + type: "leather_boots" + color: "50, 255, 50" + glow: false + 2: + range: 2.5 + speed: 190 + requirements: + money: 1000 + actions: 10 + 3: + range: 3 + speed: 180 + requirements: + money: 3000 + actions: 30 + 4: + range: 3.5 + speed: 170 + requirements: + money: 10000 + actions: 100 + 5: + range: 3.5 + speed: 160 + requirements: + money: 20000 + actions: 300 + 6: + range: 4 + speed: 150 + requirements: + money: 50000 + actions: 600 + 7: + range: 4.5 + speed: 140 + requirements: + money: 150000 + actions: 1000 + 8: + range: 5 + speed: 120 + requirements: + money: 500000 + actions: 1750 + 9: + range: 5.5 + speed: 110 + requirements: + money: 1000000 + actions: 25000 + 10: + range: 6 + speed: 100 + requirements: + money: 5000000 + actions: 5000 + items: + chestplate: + type: LEATHER_CHESTPLATE + color: "50, 225, 50" + glow: true + leggings: + type: LEATHER_LEGGINGS + color: "50, 225, 50" + glow: true + boots: + type: LEATHER_BOOTS + color: "50, 225, 50" + glow: true \ No newline at end of file diff --git a/common/src/main/resources/plugin.yml b/common/src/main/resources/plugin.yml new file mode 100644 index 0000000..5d8878c --- /dev/null +++ b/common/src/main/resources/plugin.yml @@ -0,0 +1,4 @@ +name: "AxMinions" +main: "com.artillexstudios.axminions.AxMinionsPlugin" +version: "1.0" +api-version: 1.19 \ No newline at end of file diff --git a/libs/AxAPI-1.0-SNAPSHOT.jar b/libs/AxAPI-1.0-SNAPSHOT.jar index c0e9eb8..bafb728 100644 Binary files a/libs/AxAPI-1.0-SNAPSHOT.jar and b/libs/AxAPI-1.0-SNAPSHOT.jar differ