mirror of
https://github.com/Artillex-Studios/AxMinions.git
synced 2024-11-23 11:45:36 +01:00
Work
This commit is contained in:
parent
985af5f6b6
commit
5495652ea9
@ -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<Minion>
|
||||
|
||||
fun getAxMinionsInstance(): AxPlugin
|
||||
|
||||
fun getMinionLimit(player: Player): Int
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
lateinit var INSTANCE: AxMinionsAPI
|
||||
|
@ -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(
|
||||
|
@ -13,16 +13,16 @@ import java.io.InputStream
|
||||
|
||||
class Messages(file: File, stream: InputStream) {
|
||||
companion object {
|
||||
@JvmField
|
||||
var PREFIX = AxMinionsAPI.INSTANCE.getMessages().get<String>("prefix")
|
||||
@JvmField
|
||||
var NO_CONTAINER_WARNING = AxMinionsAPI.INSTANCE.getMessages().get<String>("warnings.no-container")
|
||||
@JvmField
|
||||
var NO_TOOL_WARNING = AxMinionsAPI.INSTANCE.getMessages().get<String>("warnings.no-tool")
|
||||
@JvmField
|
||||
var NO_WATER_NEARBY_WARNING = AxMinionsAPI.INSTANCE.getMessages().get<String>("warnings.no-water-nearby")
|
||||
@JvmField
|
||||
var CONTAINER_FULL_WARNING = AxMinionsAPI.INSTANCE.getMessages().get<String>("warnings.container-full")
|
||||
@JvmStatic
|
||||
fun PREFIX() = AxMinionsAPI.INSTANCE.getMessages().get<String>("prefix")
|
||||
@JvmStatic
|
||||
fun NO_CONTAINER_WARNING() = AxMinionsAPI.INSTANCE.getMessages().get<String>("warnings.no-container")
|
||||
@JvmStatic
|
||||
fun NO_TOOL_WARNING() = AxMinionsAPI.INSTANCE.getMessages().get<String>("warnings.no-tool")
|
||||
@JvmStatic
|
||||
fun NO_WATER_NEARBY_WARNING() = AxMinionsAPI.INSTANCE.getMessages().get<String>("warnings.no-water-nearby")
|
||||
@JvmStatic
|
||||
fun CONTAINER_FULL_WARNING() = AxMinionsAPI.INSTANCE.getMessages().get<String>("warnings.container-full")
|
||||
}
|
||||
|
||||
private val config = Config(
|
||||
|
@ -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<ItemStack>)
|
||||
}
|
@ -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 <T> get(key: String, level: Int, defaultValue: T?, clazz: Class<T>): 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)
|
||||
}
|
@ -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<String, MinionType>()
|
||||
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<String, MinionType> {
|
||||
return Collections.unmodifiableMap(TYPES)
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
@ -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())
|
||||
}
|
||||
}
|
@ -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())
|
||||
}
|
||||
}
|
@ -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())
|
||||
}
|
||||
}
|
@ -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')
|
||||
}
|
||||
|
||||
|
@ -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<Runnable>
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -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<Minion> {
|
||||
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
|
||||
}
|
||||
}
|
@ -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) {
|
||||
|
||||
}
|
||||
}
|
@ -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()
|
||||
|
@ -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<String, String>()
|
||||
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>) {
|
||||
itemStack.forEach {
|
||||
addToContainerOrDrop(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadExtraData(data: String) {
|
||||
data.split("|").fastFor { split ->
|
||||
val secondSplit = split.split("=")
|
@ -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
|
||||
}
|
||||
|
@ -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<Minion>()
|
||||
|
||||
fun load(minion: Minion) {
|
||||
entities.add(minion)
|
||||
}
|
||||
|
||||
fun remove(minion: Minion) {
|
||||
entities.remove(minion)
|
||||
}
|
||||
|
||||
fun getMinions(): List<Minion> {
|
||||
return Collections.unmodifiableList(entities)
|
||||
}
|
||||
}
|
@ -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<Item>()?.forEach { item ->
|
||||
if (state.inventory.firstEmpty() == -1) {
|
||||
if (minion.getLinkedInventory()?.firstEmpty() == -1) {
|
||||
Warnings.CONTAINER_FULL.display(minion)
|
||||
return
|
||||
}
|
||||
|
@ -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<ItemStack>()
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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")
|
||||
|
||||
}
|
||||
}
|
@ -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")
|
||||
|
||||
}
|
||||
}
|
@ -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")
|
||||
|
||||
}
|
||||
}
|
@ -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")
|
||||
|
||||
}
|
||||
}
|
@ -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")
|
||||
|
||||
}
|
||||
}
|
@ -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<Location> {
|
||||
// Approximate the volume of the sphere
|
||||
val blocks = ArrayList<Location>((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
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.artillexstudios.axminions.utils
|
||||
|
||||
// Thanks a lot to this hero! https://stackoverflow.com/a/44332139
|
||||
infix fun ClosedRange<Double>.step(step: Double): Iterable<Double> {
|
||||
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()
|
||||
}
|
@ -10,7 +10,7 @@ tool:
|
||||
- "NETHERITE_SHOVEL"
|
||||
|
||||
item:
|
||||
material: "player_head"
|
||||
type: "player_head"
|
||||
texture: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvN2UzZDM2MzVjZTQxMWFiZjFlNGYzNzNkMTYxZDA3YjhjNDdlMzU5YjZjNTZmNzRiNDEzY2I0OTRhYzc0NmUyZCJ9fX0="
|
||||
name: "<#FFEE00>Collector <white>Minion"
|
||||
lore:
|
||||
@ -25,7 +25,7 @@ item:
|
||||
|
||||
gui:
|
||||
upgrade:
|
||||
material: "gold_ingot"
|
||||
type: "gold_ingot"
|
||||
name: "<#00CCFF><b>Upgrade minion"
|
||||
lore:
|
||||
- ""
|
||||
@ -39,7 +39,7 @@ gui:
|
||||
- ""
|
||||
- "<#00CCFF><b>(!)</b> Click here to upgrade your minion!"
|
||||
statistics:
|
||||
material: "paper"
|
||||
type: "paper"
|
||||
name: "<#FFEE00><b>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
|
135
common/src/main/resources/minions/farmer.yml
Normal file
135
common/src/main/resources/minions/farmer.yml
Normal file
@ -0,0 +1,135 @@
|
||||
name: "<level_color>[<level>] <#33FF33>Farmer <white>Minion <gray>[<owner>]"
|
||||
|
||||
tool:
|
||||
material:
|
||||
- "WOODEN_HOE"
|
||||
- "STONE_HOE"
|
||||
- "GOLDEN_HOE"
|
||||
- "IRON_HOE"
|
||||
- "DIAMOND_HOE"
|
||||
- "NETHERITE_HOE"
|
||||
|
||||
item:
|
||||
type: "player_head"
|
||||
texture: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDAxZTAzNWEzZDhkNjEyNjA3MmJjYmU1MmE5NzkxM2FjZTkzNTUyYTk5OTk1YjVkNDA3MGQ2NzgzYTMxZTkwOSJ9fX0="
|
||||
name: "<#33FF33>Collector <white>Minion"
|
||||
lore:
|
||||
- ""
|
||||
- " <gray>- <white>Harvests and replants nearby crops."
|
||||
- ""
|
||||
- "<#33FF33>Statistics"
|
||||
- " <#33FF33>❙ <white>Level: <#AAFFAA><level>"
|
||||
- " <#33FF33>❙ <white>Harvested crops: <#AAFFAA><items>"
|
||||
- ""
|
||||
- "<#33FF33><b>(!)</b> Place the minion and give it a hoe!"
|
||||
|
||||
gui:
|
||||
upgrade:
|
||||
type: "gold_ingot"
|
||||
name: "<#00CCFF><b>Upgrade minion"
|
||||
lore:
|
||||
- ""
|
||||
- " <gray>- <white>Level: <green><current_level> » <dark_green><next_level>"
|
||||
- " <gray>- <white>Range: <green><current_range> » <dark_green><next_range>"
|
||||
- " <gray>- <white>Speed: <green><current_speed> » <dark_green><next_speed>"
|
||||
- ""
|
||||
- "<#00CCFF>Requirements:"
|
||||
- " <gray>- <white>Money: <#33FF33><price>$"
|
||||
- " <gray>- <white>Crops harvested: <#33FF33><required_actions>"
|
||||
- ""
|
||||
- "<#00CCFF><b>(!)</b> Click here to upgrade your minion!"
|
||||
statistics:
|
||||
type: "paper"
|
||||
name: "<#33FF33><b>Statistics"
|
||||
lore:
|
||||
- ""
|
||||
- " <gray>- <white>Crops harvested: <#33FF33><statistic_collected>"
|
||||
- ""
|
||||
|
||||
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
|
4
common/src/main/resources/plugin.yml
Normal file
4
common/src/main/resources/plugin.yml
Normal file
@ -0,0 +1,4 @@
|
||||
name: "AxMinions"
|
||||
main: "com.artillexstudios.axminions.AxMinionsPlugin"
|
||||
version: "1.0"
|
||||
api-version: 1.19
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user