mirror of
https://github.com/Artillex-Studios/AxMinions.git
synced 2025-01-08 19:07:41 +01:00
Something is really broken with the minions
This commit is contained in:
parent
8b83c4867f
commit
f34b153da2
@ -38,6 +38,8 @@ class Config(file: File, stream: InputStream) {
|
||||
fun PRICES_HOOK() = AxMinionsAPI.INSTANCE.getConfig().get("hooks.prices", "ShopGUIPlus")
|
||||
@JvmStatic
|
||||
fun GUI_SIZE() = AxMinionsAPI.INSTANCE.getConfig().get<Int>("gui.size")
|
||||
@JvmStatic
|
||||
fun DEBUG() = AxMinionsAPI.INSTANCE.getConfig().get<Boolean>("debug")
|
||||
}
|
||||
|
||||
private val config = Config(
|
||||
|
@ -1,8 +1,10 @@
|
||||
package com.artillexstudios.axminions.api.minions
|
||||
|
||||
enum class Direction(val yaw: Float) {
|
||||
NORTH(180f),
|
||||
WEST(90f),
|
||||
SOUTH(0f),
|
||||
EAST(-90f);
|
||||
import org.bukkit.block.BlockFace
|
||||
|
||||
enum class Direction(val yaw: Float, val facing: BlockFace) {
|
||||
NORTH(180f, BlockFace.NORTH),
|
||||
WEST(90f, BlockFace.WEST),
|
||||
SOUTH(0f, BlockFace.SOUTH),
|
||||
EAST(-90f, BlockFace.EAST);
|
||||
}
|
@ -103,4 +103,10 @@ interface Minion : InventoryHolder {
|
||||
fun setRange(range: Double)
|
||||
|
||||
fun setNextAction(nextAction: Int)
|
||||
|
||||
fun markDirty()
|
||||
|
||||
fun damageTool(amount: Int = 1)
|
||||
|
||||
fun canUseTool(): Boolean
|
||||
}
|
@ -6,6 +6,7 @@ import com.artillexstudios.axapi.libs.kyori.adventure.text.minimessage.tag.resol
|
||||
import com.artillexstudios.axapi.utils.ItemBuilder
|
||||
import com.artillexstudios.axminions.api.AxMinionsAPI
|
||||
import com.artillexstudios.axminions.api.minions.Minion
|
||||
import com.artillexstudios.axminions.api.utils.Keys
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
@ -41,13 +42,14 @@ abstract class MinionType(private val name: String, private val defaults: InputS
|
||||
if (!minion.isTicking()) return
|
||||
if (!shouldRun(minion)) return
|
||||
|
||||
minion.resetAnimation()
|
||||
run(minion)
|
||||
}
|
||||
|
||||
fun getItem(level: Int = 1): ItemStack {
|
||||
val builder = ItemBuilder(config.getSection("item"), Placeholder.unparsed("level", level.toString()), Placeholder.unparsed("actions", "0"))
|
||||
builder.storePersistentData(MinionTypes.getMinionKey(), PersistentDataType.STRING, name)
|
||||
builder.storePersistentData(MinionTypes.getLevelKey(), PersistentDataType.INTEGER, level)
|
||||
fun getItem(level: Int = 1, actions: Long = 0): ItemStack {
|
||||
val builder = ItemBuilder(config.getSection("item"), Placeholder.unparsed("level", level.toString()), Placeholder.unparsed("actions", actions.toString()))
|
||||
builder.storePersistentData(Keys.MINION_TYPE, PersistentDataType.STRING, name)
|
||||
builder.storePersistentData(Keys.LEVEL, PersistentDataType.INTEGER, level)
|
||||
|
||||
return builder.clonedGet()
|
||||
}
|
||||
|
@ -7,9 +7,7 @@ import java.util.Collections
|
||||
|
||||
object MinionTypes {
|
||||
private val TYPES = hashMapOf<String, MinionType>()
|
||||
private val MINION_KEY = NamespacedKey(AxMinionsAPI.INSTANCE.getAxMinionsInstance(), "minion_type")
|
||||
private val LEVEL_KEY = NamespacedKey(AxMinionsAPI.INSTANCE.getAxMinionsInstance(), "level")
|
||||
private val GUI_KEY = NamespacedKey(AxMinionsAPI.INSTANCE.getAxMinionsInstance(), "gui_item")
|
||||
|
||||
|
||||
@JvmStatic
|
||||
fun register(type: MinionType): MinionType {
|
||||
@ -32,21 +30,6 @@ object MinionTypes {
|
||||
return TYPES[name]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getMinionKey(): NamespacedKey {
|
||||
return MINION_KEY
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getLevelKey(): NamespacedKey {
|
||||
return LEVEL_KEY
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getGuiKey(): NamespacedKey {
|
||||
return GUI_KEY
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getMinionTypes(): Map<String, MinionType> {
|
||||
return Collections.unmodifiableMap(TYPES)
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.artillexstudios.axminions.utils
|
||||
package com.artillexstudios.axminions.api.utils
|
||||
|
||||
inline fun <T> Array<T>.fastFor(action: (T) -> Unit) {
|
||||
val indices = indices
|
@ -0,0 +1,36 @@
|
||||
package com.artillexstudios.axminions.api.utils
|
||||
|
||||
class CoolDown<T> : HashMap<T, Long>() {
|
||||
|
||||
fun add(value: T, time: Long) {
|
||||
expire()
|
||||
put(value, System.currentTimeMillis() + time)
|
||||
}
|
||||
|
||||
override fun containsKey(key: T): Boolean {
|
||||
expire()
|
||||
return super.containsKey(key)
|
||||
}
|
||||
|
||||
|
||||
fun contains(value: T): Boolean {
|
||||
return containsKey(value)
|
||||
}
|
||||
|
||||
override fun remove(key: T): Long? {
|
||||
expire()
|
||||
return super.remove(key)
|
||||
}
|
||||
|
||||
private fun expire() {
|
||||
val currentTime = System.currentTimeMillis()
|
||||
|
||||
val iterator = iterator()
|
||||
while (iterator.hasNext()) {
|
||||
val next = iterator.next()
|
||||
if (next.value <= currentTime) {
|
||||
iterator.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.artillexstudios.axminions.api.utils
|
||||
|
||||
import com.artillexstudios.axminions.api.AxMinionsAPI
|
||||
import org.bukkit.NamespacedKey
|
||||
|
||||
object Keys {
|
||||
@JvmField
|
||||
val MINION_TYPE = NamespacedKey(AxMinionsAPI.INSTANCE.getAxMinionsInstance(), "minion_type")
|
||||
@JvmField
|
||||
val LEVEL = NamespacedKey(AxMinionsAPI.INSTANCE.getAxMinionsInstance(), "level")
|
||||
@JvmField
|
||||
val GUI = NamespacedKey(AxMinionsAPI.INSTANCE.getAxMinionsInstance(), "gui_item")
|
||||
@JvmField
|
||||
val STATISTICS = NamespacedKey(AxMinionsAPI.INSTANCE.getAxMinionsInstance(), "statistics")
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
package com.artillexstudios.axminions.utils
|
||||
package com.artillexstudios.axminions.api.utils
|
||||
|
||||
import kotlin.math.roundToInt
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.block.BlockFace
|
||||
|
||||
object LocationUtils {
|
||||
|
||||
@JvmStatic
|
||||
@ -34,4 +37,17 @@ object LocationUtils {
|
||||
|
||||
return blocks
|
||||
}
|
||||
|
||||
fun getAllBlocksFacing(location: Location, radius: Double, face: BlockFace): ArrayList<Location> {
|
||||
val blocks = ArrayList<Location>(radius.toInt())
|
||||
|
||||
val modX = face.modX
|
||||
val modZ = face.modZ
|
||||
|
||||
for (i in 1..radius.roundToInt()) {
|
||||
blocks.add(location.clone().add(i * modX.toDouble(), 0.0, i * modZ.toDouble()))
|
||||
}
|
||||
|
||||
return blocks
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package com.artillexstudios.axminions.api.utils
|
||||
|
||||
import java.util.LinkedList
|
||||
import java.util.Queue
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.block.Block
|
||||
import org.bukkit.block.BlockFace
|
||||
|
||||
object MinionUtils {
|
||||
private val FACES =
|
||||
arrayOf(BlockFace.DOWN, BlockFace.UP, BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST)
|
||||
|
||||
@JvmStatic
|
||||
fun getPlant(block: Block): ArrayList<Block> {
|
||||
val blocks = arrayListOf<Block>()
|
||||
var loc = block.location.clone()
|
||||
|
||||
for (i in block.y downTo -65) {
|
||||
loc.add(0.0, -1.0, 0.0)
|
||||
val locBlock = loc.block
|
||||
if (!(locBlock.type == block.type && locBlock.getRelative(BlockFace.DOWN) == block)) break
|
||||
|
||||
blocks.add(locBlock)
|
||||
}
|
||||
|
||||
loc = block.location.clone()
|
||||
for (i in block.y..328) {
|
||||
loc.add(0.0, 1.0, 0.0)
|
||||
val locBlock = loc.block
|
||||
if (locBlock.type != block.type) break
|
||||
|
||||
blocks.add(locBlock)
|
||||
}
|
||||
|
||||
return blocks
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun isStoneGenerator(location: Location): Boolean {
|
||||
var lava = false
|
||||
var water = false
|
||||
|
||||
FACES.fastFor {
|
||||
val relative = location.block.getRelative(it)
|
||||
val type = relative.type
|
||||
if (!lava) {
|
||||
lava = type == Material.LAVA
|
||||
}
|
||||
|
||||
if (!water) {
|
||||
water = type == Material.WATER
|
||||
}
|
||||
|
||||
if (water && lava) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getTree(startBlock: Block): List<Block> {
|
||||
val queue: Queue<Block> = LinkedList()
|
||||
val visited = mutableSetOf<Block>()
|
||||
val tree = mutableListOf<Block>()
|
||||
|
||||
queue.add(startBlock)
|
||||
|
||||
while (queue.isNotEmpty()) {
|
||||
val block = queue.poll()
|
||||
|
||||
val type = block.type.toString()
|
||||
if (type.endsWith("_WOOD") || type.endsWith("_LOG")) {
|
||||
tree.add(block)
|
||||
|
||||
FACES.fastFor {
|
||||
val relative = block.getRelative(it)
|
||||
if (!visited.contains(relative)) {
|
||||
queue.add(relative)
|
||||
visited.add(relative)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tree
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.artillexstudios.axminions.utils
|
||||
package com.artillexstudios.axminions.api.utils
|
||||
|
||||
// Thanks a lot to this hero! https://stackoverflow.com/a/44332139
|
||||
infix fun ClosedRange<Double>.step(step: Double): Iterable<Double> {
|
@ -15,7 +15,7 @@ abstract class Warning(private val name: String) {
|
||||
fun display(minion: Minion) {
|
||||
if (minion.getWarning() == null) {
|
||||
val hologram = HologramFactory.get()
|
||||
.spawnHologram(minion.getLocation().clone().add(0.0, 1.15, 0.0), minion.getLocation().toString())
|
||||
.spawnHologram(minion.getLocation().clone().add(0.0, 1.35, 0.0), minion.getLocation().toString())
|
||||
hologram.addLine(getContent())
|
||||
minion.setWarning(this)
|
||||
minion.setWarningHologram(hologram)
|
||||
|
38
build.gradle
38
build.gradle
@ -61,6 +61,30 @@ allprojects {
|
||||
maven {
|
||||
url = uri('https://repo.alessiodp.com/releases/')
|
||||
}
|
||||
|
||||
maven {
|
||||
url = uri('https://repo.rosewooddev.io/repository/public/')
|
||||
}
|
||||
|
||||
maven {
|
||||
url = uri('https://repo.bg-software.com/repository/api/')
|
||||
}
|
||||
|
||||
maven {
|
||||
url = uri('https://repo.essentialsx.net/releases/')
|
||||
}
|
||||
|
||||
maven {
|
||||
url = uri('https://maven.enginehub.org/repo/')
|
||||
}
|
||||
|
||||
maven {
|
||||
url = uri('https://repo.codemc.org/repository/maven-snapshots')
|
||||
}
|
||||
|
||||
maven {
|
||||
url = uri('https://repo.codemc.org/repository/maven-public/')
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@ -71,6 +95,20 @@ allprojects {
|
||||
compileOnly 'com.github.brcdev-minecraft:shopgui-api:3.0.0'
|
||||
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.9.0'
|
||||
compileOnly 'com.h2database:h2:2.2.220'
|
||||
compileOnly 'dev.rosewood:rosestacker:1.5.9'
|
||||
compileOnly 'com.bgsoftware:WildStackerAPI:2023.2'
|
||||
compileOnly 'net.essentialsx:EssentialsX:2.19.0'
|
||||
compileOnly 'com.github.Gypopo:EconomyShopGUI-API:1.6.0'
|
||||
compileOnly 'com.github.Gypopo:EconomyShopGUI-API:1.6.0'
|
||||
compileOnly 'com.github.brcdev-minecraft:shopgui-api:3.0.0'
|
||||
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.1.0-SNAPSHOT'
|
||||
compileOnly 'com.bgsoftware:SuperiorSkyblockAPI:2023.2'
|
||||
compileOnly 'world.bentobox:bentobox:1.24.0-SNAPSHOT'
|
||||
compileOnly 'com.github.TechFortress:GriefPrevention:16.18'
|
||||
compileOnly 'com.github.angeschossen:LandsAPI:6.29.12'
|
||||
compileOnly 'com.intellectualsites.plotsquared:plotsquared-core:7.0.0-rc.4'
|
||||
compileOnly 'com.intellectualsites.plotsquared:plotsquared-bukkit:7.0.0-rc.4'
|
||||
implementation platform('com.intellectualsites.bom:bom-newest:1.35')
|
||||
implementation files('../libs/AxAPI-1.0-SNAPSHOT.jar')
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@ import com.artillexstudios.axminions.listeners.MinionPlaceListener
|
||||
import com.artillexstudios.axminions.minions.MinionTicker
|
||||
import com.artillexstudios.axminions.minions.miniontype.CollectorMinionType
|
||||
import com.artillexstudios.axminions.minions.miniontype.FarmerMinionType
|
||||
import com.artillexstudios.axminions.minions.miniontype.LumberMinionType
|
||||
import com.artillexstudios.axminions.minions.miniontype.MinerMinionType
|
||||
import org.bukkit.Bukkit
|
||||
import java.io.File
|
||||
|
||||
@ -47,12 +49,13 @@ class AxMinionsPlugin : AxPlugin() {
|
||||
override fun load() {
|
||||
INSTANCE = this
|
||||
AxMinionsAPI.INSTANCE = AxMinionsAPIImpl(this)
|
||||
integrations = Integrations()
|
||||
}
|
||||
|
||||
override fun enable() {
|
||||
AxMinionsPlugin.config = Config(File(dataFolder, "config.yml"), getResource("config.yml")!!)
|
||||
messages = Messages(File(dataFolder, "messages.yml"), getResource("messages.yml")!!)
|
||||
integrations = Integrations()
|
||||
integrations.reload()
|
||||
|
||||
loadDataHandler()
|
||||
dataQueue = ThreadedQueue("AxMinions-Database-Queue")
|
||||
@ -60,6 +63,8 @@ class AxMinionsPlugin : AxPlugin() {
|
||||
MinionTypes.also {
|
||||
it.register(CollectorMinionType())
|
||||
it.register(FarmerMinionType())
|
||||
it.register(MinerMinionType())
|
||||
it.register(LumberMinionType())
|
||||
}
|
||||
|
||||
val handler = BukkitCommandHandler.create(this)
|
||||
|
@ -14,7 +14,7 @@ import com.artillexstudios.axminions.api.AxMinionsAPI
|
||||
import com.artillexstudios.axminions.api.config.Messages
|
||||
import com.artillexstudios.axminions.api.minions.miniontype.MinionType
|
||||
import com.artillexstudios.axminions.api.minions.miniontype.MinionTypes
|
||||
import com.artillexstudios.axminions.utils.fastFor
|
||||
import com.artillexstudios.axminions.api.utils.fastFor
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
@ -50,6 +50,10 @@ class AxMinionsCommand {
|
||||
it.value.getConfig().reload()
|
||||
}
|
||||
|
||||
AxMinionsAPI.INSTANCE.getMinions().fastFor {
|
||||
it.markDirty()
|
||||
}
|
||||
|
||||
sender.sendMessage(
|
||||
StringUtils.formatToString(
|
||||
Messages.PREFIX() + Messages.RELOAD_SUCCESS(),
|
||||
|
@ -16,6 +16,11 @@ import com.artillexstudios.axminions.integrations.prices.CMIIntegration
|
||||
import com.artillexstudios.axminions.integrations.prices.EconomyShopGUIIntegration
|
||||
import com.artillexstudios.axminions.integrations.prices.EssentialsIntegration
|
||||
import com.artillexstudios.axminions.integrations.prices.ShopGUIPlusIntegration
|
||||
import com.artillexstudios.axminions.integrations.protection.BentoBoxIntegration
|
||||
import com.artillexstudios.axminions.integrations.protection.GriefPreventionIntegration
|
||||
import com.artillexstudios.axminions.integrations.protection.LandsIntegration
|
||||
import com.artillexstudios.axminions.integrations.protection.SuperiorSkyBlock2Integration
|
||||
import com.artillexstudios.axminions.integrations.protection.WorldGuardIntegration
|
||||
import com.artillexstudios.axminions.integrations.stacker.DefaultStackerIntegration
|
||||
import com.artillexstudios.axminions.integrations.stacker.RoseStackerIntegration
|
||||
import com.artillexstudios.axminions.integrations.stacker.WildStackerIntegration
|
||||
@ -26,7 +31,7 @@ class Integrations : Integrations {
|
||||
private lateinit var stackerIntegration: StackerIntegration
|
||||
private lateinit var pricesIntegration: PricesIntegration
|
||||
private lateinit var economyIntegration: EconomyIntegration
|
||||
private lateinit var protectionIntegrations: ProtectionIntegrations
|
||||
private val protectionIntegrations = com.artillexstudios.axminions.integrations.protection.ProtectionIntegrations()
|
||||
|
||||
override fun getStackerIntegration(): StackerIntegration {
|
||||
return stackerIntegration
|
||||
@ -107,7 +112,27 @@ class Integrations : Integrations {
|
||||
}
|
||||
}
|
||||
|
||||
protectionIntegrations.clear()
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("SuperiorSkyblock2") != null) {
|
||||
register(SuperiorSkyBlock2Integration())
|
||||
}
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null) {
|
||||
register(WorldGuardIntegration())
|
||||
}
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("BentoBox") != null) {
|
||||
register(BentoBoxIntegration())
|
||||
}
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("GriefPrevention") != null) {
|
||||
register(GriefPreventionIntegration())
|
||||
}
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("Lands") != null) {
|
||||
register(LandsIntegration())
|
||||
}
|
||||
}
|
||||
|
||||
override fun register(integration: Integration) {
|
||||
@ -117,7 +142,7 @@ class Integrations : Integrations {
|
||||
}
|
||||
|
||||
is ProtectionIntegration -> {
|
||||
// Hook into protection
|
||||
protectionIntegrations.register(integration)
|
||||
}
|
||||
|
||||
is EconomyIntegration -> {
|
||||
@ -132,6 +157,7 @@ class Integrations : Integrations {
|
||||
throw InvalidIntegrationException("There is no builtin integration that the following class extends: ${integration::class.java}")
|
||||
}
|
||||
}
|
||||
integration.register()
|
||||
}
|
||||
|
||||
private fun isPluginLoaded(pluginName: String): Boolean {
|
||||
@ -147,6 +173,14 @@ class Integrations : Integrations {
|
||||
}
|
||||
|
||||
override fun deregister(integration: Integration) {
|
||||
TODO("Not yet implemented")
|
||||
when (integration) {
|
||||
is ProtectionIntegration -> {
|
||||
protectionIntegrations.deregister(integration)
|
||||
}
|
||||
|
||||
else -> {
|
||||
throw InvalidIntegrationException("You can only unregister a protection integration!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import com.artillexstudios.axminions.api.integrations.types.EconomyIntegration
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class PlayerPointsIntegration : EconomyIntegration {
|
||||
|
||||
override fun getBalance(player: Player): Double {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
@ -1,22 +1,28 @@
|
||||
package com.artillexstudios.axminions.integrations.economy
|
||||
|
||||
import com.artillexstudios.axminions.api.integrations.types.EconomyIntegration
|
||||
import net.milkbowl.vault.economy.Economy
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class VaultIntegration : EconomyIntegration {
|
||||
private lateinit var economy: Economy
|
||||
|
||||
override fun getBalance(player: Player): Double {
|
||||
TODO("Not yet implemented")
|
||||
return economy.getBalance(player)
|
||||
}
|
||||
|
||||
override fun giveBalance(player: Player, amount: Double) {
|
||||
TODO("Not yet implemented")
|
||||
economy.depositPlayer(player, amount)
|
||||
}
|
||||
|
||||
override fun takeBalance(player: Player, amount: Double) {
|
||||
TODO("Not yet implemented")
|
||||
economy.withdrawPlayer(player, amount)
|
||||
}
|
||||
|
||||
override fun register() {
|
||||
TODO("Not yet implemented")
|
||||
val rsp = Bukkit.getServicesManager().getRegistration(Economy::class.java) ?: return
|
||||
|
||||
economy = rsp.provider
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import com.artillexstudios.axminions.api.integrations.types.PricesIntegration
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
class CMIIntegration : PricesIntegration {
|
||||
|
||||
override fun getPrice(itemStack: ItemStack): Double {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
@ -1,14 +1,17 @@
|
||||
package com.artillexstudios.axminions.integrations.prices
|
||||
|
||||
import com.artillexstudios.axminions.api.integrations.types.PricesIntegration
|
||||
import me.gypopo.economyshopgui.api.EconomyShopGUIHook
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
class EconomyShopGUIIntegration : PricesIntegration {
|
||||
|
||||
override fun getPrice(itemStack: ItemStack): Double {
|
||||
TODO("Not yet implemented")
|
||||
val item = EconomyShopGUIHook.getShopItem(itemStack) ?: return 0.0
|
||||
return EconomyShopGUIHook.getItemSellPrice(item, itemStack) ?: 0.0
|
||||
}
|
||||
|
||||
override fun register() {
|
||||
TODO("Not yet implemented")
|
||||
|
||||
}
|
||||
}
|
@ -1,14 +1,18 @@
|
||||
package com.artillexstudios.axminions.integrations.prices
|
||||
|
||||
import com.artillexstudios.axminions.api.integrations.types.PricesIntegration
|
||||
import com.earth2me.essentials.IEssentials
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
class EssentialsIntegration : PricesIntegration {
|
||||
private lateinit var manager: IEssentials;
|
||||
|
||||
override fun getPrice(itemStack: ItemStack): Double {
|
||||
TODO("Not yet implemented")
|
||||
return manager.worth.getPrice(manager, itemStack).toDouble() * itemStack.amount
|
||||
}
|
||||
|
||||
override fun register() {
|
||||
TODO("Not yet implemented")
|
||||
manager = Bukkit.getPluginManager().getPlugin("Essentials") as IEssentials
|
||||
}
|
||||
}
|
@ -1,15 +1,16 @@
|
||||
package com.artillexstudios.axminions.integrations.prices
|
||||
|
||||
import com.artillexstudios.axminions.api.integrations.types.PricesIntegration
|
||||
import net.brcdev.shopgui.ShopGuiPlusApi
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
class ShopGUIPlusIntegration : PricesIntegration {
|
||||
|
||||
override fun getPrice(itemStack: ItemStack): Double {
|
||||
TODO("Not yet implemented")
|
||||
return ShopGuiPlusApi.getItemStackPriceSell(itemStack)
|
||||
}
|
||||
|
||||
override fun register() {
|
||||
TODO("Not yet implemented")
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.artillexstudios.axminions.integrations.protection
|
||||
|
||||
import com.artillexstudios.axminions.api.integrations.types.ProtectionIntegration
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.entity.Player
|
||||
import world.bentobox.bentobox.BentoBox
|
||||
|
||||
class BentoBoxIntegration : ProtectionIntegration {
|
||||
|
||||
override fun canBuildAt(player: Player, location: Location): Boolean {
|
||||
val island = BentoBox.getInstance().islands.getIslandAt(location)
|
||||
|
||||
return island.map {
|
||||
player.uniqueId in it.memberSet
|
||||
}.orElse(true)
|
||||
}
|
||||
|
||||
override fun register() {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.artillexstudios.axminions.integrations.protection
|
||||
|
||||
import com.artillexstudios.axminions.api.integrations.types.ProtectionIntegration
|
||||
import me.ryanhamshire.GriefPrevention.GriefPrevention
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class GriefPreventionIntegration : ProtectionIntegration {
|
||||
|
||||
override fun canBuildAt(player: Player, location: Location): Boolean {
|
||||
return GriefPrevention.instance.allowBuild(player, location) == null
|
||||
}
|
||||
|
||||
override fun register() {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.artillexstudios.axminions.integrations.protection
|
||||
|
||||
import com.artillexstudios.axminions.AxMinionsPlugin
|
||||
import com.artillexstudios.axminions.api.integrations.types.ProtectionIntegration
|
||||
import me.angeschossen.lands.api.LandsIntegration
|
||||
import me.angeschossen.lands.api.flags.type.Flags
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class LandsIntegration : ProtectionIntegration {
|
||||
|
||||
override fun canBuildAt(player: Player, location: Location): Boolean {
|
||||
val api = LandsIntegration.of(AxMinionsPlugin.INSTANCE)
|
||||
val world = api.getWorld(location.world ?: return true) ?: return true
|
||||
|
||||
return world.hasRoleFlag(player.uniqueId, location, Flags.BLOCK_PLACE);
|
||||
}
|
||||
|
||||
override fun register() {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.artillexstudios.axminions.integrations.protection
|
||||
|
||||
import com.artillexstudios.axminions.api.integrations.types.ProtectionIntegration
|
||||
import com.artillexstudios.axminions.api.integrations.types.ProtectionIntegrations
|
||||
import com.artillexstudios.axminions.api.utils.fastFor
|
||||
import java.util.Collections
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class ProtectionIntegrations : ProtectionIntegrations {
|
||||
private val integrations = arrayListOf<ProtectionIntegration>()
|
||||
|
||||
override fun getProtectionIntegrations(): List<ProtectionIntegration> {
|
||||
return Collections.unmodifiableList(integrations)
|
||||
}
|
||||
|
||||
override fun canBuildAt(player: Player, location: Location): Boolean {
|
||||
integrations.fastFor {
|
||||
if (!it.canBuildAt(player, location)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
integrations.clear()
|
||||
}
|
||||
|
||||
fun register(integration: ProtectionIntegration) {
|
||||
integrations.add(integration)
|
||||
}
|
||||
|
||||
fun deregister(integration: ProtectionIntegration) {
|
||||
integrations.remove(integration)
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.artillexstudios.axminions.integrations.protection
|
||||
|
||||
import com.artillexstudios.axminions.api.integrations.types.ProtectionIntegration
|
||||
import com.bgsoftware.superiorskyblock.api.SuperiorSkyblockAPI
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class SuperiorSkyBlock2Integration : ProtectionIntegration {
|
||||
|
||||
override fun canBuildAt(player: Player, location: Location): Boolean {
|
||||
val localPlayer = SuperiorSkyblockAPI.getPlayer(player.uniqueId)
|
||||
|
||||
val island = SuperiorSkyblockAPI.getIslandAt(location) ?: return true
|
||||
|
||||
return island.isMember(localPlayer)
|
||||
}
|
||||
|
||||
override fun register() {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.artillexstudios.axminions.integrations.protection
|
||||
|
||||
import com.artillexstudios.axminions.api.integrations.types.ProtectionIntegration
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter
|
||||
import com.sk89q.worldguard.WorldGuard
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin
|
||||
import com.sk89q.worldguard.protection.flags.Flags
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class WorldGuardIntegration : ProtectionIntegration {
|
||||
|
||||
override fun canBuildAt(player: Player, location: Location): Boolean {
|
||||
val localPlayer = WorldGuardPlugin.inst().wrapPlayer(player)
|
||||
val world = BukkitAdapter.adapt(player.world)
|
||||
|
||||
if (WorldGuard.getInstance().platform.sessionManager.hasBypass(localPlayer, world)) {
|
||||
return true
|
||||
}
|
||||
|
||||
val container = WorldGuard.getInstance().platform.regionContainer
|
||||
val query = container.createQuery()
|
||||
|
||||
return query.testState(BukkitAdapter.adapt(location), localPlayer, Flags.BUILD)
|
||||
}
|
||||
|
||||
override fun register() {
|
||||
|
||||
}
|
||||
}
|
@ -1,25 +1,28 @@
|
||||
package com.artillexstudios.axminions.integrations.stacker
|
||||
|
||||
import com.artillexstudios.axminions.api.integrations.types.StackerIntegration
|
||||
import dev.rosewood.rosestacker.api.RoseStackerAPI
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.entity.Item
|
||||
import org.bukkit.entity.LivingEntity
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
class RoseStackerIntegration : StackerIntegration {
|
||||
lateinit var instance: RoseStackerAPI
|
||||
|
||||
override fun getStackSize(entity: LivingEntity): Long {
|
||||
TODO("Not yet implemented")
|
||||
return instance.getStackedEntity(entity)?.stackSize?.toLong() ?: 1
|
||||
}
|
||||
|
||||
override fun getStackSize(item: Item): Long {
|
||||
TODO("Not yet implemented")
|
||||
return instance.getStackedItem(item)?.stackSize?.toLong() ?: 1
|
||||
}
|
||||
|
||||
override fun dropItemAt(itemStack: ItemStack, amount: Int, location: Location) {
|
||||
TODO("Not yet implemented")
|
||||
instance.dropItemStack(itemStack, amount, location, false)
|
||||
}
|
||||
|
||||
override fun register() {
|
||||
TODO("Not yet implemented")
|
||||
instance = RoseStackerAPI.getInstance()
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package com.artillexstudios.axminions.integrations.stacker
|
||||
|
||||
import com.artillexstudios.axminions.api.integrations.types.StackerIntegration
|
||||
import com.bgsoftware.wildstacker.api.WildStackerAPI
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.entity.Item
|
||||
import org.bukkit.entity.LivingEntity
|
||||
@ -9,18 +10,18 @@ import org.bukkit.inventory.ItemStack
|
||||
class WildStackerIntegration : StackerIntegration {
|
||||
|
||||
override fun getStackSize(entity: LivingEntity): Long {
|
||||
TODO("Not yet implemented")
|
||||
return WildStackerAPI.getStackedEntity(entity)?.stackAmount?.toLong() ?: 1
|
||||
}
|
||||
|
||||
override fun getStackSize(item: Item): Long {
|
||||
TODO("Not yet implemented")
|
||||
return WildStackerAPI.getStackedItem(item)?.stackAmount?.toLong() ?: 1
|
||||
}
|
||||
|
||||
override fun dropItemAt(itemStack: ItemStack, amount: Int, location: Location) {
|
||||
TODO("Not yet implemented")
|
||||
WildStackerAPI.getWildStacker().systemManager.spawnItemWithAmount(location, itemStack, amount);
|
||||
}
|
||||
|
||||
override fun register() {
|
||||
TODO("Not yet implemented")
|
||||
|
||||
}
|
||||
}
|
@ -5,8 +5,11 @@ import com.artillexstudios.axminions.api.AxMinionsAPI
|
||||
import com.artillexstudios.axminions.api.config.Messages
|
||||
import com.artillexstudios.axminions.api.minions.Direction
|
||||
import com.artillexstudios.axminions.api.minions.Minion
|
||||
import com.artillexstudios.axminions.api.minions.miniontype.MinionTypes
|
||||
import com.artillexstudios.axminions.utils.fastFor
|
||||
import com.artillexstudios.axminions.api.utils.CoolDown
|
||||
import com.artillexstudios.axminions.api.utils.Keys
|
||||
import com.artillexstudios.axminions.api.utils.fastFor
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.TimeUnit
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.EventHandler
|
||||
@ -18,6 +21,7 @@ import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
|
||||
class MinionInventoryListener : Listener {
|
||||
private val coolDown = CoolDown<UUID>()
|
||||
|
||||
@EventHandler
|
||||
fun onInventoryDragEvent(event: InventoryDragEvent) {
|
||||
@ -33,6 +37,12 @@ class MinionInventoryListener : Listener {
|
||||
event.isCancelled = true
|
||||
val player = event.whoClicked as Player
|
||||
|
||||
if (coolDown.contains(player.uniqueId)) {
|
||||
return
|
||||
}
|
||||
|
||||
coolDown.add(player.uniqueId, 250)
|
||||
|
||||
val allowedTools = arrayListOf<Material>()
|
||||
minion.getType().getConfig().getStringList("tool.material").fastFor {
|
||||
allowedTools.add(Material.matchMaterial(it) ?: return@fastFor)
|
||||
@ -48,6 +58,7 @@ class MinionInventoryListener : Listener {
|
||||
val current = event.currentItem!!.clone()
|
||||
val tool = minion.getTool()?.clone()
|
||||
minion.setTool(current)
|
||||
minion.updateArmour()
|
||||
event.currentItem!!.amount = 0
|
||||
event.clickedInventory!!.addItem(tool)
|
||||
} else {
|
||||
@ -68,8 +79,9 @@ class MinionInventoryListener : Listener {
|
||||
|
||||
val tool = minion.getTool()?.clone() ?: return
|
||||
minion.setTool(ItemStack(Material.AIR))
|
||||
minion.updateArmour()
|
||||
val toolMeta = tool.itemMeta ?: return
|
||||
toolMeta.persistentDataContainer.remove(MinionTypes.getGuiKey())
|
||||
toolMeta.persistentDataContainer.remove(Keys.GUI)
|
||||
tool.setItemMeta(toolMeta)
|
||||
|
||||
player.inventory.addItem(tool)
|
||||
@ -82,16 +94,16 @@ class MinionInventoryListener : Listener {
|
||||
}
|
||||
|
||||
val meta = event.clickedInventory?.getItem(event.slot)?.itemMeta ?: return
|
||||
if (!meta.persistentDataContainer.has(MinionTypes.getGuiKey(), PersistentDataType.STRING)) return
|
||||
val type = meta.persistentDataContainer.get(MinionTypes.getGuiKey(), PersistentDataType.STRING)
|
||||
if (!meta.persistentDataContainer.has(Keys.GUI, PersistentDataType.STRING)) return
|
||||
val type = meta.persistentDataContainer.get(Keys.GUI, PersistentDataType.STRING)
|
||||
|
||||
when (type) {
|
||||
"rotate" -> {
|
||||
when (minion.getDirection()) {
|
||||
Direction.NORTH -> minion.setDirection(Direction.WEST)
|
||||
Direction.EAST -> minion.setDirection(Direction.NORTH)
|
||||
Direction.SOUTH -> minion.setDirection(Direction.EAST)
|
||||
Direction.WEST -> minion.setDirection(Direction.SOUTH)
|
||||
Direction.EAST -> minion.setDirection(Direction.NORTH)
|
||||
Direction.SOUTH -> minion.setDirection(Direction.EAST)
|
||||
Direction.WEST -> minion.setDirection(Direction.SOUTH)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,16 @@
|
||||
package com.artillexstudios.axminions.listeners
|
||||
|
||||
import com.artillexstudios.axapi.libs.kyori.adventure.text.minimessage.tag.resolver.Placeholder
|
||||
import com.artillexstudios.axapi.scheduler.Scheduler
|
||||
import com.artillexstudios.axapi.utils.StringUtils
|
||||
import com.artillexstudios.axminions.AxMinionsPlugin
|
||||
import com.artillexstudios.axminions.api.AxMinionsAPI
|
||||
import com.artillexstudios.axminions.api.config.Messages
|
||||
import com.artillexstudios.axminions.api.minions.Direction
|
||||
import com.artillexstudios.axminions.api.minions.miniontype.MinionTypes
|
||||
import com.artillexstudios.axminions.api.utils.Keys
|
||||
import com.artillexstudios.axminions.minions.Minion
|
||||
import com.artillexstudios.axminions.minions.Minions
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.Listener
|
||||
@ -25,10 +28,13 @@ class MinionPlaceListener : Listener {
|
||||
if (event.item == null) return
|
||||
if (!event.item!!.hasItemMeta()) return
|
||||
|
||||
val type = event.item!!.itemMeta!!.persistentDataContainer.get(MinionTypes.getMinionKey(), PersistentDataType.STRING) ?: return
|
||||
val type = event.item!!.itemMeta!!.persistentDataContainer.get(Keys.MINION_TYPE, PersistentDataType.STRING) ?: return
|
||||
val minionType = MinionTypes.valueOf(type) ?: return
|
||||
event.isCancelled = true
|
||||
|
||||
val level = event.item!!.itemMeta!!.persistentDataContainer.get(Keys.LEVEL, PersistentDataType.INTEGER) ?: 0
|
||||
val stats = event.item!!.itemMeta!!.persistentDataContainer.get(Keys.STATISTICS, PersistentDataType.LONG) ?: 0
|
||||
|
||||
val location = event.clickedBlock!!.getRelative(event.blockFace).location
|
||||
|
||||
val maxMinions = AxMinionsAPI.INSTANCE.getMinionLimit(event.player)
|
||||
@ -46,9 +52,16 @@ class MinionPlaceListener : Listener {
|
||||
return@submit
|
||||
}
|
||||
|
||||
val minion = Minion(location, event.player.uniqueId, event.player, minionType, 1, ItemStack(Material.AIR), null, Direction.NORTH, 0, 0.0, AxMinionsPlugin.dataHandler.getLocationID(location), 0)
|
||||
minion.setTicking(true)
|
||||
AxMinionsPlugin.dataHandler.saveMinion(minion)
|
||||
val locationId = AxMinionsPlugin.dataHandler.getLocationID(location)
|
||||
Scheduler.get().run {
|
||||
val minion = Minion(location, event.player.uniqueId, event.player, minionType, 1, ItemStack(Material.AIR), null, Direction.NORTH, 0, 0.0, locationId, 0)
|
||||
minion.setLevel(level)
|
||||
minion.setActions(stats)
|
||||
minion.setTicking(true)
|
||||
Minions.addTicking(location.chunk)
|
||||
event.player.sendMessage("Placed minion $minion. Ticking? ${minion.isTicking()} Is chunk ticking? ${Minions.isTicking(location.chunk)}")
|
||||
AxMinionsPlugin.dataHandler.saveMinion(minion)
|
||||
}
|
||||
|
||||
event.player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.PLACE_SUCCESS(), Placeholder.unparsed("type", minionType.getName()), Placeholder.unparsed("placed", (placed + 1).toString()), Placeholder.unparsed("max", (maxMinions).toString())))
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import com.artillexstudios.axapi.entity.PacketEntityFactory
|
||||
import com.artillexstudios.axapi.entity.impl.PacketArmorStand
|
||||
import com.artillexstudios.axapi.entity.impl.PacketEntity
|
||||
import com.artillexstudios.axapi.hologram.Hologram
|
||||
import com.artillexstudios.axapi.hologram.HologramFactory
|
||||
import com.artillexstudios.axapi.libs.kyori.adventure.text.minimessage.tag.resolver.Placeholder
|
||||
import com.artillexstudios.axapi.scheduler.Scheduler
|
||||
import com.artillexstudios.axapi.serializers.Serializers
|
||||
@ -18,23 +19,25 @@ import com.artillexstudios.axminions.api.config.Messages
|
||||
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.minions.miniontype.MinionTypes
|
||||
import com.artillexstudios.axminions.api.utils.Keys
|
||||
import com.artillexstudios.axminions.api.utils.fastFor
|
||||
import com.artillexstudios.axminions.api.warnings.Warning
|
||||
import com.artillexstudios.axminions.api.warnings.Warnings
|
||||
import com.artillexstudios.axminions.listeners.LinkingListener
|
||||
import com.artillexstudios.axminions.utils.fastFor
|
||||
import java.util.UUID
|
||||
import org.bukkit.Bukkit
|
||||
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
|
||||
import org.bukkit.inventory.Inventory
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.util.EulerAngle
|
||||
import java.util.UUID
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.inventory.meta.Damageable
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
import org.bukkit.util.EulerAngle
|
||||
|
||||
class Minion(
|
||||
private var location: Location,
|
||||
@ -61,6 +64,7 @@ class Minion(
|
||||
private var linkedInventory: Inventory? = null
|
||||
private val openInventories = mutableListOf<Inventory>()
|
||||
private var ticking = false
|
||||
private var debugHologram: Hologram? = null
|
||||
|
||||
init {
|
||||
spawn()
|
||||
@ -79,6 +83,18 @@ class Minion(
|
||||
entity.setHasBasePlate(false)
|
||||
entity.setSmall(true)
|
||||
entity.setHasArms(true)
|
||||
entity.name = StringUtils.format(
|
||||
type.getConfig().get("entity.name"),
|
||||
Placeholder.unparsed("owner", owner.name ?: "???"),
|
||||
Placeholder.unparsed("level", level.toString()),
|
||||
Placeholder.parsed("level_color", Messages.LEVEL_COLOR(level))
|
||||
)
|
||||
|
||||
if (Config.DEBUG()) {
|
||||
debugHologram = HologramFactory.get().spawnHologram(location.clone().add(0.0, 2.0, 0.0), "$locationID")
|
||||
debugHologram?.addLine(StringUtils.format("ticking: $ticking"))
|
||||
}
|
||||
|
||||
setDirection(direction)
|
||||
updateArmour()
|
||||
entity.onClick { event ->
|
||||
@ -98,6 +114,10 @@ class Minion(
|
||||
type.onToolDirty(this)
|
||||
}
|
||||
|
||||
if (Config.DEBUG() && debugHologram != null) {
|
||||
debugHologram?.setLine(0, StringUtils.format("Ticking: $ticking Chunk ticking: ${Minions.isTicking(location.chunk)} CHUNK X: ${location.chunk.x} CHUNK Z: ${location.chunk.z}"))
|
||||
}
|
||||
|
||||
type.tick(this)
|
||||
animate()
|
||||
}
|
||||
@ -118,10 +138,12 @@ class Minion(
|
||||
val item: ItemStack
|
||||
if (it.equals("upgrade", true) || it.equals("statistics", true)) {
|
||||
val level = Placeholder.unparsed("level", level.toString())
|
||||
val nextLevel = Placeholder.unparsed("next_level", when (type.hasReachedMaxLevel(this)) {
|
||||
true -> Messages.UPGRADES_MAX_LEVEL_REACHED()
|
||||
else -> (this.level + 1).toString()
|
||||
})
|
||||
val nextLevel = Placeholder.unparsed(
|
||||
"next_level", when (type.hasReachedMaxLevel(this)) {
|
||||
true -> Messages.UPGRADES_MAX_LEVEL_REACHED()
|
||||
else -> (this.level + 1).toString()
|
||||
}
|
||||
)
|
||||
val range = Placeholder.unparsed("range", type.getString("range", this.level))
|
||||
val nextRange = Placeholder.unparsed("next_range", type.getString("range", this.level + 1))
|
||||
val extra = Placeholder.unparsed("extra", type.getString("extra", this.level))
|
||||
@ -129,22 +151,45 @@ class Minion(
|
||||
val speed = Placeholder.unparsed("speed", type.getString("speed", this.level))
|
||||
val nextSpeed = Placeholder.unparsed("next_speed", type.getString("speed", this.level + 1))
|
||||
val price = Placeholder.unparsed("price", type.getString("requirements.money", this.level + 1))
|
||||
val requiredActions = Placeholder.unparsed("required_actions", type.getString("requirements.actions", this.level + 1))
|
||||
val requiredActions =
|
||||
Placeholder.unparsed("required_actions", type.getString("requirements.actions", this.level + 1))
|
||||
val stored = Placeholder.unparsed("storage", storage.toString())
|
||||
val actions = Placeholder.unparsed("actions", actions.toString())
|
||||
|
||||
item = ItemBuilder(type.getConfig().getSection("gui.$it"), level, nextLevel, range, nextRange, extra, nextExtra, speed, nextSpeed, price, requiredActions, stored, actions).storePersistentData(
|
||||
MinionTypes.getGuiKey(), PersistentDataType.STRING, it).get()
|
||||
item = ItemBuilder(
|
||||
type.getConfig().getSection("gui.$it"),
|
||||
level,
|
||||
nextLevel,
|
||||
range,
|
||||
nextRange,
|
||||
extra,
|
||||
nextExtra,
|
||||
speed,
|
||||
nextSpeed,
|
||||
price,
|
||||
requiredActions,
|
||||
stored,
|
||||
actions
|
||||
).storePersistentData(
|
||||
Keys.GUI, PersistentDataType.STRING, it
|
||||
).get()
|
||||
} else if (it.equals("item")) {
|
||||
item = tool?.clone() ?: ItemStack(Material.AIR)
|
||||
} else {
|
||||
val rotation = Placeholder.unparsed("direction", Messages.ROTATION_NAME(direction))
|
||||
val linked = Placeholder.unparsed("linked", when (linkedChest) {
|
||||
null -> "---"
|
||||
else -> Serializers.LOCATION.serialize(linkedChest)
|
||||
})
|
||||
item = ItemBuilder(AxMinionsAPI.INSTANCE.getConfig().getConfig().getSection("gui.items.$it"), rotation, linked).storePersistentData(
|
||||
MinionTypes.getGuiKey(), PersistentDataType.STRING, it).get()
|
||||
val linked = Placeholder.unparsed(
|
||||
"linked", when (linkedChest) {
|
||||
null -> "---"
|
||||
else -> Serializers.LOCATION.serialize(linkedChest)
|
||||
}
|
||||
)
|
||||
item = ItemBuilder(
|
||||
AxMinionsAPI.INSTANCE.getConfig().getConfig().getSection("gui.items.$it"),
|
||||
rotation,
|
||||
linked
|
||||
).storePersistentData(
|
||||
Keys.GUI, PersistentDataType.STRING, it
|
||||
).get()
|
||||
}
|
||||
|
||||
inventory.setItem(AxMinionsAPI.INSTANCE.getConfig().get("gui.items.$it.slot"), item)
|
||||
@ -153,10 +198,19 @@ class Minion(
|
||||
|
||||
override fun openInventory(player: Player) {
|
||||
LinkingListener.linking.remove(player.uniqueId)
|
||||
val inventory = Bukkit.createInventory(this, Config.GUI_SIZE(), StringUtils.formatToString(type.getConfig().get("name"), Placeholder.unparsed("level_color", Messages.LEVEL_COLOR(level)), Placeholder.unparsed("level", level.toString()), Placeholder.unparsed("owner", owner.name ?: "???")))
|
||||
val inventory = Bukkit.createInventory(
|
||||
this,
|
||||
Config.GUI_SIZE(),
|
||||
StringUtils.formatToString(
|
||||
type.getConfig().get("name"),
|
||||
Placeholder.parsed("level_color", Messages.LEVEL_COLOR(level)),
|
||||
Placeholder.unparsed("level", level.toString()),
|
||||
Placeholder.unparsed("owner", owner.name ?: "???")
|
||||
)
|
||||
)
|
||||
|
||||
val filler = ItemBuilder(AxMinionsAPI.INSTANCE.getConfig().getConfig().getSection("gui.items.filler")).get()
|
||||
for (i in 0..< Config.GUI_SIZE()) {
|
||||
for (i in 0..<Config.GUI_SIZE()) {
|
||||
inventory.setItem(i, filler)
|
||||
}
|
||||
|
||||
@ -166,7 +220,7 @@ class Minion(
|
||||
}
|
||||
|
||||
override fun getAsItem(): ItemStack {
|
||||
return type.getItem(level)
|
||||
return type.getItem(level, actions)
|
||||
}
|
||||
|
||||
override fun getLevel(): Int {
|
||||
@ -207,7 +261,7 @@ class Minion(
|
||||
|
||||
override fun setTool(tool: ItemStack) {
|
||||
this.tool = tool.clone()
|
||||
updateInventories()
|
||||
dirty = true
|
||||
|
||||
if (tool.type == Material.AIR) {
|
||||
entity.setItem(EquipmentSlot.MAIN_HAND, null)
|
||||
@ -230,6 +284,17 @@ class Minion(
|
||||
|
||||
override fun setLevel(level: Int) {
|
||||
this.level = level
|
||||
|
||||
entity.name = StringUtils.format(
|
||||
type.getConfig().get("entity.name"),
|
||||
Placeholder.unparsed("owner", owner.name ?: "???"),
|
||||
Placeholder.unparsed("level", level.toString()),
|
||||
Placeholder.parsed("level_color", Messages.LEVEL_COLOR(level))
|
||||
)
|
||||
|
||||
AxMinionsPlugin.dataQueue.submit {
|
||||
AxMinionsPlugin.dataHandler.saveMinion(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getData(key: String): String? {
|
||||
@ -306,10 +371,15 @@ class Minion(
|
||||
}
|
||||
|
||||
override fun addToContainerOrDrop(itemStack: ItemStack) {
|
||||
if (linkedInventory == null) {
|
||||
AxMinionsPlugin.integrations.getStackerIntegration().dropItemAt(itemStack, itemStack.amount, location)
|
||||
return
|
||||
}
|
||||
|
||||
val remaining = linkedInventory?.addItem(itemStack)
|
||||
|
||||
remaining?.forEach { (_, u) ->
|
||||
location.world?.dropItem(location, u)
|
||||
AxMinionsPlugin.integrations.getStackerIntegration().dropItemAt(u, u.amount, location)
|
||||
}
|
||||
}
|
||||
|
||||
@ -371,6 +441,46 @@ class Minion(
|
||||
this.nextAction = nextAction
|
||||
}
|
||||
|
||||
override fun markDirty() {
|
||||
dirty = true
|
||||
}
|
||||
|
||||
override fun damageTool(amount: Int) {
|
||||
val meta = this.tool?.itemMeta as? Damageable ?: return
|
||||
|
||||
if (Math.random() > 1f / (meta.getEnchantLevel(Enchantment.DURABILITY) + 1)) return
|
||||
|
||||
if ((tool?.type?.maxDurability ?: return) <= meta.damage + amount) {
|
||||
if (Config.CAN_BREAK_TOOLS()) {
|
||||
setTool(ItemStack(Material.AIR))
|
||||
}
|
||||
} else {
|
||||
meta.damage += amount
|
||||
tool?.itemMeta = meta
|
||||
}
|
||||
}
|
||||
|
||||
override fun canUseTool(): Boolean {
|
||||
val meta = this.tool?.itemMeta ?: return false
|
||||
|
||||
if (!Config.USE_DURABILITY() && meta is Damageable) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (meta is Damageable) {
|
||||
if ((tool?.type?.maxDurability ?: return false) <= meta.damage + 1) {
|
||||
if (Config.CAN_BREAK_TOOLS()) {
|
||||
setTool(ItemStack(Material.AIR))
|
||||
}
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
override fun getInventory(): Inventory {
|
||||
return Bukkit.createInventory(this, 9)
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.artillexstudios.axminions.minions
|
||||
|
||||
import com.artillexstudios.axapi.scheduler.Scheduler
|
||||
import com.artillexstudios.axminions.utils.fastFor
|
||||
import com.artillexstudios.axminions.api.utils.fastFor
|
||||
|
||||
object MinionTicker {
|
||||
private var tick = 0L
|
||||
|
@ -2,77 +2,70 @@ package com.artillexstudios.axminions.minions
|
||||
|
||||
import com.artillexstudios.axminions.api.minions.Minion
|
||||
import com.artillexstudios.axminions.api.minions.utils.ChunkPos
|
||||
import com.artillexstudios.axminions.utils.fastFor
|
||||
import com.artillexstudios.axminions.api.utils.fastFor
|
||||
import java.util.Collections
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import org.bukkit.Chunk
|
||||
|
||||
object Minions {
|
||||
private val mutex = Object()
|
||||
private val minions = hashMapOf<ChunkPos, ArrayList<Minion>>()
|
||||
private val mutableChunkPos = ChunkPos(0, 0)
|
||||
private val minions = ConcurrentHashMap<ChunkPos, ArrayList<Minion>>()
|
||||
|
||||
fun addTicking(chunk: Chunk) {
|
||||
synchronized(mutex) {
|
||||
mutableChunkPos.x = chunk.x
|
||||
mutableChunkPos.z = chunk.z
|
||||
val pos = ChunkPos(chunk.x, chunk.z)
|
||||
|
||||
minions[mutableChunkPos]?.fastFor {
|
||||
it.setTicking(true)
|
||||
} ?: return
|
||||
}
|
||||
minions[pos]?.fastFor {
|
||||
it.setTicking(true)
|
||||
} ?: return
|
||||
println("LOADING CHUNK! X: ${chunk.x} Z: ${chunk.z}")
|
||||
}
|
||||
|
||||
fun isTicking(chunk: Chunk): Boolean {
|
||||
val pos = ChunkPos(chunk.x, chunk.z)
|
||||
|
||||
return minions.contains(pos)
|
||||
}
|
||||
|
||||
fun removeTicking(chunk: Chunk) {
|
||||
synchronized(mutex) {
|
||||
mutableChunkPos.x = chunk.x
|
||||
mutableChunkPos.z = chunk.z
|
||||
val pos = ChunkPos(chunk.x, chunk.z)
|
||||
|
||||
val minions = this.minions[mutableChunkPos] ?: return
|
||||
val minions = this.minions[pos] ?: return
|
||||
|
||||
minions.fastFor {
|
||||
it.setTicking(false)
|
||||
}
|
||||
minions.fastFor {
|
||||
it.setTicking(false)
|
||||
}
|
||||
}
|
||||
|
||||
fun load(minion: Minion) {
|
||||
synchronized(mutex) {
|
||||
mutableChunkPos.x = round(minion.getLocation().x) shr 4
|
||||
mutableChunkPos.z = round(minion.getLocation().z) shr 4
|
||||
val pos = minions[mutableChunkPos] ?: arrayListOf()
|
||||
println("LOADING MINION!!")
|
||||
val chunkPos = ChunkPos(minion.getLocation().chunk.x, minion.getLocation().chunk.z)
|
||||
val pos = minions[chunkPos] ?: arrayListOf()
|
||||
|
||||
pos.add(minion)
|
||||
minions[mutableChunkPos] = pos
|
||||
}
|
||||
pos.add(minion)
|
||||
minions[chunkPos] = pos
|
||||
}
|
||||
|
||||
fun remove(minion: Minion) {
|
||||
synchronized(mutex) {
|
||||
mutableChunkPos.x = minion.getLocation().blockX shr 4
|
||||
mutableChunkPos.z = minion.getLocation().blockZ shr 4
|
||||
val pos = minions[mutableChunkPos] ?: return
|
||||
val chunkPos = ChunkPos(minion.getLocation().chunk.x, minion.getLocation().chunk.z)
|
||||
|
||||
pos.remove(minion)
|
||||
if (pos.isEmpty()) {
|
||||
minions.remove(mutableChunkPos)
|
||||
}
|
||||
val pos = minions[chunkPos] ?: return
|
||||
|
||||
pos.remove(minion)
|
||||
if (pos.isEmpty()) {
|
||||
minions.remove(chunkPos)
|
||||
}
|
||||
}
|
||||
|
||||
fun getMinions(): List<Minion> {
|
||||
synchronized(mutex) {
|
||||
val list = mutableListOf<Minion>()
|
||||
minions.forEach { (_, value) ->
|
||||
list.addAll(value)
|
||||
}
|
||||
return Collections.unmodifiableList(list)
|
||||
val list = mutableListOf<Minion>()
|
||||
minions.forEach { (_, value) ->
|
||||
list.addAll(value)
|
||||
}
|
||||
return Collections.unmodifiableList(list)
|
||||
|
||||
}
|
||||
|
||||
internal fun get(): HashMap<ChunkPos, ArrayList<Minion>> {
|
||||
synchronized(mutex) {
|
||||
return minions
|
||||
}
|
||||
internal fun get(): ConcurrentHashMap<ChunkPos, ArrayList<Minion>> {
|
||||
return minions
|
||||
}
|
||||
|
||||
private infix fun round(double: Double): Int {
|
||||
|
@ -24,7 +24,6 @@ class CollectorMinionType : MinionType("collector", AxMinionsPlugin.INSTANCE.get
|
||||
}
|
||||
|
||||
override fun run(minion: Minion) {
|
||||
minion.resetAnimation()
|
||||
if (minion.getLinkedChest() == null) {
|
||||
Warnings.NO_CONTAINER.display(minion)
|
||||
return
|
||||
@ -45,6 +44,13 @@ class CollectorMinionType : MinionType("collector", AxMinionsPlugin.INSTANCE.get
|
||||
|
||||
Warnings.remove(minion)
|
||||
|
||||
if (!minion.canUseTool()) {
|
||||
Warnings.NO_TOOL.display(minion)
|
||||
return
|
||||
}
|
||||
|
||||
Warnings.remove(minion)
|
||||
|
||||
val entities = minion.getLocation().world?.getNearbyEntities(
|
||||
minion.getLocation(),
|
||||
minion.getRange(),
|
||||
@ -58,7 +64,14 @@ class CollectorMinionType : MinionType("collector", AxMinionsPlugin.INSTANCE.get
|
||||
return
|
||||
}
|
||||
|
||||
//TODO: Add to inventory and remove items
|
||||
val amount = AxMinionsPlugin.integrations.getStackerIntegration().getStackSize(item)
|
||||
val stack = item.itemStack.clone()
|
||||
stack.amount = amount.toInt()
|
||||
|
||||
minion.addToContainerOrDrop(stack)
|
||||
minion.setActions(minion.getActionAmount() + 1)
|
||||
minion.damageTool()
|
||||
item.remove()
|
||||
}
|
||||
}
|
||||
}
|
@ -4,8 +4,10 @@ import com.artillexstudios.axminions.AxMinionsPlugin
|
||||
import com.artillexstudios.axminions.api.minions.Minion
|
||||
import com.artillexstudios.axminions.api.minions.miniontype.MinionType
|
||||
import com.artillexstudios.axminions.minions.MinionTicker
|
||||
import com.artillexstudios.axminions.utils.LocationUtils
|
||||
import com.artillexstudios.axminions.utils.fastFor
|
||||
import com.artillexstudios.axminions.api.utils.LocationUtils
|
||||
import com.artillexstudios.axminions.api.utils.MinionUtils
|
||||
import com.artillexstudios.axminions.api.utils.fastFor
|
||||
import com.artillexstudios.axminions.api.warnings.Warnings
|
||||
import kotlin.math.roundToInt
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.block.data.Ageable
|
||||
@ -26,16 +28,41 @@ class FarmerMinionType : MinionType("farmer", AxMinionsPlugin.INSTANCE.getResour
|
||||
}
|
||||
|
||||
override fun run(minion: Minion) {
|
||||
minion.resetAnimation()
|
||||
if (minion.getLinkedChest() != null) {
|
||||
val type = minion.getLinkedChest()!!.block.type
|
||||
if (type != Material.CHEST && type != Material.TRAPPED_CHEST && type != Material.BARREL) {
|
||||
minion.setLinkedChest(null)
|
||||
}
|
||||
}
|
||||
|
||||
if (minion.getLinkedInventory() == null) {
|
||||
minion.setLinkedChest(null)
|
||||
}
|
||||
|
||||
if (!minion.canUseTool()) {
|
||||
Warnings.NO_TOOL.display(minion)
|
||||
return
|
||||
}
|
||||
|
||||
Warnings.remove(minion)
|
||||
|
||||
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 -> {
|
||||
Material.CACTUS, Material.SUGAR_CANE, Material.BAMBOO -> {
|
||||
MinionUtils.getPlant(block).fastFor {
|
||||
drops.addAll(it.getDrops(minion.getTool()))
|
||||
it.type = Material.AIR
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@ -43,6 +70,7 @@ class FarmerMinionType : MinionType("farmer", AxMinionsPlugin.INSTANCE.getResour
|
||||
ageable.age = 0
|
||||
block.blockData = ageable
|
||||
}
|
||||
|
||||
Material.SWEET_BERRY_BUSH -> {
|
||||
val ageable = block.blockData as Ageable
|
||||
if (ageable.age != ageable.maximumAge) return@fastFor
|
||||
@ -50,10 +78,14 @@ class FarmerMinionType : MinionType("farmer", AxMinionsPlugin.INSTANCE.getResour
|
||||
ageable.age = 1
|
||||
block.blockData = ageable
|
||||
}
|
||||
|
||||
else -> return@fastFor
|
||||
}
|
||||
|
||||
minion.addToContainerOrDrop(drops)
|
||||
val dropsSize = drops.size
|
||||
minion.damageTool(dropsSize)
|
||||
minion.setActions(minion.getActionAmount() + dropsSize)
|
||||
}
|
||||
}
|
||||
}
|
@ -3,10 +3,92 @@ 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.api.utils.LocationUtils
|
||||
import com.artillexstudios.axminions.api.utils.MinionUtils
|
||||
import com.artillexstudios.axminions.api.utils.fastFor
|
||||
import com.artillexstudios.axminions.api.warnings.Warnings
|
||||
import com.artillexstudios.axminions.minions.MinionTicker
|
||||
import kotlin.math.roundToInt
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.block.BlockFace
|
||||
import org.bukkit.enchantments.Enchantment
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
class LumberMinionType : MinionType("lumber", AxMinionsPlugin.INSTANCE.getResource("minions/lumber.yml")!!) {
|
||||
|
||||
override fun run(minion: Minion) {
|
||||
override fun shouldRun(minion: Minion): Boolean {
|
||||
return MinionTicker.getTick() % minion.getNextAction() == 0L
|
||||
}
|
||||
|
||||
override fun onToolDirty(minion: Minion) {
|
||||
val minionImpl = minion as com.artillexstudios.axminions.minions.Minion
|
||||
minionImpl.setRange(getDouble("range", minion.getLevel()))
|
||||
val efficiency = 1.0 - (minion.getTool()?.getEnchantmentLevel(Enchantment.DIG_SPEED)?.div(10.0) ?: 0.1)
|
||||
minionImpl.setNextAction((getLong("speed", minion.getLevel()) * efficiency).roundToInt())
|
||||
}
|
||||
|
||||
override fun run(minion: Minion) {
|
||||
if (minion.getLinkedChest() != null) {
|
||||
val type = minion.getLinkedChest()!!.block.type
|
||||
if (type != Material.CHEST && type != Material.TRAPPED_CHEST && type != Material.BARREL) {
|
||||
minion.setLinkedChest(null)
|
||||
}
|
||||
}
|
||||
|
||||
if (minion.getLinkedInventory() == null) {
|
||||
minion.setLinkedChest(null)
|
||||
}
|
||||
|
||||
if (!minion.canUseTool()) {
|
||||
Warnings.NO_TOOL.display(minion)
|
||||
return
|
||||
}
|
||||
|
||||
Warnings.remove(minion)
|
||||
|
||||
val loot = ArrayList<ItemStack>()
|
||||
LocationUtils.getAllBlocksInRadius(minion.getLocation(), minion.getRange(), false).fastFor { location ->
|
||||
MinionUtils.getTree(location.block).fastFor {
|
||||
val down = it.getRelative(BlockFace.DOWN).type
|
||||
loot.addAll(it.getDrops(minion.getTool()))
|
||||
|
||||
if (down == Material.DIRT || down == Material.GRASS_BLOCK || down == Material.COARSE_DIRT || down == Material.ROOTED_DIRT || down == Material.DIRT_PATH) {
|
||||
it.type = getSaplingType(it.type)
|
||||
} else {
|
||||
it.type = Material.AIR
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val lootSize = loot.size
|
||||
minion.damageTool(lootSize)
|
||||
minion.setActions(minion.getActionAmount() + lootSize)
|
||||
minion.addToContainerOrDrop(loot)
|
||||
}
|
||||
|
||||
private fun getSaplingType(material: Material): Material {
|
||||
return when (material) {
|
||||
Material.DARK_OAK_LOG -> {
|
||||
Material.DARK_OAK_SAPLING
|
||||
}
|
||||
|
||||
Material.BIRCH_LOG -> {
|
||||
Material.BIRCH_SAPLING
|
||||
}
|
||||
|
||||
Material.ACACIA_LOG -> {
|
||||
Material.ACACIA_SAPLING
|
||||
}
|
||||
|
||||
Material.JUNGLE_LOG -> {
|
||||
Material.JUNGLE_SAPLING
|
||||
}
|
||||
|
||||
Material.SPRUCE_LOG -> {
|
||||
Material.SPRUCE_SAPLING
|
||||
}
|
||||
|
||||
else -> Material.OAK_SAPLING
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +1,110 @@
|
||||
package com.artillexstudios.axminions.minions.miniontype
|
||||
|
||||
import com.artillexstudios.axapi.scheduler.Scheduler
|
||||
import com.artillexstudios.axminions.AxMinionsPlugin
|
||||
import com.artillexstudios.axminions.api.minions.Minion
|
||||
import com.artillexstudios.axminions.api.minions.miniontype.MinionType
|
||||
import com.artillexstudios.axminions.api.utils.LocationUtils
|
||||
import com.artillexstudios.axminions.api.utils.MinionUtils
|
||||
import com.artillexstudios.axminions.api.utils.fastFor
|
||||
import com.artillexstudios.axminions.api.warnings.Warnings
|
||||
import com.artillexstudios.axminions.minions.MinionTicker
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.ExecutorService
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.math.roundToInt
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.block.BlockFace
|
||||
import org.bukkit.enchantments.Enchantment
|
||||
|
||||
class MinerMinionType : MinionType("miner", AxMinionsPlugin.INSTANCE.getResource("minions/miner.yml")!!) {
|
||||
private var asyncExecutor: ExecutorService? = null
|
||||
private val faces = arrayOf(BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST)
|
||||
|
||||
override fun shouldRun(minion: Minion): Boolean {
|
||||
return MinionTicker.getTick() % minion.getNextAction() == 0L
|
||||
}
|
||||
|
||||
override fun onToolDirty(minion: Minion) {
|
||||
val minionImpl = minion as com.artillexstudios.axminions.minions.Minion
|
||||
minionImpl.setRange(getDouble("range", minion.getLevel()))
|
||||
val efficiency = 1.0 - (minion.getTool()?.getEnchantmentLevel(Enchantment.DIG_SPEED)?.div(10.0) ?: 0.1)
|
||||
minionImpl.setNextAction((getLong("speed", minion.getLevel()) * efficiency).roundToInt())
|
||||
}
|
||||
|
||||
override fun run(minion: Minion) {
|
||||
if (minion.getLinkedChest() != null) {
|
||||
val type = minion.getLinkedChest()!!.block.type
|
||||
if (type != Material.CHEST && type != Material.TRAPPED_CHEST && type != Material.BARREL) {
|
||||
minion.setLinkedChest(null)
|
||||
}
|
||||
}
|
||||
|
||||
if (minion.getLinkedInventory() == null) {
|
||||
minion.setLinkedChest(null)
|
||||
}
|
||||
|
||||
if (!minion.canUseTool()) {
|
||||
Warnings.NO_TOOL.display(minion)
|
||||
return
|
||||
}
|
||||
|
||||
Warnings.remove(minion)
|
||||
|
||||
when (getConfig().getString("mode").lowercase(Locale.ENGLISH)) {
|
||||
"sphere" -> {
|
||||
LocationUtils.getAllBlocksInRadius(minion.getLocation(), minion.getRange(), false).fastFor { location ->
|
||||
val isStoneGenerator = MinionUtils.isStoneGenerator(location)
|
||||
|
||||
if (isStoneGenerator) {
|
||||
minion.addToContainerOrDrop(location.block.getDrops(minion.getTool()))
|
||||
location.block.type = Material.AIR
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"asphere" -> {
|
||||
if (asyncExecutor == null) {
|
||||
asyncExecutor = Executors.newFixedThreadPool(3)
|
||||
}
|
||||
|
||||
asyncExecutor!!.execute {
|
||||
LocationUtils.getAllBlocksInRadius(minion.getLocation(), minion.getRange(), false).fastFor { location ->
|
||||
val isStoneGenerator = MinionUtils.isStoneGenerator(location)
|
||||
|
||||
if (isStoneGenerator) {
|
||||
Scheduler.get().run {
|
||||
minion.addToContainerOrDrop(location.block.getDrops(minion.getTool()))
|
||||
location.block.type = Material.AIR
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"line" -> {
|
||||
faces.fastFor {
|
||||
LocationUtils.getAllBlocksFacing(minion.getLocation(), minion.getRange(), it).fastFor { location ->
|
||||
val isStoneGenerator = MinionUtils.isStoneGenerator(location)
|
||||
|
||||
if (isStoneGenerator) {
|
||||
minion.addToContainerOrDrop(location.block.getDrops(minion.getTool()))
|
||||
location.block.type = Material.AIR
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"face" -> {
|
||||
LocationUtils.getAllBlocksFacing(minion.getLocation(), minion.getRange(), minion.getDirection().facing).fastFor { location ->
|
||||
val isStoneGenerator = MinionUtils.isStoneGenerator(location)
|
||||
|
||||
if (isStoneGenerator) {
|
||||
minion.addToContainerOrDrop(location.block.getDrops(minion.getTool()))
|
||||
location.block.type = Material.AIR
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -77,5 +77,9 @@ gui:
|
||||
statistics:
|
||||
slot: 16
|
||||
|
||||
# Only change this, if you are asked to! This will make your performance worse, and will spam messages in your console!
|
||||
# Requires restart!
|
||||
debug: false
|
||||
|
||||
# Do not change!
|
||||
config-version: 1
|
138
common/src/main/resources/minions/lumber.yml
Normal file
138
common/src/main/resources/minions/lumber.yml
Normal file
@ -0,0 +1,138 @@
|
||||
name: "<#00AAFF>Lumberjack <white>Minion"
|
||||
|
||||
entity:
|
||||
name: "<level_color>[<level>] <#00AAFF>Lumberjack <white>Minion <gray>[<owner>]"
|
||||
|
||||
tool:
|
||||
material:
|
||||
- "WOODEN_AXE"
|
||||
- "STONE_AXE"
|
||||
- "GOLDEN_AXE"
|
||||
- "IRON_AXE"
|
||||
- "DIAMOND_AXE"
|
||||
- "NETHERITE_AXE"
|
||||
|
||||
item:
|
||||
type: "player_head"
|
||||
texture: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzk2MjdiZTYyY2VkNzE0MTEzOWQzZjE1NTc5MGE1ZDQzNTZlYjdiOWVlOTVlNTA0YjMzMjI5NzRjYmM1MTVlYSJ9fX0="
|
||||
name: "<#00AAFF>Lumberjack <white>Minion"
|
||||
lore:
|
||||
- ""
|
||||
- " <gray>- <white>Collects all items around itself."
|
||||
- ""
|
||||
- "<#00AAFF>Statistics"
|
||||
- " <#00AAFF>❙ <white>Level: <#FFEEAA><level>"
|
||||
- " <#00AAFF>❙ <white>Broken blocks: <#FFEEAA><actions>"
|
||||
- ""
|
||||
- "<#00AAFF><b>(!)</b> Place the minion and give it an axe!"
|
||||
|
||||
gui:
|
||||
upgrade:
|
||||
type: "gold_ingot"
|
||||
name: "<#00CCFF><b>Upgrade minion"
|
||||
lore:
|
||||
- ""
|
||||
- " <gray>- <white>Level: <green><level> » <dark_green><next_level>"
|
||||
- " <gray>- <white>Range: <green><range> » <dark_green><next_range>"
|
||||
- " <gray>- <white>Speed: <green><speed> » <dark_green><next_speed>"
|
||||
- ""
|
||||
- "<#00CCFF>Requirements:"
|
||||
- " <gray>- <white>Money: <#33FF33><price>$"
|
||||
- " <gray>- <white>Collected items: <#33FF33><required_actions>"
|
||||
- ""
|
||||
- "<#00CCFF><b>(!)</b> Click here to upgrade your minion!"
|
||||
statistics:
|
||||
type: "paper"
|
||||
name: "<#00AAFF><b>Statistics"
|
||||
lore:
|
||||
- ""
|
||||
- " <gray>- <white>Broken blocks: <#00AAFF><actions>"
|
||||
- ""
|
||||
|
||||
upgrades:
|
||||
1:
|
||||
range: 3
|
||||
speed: 200
|
||||
items:
|
||||
helmet:
|
||||
type: "player_head"
|
||||
texture: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzk2MjdiZTYyY2VkNzE0MTEzOWQzZjE1NTc5MGE1ZDQzNTZlYjdiOWVlOTVlNTA0YjMzMjI5NzRjYmM1MTVlYSJ9fX0="
|
||||
chestplate:
|
||||
type: "leather_chestplate"
|
||||
color: "0, 150, 255"
|
||||
glow: false
|
||||
leggings:
|
||||
type: "leather_leggings"
|
||||
color: "0, 150, 255"
|
||||
glow: false
|
||||
boots:
|
||||
type: "leather_boots"
|
||||
color: "0, 150, 255"
|
||||
glow: false
|
||||
2:
|
||||
range: 4
|
||||
speed: 190
|
||||
requirements:
|
||||
money: 1000
|
||||
actions: 100
|
||||
3:
|
||||
range: 5
|
||||
speed: 175
|
||||
requirements:
|
||||
money: 3000
|
||||
actions: 300
|
||||
4:
|
||||
range: 6
|
||||
speed: 160
|
||||
requirements:
|
||||
money: 10000
|
||||
actions: 1000
|
||||
5:
|
||||
range: 7
|
||||
speed: 150
|
||||
requirements:
|
||||
money: 20000
|
||||
actions: 3000
|
||||
6:
|
||||
range: 8
|
||||
speed: 130
|
||||
requirements:
|
||||
money: 50000
|
||||
actions: 6000
|
||||
7:
|
||||
range: 9
|
||||
speed: 115
|
||||
requirements:
|
||||
money: 150000
|
||||
actions: 10000
|
||||
8:
|
||||
range: 10
|
||||
speed: 100
|
||||
requirements:
|
||||
money: 500000
|
||||
actions: 17500
|
||||
9:
|
||||
range: 11
|
||||
speed: 85
|
||||
requirements:
|
||||
money: 1000000
|
||||
actions: 25000
|
||||
10:
|
||||
range: 12
|
||||
speed: 60
|
||||
requirements:
|
||||
money: 5000000
|
||||
actions: 50000
|
||||
items:
|
||||
chestplate:
|
||||
type: LEATHER_CHESTPLATE
|
||||
color: "255, 200, 0"
|
||||
glow: true
|
||||
leggings:
|
||||
type: LEATHER_LEGGINGS
|
||||
color: "255, 200, 0"
|
||||
glow: true
|
||||
boots:
|
||||
type: LEATHER_BOOTS
|
||||
color: "255, 200, 0"
|
||||
glow: true
|
147
common/src/main/resources/minions/miner.yml
Normal file
147
common/src/main/resources/minions/miner.yml
Normal file
@ -0,0 +1,147 @@
|
||||
name: "<#00AAFF>Miner <white>Minion"
|
||||
|
||||
entity:
|
||||
name: "<level_color>[<level>] <#00AAFF>Miner <white>Minion <gray>[<owner>]"
|
||||
|
||||
tool:
|
||||
material:
|
||||
- "WOODEN_PICKAXE"
|
||||
- "STONE_PICKAXE"
|
||||
- "GOLDEN_PICKAXE"
|
||||
- "IRON_PICKAXE"
|
||||
- "DIAMOND_PICKAXE"
|
||||
- "NETHERITE_PICKAXE"
|
||||
|
||||
# Can be: sphere, line, face, asphere
|
||||
# If set to sphere: checks blocks in a sphere with the range of the minion as radius (Most resource intensive, the larger the radius, the worse)
|
||||
# If set to line: checks blocks in all 4 directions from the minion in the range of the minion
|
||||
# If set to face: checks blocks only in the facing of the minion (Least resource intensive)
|
||||
# If set to asphere: checks blocks in a sphere with the range of the minion as the radius, around the minion
|
||||
# Only switch to asphere mode, if you know what you're doing,
|
||||
# as it may cause some issues due to states being concurrently modified!
|
||||
mode: line
|
||||
|
||||
item:
|
||||
type: "player_head"
|
||||
texture: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzk2MjdiZTYyY2VkNzE0MTEzOWQzZjE1NTc5MGE1ZDQzNTZlYjdiOWVlOTVlNTA0YjMzMjI5NzRjYmM1MTVlYSJ9fX0="
|
||||
name: "<#00AAFF>Miner <white>Minion"
|
||||
lore:
|
||||
- ""
|
||||
- " <gray>- <white>Collects all items around itself."
|
||||
- ""
|
||||
- "<#00AAFF>Statistics"
|
||||
- " <#00AAFF>❙ <white>Level: <#FFEEAA><level>"
|
||||
- " <#00AAFF>❙ <white>Broken blocks: <#FFEEAA><actions>"
|
||||
- ""
|
||||
- "<#00AAFF><b>(!)</b> Place the minion and give it a pickaxe!"
|
||||
|
||||
gui:
|
||||
upgrade:
|
||||
type: "gold_ingot"
|
||||
name: "<#00CCFF><b>Upgrade minion"
|
||||
lore:
|
||||
- ""
|
||||
- " <gray>- <white>Level: <green><level> » <dark_green><next_level>"
|
||||
- " <gray>- <white>Range: <green><range> » <dark_green><next_range>"
|
||||
- " <gray>- <white>Speed: <green><speed> » <dark_green><next_speed>"
|
||||
- ""
|
||||
- "<#00CCFF>Requirements:"
|
||||
- " <gray>- <white>Money: <#33FF33><price>$"
|
||||
- " <gray>- <white>Collected items: <#33FF33><required_actions>"
|
||||
- ""
|
||||
- "<#00CCFF><b>(!)</b> Click here to upgrade your minion!"
|
||||
statistics:
|
||||
type: "paper"
|
||||
name: "<#00AAFF><b>Statistics"
|
||||
lore:
|
||||
- ""
|
||||
- " <gray>- <white>Broken blocks: <#00AAFF><actions>"
|
||||
- ""
|
||||
|
||||
upgrades:
|
||||
1:
|
||||
range: 3
|
||||
speed: 200
|
||||
items:
|
||||
helmet:
|
||||
type: "player_head"
|
||||
texture: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzk2MjdiZTYyY2VkNzE0MTEzOWQzZjE1NTc5MGE1ZDQzNTZlYjdiOWVlOTVlNTA0YjMzMjI5NzRjYmM1MTVlYSJ9fX0="
|
||||
chestplate:
|
||||
type: "leather_chestplate"
|
||||
color: "0, 150, 255"
|
||||
glow: false
|
||||
leggings:
|
||||
type: "leather_leggings"
|
||||
color: "0, 150, 255"
|
||||
glow: false
|
||||
boots:
|
||||
type: "leather_boots"
|
||||
color: "0, 150, 255"
|
||||
glow: false
|
||||
2:
|
||||
range: 4
|
||||
speed: 190
|
||||
requirements:
|
||||
money: 1000
|
||||
actions: 100
|
||||
3:
|
||||
range: 5
|
||||
speed: 175
|
||||
requirements:
|
||||
money: 3000
|
||||
actions: 300
|
||||
4:
|
||||
range: 6
|
||||
speed: 160
|
||||
requirements:
|
||||
money: 10000
|
||||
actions: 1000
|
||||
5:
|
||||
range: 7
|
||||
speed: 150
|
||||
requirements:
|
||||
money: 20000
|
||||
actions: 3000
|
||||
6:
|
||||
range: 8
|
||||
speed: 130
|
||||
requirements:
|
||||
money: 50000
|
||||
actions: 6000
|
||||
7:
|
||||
range: 9
|
||||
speed: 115
|
||||
requirements:
|
||||
money: 150000
|
||||
actions: 10000
|
||||
8:
|
||||
range: 10
|
||||
speed: 100
|
||||
requirements:
|
||||
money: 500000
|
||||
actions: 17500
|
||||
9:
|
||||
range: 11
|
||||
speed: 85
|
||||
requirements:
|
||||
money: 1000000
|
||||
actions: 25000
|
||||
10:
|
||||
range: 12
|
||||
speed: 60
|
||||
requirements:
|
||||
money: 5000000
|
||||
actions: 50000
|
||||
items:
|
||||
chestplate:
|
||||
type: LEATHER_CHESTPLATE
|
||||
color: "255, 200, 0"
|
||||
glow: true
|
||||
leggings:
|
||||
type: LEATHER_LEGGINGS
|
||||
color: "255, 200, 0"
|
||||
glow: true
|
||||
boots:
|
||||
type: LEATHER_BOOTS
|
||||
color: "255, 200, 0"
|
||||
glow: true
|
@ -1,4 +1,7 @@
|
||||
name: "AxMinions"
|
||||
main: "com.artillexstudios.axminions.AxMinionsPlugin"
|
||||
version: "1.0"
|
||||
api-version: 1.19
|
||||
api-version: 1.19
|
||||
softdepend:
|
||||
- RoseStacker
|
||||
- WildStacker
|
Loading…
Reference in New Issue
Block a user