Lots of work

This commit is contained in:
TomTom 2023-10-21 19:29:05 +02:00
parent 2069ced74f
commit 0998df532b
37 changed files with 186 additions and 131 deletions

View File

@ -55,6 +55,8 @@ class Messages(file: File, stream: InputStream) {
fun LINK_FAIL() = AxMinionsAPI.INSTANCE.getMessages().get<String>("link.fail")
@JvmStatic
fun LINK_START() = AxMinionsAPI.INSTANCE.getMessages().get<String>("link.start")
@JvmStatic
fun UPGRADE_FAIL() = AxMinionsAPI.INSTANCE.getMessages().get<String>("upgrades.fail")
}
private val config = Config(

View File

@ -14,7 +14,7 @@ interface DataHandler {
fun insertType(minionType: MinionType)
fun loadMinionsOfType(minionType: MinionType)
fun loadMinionsForWorld(minionType: MinionType, world: World)
fun getLocationID(location: Location): Int

View File

@ -1,13 +1,14 @@
package com.artillexstudios.axminions.api.integrations.types
import com.artillexstudios.axminions.api.integrations.Integration
import org.bukkit.OfflinePlayer
import org.bukkit.entity.Player
interface EconomyIntegration : Integration {
fun getBalance(player: Player): Double
fun getBalance(player: OfflinePlayer): Double
fun giveBalance(player: Player, amount: Double)
fun giveBalance(player: OfflinePlayer, amount: Double)
fun takeBalance(player: Player, amount: Double)
fun takeBalance(player: OfflinePlayer, amount: Double)
}

View File

@ -7,7 +7,6 @@ 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
import java.io.File
@ -19,7 +18,6 @@ abstract class MinionType(private val name: String, private val defaults: InputS
fun load() {
config = Config(File(AxMinionsAPI.INSTANCE.getAxMinionsDataFolder(), "/minions/$name.yml"), defaults)
AxMinionsAPI.INSTANCE.getDataHandler().insertType(this)
AxMinionsAPI.INSTANCE.getDataHandler().loadMinionsOfType(this)
}
fun getName(): String {
@ -78,7 +76,9 @@ abstract class MinionType(private val name: String, private val defaults: InputS
var n = defaultValue
config.getSection("upgrades").getRoutesAsStrings(false).forEach {
if (it.toInt() > level) return n
if (it.toInt() > level) {
return n
}
if (config.backingDocument.getAsOptional("upgrades.$it.$key", clazz).isEmpty) return@forEach

View File

@ -2,13 +2,12 @@ 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
import org.bukkit.World
object MinionTypes {
private val TYPES = hashMapOf<String, MinionType>()
@JvmStatic
fun register(type: MinionType): MinionType {
if (TYPES.containsKey(type.getName())) {
@ -20,6 +19,13 @@ object MinionTypes {
return type
}
@JvmStatic
fun loadForWorld(world: World) {
TYPES.forEach {
AxMinionsAPI.INSTANCE.getDataHandler().loadMinionsForWorld(it.value, world)
}
}
@JvmStatic
fun unregister(key: String) {
TYPES.remove(key)

View File

@ -1,31 +1,27 @@
package com.artillexstudios.axminions.api.utils
class CoolDown<T> : HashMap<T, Long>() {
class CoolDown<T> {
private val map = HashMap<T, Long>()
fun add(value: T, time: Long) {
expire()
put(value, System.currentTimeMillis() + time)
map[value] = System.currentTimeMillis() + time
}
override fun containsKey(key: T): Boolean {
expire()
return super.containsKey(key)
}
fun contains(value: T): Boolean {
return containsKey(value)
expire()
return map.containsKey(value)
}
override fun remove(key: T): Long? {
fun remove(key: T): Long? {
expire()
return super.remove(key)
return map.remove(key)
}
private fun expire() {
val currentTime = System.currentTimeMillis()
val iterator = iterator()
val iterator = map.iterator()
while (iterator.hasNext()) {
val next = iterator.next()
if (next.value <= currentTime) {

View File

@ -62,10 +62,10 @@ object MinionUtils {
}
@JvmStatic
fun getTree(startBlock: Block): List<Block> {
fun getTree(startBlock: Block): Set<Block> {
val queue: Queue<Block> = LinkedList()
val visited = mutableSetOf<Block>()
val tree = mutableListOf<Block>()
val tree = mutableSetOf<Block>()
queue.add(startBlock)

View File

@ -111,9 +111,9 @@ allprojects {
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')
// compileOnly files('../libs/CMI-API9.5.0.8.jar')
// compileOnly files('../libs/IridiumSkyblock-3.2.12.jar')
// compileOnly files('../libs/KingdomsX-1.16.12.jar')
compileOnly files('../libs/CMI-API9.5.0.8.jar')
compileOnly files('../libs/IridiumSkyblock-3.2.12.jar')
compileOnly files('../libs/KingdomsX-1.16.12.jar')
}
shadowJar {

View File

@ -11,6 +11,7 @@ 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.api.utils.fastFor
import com.artillexstudios.axminions.commands.AxMinionsCommand
import com.artillexstudios.axminions.data.H2DataHandler
import com.artillexstudios.axminions.integrations.Integrations
@ -19,6 +20,7 @@ import com.artillexstudios.axminions.listeners.LinkingListener
import com.artillexstudios.axminions.listeners.MinionDamageListener
import com.artillexstudios.axminions.listeners.MinionInventoryListener
import com.artillexstudios.axminions.listeners.MinionPlaceListener
import com.artillexstudios.axminions.listeners.WorldListener
import com.artillexstudios.axminions.minions.MinionTicker
import com.artillexstudios.axminions.minions.miniontype.CollectorMinionType
import com.artillexstudios.axminions.minions.miniontype.FarmerMinionType
@ -97,12 +99,21 @@ class AxMinionsPlugin : AxPlugin() {
handler.registerBrigadier()
}
Bukkit.getPluginManager().registerEvents(MinionPlaceListener(), this)
Bukkit.getPluginManager().registerEvents(LinkingListener(), this)
Bukkit.getPluginManager().registerEvents(MinionInventoryListener(), this)
Bukkit.getPluginManager().registerEvents(ChunkListener(), this)
Bukkit.getPluginManager().registerEvents(MinionDamageListener(), this)
// Retroactively load minions for the already loaded worlds
Bukkit.getWorlds().fastFor { world ->
MinionTypes.getMinionTypes().forEach { map ->
dataHandler.loadMinionsForWorld(map.value, world)
}
}
Bukkit.getPluginManager().also {
it.registerEvents(MinionPlaceListener(), this)
it.registerEvents(LinkingListener(), this)
it.registerEvents(MinionInventoryListener(), this)
it.registerEvents(ChunkListener(), this)
it.registerEvents(MinionDamageListener(), this)
it.registerEvents(WorldListener(), this)
}
MinionTicker.startTicking()
}

View File

@ -58,6 +58,6 @@ class AxMinionsAPIImpl(private val plugin: AxMinionsPlugin) : AxMinionsAPI {
}
override fun getIntegrations(): Integrations {
TODO("Not yet implemented")
return AxMinionsPlugin.integrations
}
}

View File

@ -8,6 +8,7 @@ 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.api.utils.fastFor
import com.artillexstudios.axminions.converter.LitMinionsConverter
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
import revxrsal.commands.annotation.AutoComplete
@ -66,7 +67,8 @@ class AxMinionsCommand {
@CommandPermission("axminions.command.convert")
@Description("Convert from a different plugin")
fun convert(sender: CommandSender) {
val converter = LitMinionsConverter()
converter.convert()
}
@Subcommand("stats", "statistics")

View File

@ -2,10 +2,14 @@ package com.artillexstudios.axminions.converter
import com.artillexstudios.axapi.serializers.Serializers
import com.artillexstudios.axapi.utils.StringUtils
import com.artillexstudios.axminions.AxMinionsPlugin
import com.artillexstudios.axminions.api.minions.Direction
import com.artillexstudios.axminions.api.minions.miniontype.MinionTypes
import com.artillexstudios.axminions.minions.Minion
import java.sql.Connection
import java.sql.DriverManager
import java.util.Locale
import java.util.UUID
import org.bukkit.Bukkit
import org.bukkit.Location
import org.bukkit.Material
@ -26,54 +30,44 @@ class LitMinionsConverter : Converter {
.sendMessage(StringUtils.formatToString("<#33FF33>[AxMinions-Converter] <#FF0000>FAILED! Database not found, or corrupted!"))
return
}
var skipped = 0
var loaded = 0
connection.use {
connection.prepareStatement("SELECT * FROM `minions_data`").use { preparedStatement ->
preparedStatement.executeQuery().use { resultSet ->
while (resultSet.next()) {
// Bukkit.getConsoleSender().sendMessage(
// StringUtils.formatToString(
//// "&#DDDDDD[AxMinions-Converter] Converting: " + resultSet.getString("minionworld") + ";" + rs.getDouble(
// "minionx"
// ) + ";" + resultSet.getDouble("miniony") + ";" + resultSet.getDouble("minionz")
// )
// )
/* val location =
resultSet.getString("minionworld") + ";" + resultSet.getDouble("minionx") + ";" + resultSet.getDouble(
"miniony"*//**//*
// ) + ";" + rs.getDouble(
"minionz"
)*/
val direction: Direction =
Direction.valueOf(resultSet.getString("minionface").uppercase(Locale.ENGLISH))
val location = Serializers.LOCATION.deserialize("${resultSet.getString("minionworld")};${resultSet.getString("minionx")};${resultSet.getString("miniony")};${resultSet.getString("minionz")};0;0")
val direction = Direction.valueOf(resultSet.getString("minionface").uppercase(Locale.ENGLISH))
val level = resultSet.getInt("level")
val type = resultSet.getString("miniontype").uppercase(Locale.getDefault())
val owner = resultSet.getString("owner")
val type = MinionTypes.valueOf(resultSet.getString("miniontype").lowercase(Locale.ENGLISH)) ?: continue
val uuid = UUID.fromString(resultSet.getString("owner"))
val storage = resultSet.getDouble("exp")
val statistics = resultSet.getLong("stat")
val chest = "${resultSet.getString("chestworld")};${resultSet.getString("chestx")};${resultSet.getString("chesty")};${resultSet.getString("chestz")};0;0"
val statistic = resultSet.getLong("stat")
val linkedChest = "${resultSet.getString("chestworld")};${resultSet.getDouble("chestx")};${
resultSet.getDouble("chesty")
};${resultSet.getDouble("chestz")};0;0"
var linkedChestLoc: Location? = null
if (resultSet.getString("chestworld") != null) {
linkedChestLoc = Serializers.LOCATION.deserialize(linkedChest)
var chestLocation: Location? = null
if (resultSet.getString("chestworld") == null) {
chestLocation = Serializers.LOCATION.deserialize(chest)
}
val it = ItemStack(Material.AIR)
if (location.world == null || (chestLocation != null && chestLocation.world == null) || AxMinionsPlugin.dataHandler.isMinion(location)) {
skipped++
continue
} else {
loaded++
}
// val locationId = AxMinionsPlugin.dataHandler.getLocationID(location)
// val minion = Minion(location, owner, Bukkit.getOfflinePlayer(owner), minionType, 1, ItemStack(Material.AIR), null, Direction.NORTH, 0, 0.0, locationId, 0)
// minion.setLevel(level)
// minion.setActions(stats)
// minion.setTicking(true)
val locationId = AxMinionsPlugin.dataHandler.getLocationID(location)
val chestLocationId = if (chestLocation != null) AxMinionsPlugin.dataHandler.getLocationID(chestLocation) else 0
val minion = Minion(location, uuid, Bukkit.getOfflinePlayer(uuid), type, level, ItemStack(Material.AIR), chestLocation, direction, statistics, storage, locationId, chestLocationId)
minion.setTicking(true)
AxMinionsPlugin.dataHandler.saveMinion(minion)
}
}
}
}
Bukkit.getConsoleSender().sendMessage(StringUtils.formatToString("<#33FF33>[AxMinions-Converter] <white>Converting done! Loaded: $loaded minion, skipped: $skipped minion!"))
}
}

View File

@ -60,7 +60,7 @@ class H2DataHandler : DataHandler {
}
}
override fun loadMinionsOfType(minionType: MinionType) {
override fun loadMinionsForWorld(minionType: MinionType, world: World) {
var typeId = 0
connection.prepareStatement("SELECT `id` FROM `axminions_types` WHERE `name` = ?;").use { statement ->
statement.setString(1, minionType.getName())
@ -71,8 +71,9 @@ class H2DataHandler : DataHandler {
}
}
connection.prepareStatement("SELECT * FROM `axminions_minions` WHERE `type_id` = ?;").use { statement ->
statement.setInt(1, typeId)
connection.prepareStatement("SELECT `minions`.* FROM `axminions_minions` AS `minions` JOIN `axminions_locations` AS `location` ON `minions`.`location_id` = `location`.`id` WHERE `location`.`world_id` = (SELECT `id` FROM `axminions_worlds` WHERE `name` = ?) AND `type_id` = ?;").use { statement ->
statement.setString(1, world.name)
statement.setInt(2, typeId)
statement.executeQuery().use { resultSet ->
while (resultSet.next()) {
val locationId = resultSet.getInt("location_id")
@ -84,8 +85,6 @@ class H2DataHandler : DataHandler {
val actions = resultSet.getLong("actions")
val tool = resultSet.getString("tool")
println("direction: $direction, tool: $tool chest location: $chestLocationId")
val location = getLocation(locationId)
var chestLocation: Location? = null
if (chestLocationId != 0) {
@ -175,7 +174,7 @@ class H2DataHandler : DataHandler {
statement.setInt(1, worldId)
statement.executeQuery().use { resultSet ->
if (resultSet.next()) {
return Bukkit.getWorld(resultSet.getString("name"))!!
return Bukkit.getWorld(resultSet.getString("name"))
}
return null
@ -280,7 +279,7 @@ class H2DataHandler : DataHandler {
}
override fun getMinionAmount(uuid: UUID): Int {
connection.prepareStatement("SELECT COUNT(`owner_id`) FROM `axminions_minions` WHERE `owner_id` = (SELECT `owner_id` FROM `axminions_users` WHERE `uuid` = ?);")
connection.prepareStatement("SELECT COUNT(`owner_id`) FROM `axminions_minions` WHERE `owner_id` = ?;")
.use { statement ->
statement.setObject(1, uuid)
statement.executeQuery().use { resultSet ->

View File

@ -1,19 +1,20 @@
package com.artillexstudios.axminions.integrations.economy
import com.artillexstudios.axminions.api.integrations.types.EconomyIntegration
import org.bukkit.OfflinePlayer
import org.bukkit.entity.Player
class PlayerPointsIntegration : EconomyIntegration {
override fun getBalance(player: Player): Double {
override fun getBalance(player: OfflinePlayer): Double {
TODO("Not yet implemented")
}
override fun giveBalance(player: Player, amount: Double) {
override fun giveBalance(player: OfflinePlayer, amount: Double) {
TODO("Not yet implemented")
}
override fun takeBalance(player: Player, amount: Double) {
override fun takeBalance(player: OfflinePlayer, amount: Double) {
TODO("Not yet implemented")
}

View File

@ -3,20 +3,20 @@ 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
import org.bukkit.OfflinePlayer
class VaultIntegration : EconomyIntegration {
private lateinit var economy: Economy
override fun getBalance(player: Player): Double {
override fun getBalance(player: OfflinePlayer): Double {
return economy.getBalance(player)
}
override fun giveBalance(player: Player, amount: Double) {
override fun giveBalance(player: OfflinePlayer, amount: Double) {
economy.depositPlayer(player, amount)
}
override fun takeBalance(player: Player, amount: Double) {
override fun takeBalance(player: OfflinePlayer, amount: Double) {
economy.withdrawPlayer(player, amount)
}

View File

@ -1,22 +1,21 @@
package com.artillexstudios.axminions.integrations.prices
//import com.Zrips.CMI.CMI
import com.Zrips.CMI.CMI
import com.artillexstudios.axminions.api.integrations.types.PricesIntegration
import org.bukkit.inventory.ItemStack
class CMIIntegration : PricesIntegration {
// private lateinit var manager: CMI
private lateinit var manager: CMI
override fun getPrice(itemStack: ItemStack): Double {
// val worth = manager.worthManager.getWorth(itemStack) ?: return -1.0
//
// return if (worth.sellPrice == 0.0) -1.0 else worth.sellPrice
return -1.0
val worth = manager.worthManager.getWorth(itemStack) ?: return -1.0
return if (worth.sellPrice == 0.0) -1.0 else worth.sellPrice
}
override fun register() {
// manager = CMI.getInstance();
manager = CMI.getInstance();
}
}

View File

@ -1,16 +1,16 @@
package com.artillexstudios.axminions.integrations.protection
import com.artillexstudios.axminions.api.integrations.types.ProtectionIntegration
import com.iridium.iridiumskyblock.api.IridiumSkyblockAPI
import org.bukkit.Location
import org.bukkit.entity.Player
class IridiumSkyBlockIntegration : ProtectionIntegration {
override fun canBuildAt(player: Player, location: Location): Boolean {
/* val island = IridiumSkyblockAPI.getInstance().getIslandViaLocation(location)
val island = IridiumSkyblockAPI.getInstance().getIslandViaLocation(location)
return island.map { IridiumSkyblockAPI.getInstance().getUser(player) in it.members }.orElse(true)*/
return true
return island.map { IridiumSkyblockAPI.getInstance().getUser(player) in it.members }.orElse(true)
}
override fun register() {

View File

@ -3,15 +3,16 @@ package com.artillexstudios.axminions.integrations.protection
import com.artillexstudios.axminions.api.integrations.types.ProtectionIntegration
import org.bukkit.Location
import org.bukkit.entity.Player
import org.kingdoms.constants.land.Land
import org.kingdoms.constants.player.KingdomPlayer
class KingdomsXIntegration : ProtectionIntegration {
override fun canBuildAt(player: Player, location: Location): Boolean {
// val localPlayer = KingdomPlayer.getKingdomPlayer(player.uniqueId);
// val land = Land.getLand(location) ?: return true
//
// return land.kingdom.isMember(localPlayer);
return true
val localPlayer = KingdomPlayer.getKingdomPlayer(player.uniqueId);
val land = Land.getLand(location) ?: return true
return land.kingdom.isMember(localPlayer);
}
override fun register() {

View File

@ -13,7 +13,6 @@ class MinionDamageListener : Listener {
@EventHandler
fun onPreMinionDamageEntityEvent(event: MinionKillEntityEvent) {
println("MINION KILL ENTITY EVENT")
val entitySize = AxMinionsPlugin.integrations.getStackerIntegration().getStackSize(event.target)
event.minion.setStorage(event.minion.getStorage() + ThreadLocalRandom.current().nextInt(1, 4) * entitySize)

View File

@ -117,6 +117,7 @@ class MinionInventoryListener : Listener {
player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.LINK_START()))
LinkingListener.linking[player.uniqueId] = minion
player.closeInventory()
}
"upgrade" -> {
@ -128,6 +129,7 @@ class MinionInventoryListener : Listener {
}
if (minion.getActionAmount() < actions) {
player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.UPGRADE_FAIL()))
return
}
@ -150,7 +152,12 @@ class MinionInventoryListener : Listener {
}
if (minion.getType() == MinionTypes.getMinionTypes()["seller"]) {
// TODO: Give money
AxMinionsPlugin.integrations.getEconomyIntegration()?.let {
minion.getOwner()?.let {
player -> it.giveBalance(player, stored)
minion.setStorage(0.0)
}
}
} else {
player.giveExp(stored.toInt())
}

View File

@ -58,6 +58,7 @@ class MinionPlaceListener : Listener {
minion.setLevel(level)
minion.setActions(stats)
minion.setTicking(true)
event.item?.amount = event.item?.amount?.minus(1) ?: 0
if (Config.DEBUG()) {
event.player.sendMessage("Placed minion $minion. Ticking? ${minion.isTicking()} Is chunk ticking? ${Minions.isTicking(location.chunk)}")
}

View File

@ -0,0 +1,14 @@
package com.artillexstudios.axminions.listeners
import com.artillexstudios.axminions.api.minions.miniontype.MinionTypes
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.world.WorldLoadEvent
class WorldListener : Listener {
@EventHandler
fun onWorldLoadEvent(event: WorldLoadEvent) {
MinionTypes.loadForWorld(event.world)
}
}

View File

@ -71,7 +71,7 @@ class Minion(
init {
spawn()
Minions.load(this)
linkedInventory = (linkedChest?.block?.blockData as? Container)?.inventory
linkedInventory = (linkedChest?.block?.state as? Container)?.inventory
}
override fun getType(): MinionType {
@ -87,7 +87,6 @@ class Minion(
entity.setHasArms(true)
entity.onClick { event ->
println("bbbbbbbbbbbbbb")
if (event.isAttack) {
if (ownerUUID == event.player.uniqueId && Config.ONLY_OWNER_BREAK()) {
breakMinion(event)
@ -167,17 +166,19 @@ class Minion(
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))
val nextExtra = Placeholder.unparsed("next_extra", type.getString("extra", this.level + 1))
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 range = Placeholder.unparsed("range", type.getDouble("range", this.level).toString())
val nextRange = Placeholder.unparsed("next_range", type.getDouble("range", this.level + 1).toString())
val extra = Placeholder.unparsed("extra", type.getDouble("extra", this.level).toString())
val nextExtra = Placeholder.unparsed("next_extra", type.getDouble("extra", this.level + 1).toString())
val speed = Placeholder.unparsed("speed", type.getDouble("speed", this.level).toString())
val nextSpeed = Placeholder.unparsed("next_speed", type.getDouble("speed", this.level + 1).toString())
val price = Placeholder.unparsed("price", type.getDouble("requirements.money", this.level + 1).toString())
val requiredActions =
Placeholder.unparsed("required_actions", type.getString("requirements.actions", this.level + 1))
Placeholder.unparsed("required_actions", type.getDouble("requirements.actions", this.level + 1).toString())
val stored = Placeholder.unparsed("storage", storage.toString())
val actions = Placeholder.unparsed("actions", actions.toString())
val multiplier = Placeholder.unparsed("multiplier", type.getDouble("multiplier", this.level).toString())
val nextMultiplier = Placeholder.unparsed("next_multiplier", type.getDouble("multiplier", this.level + 1).toString())
item = ItemBuilder(
type.getConfig().getSection("gui.$it"),
@ -192,7 +193,9 @@ class Minion(
price,
requiredActions,
stored,
actions
actions,
multiplier,
nextMultiplier
).storePersistentData(
Keys.GUI, PersistentDataType.STRING, it
).get()
@ -237,7 +240,6 @@ class Minion(
inventory.setItem(i, filler)
}
println("aaaaa")
player.openInventory(inventory)
updateInventory(inventory)
openInventories.add(inventory)
@ -287,14 +289,13 @@ class Minion(
this.tool = tool.clone()
dirty = true
if (tool.type == Material.AIR) {
if (this.tool?.type == Material.AIR) {
entity.setItem(EquipmentSlot.MAIN_HAND, null)
} else {
entity.setItem(EquipmentSlot.MAIN_HAND, tool.clone())
}
AxMinionsPlugin.dataQueue.submit {
println("Saving minion!")
AxMinionsPlugin.dataHandler.saveMinion(this)
}
}
@ -379,7 +380,6 @@ class Minion(
entity.teleport(location)
AxMinionsPlugin.dataQueue.submit {
println("Saving minion!")
AxMinionsPlugin.dataHandler.saveMinion(this)
}
}

View File

@ -69,7 +69,7 @@ class CollectorMinionType : MinionType("collector", AxMinionsPlugin.INSTANCE.get
stack.amount = amount.toInt()
minion.addToContainerOrDrop(stack)
minion.setActions(minion.getActionAmount() + 1)
minion.setActions(minion.getActionAmount() + amount)
minion.damageTool()
item.remove()
}

View File

@ -10,6 +10,7 @@ import com.artillexstudios.axminions.minions.MinionTicker
import com.artillexstudios.axminions.nms.NMSHandler
import java.util.concurrent.ThreadLocalRandom
import kotlin.math.roundToInt
import org.bukkit.Location
import org.bukkit.Material
import org.bukkit.enchantments.Enchantment
@ -38,17 +39,17 @@ class FisherMinionType : MinionType("fisher", AxMinionsPlugin.INSTANCE.getResour
minion.setLinkedChest(null)
}
var hasWater = false
run breaking@{
var waterLocation: Location? = null
run breaking@ {
LocationUtils.getAllBlocksInRadius(minion.getLocation(), 2.0, false).fastFor {
if (it.block.type != Material.WATER) return@fastFor
hasWater = true
waterLocation = it
return@breaking
}
}
if (!hasWater) {
if (waterLocation == null) {
Warnings.NO_WATER_NEARBY.display(minion)
return
}
@ -61,7 +62,7 @@ class FisherMinionType : MinionType("fisher", AxMinionsPlugin.INSTANCE.getResour
Warnings.remove(minion, Warnings.NO_TOOL)
val loot = NMSHandler.get().generateRandomFishingLoot(minion)
val loot = NMSHandler.get().generateRandomFishingLoot(minion, waterLocation!!)
val xp = ThreadLocalRandom.current().nextInt(6) + 1
minion.addToContainerOrDrop(loot)

View File

@ -48,7 +48,7 @@ class LumberMinionType : MinionType("lumber", AxMinionsPlugin.INSTANCE.getResour
val loot = ArrayList<ItemStack>()
LocationUtils.getAllBlocksInRadius(minion.getLocation(), minion.getRange(), false).fastFor { location ->
MinionUtils.getTree(location.block).fastFor {
MinionUtils.getTree(location.block).forEach {
val down = it.getRelative(BlockFace.DOWN).type
loot.addAll(it.getDrops(minion.getTool()))
@ -88,7 +88,10 @@ class LumberMinionType : MinionType("lumber", AxMinionsPlugin.INSTANCE.getResour
Material.SPRUCE_SAPLING
}
else -> Material.OAK_SAPLING
else -> {
println("Material: $material")
Material.OAK_SAPLING
}
}
}
}

View File

@ -62,6 +62,7 @@ class SlayerMinionType : MinionType("slayer", AxMinionsPlugin.INSTANCE.getResour
}
NMSHandler.get().attack(minion, it)
minion.damageTool()
}
}
}

View File

@ -2,6 +2,7 @@ package com.artillexstudios.axminions.nms
import com.artillexstudios.axapi.utils.Version
import com.artillexstudios.axminions.api.minions.Minion
import org.bukkit.Location
import org.bukkit.entity.Entity
import org.bukkit.inventory.ItemStack
@ -17,7 +18,7 @@ interface NMSHandler {
fun attack(source: Minion, target: Entity)
fun generateRandomFishingLoot(minion: Minion): List<ItemStack>
fun generateRandomFishingLoot(minion: Minion, waterLocation: Location): List<ItemStack>
fun isAnimal(entity: Entity): Boolean
}

View File

@ -54,9 +54,9 @@ gui:
name: "<#33FF33><b>Rotate"
lore:
- ""
- " <gray>- <white>Current: <#FFCC00><rotation>"
- " <gray>- <white>Current: <#33FF33><direction>"
- ""
- "<#FFCC00><b>(!)</b> Click here to rotate your minion!"
- "<#33FF33><b>(!)</b> Click here to rotate your minion!"
slot: 10
link:
type: "chest"

View File

@ -31,6 +31,7 @@ statistics: |
upgrades:
upgraded: "<green>Successfully upgraded the minion to level: <white><level></white>!"
limit-reached: "<red>You have maxed this minion!"
fail: "<red>Your minion either doesn't have enough actions, or you don't have enough money to buy this upgrade!"
link:
success: "<green>Successfully linked the minion to a container!"

View File

@ -31,12 +31,12 @@ gui:
lore:
- ""
- " <gray>- <white>Level: <green><level> » <dark_green><next_level>"
- " <gray>- <white>Range: <green><range> » <dark_green><next_range>"
- " <gray>- <white>Multiplier: <green><multiplier> » <dark_green><next_multiplier>"
- " <gray>- <white>Speed: <green><speed> » <dark_green><next_speed>"
- ""
- "<#00CCFF>Requirements:"
- " <gray>- <white>Money: <#33FF33><price>$"
- " <gray>- <white>Collected items: <#33FF33><required_actions>"
- " <gray>- <white>Sold items: <#33FF33><required_actions>"
- ""
- "<#00CCFF><b>(!)</b> Click here to upgrade your minion!"
statistics:

View File

@ -4,4 +4,17 @@ version: "1.0"
api-version: 1.19
softdepend:
- RoseStacker
- WildStacker
- WildStacker
- CMI
- Vault
- EconomyShopGUI
- Essentials
- ShopGUIPlus
- BentoBox
- GriefPrevention
- IridiumSkyBlock
- KingdomsX
- Lands
- SuperiorSkyBlock2
- WorldGuard
- PlotSquared

BIN
nms/libs/CMI-API9.5.0.8.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -7,13 +7,14 @@ import net.minecraft.world.level.storage.loot.LootParams
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets
import net.minecraft.world.level.storage.loot.parameters.LootContextParams
import net.minecraft.world.phys.Vec3
import org.bukkit.Location
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack
import org.bukkit.inventory.ItemStack
object LootHandler {
fun generateFishingLoot(minion: Minion): List<ItemStack> {
fun generateFishingLoot(minion: Minion, waterLocation: Location): List<ItemStack> {
val nmsItem: net.minecraft.world.item.ItemStack = if (minion.getTool() == null) {
net.minecraft.world.item.ItemStack.EMPTY
} else {
@ -23,7 +24,7 @@ object LootHandler {
val level = (minion.getLocation().world as CraftWorld).handle
val lootparams = LootParams.Builder(level).withParameter(
LootContextParams.ORIGIN, Vec3(minion.getLocation().x, minion.getLocation().y, minion.getLocation().z)
LootContextParams.ORIGIN, Vec3(waterLocation.x, waterLocation.y, waterLocation.z)
).withParameter(LootContextParams.TOOL, nmsItem).withOptionalParameter(LootContextParams.THIS_ENTITY, null)
.create(LootContextParamSets.FISHING)

View File

@ -3,6 +3,7 @@ package com.artillexstudios.axminions.nms.v1_20_R1
import com.artillexstudios.axminions.api.minions.Minion
import com.artillexstudios.axminions.nms.NMSHandler
import net.minecraft.world.entity.MobCategory
import org.bukkit.Location
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity
import org.bukkit.entity.Entity
import org.bukkit.inventory.ItemStack
@ -13,8 +14,8 @@ class NMSHandler : NMSHandler {
DamageHandler.damage(source, target)
}
override fun generateRandomFishingLoot(minion: Minion): List<ItemStack> {
return LootHandler.generateFishingLoot(minion)
override fun generateRandomFishingLoot(minion: Minion, waterLocation: Location): List<ItemStack> {
return LootHandler.generateFishingLoot(minion, waterLocation)
}
override fun isAnimal(entity: Entity): Boolean {