From 2bb47ffae7b213e1d973d514a2df9886961f20e6 Mon Sep 17 00:00:00 2001
From: TomTom <93038247+AverageGithub@users.noreply.github.com>
Date: Sun, 15 Oct 2023 17:29:21 +0200
Subject: [PATCH] So much work, nms & stuff
---
.idea/gradle.xml | 2 +
.../axminions/api/config/Config.kt | 9 +-
.../axminions/api/config/Messages.kt | 8 +
.../api/events/MinionDamageEntityEvent.kt | 30 +++
.../axminions/api/events/MinionEvent.kt | 6 +
.../api/integrations/Integrations.kt | 4 +-
.../axminions/api/minions/Minion.kt | 2 -
.../axminions/api/utils/Collections.kt | 1 +
.../axminions/api/warnings/Warnings.kt | 10 +-
build.gradle | 4 +
.../axminions/AxMinionsPlugin.kt | 14 +-
.../axminions/converter/Converter.kt | 6 +
.../converter/JetsMinionsConverter.kt | 8 +
.../converter/LitMinionsConverter.kt | 79 +++++++
.../axminions/integrations/Integrations.kt | 18 +-
.../integrations/prices/CMIIntegration.kt | 10 +-
.../protection/IridiumSkyBlockIntegration.kt | 19 ++
.../protection/KingdomsXIntegration.kt | 21 ++
.../axminions/listeners/LinkingListener.kt | 8 +-
.../listeners/MinionDamageListener.kt | 19 ++
.../listeners/MinionInventoryListener.kt | 9 +-
.../listeners/MinionPlaceListener.kt | 14 +-
.../axminions/minions/Minion.kt | 34 ++-
.../minions/miniontype/CollectorMinionType.kt | 4 +-
.../minions/miniontype/FarmerMinionType.kt | 2 +-
.../minions/miniontype/FisherMinionType.kt | 61 +++++-
.../minions/miniontype/LumberMinionType.kt | 2 +-
.../minions/miniontype/MinerMinionType.kt | 2 +-
.../minions/miniontype/SellerMinionType.kt | 73 ++++++-
.../minions/miniontype/SlayerMinionType.kt | 71 +++++-
.../axminions/nms/NMSHandler.kt | 23 ++
common/src/main/resources/messages.yml | 6 +
common/src/main/resources/minions/fisher.yml | 133 ++++++++++++
common/src/main/resources/minions/lumber.yml | 16 +-
common/src/main/resources/minions/miner.yml | 22 +-
common/src/main/resources/minions/seller.yml | 148 +++++++++++++
common/src/main/resources/minions/slayer.yml | 142 ++++++++++++
nms/build.gradle | 13 ++
nms/v1_20_R1/build.gradle | 20 ++
.../axminions/nms/v1_20_R1/DamageHandler.kt | 205 ++++++++++++++++++
.../axminions/nms/v1_20_R1/LootHandler.kt | 38 ++++
.../axminions/nms/v1_20_R1/NMSHandler.kt | 23 ++
settings.gradle | 2 +
43 files changed, 1280 insertions(+), 61 deletions(-)
create mode 100644 api/src/main/kotlin/com/artillexstudios/axminions/api/events/MinionDamageEntityEvent.kt
create mode 100644 api/src/main/kotlin/com/artillexstudios/axminions/api/events/MinionEvent.kt
create mode 100644 common/src/main/kotlin/com/artillexstudios/axminions/converter/Converter.kt
create mode 100644 common/src/main/kotlin/com/artillexstudios/axminions/converter/JetsMinionsConverter.kt
create mode 100644 common/src/main/kotlin/com/artillexstudios/axminions/converter/LitMinionsConverter.kt
create mode 100644 common/src/main/kotlin/com/artillexstudios/axminions/integrations/protection/IridiumSkyBlockIntegration.kt
create mode 100644 common/src/main/kotlin/com/artillexstudios/axminions/integrations/protection/KingdomsXIntegration.kt
create mode 100644 common/src/main/kotlin/com/artillexstudios/axminions/listeners/MinionDamageListener.kt
create mode 100644 common/src/main/kotlin/com/artillexstudios/axminions/nms/NMSHandler.kt
create mode 100644 common/src/main/resources/minions/fisher.yml
create mode 100644 common/src/main/resources/minions/seller.yml
create mode 100644 common/src/main/resources/minions/slayer.yml
create mode 100644 nms/build.gradle
create mode 100644 nms/v1_20_R1/build.gradle
create mode 100644 nms/v1_20_R1/src/main/kotlin/com/artillexstudios/axminions/nms/v1_20_R1/DamageHandler.kt
create mode 100644 nms/v1_20_R1/src/main/kotlin/com/artillexstudios/axminions/nms/v1_20_R1/LootHandler.kt
create mode 100644 nms/v1_20_R1/src/main/kotlin/com/artillexstudios/axminions/nms/v1_20_R1/NMSHandler.kt
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index b01719d..544d142 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -10,6 +10,8 @@
+
+
diff --git a/api/src/main/kotlin/com/artillexstudios/axminions/api/config/Config.kt b/api/src/main/kotlin/com/artillexstudios/axminions/api/config/Config.kt
index 3fa7321..59f6b36 100644
--- a/api/src/main/kotlin/com/artillexstudios/axminions/api/config/Config.kt
+++ b/api/src/main/kotlin/com/artillexstudios/axminions/api/config/Config.kt
@@ -12,6 +12,7 @@ import java.io.InputStream
class Config(file: File, stream: InputStream) {
companion object {
+ private var debug: Boolean? = null
@JvmStatic
fun AUTO_SAVE_MINUTES() = AxMinionsAPI.INSTANCE.getConfig().get("autosave-minutes", 3L)
@JvmStatic
@@ -39,7 +40,13 @@ class Config(file: File, stream: InputStream) {
@JvmStatic
fun GUI_SIZE() = AxMinionsAPI.INSTANCE.getConfig().get("gui.size")
@JvmStatic
- fun DEBUG() = AxMinionsAPI.INSTANCE.getConfig().get("debug")
+ fun DEBUG(): Boolean {
+ if (debug === null) {
+ debug = AxMinionsAPI.INSTANCE.getConfig().get("debug", false)
+ }
+
+ return debug ?: false
+ }
}
private val config = Config(
diff --git a/api/src/main/kotlin/com/artillexstudios/axminions/api/config/Messages.kt b/api/src/main/kotlin/com/artillexstudios/axminions/api/config/Messages.kt
index ca4079e..352089f 100644
--- a/api/src/main/kotlin/com/artillexstudios/axminions/api/config/Messages.kt
+++ b/api/src/main/kotlin/com/artillexstudios/axminions/api/config/Messages.kt
@@ -47,6 +47,14 @@ class Messages(file: File, stream: InputStream) {
fun WRONG_TOOL() = AxMinionsAPI.INSTANCE.getMessages().get("tools.wrong-tool")
@JvmStatic
fun ERROR_INVENTORY_FULL() = AxMinionsAPI.INSTANCE.getMessages().get("errors.inventory-full")
+ @JvmStatic
+ fun LINK_SUCCESS() = AxMinionsAPI.INSTANCE.getMessages().get("link.success")
+ @JvmStatic
+ fun LINK_UNLINK() = AxMinionsAPI.INSTANCE.getMessages().get("link.unlink")
+ @JvmStatic
+ fun LINK_FAIL() = AxMinionsAPI.INSTANCE.getMessages().get("link.fail")
+ @JvmStatic
+ fun LINK_START() = AxMinionsAPI.INSTANCE.getMessages().get("link.start")
}
private val config = Config(
diff --git a/api/src/main/kotlin/com/artillexstudios/axminions/api/events/MinionDamageEntityEvent.kt b/api/src/main/kotlin/com/artillexstudios/axminions/api/events/MinionDamageEntityEvent.kt
new file mode 100644
index 0000000..1fd552a
--- /dev/null
+++ b/api/src/main/kotlin/com/artillexstudios/axminions/api/events/MinionDamageEntityEvent.kt
@@ -0,0 +1,30 @@
+package com.artillexstudios.axminions.api.events
+
+import com.artillexstudios.axminions.api.minions.Minion
+import org.bukkit.entity.LivingEntity
+import org.bukkit.event.Cancellable
+import org.bukkit.event.HandlerList
+
+class MinionDamageEntityEvent(minion: Minion, val target: LivingEntity, val damage: Double) : MinionEvent(minion), Cancellable {
+ companion object {
+ private val handlerList = HandlerList()
+
+ @JvmStatic
+ fun getHandlerList(): HandlerList = handlerList
+ }
+
+ private var isCancelled = false
+
+
+ override fun getHandlers(): HandlerList {
+ return handlerList
+ }
+
+ override fun isCancelled(): Boolean {
+ return isCancelled
+ }
+
+ override fun setCancelled(cancelled: Boolean) {
+ isCancelled = cancelled
+ }
+}
\ No newline at end of file
diff --git a/api/src/main/kotlin/com/artillexstudios/axminions/api/events/MinionEvent.kt b/api/src/main/kotlin/com/artillexstudios/axminions/api/events/MinionEvent.kt
new file mode 100644
index 0000000..ed718c3
--- /dev/null
+++ b/api/src/main/kotlin/com/artillexstudios/axminions/api/events/MinionEvent.kt
@@ -0,0 +1,6 @@
+package com.artillexstudios.axminions.api.events
+
+import com.artillexstudios.axminions.api.minions.Minion
+import org.bukkit.event.Event
+
+abstract class MinionEvent(val minion: Minion) : Event()
\ No newline at end of file
diff --git a/api/src/main/kotlin/com/artillexstudios/axminions/api/integrations/Integrations.kt b/api/src/main/kotlin/com/artillexstudios/axminions/api/integrations/Integrations.kt
index 42e3a22..0c63866 100644
--- a/api/src/main/kotlin/com/artillexstudios/axminions/api/integrations/Integrations.kt
+++ b/api/src/main/kotlin/com/artillexstudios/axminions/api/integrations/Integrations.kt
@@ -9,9 +9,9 @@ interface Integrations {
fun getStackerIntegration(): StackerIntegration
- fun getPricesIntegration(): PricesIntegration
+ fun getPricesIntegration(): PricesIntegration?
- fun getEconomyIntegration(): EconomyIntegration
+ fun getEconomyIntegration(): EconomyIntegration?
fun getProtectionIntegration(): ProtectionIntegrations
diff --git a/api/src/main/kotlin/com/artillexstudios/axminions/api/minions/Minion.kt b/api/src/main/kotlin/com/artillexstudios/axminions/api/minions/Minion.kt
index 5d3e07b..db57df2 100644
--- a/api/src/main/kotlin/com/artillexstudios/axminions/api/minions/Minion.kt
+++ b/api/src/main/kotlin/com/artillexstudios/axminions/api/minions/Minion.kt
@@ -24,8 +24,6 @@ interface Minion : InventoryHolder {
fun updateInventories()
- fun updateInventory(inventory: Inventory)
-
fun openInventory(player: Player)
fun getAsItem(): ItemStack
diff --git a/api/src/main/kotlin/com/artillexstudios/axminions/api/utils/Collections.kt b/api/src/main/kotlin/com/artillexstudios/axminions/api/utils/Collections.kt
index c9c31c1..8739e34 100644
--- a/api/src/main/kotlin/com/artillexstudios/axminions/api/utils/Collections.kt
+++ b/api/src/main/kotlin/com/artillexstudios/axminions/api/utils/Collections.kt
@@ -8,6 +8,7 @@ inline fun Array.fastFor(action: (T) -> Unit) {
}
inline fun List.fastFor(action: (T) -> Unit) {
+ if (isEmpty()) return
val indices = indices
for (i in indices) {
action(get(i))
diff --git a/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/Warnings.kt b/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/Warnings.kt
index a1c4875..5044edd 100644
--- a/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/Warnings.kt
+++ b/api/src/main/kotlin/com/artillexstudios/axminions/api/warnings/Warnings.kt
@@ -29,9 +29,11 @@ object Warnings {
}
@JvmStatic
- fun remove(minion: Minion) {
- minion.getWarningHologram()?.remove()
- minion.setWarningHologram(null)
- minion.setWarning(null)
+ fun remove(minion: Minion, warning: Warning) {
+ if (minion.getWarning() == warning) {
+ minion.getWarningHologram()?.remove()
+ minion.setWarningHologram(null)
+ minion.setWarning(null)
+ }
}
}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index f7d9569..37e8cac 100644
--- a/build.gradle
+++ b/build.gradle
@@ -20,6 +20,7 @@ repositories {
dependencies {
implementation project(path: ":api")
implementation project(path: ":common")
+ implementation project(path: ":nms:v1_20_R1", configuration: "reobf")
}
allprojects {
@@ -110,6 +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')
}
shadowJar {
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/AxMinionsPlugin.kt b/common/src/main/kotlin/com/artillexstudios/axminions/AxMinionsPlugin.kt
index a0a9709..6f0711a 100644
--- a/common/src/main/kotlin/com/artillexstudios/axminions/AxMinionsPlugin.kt
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/AxMinionsPlugin.kt
@@ -17,13 +17,17 @@ import com.artillexstudios.axminions.data.H2DataHandler
import com.artillexstudios.axminions.integrations.Integrations
import com.artillexstudios.axminions.listeners.ChunkListener
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.minions.MinionTicker
import com.artillexstudios.axminions.minions.miniontype.CollectorMinionType
import com.artillexstudios.axminions.minions.miniontype.FarmerMinionType
+import com.artillexstudios.axminions.minions.miniontype.FisherMinionType
import com.artillexstudios.axminions.minions.miniontype.LumberMinionType
import com.artillexstudios.axminions.minions.miniontype.MinerMinionType
+import com.artillexstudios.axminions.minions.miniontype.SellerMinionType
+import com.artillexstudios.axminions.minions.miniontype.SlayerMinionType
import org.bukkit.Bukkit
import java.io.File
@@ -65,6 +69,9 @@ class AxMinionsPlugin : AxPlugin() {
it.register(FarmerMinionType())
it.register(MinerMinionType())
it.register(LumberMinionType())
+ it.register(SellerMinionType())
+ it.register(FisherMinionType())
+ it.register(SlayerMinionType())
}
val handler = BukkitCommandHandler.create(this)
@@ -84,12 +91,15 @@ class AxMinionsPlugin : AxPlugin() {
handler.register(AxMinionsCommand())
- handler.registerBrigadier()
+ if (handler.isBrigadierSupported) {
+ 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)
MinionTicker.startTicking()
}
@@ -102,8 +112,6 @@ class AxMinionsPlugin : AxPlugin() {
if (Config.DATABASE_TYPE().equals("H2", true)) {
dataHandler = H2DataHandler()
dataHandler.setup()
- } else {
-
}
}
}
\ No newline at end of file
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/converter/Converter.kt b/common/src/main/kotlin/com/artillexstudios/axminions/converter/Converter.kt
new file mode 100644
index 0000000..b77b570
--- /dev/null
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/converter/Converter.kt
@@ -0,0 +1,6 @@
+package com.artillexstudios.axminions.converter
+
+interface Converter {
+
+ fun convert();
+}
\ No newline at end of file
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/converter/JetsMinionsConverter.kt b/common/src/main/kotlin/com/artillexstudios/axminions/converter/JetsMinionsConverter.kt
new file mode 100644
index 0000000..3fe5877
--- /dev/null
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/converter/JetsMinionsConverter.kt
@@ -0,0 +1,8 @@
+package com.artillexstudios.axminions.converter
+
+class JetsMinionsConverter : Converter {
+
+ override fun convert() {
+ TODO("Not yet implemented")
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/converter/LitMinionsConverter.kt b/common/src/main/kotlin/com/artillexstudios/axminions/converter/LitMinionsConverter.kt
new file mode 100644
index 0000000..6402bcd
--- /dev/null
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/converter/LitMinionsConverter.kt
@@ -0,0 +1,79 @@
+package com.artillexstudios.axminions.converter
+
+import com.artillexstudios.axapi.serializers.Serializers
+import com.artillexstudios.axapi.utils.StringUtils
+import com.artillexstudios.axminions.api.minions.Direction
+import java.sql.Connection
+import java.sql.DriverManager
+import java.util.Locale
+import org.bukkit.Bukkit
+import org.bukkit.Location
+import org.bukkit.Material
+import org.bukkit.inventory.ItemStack
+
+
+class LitMinionsConverter : Converter {
+ private lateinit var connection: Connection
+
+ override fun convert() {
+ Bukkit.getConsoleSender()
+ .sendMessage(StringUtils.formatToString("<#33FF33>[AxMinions-Converter] Converting from LitMinions..."))
+ val url = "jdbc:sqlite:" + "plugins/LitMinions/minions.db"
+ try {
+ connection = DriverManager.getConnection(url) ?: return
+ } catch (exception: Exception) {
+ Bukkit.getConsoleSender()
+ .sendMessage(StringUtils.formatToString("<#33FF33>[AxMinions-Converter] <#FF0000>FAILED! Database not found, or corrupted!"))
+ return
+ }
+
+ 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 level = resultSet.getInt("level")
+ val type = resultSet.getString("miniontype").uppercase(Locale.getDefault())
+ val owner = resultSet.getString("owner")
+
+ val storage = resultSet.getDouble("exp")
+
+ 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)
+ }
+
+ val it = ItemStack(Material.AIR)
+
+// 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)
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/integrations/Integrations.kt b/common/src/main/kotlin/com/artillexstudios/axminions/integrations/Integrations.kt
index c97f267..5aaefb7 100644
--- a/common/src/main/kotlin/com/artillexstudios/axminions/integrations/Integrations.kt
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/integrations/Integrations.kt
@@ -18,6 +18,8 @@ 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.IridiumSkyBlockIntegration
+import com.artillexstudios.axminions.integrations.protection.KingdomsXIntegration
import com.artillexstudios.axminions.integrations.protection.LandsIntegration
import com.artillexstudios.axminions.integrations.protection.SuperiorSkyBlock2Integration
import com.artillexstudios.axminions.integrations.protection.WorldGuardIntegration
@@ -29,19 +31,19 @@ import org.bukkit.Bukkit
class Integrations : Integrations {
private lateinit var stackerIntegration: StackerIntegration
- private lateinit var pricesIntegration: PricesIntegration
- private lateinit var economyIntegration: EconomyIntegration
+ private var pricesIntegration: PricesIntegration? = null
+ private var economyIntegration: EconomyIntegration? = null
private val protectionIntegrations = com.artillexstudios.axminions.integrations.protection.ProtectionIntegrations()
override fun getStackerIntegration(): StackerIntegration {
return stackerIntegration
}
- override fun getPricesIntegration(): PricesIntegration {
+ override fun getPricesIntegration(): PricesIntegration? {
return pricesIntegration
}
- override fun getEconomyIntegration(): EconomyIntegration {
+ override fun getEconomyIntegration(): EconomyIntegration? {
return economyIntegration
}
@@ -133,6 +135,14 @@ class Integrations : Integrations {
if (Bukkit.getPluginManager().getPlugin("Lands") != null) {
register(LandsIntegration())
}
+
+ if (Bukkit.getPluginManager().getPlugin("IridiumSkyBlock") != null) {
+ register(IridiumSkyBlockIntegration())
+ }
+
+ if (Bukkit.getPluginManager().getPlugin("KingdomsX") != null) {
+ register(KingdomsXIntegration())
+ }
}
override fun register(integration: Integration) {
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/integrations/prices/CMIIntegration.kt b/common/src/main/kotlin/com/artillexstudios/axminions/integrations/prices/CMIIntegration.kt
index 5670160..62752a5 100644
--- a/common/src/main/kotlin/com/artillexstudios/axminions/integrations/prices/CMIIntegration.kt
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/integrations/prices/CMIIntegration.kt
@@ -1,15 +1,21 @@
package com.artillexstudios.axminions.integrations.prices
+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
+
override fun getPrice(itemStack: ItemStack): Double {
- TODO("Not yet implemented")
+ val worth = manager.worthManager.getWorth(itemStack) ?: return -1.0
+
+ return if (worth.sellPrice == 0.0) -1.0 else worth.sellPrice
}
override fun register() {
- TODO("Not yet implemented")
+ manager = CMI.getInstance();
}
}
\ No newline at end of file
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/integrations/protection/IridiumSkyBlockIntegration.kt b/common/src/main/kotlin/com/artillexstudios/axminions/integrations/protection/IridiumSkyBlockIntegration.kt
new file mode 100644
index 0000000..e1d23e7
--- /dev/null
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/integrations/protection/IridiumSkyBlockIntegration.kt
@@ -0,0 +1,19 @@
+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)
+
+ return island.map { IridiumSkyblockAPI.getInstance().getUser(player) in it.members }.orElse(true)
+ }
+
+ override fun register() {
+
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/integrations/protection/KingdomsXIntegration.kt b/common/src/main/kotlin/com/artillexstudios/axminions/integrations/protection/KingdomsXIntegration.kt
new file mode 100644
index 0000000..40639ce
--- /dev/null
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/integrations/protection/KingdomsXIntegration.kt
@@ -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 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);
+ }
+
+ override fun register() {
+
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/listeners/LinkingListener.kt b/common/src/main/kotlin/com/artillexstudios/axminions/listeners/LinkingListener.kt
index c85aa50..24ae158 100644
--- a/common/src/main/kotlin/com/artillexstudios/axminions/listeners/LinkingListener.kt
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/listeners/LinkingListener.kt
@@ -1,6 +1,9 @@
package com.artillexstudios.axminions.listeners
+import com.artillexstudios.axapi.utils.StringUtils
+import com.artillexstudios.axminions.AxMinionsPlugin
import com.artillexstudios.axminions.api.config.Config
+import com.artillexstudios.axminions.api.config.Messages
import com.artillexstudios.axminions.api.minions.Minion
import java.util.UUID
import org.bukkit.Material
@@ -19,17 +22,18 @@ class LinkingListener : Listener {
if (event.player.uniqueId !in linking) return
if (event.clickedBlock == null) return
if (event.clickedBlock!!.type !in CONTAINERS) return
- // TODO Check if player can build at location
+ if (!AxMinionsPlugin.integrations.getProtectionIntegration().canBuildAt(event.player, event.clickedBlock!!.location)) return
val minion = linking.remove(event.player.uniqueId) ?: return
event.isCancelled = true
if (minion.getLocation()
.distanceSquared(event.clickedBlock!!.location) > Config.MAX_LINKING_DISTANCE() * Config.MAX_LINKING_DISTANCE()
) {
- // TODO Send too far message
+ event.player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.LINK_FAIL()))
return
}
+ event.player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.LINK_SUCCESS()))
minion.setLinkedChest(event.clickedBlock!!.location)
}
}
\ No newline at end of file
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/listeners/MinionDamageListener.kt b/common/src/main/kotlin/com/artillexstudios/axminions/listeners/MinionDamageListener.kt
new file mode 100644
index 0000000..dcf4d2b
--- /dev/null
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/listeners/MinionDamageListener.kt
@@ -0,0 +1,19 @@
+package com.artillexstudios.axminions.listeners
+
+import com.artillexstudios.axminions.AxMinionsPlugin
+import com.artillexstudios.axminions.api.events.MinionDamageEntityEvent
+import java.util.concurrent.ThreadLocalRandom
+import org.bukkit.event.EventHandler
+import org.bukkit.event.Listener
+
+class MinionDamageListener : Listener {
+
+ @EventHandler
+ fun onMinionDamageEntityEvent(event: MinionDamageEntityEvent) {
+ if (event.damage < event.target.health) return
+
+ val entitySize = AxMinionsPlugin.integrations.getStackerIntegration().getStackSize(event.target)
+
+ event.minion.setStorage(event.minion.getStorage() + ThreadLocalRandom.current().nextInt(1, 4) * entitySize)
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/listeners/MinionInventoryListener.kt b/common/src/main/kotlin/com/artillexstudios/axminions/listeners/MinionInventoryListener.kt
index 2eefbda..d407656 100644
--- a/common/src/main/kotlin/com/artillexstudios/axminions/listeners/MinionInventoryListener.kt
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/listeners/MinionInventoryListener.kt
@@ -66,7 +66,7 @@ class MinionInventoryListener : Listener {
event.currentItem!!.amount = 0
}
- minion.updateInventory(event.inventory)
+ minion.updateInventories()
return
}
@@ -85,7 +85,7 @@ class MinionInventoryListener : Listener {
tool.setItemMeta(toolMeta)
player.inventory.addItem(tool)
- minion.updateInventory(event.inventory)
+ minion.updateInventories()
return
}
@@ -110,15 +110,16 @@ class MinionInventoryListener : Listener {
"link" -> {
if (minion.getLinkedChest() != null) {
minion.setLinkedChest(null)
- // TODO Unlink message
+ player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.LINK_UNLINK()))
return
}
+ player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.LINK_START()))
LinkingListener.linking[player.uniqueId] = minion
}
}
- minion.updateInventory(event.inventory)
+ minion.updateInventories()
}
@EventHandler
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/listeners/MinionPlaceListener.kt b/common/src/main/kotlin/com/artillexstudios/axminions/listeners/MinionPlaceListener.kt
index 7ed99b9..d80a5b5 100644
--- a/common/src/main/kotlin/com/artillexstudios/axminions/listeners/MinionPlaceListener.kt
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/listeners/MinionPlaceListener.kt
@@ -5,6 +5,7 @@ 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.Config
import com.artillexstudios.axminions.api.config.Messages
import com.artillexstudios.axminions.api.minions.Direction
import com.artillexstudios.axminions.api.minions.miniontype.MinionTypes
@@ -53,15 +54,16 @@ class MinionPlaceListener : Listener {
}
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)
+ 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)
+ if (Config.DEBUG()) {
event.player.sendMessage("Placed minion $minion. Ticking? ${minion.isTicking()} Is chunk ticking? ${Minions.isTicking(location.chunk)}")
- AxMinionsPlugin.dataHandler.saveMinion(minion)
}
+ 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())))
}
}
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/minions/Minion.kt b/common/src/main/kotlin/com/artillexstudios/axminions/minions/Minion.kt
index b9b38f1..1f64270 100644
--- a/common/src/main/kotlin/com/artillexstudios/axminions/minions/Minion.kt
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/minions/Minion.kt
@@ -3,6 +3,7 @@ package com.artillexstudios.axminions.minions
import com.artillexstudios.axapi.entity.PacketEntityFactory
import com.artillexstudios.axapi.entity.impl.PacketArmorStand
import com.artillexstudios.axapi.entity.impl.PacketEntity
+import com.artillexstudios.axapi.events.PacketEntityInteractEvent
import com.artillexstudios.axapi.hologram.Hologram
import com.artillexstudios.axapi.hologram.HologramFactory
import com.artillexstudios.axapi.libs.kyori.adventure.text.minimessage.tag.resolver.Placeholder
@@ -99,8 +100,16 @@ class Minion(
updateArmour()
entity.onClick { event ->
if (event.isAttack) {
- println("LEFT CLICKED!")
+// if (ownerUUID == event.player.uniqueId && Config.ONLY_OWNER_BREAK()) {
+// breakMinion(event)
+// } else if (AxMinionsPlugin.integrations.getProtectionIntegration().canBuildAt(event.player, event.packetEntity.location)) {
+ breakMinion(event)
+// }
} else {
+/* if (ownerUUID == event.player.uniqueId || AxMinionsPlugin.integrations.getProtectionIntegration().canBuildAt(event.player, event.packetEntity.location)) {
+
+ }*/
+
Scheduler.get().run {
openInventory(event.player)
}
@@ -108,6 +117,18 @@ class Minion(
}
}
+ private fun breakMinion(event: PacketEntityInteractEvent) {
+ setTicking(false)
+ val tool = getTool()
+ val asItem = getAsItem()
+ val remaining = event.player.inventory.addItem(tool, asItem)
+ remove()
+
+ remaining.forEach { (_, i) ->
+ AxMinionsPlugin.integrations.getStackerIntegration().dropItemAt(i, i.amount, location)
+ }
+ }
+
override fun tick() {
if (dirty) {
dirty = false
@@ -132,7 +153,7 @@ class Minion(
}
}
- override fun updateInventory(inventory: Inventory) {
+ private fun updateInventory(inventory: Inventory) {
AxMinionsAPI.INSTANCE.getConfig().getConfig().getSection("gui.items").getRoutesAsStrings(false).forEach {
if (it.equals("filler")) return@forEach
val item: ItemStack
@@ -284,6 +305,8 @@ class Minion(
override fun setLevel(level: Int) {
this.level = level
+ updateArmour()
+ updateInventories()
entity.name = StringUtils.format(
type.getConfig().get("entity.name"),
@@ -361,9 +384,13 @@ class Minion(
}
override fun remove() {
- Warnings.remove(this)
+ Warnings.remove(this, warning ?: Warnings.NO_CONTAINER)
Minions.remove(this)
entity.remove()
+
+ AxMinionsPlugin.dataQueue.submit {
+ AxMinionsPlugin.dataHandler.deleteMinion(this)
+ }
}
override fun getLinkedInventory(): Inventory? {
@@ -457,6 +484,7 @@ class Minion(
} else {
meta.damage += amount
tool?.itemMeta = meta
+ updateInventories()
}
}
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/CollectorMinionType.kt b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/CollectorMinionType.kt
index c4d9635..9e3ec15 100644
--- a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/CollectorMinionType.kt
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/CollectorMinionType.kt
@@ -42,14 +42,14 @@ class CollectorMinionType : MinionType("collector", AxMinionsPlugin.INSTANCE.get
return
}
- Warnings.remove(minion)
+ Warnings.remove(minion, Warnings.NO_CONTAINER)
if (!minion.canUseTool()) {
Warnings.NO_TOOL.display(minion)
return
}
- Warnings.remove(minion)
+ Warnings.remove(minion, Warnings.NO_TOOL)
val entities = minion.getLocation().world?.getNearbyEntities(
minion.getLocation(),
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/FarmerMinionType.kt b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/FarmerMinionType.kt
index 55e25d5..c94232f 100644
--- a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/FarmerMinionType.kt
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/FarmerMinionType.kt
@@ -44,7 +44,7 @@ class FarmerMinionType : MinionType("farmer", AxMinionsPlugin.INSTANCE.getResour
return
}
- Warnings.remove(minion)
+ Warnings.remove(minion, Warnings.NO_TOOL)
LocationUtils.getAllBlocksInRadius(minion.getLocation(), minion.getRange(), false).fastFor { location ->
val block = location.block
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/FisherMinionType.kt b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/FisherMinionType.kt
index fccee2b..5b7d9f6 100644
--- a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/FisherMinionType.kt
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/FisherMinionType.kt
@@ -3,11 +3,68 @@ package com.artillexstudios.axminions.minions.miniontype
import com.artillexstudios.axminions.AxMinionsPlugin
import com.artillexstudios.axminions.api.minions.Minion
import com.artillexstudios.axminions.api.minions.miniontype.MinionType
-import org.bukkit.loot.LootTables
+import com.artillexstudios.axminions.api.utils.LocationUtils
+import com.artillexstudios.axminions.api.utils.fastFor
+import com.artillexstudios.axminions.api.warnings.Warnings
+import com.artillexstudios.axminions.minions.MinionTicker
+import com.artillexstudios.axminions.nms.NMSHandler
+import java.util.concurrent.ThreadLocalRandom
+import kotlin.math.roundToInt
+import org.bukkit.Material
+import org.bukkit.enchantments.Enchantment
class FisherMinionType : MinionType("fisher", AxMinionsPlugin.INSTANCE.getResource("minions/fisher.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.LURE)?.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)
+ }
+
+ var hasWater = false
+ run breaking@{
+ LocationUtils.getAllBlocksInRadius(minion.getLocation(), 2.0, false).fastFor {
+ if (it.block.type != Material.WATER) return@fastFor
+
+ hasWater = true
+ return@breaking
+ }
+ }
+
+ if (!hasWater) {
+ Warnings.NO_WATER_NEARBY.display(minion)
+ return
+ }
+ Warnings.remove(minion, Warnings.NO_WATER_NEARBY)
+
+ if (!minion.canUseTool()) {
+ Warnings.NO_TOOL.display(minion)
+ return
+ }
+
+ Warnings.remove(minion, Warnings.NO_TOOL)
+
+ val loot = NMSHandler.get().generateRandomFishingLoot(minion)
+ val xp = ThreadLocalRandom.current().nextInt(6) + 1
+
+ minion.addToContainerOrDrop(loot)
+ minion.setStorage(minion.getStorage() + xp)
}
}
\ No newline at end of file
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/LumberMinionType.kt b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/LumberMinionType.kt
index ca460d8..6fec6ae 100644
--- a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/LumberMinionType.kt
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/LumberMinionType.kt
@@ -44,7 +44,7 @@ class LumberMinionType : MinionType("lumber", AxMinionsPlugin.INSTANCE.getResour
return
}
- Warnings.remove(minion)
+ Warnings.remove(minion, Warnings.NO_TOOL)
val loot = ArrayList()
LocationUtils.getAllBlocksInRadius(minion.getLocation(), minion.getRange(), false).fastFor { location ->
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/MinerMinionType.kt b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/MinerMinionType.kt
index d8fa215..bdc89fe 100644
--- a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/MinerMinionType.kt
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/MinerMinionType.kt
@@ -49,7 +49,7 @@ class MinerMinionType : MinionType("miner", AxMinionsPlugin.INSTANCE.getResource
return
}
- Warnings.remove(minion)
+ Warnings.remove(minion, Warnings.NO_TOOL)
when (getConfig().getString("mode").lowercase(Locale.ENGLISH)) {
"sphere" -> {
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/SellerMinionType.kt b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/SellerMinionType.kt
index ab6189b..53ae8dc 100644
--- a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/SellerMinionType.kt
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/SellerMinionType.kt
@@ -3,10 +3,81 @@ 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.warnings.Warnings
+import com.artillexstudios.axminions.minions.MinionTicker
+import kotlin.math.roundToInt
+import org.bukkit.Material
+import org.bukkit.enchantments.Enchantment
class SellerMinionType : MinionType("seller", AxMinionsPlugin.INSTANCE.getResource("minions/seller.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) {
+ Warnings.NO_CONTAINER.display(minion)
+ return
+ }
+
+ val type = minion.getLinkedChest()!!.block.type
+ if (type != Material.CHEST && type != Material.TRAPPED_CHEST && type != Material.BARREL) {
+ Warnings.NO_CONTAINER.display(minion)
+ minion.setLinkedChest(null)
+ return
+ }
+
+ if (minion.getLinkedInventory() == null) {
+ Warnings.NO_CONTAINER.display(minion)
+ minion.setLinkedChest(null)
+ return
+ }
+
+ Warnings.remove(minion, Warnings.NO_CONTAINER)
+
+ if (!minion.canUseTool()) {
+ Warnings.NO_TOOL.display(minion)
+ return
+ }
+
+ Warnings.remove(minion, Warnings.NO_TOOL)
+
+ if (AxMinionsPlugin.integrations.getPricesIntegration() === null) {
+ return
+ }
+
+ for (it in minion.getLinkedInventory()!!.contents) {
+ if (it == null || it.type == Material.AIR) {
+ continue
+ }
+
+ var price = AxMinionsPlugin.integrations.getPricesIntegration()!!.getPrice(it)
+
+ if (price == -1.0) {
+ if (getConfig().get("delete-unsellable")) {
+ it.amount = 0
+ }
+ continue
+ }
+
+ price *= getDouble("multiplier", minion.getLevel())
+
+ if (minion.getStorage() + price > getDouble("storage", minion.getLevel())) {
+ continue
+ }
+
+ minion.setActions(minion.getActionAmount() + it.amount)
+ minion.damageTool()
+ minion.setStorage(minion.getStorage() + price)
+ it.amount = 0
+ }
}
}
\ No newline at end of file
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/SlayerMinionType.kt b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/SlayerMinionType.kt
index d1486a0..4ba15d8 100644
--- a/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/SlayerMinionType.kt
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/minions/miniontype/SlayerMinionType.kt
@@ -3,10 +3,79 @@ 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.fastFor
+import com.artillexstudios.axminions.api.warnings.Warnings
+import com.artillexstudios.axminions.minions.MinionTicker
+import com.artillexstudios.axminions.nms.NMSHandler
+import kotlin.math.roundToInt
+import org.bukkit.Material
+import org.bukkit.enchantments.Enchantment
+import org.bukkit.entity.Item
+import org.bukkit.entity.LivingEntity
+import org.bukkit.entity.Player
+import org.bukkit.entity.Tameable
class SlayerMinionType : MinionType("slayer", AxMinionsPlugin.INSTANCE.getResource("minions/slayer.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, Warnings.NO_TOOL)
+
+ minion.getLocation().world!!.getNearbyEntities(minion.getLocation(), minion.getRange(), minion.getRange(), minion.getRange()).filterIsInstance().fastFor {
+ if (it is Player) return@fastFor
+
+ if (!getConfig().getBoolean("damage-animals") && NMSHandler.get().isAnimal(it)) {
+ return@fastFor
+ }
+
+ if (!getConfig().getBoolean("damage-renamed") && it.customName != null) {
+ return@fastFor
+ }
+
+ if (!getConfig().getBoolean("damage-tamed") && it is Tameable && it.isTamed) {
+ return@fastFor
+ }
+
+ NMSHandler.get().attack(minion, it)
+ it.location.world!!.getNearbyEntities(it.location, 2.0, 2.0, 2.0).filterIsInstance- ().fastFor { item ->
+ if (minion.getLinkedInventory()?.firstEmpty() == -1) {
+ Warnings.CONTAINER_FULL.display(minion)
+ return
+ }
+
+ val amount = AxMinionsPlugin.integrations.getStackerIntegration().getStackSize(item)
+ val stack = item.itemStack
+ stack.amount = amount.toInt()
+
+ minion.addToContainerOrDrop(stack)
+ item.remove()
+ }
+ }
}
}
\ No newline at end of file
diff --git a/common/src/main/kotlin/com/artillexstudios/axminions/nms/NMSHandler.kt b/common/src/main/kotlin/com/artillexstudios/axminions/nms/NMSHandler.kt
new file mode 100644
index 0000000..d57d9e1
--- /dev/null
+++ b/common/src/main/kotlin/com/artillexstudios/axminions/nms/NMSHandler.kt
@@ -0,0 +1,23 @@
+package com.artillexstudios.axminions.nms
+
+import com.artillexstudios.axapi.utils.Version
+import com.artillexstudios.axminions.api.minions.Minion
+import org.bukkit.entity.Entity
+import org.bukkit.inventory.ItemStack
+
+interface NMSHandler {
+ companion object {
+ private val handler: NMSHandler =
+ Class.forName("com.artillexstudios.axminions.nms.${Version.getServerVersion().nmsVersion}.NMSHandler").getConstructor().newInstance() as NMSHandler
+
+ fun get(): NMSHandler {
+ return handler
+ }
+ }
+
+ fun attack(source: Minion, target: Entity)
+
+ fun generateRandomFishingLoot(minion: Minion): List
+
+ fun isAnimal(entity: Entity): Boolean
+}
\ No newline at end of file
diff --git a/common/src/main/resources/messages.yml b/common/src/main/resources/messages.yml
index 090c97f..4f11515 100644
--- a/common/src/main/resources/messages.yml
+++ b/common/src/main/resources/messages.yml
@@ -32,6 +32,12 @@ upgrades:
upgraded: "Successfully upgraded the minion to level: !"
limit-reached: "You have maxed this minion!"
+link:
+ success: "Successfully linked the minion to a container!"
+ unlink: "You have unliked the minion."
+ fail: "You can't link to that block! It's either too far away, or not a container!"
+ start: "Started linking! Click on a container!"
+
levels:
1: "<#33FF33>"
2: "<#66FF00>"
diff --git a/common/src/main/resources/minions/fisher.yml b/common/src/main/resources/minions/fisher.yml
new file mode 100644
index 0000000..4334745
--- /dev/null
+++ b/common/src/main/resources/minions/fisher.yml
@@ -0,0 +1,133 @@
+name: "<#00EEFF>Fisher Minion"
+
+entity:
+ name: "[] <#00EEFF>Fisher Minion []"
+
+tool:
+ material:
+ - "FISHING_ROD"
+
+item:
+ type: "player_head"
+ texture: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYWMxNWU1ZmI1NmZhMTZiMDc0N2IxYmNiMDUzMzVmNTVkMWZhMzE1NjFjMDgyYjVlMzY0M2RiNTU2NTQxMDg1MiJ9fX0="
+ name: "<#00EEFF>Fisher Minion"
+ lore:
+ - ""
+ - " - It catches fish."
+ - ""
+ - "<#00EEFF>Statistics"
+ - " <#00EEFF>❙ Level: <#FFEEAA>"
+ - " <#00EEFF>❙ Fish caught: <#FFEEAA>"
+ - ""
+ - "<#00EEFF>(!) Place the minion and give it a fishing rod!"
+
+gui:
+ upgrade:
+ type: "gold_ingot"
+ name: "<#00CCFF>Upgrade minion"
+ lore:
+ - ""
+ - " - Level: » "
+ - " - Range: » "
+ - " - Speed: » "
+ - ""
+ - "<#00CCFF>Requirements:"
+ - " - Money: <#33FF33>$"
+ - " - Fish caught: <#33FF33>"
+ - ""
+ - "<#00CCFF>(!) Click here to upgrade your minion!"
+ statistics:
+ type: "paper"
+ name: "<#00EEFF>Statistics"
+ lore:
+ - ""
+ - " - Killed mobs: <#00EEFF>"
+ - ""
+
+upgrades:
+ 1:
+ range: 3
+ speed: 200
+ items:
+ helmet:
+ type: "player_head"
+ texture: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYWMxNWU1ZmI1NmZhMTZiMDc0N2IxYmNiMDUzMzVmNTVkMWZhMzE1NjFjMDgyYjVlMzY0M2RiNTU2NTQxMDg1MiJ9fX0="
+ 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: 4
+ speed: 175
+ requirements:
+ money: 3000
+ actions: 300
+ 4:
+ range: 5
+ speed: 160
+ requirements:
+ money: 10000
+ actions: 1000
+ 5:
+ range: 5
+ speed: 150
+ requirements:
+ money: 20000
+ actions: 3000
+ 6:
+ range: 6
+ speed: 130
+ requirements:
+ money: 50000
+ actions: 6000
+ 7:
+ range: 6
+ speed: 115
+ requirements:
+ money: 150000
+ actions: 10000
+ 8:
+ range: 7
+ speed: 100
+ requirements:
+ money: 500000
+ actions: 17500
+ 9:
+ range: 8
+ speed: 85
+ requirements:
+ money: 1000000
+ actions: 25000
+ 10:
+ range: 8
+ 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
\ No newline at end of file
diff --git a/common/src/main/resources/minions/lumber.yml b/common/src/main/resources/minions/lumber.yml
index 3b87bd0..693d4f2 100644
--- a/common/src/main/resources/minions/lumber.yml
+++ b/common/src/main/resources/minions/lumber.yml
@@ -76,49 +76,49 @@ upgrades:
money: 1000
actions: 100
3:
- range: 5
+ range: 4
speed: 175
requirements:
money: 3000
actions: 300
4:
- range: 6
+ range: 5
speed: 160
requirements:
money: 10000
actions: 1000
5:
- range: 7
+ range: 5
speed: 150
requirements:
money: 20000
actions: 3000
6:
- range: 8
+ range: 6
speed: 130
requirements:
money: 50000
actions: 6000
7:
- range: 9
+ range: 6
speed: 115
requirements:
money: 150000
actions: 10000
8:
- range: 10
+ range: 7
speed: 100
requirements:
money: 500000
actions: 17500
9:
- range: 11
+ range: 8
speed: 85
requirements:
money: 1000000
actions: 25000
10:
- range: 12
+ range: 8
speed: 60
requirements:
money: 5000000
diff --git a/common/src/main/resources/minions/miner.yml b/common/src/main/resources/minions/miner.yml
index e66fb50..e71bd92 100644
--- a/common/src/main/resources/minions/miner.yml
+++ b/common/src/main/resources/minions/miner.yml
@@ -14,7 +14,7 @@ tool:
# 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 line: checks blocks in all 4 directions from the minion in the range of the minion (Best performance to blocks broken ratio)
# 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,
@@ -79,55 +79,55 @@ upgrades:
color: "0, 150, 255"
glow: false
2:
- range: 4
- speed: 190
+ range: 3
+ speed: 185
requirements:
money: 1000
actions: 100
3:
- range: 5
+ range: 3
speed: 175
requirements:
money: 3000
actions: 300
4:
- range: 6
+ range: 4
speed: 160
requirements:
money: 10000
actions: 1000
5:
- range: 7
+ range: 4
speed: 150
requirements:
money: 20000
actions: 3000
6:
- range: 8
+ range: 5
speed: 130
requirements:
money: 50000
actions: 6000
7:
- range: 9
+ range: 5
speed: 115
requirements:
money: 150000
actions: 10000
8:
- range: 10
+ range: 6
speed: 100
requirements:
money: 500000
actions: 17500
9:
- range: 11
+ range: 6
speed: 85
requirements:
money: 1000000
actions: 25000
10:
- range: 12
+ range: 7
speed: 60
requirements:
money: 5000000
diff --git a/common/src/main/resources/minions/seller.yml b/common/src/main/resources/minions/seller.yml
new file mode 100644
index 0000000..7742044
--- /dev/null
+++ b/common/src/main/resources/minions/seller.yml
@@ -0,0 +1,148 @@
+name: "<#CC00FF>Seller Minion"
+
+entity:
+ name: "[] <#CC00FF>Seller Minion []"
+
+tool:
+ material:
+ - "BOW"
+ - "CROSSBOW"
+
+delete-unsellable: true
+
+item:
+ type: "player_head"
+ texture: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDI0YmE3NjBhNjFkZDI1NmM1MmIzMjUxMjlmNDYwMTZhZTg5MjIzMmEwZGVhMTcxNWY5OTdmN2M0ZDYyMmJlZiJ9fX0="
+ name: "<#CC00FF>Seller Minion"
+ lore:
+ - ""
+ - " - Sells all items from it's container."
+ - ""
+ - "<#CC00FF>Statistics"
+ - " <#CC00FF>❙ Level: <#FFEEAA>"
+ - " <#CC00FF>❙ Sold items: <#FFEEAA>"
+ - ""
+ - "<#CC00FF>(!) Place the minion and give it a bow!"
+
+gui:
+ upgrade:
+ type: "gold_ingot"
+ name: "<#00CCFF>Upgrade minion"
+ lore:
+ - ""
+ - " - Level: » "
+ - " - Range: » "
+ - " - Speed: » "
+ - ""
+ - "<#00CCFF>Requirements:"
+ - " - Money: <#33FF33>$"
+ - " - Collected items: <#33FF33>"
+ - ""
+ - "<#00CCFF>(!) Click here to upgrade your minion!"
+ statistics:
+ type: "paper"
+ name: "<#CC00FF>Statistics"
+ lore:
+ - ""
+ - " - Collected items: <#CC00FF>"
+ - " - Stored coins: <#CC00FF>"
+ - ""
+ - "<#CC00FF>(!) Click here to collect the stored coins!"
+
+upgrades:
+ 1:
+ multiplier: 1
+ speed: 600
+ storage: 100000
+ items:
+ helmet:
+ type: "player_head"
+ texture: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDI0YmE3NjBhNjFkZDI1NmM1MmIzMjUxMjlmNDYwMTZhZTg5MjIzMmEwZGVhMTcxNWY5OTdmN2M0ZDYyMmJlZiJ9fX0="
+ chestplate:
+ type: "leather_chestplate"
+ color: "200, 0, 255"
+ glow: false
+ leggings:
+ type: "leather_leggings"
+ color: "255, 230, 0"
+ glow: false
+ boots:
+ type: "leather_boots"
+ color: "255, 230, 0"
+ glow: false
+ 2:
+ multiplier: 1.05
+ speed: 500
+ storage: 500000
+ requirements:
+ money: 1000
+ actions: 100
+ 3:
+ multiplier: 1.1
+ speed: 450
+ storage: 1000000
+ requirements:
+ money: 3000
+ actions: 300
+ 4:
+ multiplier: 1.15
+ speed: 400
+ storage: 4000000
+ requirements:
+ money: 10000
+ actions: 1000
+ 5:
+ multiplier: 1.2
+ speed: 350
+ storage: 7000000
+ requirements:
+ money: 20000
+ actions: 3000
+ 6:
+ multiplier: 1.25
+ speed: 300
+ storage: 10000000
+ requirements:
+ money: 50000
+ actions: 6000
+ 7:
+ multiplier: 1.3
+ speed: 250
+ storage: 30000000
+ requirements:
+ money: 150000
+ actions: 10000
+ 8:
+ multiplier: 1.35
+ speed: 200
+ storage: 50000000
+ requirements:
+ money: 500000
+ actions: 17500
+ 9:
+ multiplier: 1.4
+ speed: 150
+ storage: 80000000
+ requirements:
+ money: 1000000
+ actions: 25000
+ 10:
+ multiplier: 1.5
+ speed: 100
+ storage: 100000000
+ 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
\ No newline at end of file
diff --git a/common/src/main/resources/minions/slayer.yml b/common/src/main/resources/minions/slayer.yml
new file mode 100644
index 0000000..1f5da8b
--- /dev/null
+++ b/common/src/main/resources/minions/slayer.yml
@@ -0,0 +1,142 @@
+name: "<#FF3333>Slayer Minion"
+
+entity:
+ name: "[] <#FF3333>Slayer Minion []"
+
+tool:
+ material:
+ - "WOODEN_SWORD"
+ - "STONE_SWORD"
+ - "GOLDEN_SWORD"
+ - "IRON_SWORD"
+ - "DIAMOND_SWORD"
+ - "NETHERITE_SWORD"
+
+damage-animals: false
+damage-tamed: false
+damage-renamed: false
+
+item:
+ type: "player_head"
+ texture: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTc1MzJlOTBjNTczYTM5NGM3ODAyYWE0MTU4MzA1ODAyYjU5ZTY3ZjJhMmI3ZTNmZDAzNjNhYTZlYTQyYjg0MSJ9fX0="
+ name: "<#FF3333>Slayer Minion"
+ lore:
+ - ""
+ - " - Kills mobs around itself."
+ - ""
+ - "<#FF3333>Statistics"
+ - " <#FF3333>❙ Level: <#FFEEAA>"
+ - " <#FF3333>❙ Mobs killed: <#FFEEAA>"
+ - ""
+ - "<#FF3333>(!) Place the minion and give it a sword!"
+
+gui:
+ upgrade:
+ type: "gold_ingot"
+ name: "<#00CCFF>Upgrade minion"
+ lore:
+ - ""
+ - " - Level: » "
+ - " - Range: » "
+ - " - Speed: » "
+ - ""
+ - "<#00CCFF>Requirements:"
+ - " - Money: <#33FF33>$"
+ - " - Killed mobs: <#33FF33>"
+ - ""
+ - "<#00CCFF>(!) Click here to upgrade your minion!"
+ statistics:
+ type: "paper"
+ name: "<#FF3333>Statistics"
+ lore:
+ - ""
+ - " - Killed mobs: <#FF3333>"
+ - ""
+
+upgrades:
+ 1:
+ range: 3
+ speed: 200
+ items:
+ helmet:
+ type: "player_head"
+ texture: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTc1MzJlOTBjNTczYTM5NGM3ODAyYWE0MTU4MzA1ODAyYjU5ZTY3ZjJhMmI3ZTNmZDAzNjNhYTZlYTQyYjg0MSJ9fX0="
+ 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: 4
+ speed: 175
+ requirements:
+ money: 3000
+ actions: 300
+ 4:
+ range: 5
+ speed: 160
+ requirements:
+ money: 10000
+ actions: 1000
+ 5:
+ range: 5
+ speed: 150
+ requirements:
+ money: 20000
+ actions: 3000
+ 6:
+ range: 6
+ speed: 130
+ requirements:
+ money: 50000
+ actions: 6000
+ 7:
+ range: 6
+ speed: 115
+ requirements:
+ money: 150000
+ actions: 10000
+ 8:
+ range: 7
+ speed: 100
+ requirements:
+ money: 500000
+ actions: 17500
+ 9:
+ range: 8
+ speed: 85
+ requirements:
+ money: 1000000
+ actions: 25000
+ 10:
+ range: 8
+ 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
\ No newline at end of file
diff --git a/nms/build.gradle b/nms/build.gradle
new file mode 100644
index 0000000..6d99e85
--- /dev/null
+++ b/nms/build.gradle
@@ -0,0 +1,13 @@
+plugins {
+ id("io.papermc.paperweight.userdev") version "1.5.4" apply false
+}
+
+group = "com.artillexstudios.axminions"
+version = rootProject.version
+
+subprojects {
+ dependencies {
+ compileOnly project(":common")
+ compileOnly project(":api")
+ }
+}
\ No newline at end of file
diff --git a/nms/v1_20_R1/build.gradle b/nms/v1_20_R1/build.gradle
new file mode 100644
index 0000000..5c7d254
--- /dev/null
+++ b/nms/v1_20_R1/build.gradle
@@ -0,0 +1,20 @@
+plugins {
+ id("io.papermc.paperweight.userdev")
+}
+
+group = 'com.artillexstudios.axminions.nms'
+version = '1.0-SNAPSHOT'
+
+dependencies {
+ paperweight.paperDevBundle("1.20-R0.1-SNAPSHOT")
+}
+
+tasks {
+ build {
+ dependsOn(reobfJar)
+ }
+
+ reobfJar {
+ mustRunAfter(shadowJar)
+ }
+}
\ No newline at end of file
diff --git a/nms/v1_20_R1/src/main/kotlin/com/artillexstudios/axminions/nms/v1_20_R1/DamageHandler.kt b/nms/v1_20_R1/src/main/kotlin/com/artillexstudios/axminions/nms/v1_20_R1/DamageHandler.kt
new file mode 100644
index 0000000..6af656c
--- /dev/null
+++ b/nms/v1_20_R1/src/main/kotlin/com/artillexstudios/axminions/nms/v1_20_R1/DamageHandler.kt
@@ -0,0 +1,205 @@
+package com.artillexstudios.axminions.nms.v1_20_R1
+
+import com.artillexstudios.axminions.api.events.MinionDamageEntityEvent
+import com.artillexstudios.axminions.api.minions.Minion
+import net.minecraft.core.particles.ParticleTypes
+import net.minecraft.server.level.ServerLevel
+import net.minecraft.util.Mth
+import net.minecraft.world.effect.MobEffectInstance
+import net.minecraft.world.effect.MobEffects
+import net.minecraft.world.entity.LivingEntity
+import net.minecraft.world.entity.MobType
+import net.minecraft.world.entity.decoration.ArmorStand
+import net.minecraft.world.item.AxeItem
+import net.minecraft.world.item.ItemStack
+import net.minecraft.world.item.SwordItem
+import net.minecraft.world.item.TridentItem
+import net.minecraft.world.item.enchantment.EnchantmentHelper
+import net.minecraft.world.item.enchantment.SweepingEdgeEnchantment
+import org.bukkit.Bukkit
+import org.bukkit.craftbukkit.v1_20_R1.CraftWorld
+import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity
+import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack
+import org.bukkit.enchantments.Enchantment
+import org.bukkit.entity.Entity
+import org.bukkit.event.entity.EntityPotionEffectEvent
+
+object DamageHandler {
+
+ fun damage(source: Minion, entity: Entity) {
+ val nmsEntity = (entity as CraftEntity).handle
+ var f = 1
+
+ val nmsItem: ItemStack
+ if (source.getTool() == null) {
+ nmsItem = ItemStack.EMPTY
+ } else {
+ nmsItem = CraftItemStack.asNMSCopy(source.getTool())
+
+ if (nmsItem.item is SwordItem) {
+ f = (f + (nmsItem.item as SwordItem).damage).toInt()
+ }
+
+ if (nmsItem.item is AxeItem) {
+ f = (f + (nmsItem.item as AxeItem).attackDamage).toInt()
+ }
+
+ if (nmsItem.item is TridentItem) {
+ f = (f + TridentItem.BASE_DAMAGE).toInt()
+ }
+ }
+
+ if (!nmsEntity.isAttackable) return
+ val f2 = 1.0f
+
+ var f1 = if (nmsEntity is LivingEntity) {
+ EnchantmentHelper.getDamageBonus(nmsItem, (nmsEntity).mobType)
+ } else {
+ EnchantmentHelper.getDamageBonus(nmsItem, MobType.UNDEFINED)
+ }
+
+ f = (f * (0.2f + f2 * f2 * 0.8f)).toInt()
+ f1 *= f2
+
+ if (f > 0.0f || f1 > 0.0f) {
+ var flag3 = false
+ val b0: Byte = 0
+ val i = b0 + (source.getTool()?.getEnchantmentLevel(Enchantment.KNOCKBACK) ?: 0)
+
+ f = (f * 1.5f).toInt()
+ f = (f + f1).toInt()
+
+ if (nmsItem.item is SwordItem) {
+ flag3 = true
+ }
+
+ var f3 = 0.0f
+ var flag4 = false
+ val j = (source.getTool()?.getEnchantmentLevel(Enchantment.FIRE_ASPECT) ?: 0)
+
+ if (nmsEntity is LivingEntity) {
+ f3 = nmsEntity.health
+ if (j > 0 && !nmsEntity.isOnFire()) {
+ flag4 = true
+ nmsEntity.setSecondsOnFire(1, false)
+ }
+ }
+
+ val event = MinionDamageEntityEvent(source, entity as org.bukkit.entity.LivingEntity, f.toDouble())
+ Bukkit.getPluginManager().callEvent(event)
+ if (event.isCancelled) {
+ return
+ }
+
+ val flag5 = nmsEntity.hurt(nmsEntity.damageSources().magic(), f.toFloat())
+
+ if (flag5) {
+ if (i > 0) {
+ if (nmsEntity is LivingEntity) {
+ (nmsEntity).knockback(
+ (i.toFloat() * 0.5f).toDouble(),
+ Mth.sin(source.getLocation().yaw * 0.017453292f).toDouble(),
+ (-Mth.cos(source.getLocation().yaw * 0.017453292f)).toDouble()
+ )
+ } else {
+ nmsEntity.push(
+ (-Mth.sin(source.getLocation().yaw * 0.017453292f) * i.toFloat() * 0.5f).toDouble(),
+ 0.1,
+ (Mth.cos(source.getLocation().yaw * 0.017453292f) * i.toFloat() * 0.5f).toDouble()
+ )
+ }
+ }
+
+ if (flag3) {
+ val sweep = source.getTool()?.getEnchantmentLevel(Enchantment.SWEEPING_EDGE) ?: 0
+ val f4 = 1.0f + if (sweep > 0) SweepingEdgeEnchantment.getSweepingDamageRatio(sweep) else 0.0f * f
+ val list: List = (source.getLocation().world as CraftWorld).handle
+ .getEntitiesOfClass(LivingEntity::class.java, nmsEntity.boundingBox.inflate(1.0, 0.25, 1.0))
+ val iterator: Iterator<*> = list.iterator()
+
+ while (iterator.hasNext()) {
+ val entityliving: LivingEntity = iterator.next() as LivingEntity
+
+ if ((entityliving !is ArmorStand || !(entityliving).isMarker) && source.getLocation().distanceSquared(
+ (entity as Entity).location
+ ) < 9.0
+ ) {
+ val damageEvent = MinionDamageEntityEvent(source, entityliving.bukkitEntity as org.bukkit.entity.LivingEntity, f4.toDouble())
+ Bukkit.getPluginManager().callEvent(damageEvent)
+ if (event.isCancelled) {
+ return
+ }
+
+ // CraftBukkit start - Only apply knockback if the damage hits
+ if (entityliving.hurt(nmsEntity.damageSources().magic(), f4)) {
+ entityliving.knockback(
+ 0.4000000059604645,
+ Mth.sin(source.getLocation().yaw * 0.017453292f).toDouble(),
+ (-Mth.cos(source.getLocation().yaw * 0.017453292f)).toDouble()
+ )
+ }
+ // CraftBukkit end
+ }
+ }
+
+ val d0 = -Mth.sin(source.getLocation().yaw * 0.017453292f).toDouble()
+ val d1 = Mth.cos(source.getLocation().yaw * 0.017453292f).toDouble()
+
+ if ((source.getLocation().world as CraftWorld).handle is ServerLevel) {
+ ((source.getLocation().world as CraftWorld).handle as ServerLevel).sendParticles(
+ ParticleTypes.SWEEP_ATTACK,
+ source.getLocation().x + d0,
+ source.getLocation().y + 0.5,
+ source.getLocation().z + d1,
+ 0,
+ d0,
+ 0.0,
+ d1,
+ 0.0
+ )
+ }
+ }
+
+
+ val baneOfArthropods = source.getTool()?.getEnchantmentLevel(Enchantment.DAMAGE_ARTHROPODS) ?: 0
+ if (nmsEntity is LivingEntity) {
+ if (baneOfArthropods > 0 && (nmsEntity.mobType === MobType.ARTHROPOD)) {
+ val p: Int = 20 + nmsEntity.random.nextInt(10 * baneOfArthropods)
+ nmsEntity.addEffect(
+ MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, p, 3),
+ EntityPotionEffectEvent.Cause.ATTACK
+ )
+ }
+ }
+
+ if (nmsEntity is LivingEntity) {
+ val f5: Float = f3 - nmsEntity.health
+
+ if (j > 0) {
+ nmsEntity.setSecondsOnFire(j * 4, false)
+ }
+
+ if ((source.getLocation().world as CraftWorld).handle is ServerLevel && f5 > 2.0f) {
+ val k = (f5.toDouble() * 0.5).toInt()
+
+ ((source.getLocation().world as CraftWorld).handle).sendParticles(
+ ParticleTypes.DAMAGE_INDICATOR,
+ nmsEntity.getX(),
+ nmsEntity.getY(0.5),
+ nmsEntity.getZ(),
+ k,
+ 0.1,
+ 0.0,
+ 0.1,
+ 0.2
+ )
+ }
+ }
+ } else {
+ if (flag4) {
+ nmsEntity.clearFire()
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/nms/v1_20_R1/src/main/kotlin/com/artillexstudios/axminions/nms/v1_20_R1/LootHandler.kt b/nms/v1_20_R1/src/main/kotlin/com/artillexstudios/axminions/nms/v1_20_R1/LootHandler.kt
new file mode 100644
index 0000000..14adb67
--- /dev/null
+++ b/nms/v1_20_R1/src/main/kotlin/com/artillexstudios/axminions/nms/v1_20_R1/LootHandler.kt
@@ -0,0 +1,38 @@
+package com.artillexstudios.axminions.nms.v1_20_R1
+
+import com.artillexstudios.axminions.api.minions.Minion
+import net.minecraft.server.MinecraftServer
+import net.minecraft.world.level.storage.loot.BuiltInLootTables
+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.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 {
+ val nmsItem: net.minecraft.world.item.ItemStack = if (minion.getTool() == null) {
+ net.minecraft.world.item.ItemStack.EMPTY
+ } else {
+ CraftItemStack.asNMSCopy(minion.getTool())
+ }
+
+ 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)
+ ).withParameter(LootContextParams.TOOL, nmsItem).withOptionalParameter(LootContextParams.THIS_ENTITY, null)
+ .create(LootContextParamSets.FISHING)
+
+ val lootTable = MinecraftServer.getServer().lootData.getLootTable(BuiltInLootTables.FISHING)
+
+ return lootTable.getRandomItems(lootparams).stream().map { original: net.minecraft.world.item.ItemStack? ->
+ CraftItemStack.asBukkitCopy(
+ original
+ )
+ }.toList()
+ }
+}
\ No newline at end of file
diff --git a/nms/v1_20_R1/src/main/kotlin/com/artillexstudios/axminions/nms/v1_20_R1/NMSHandler.kt b/nms/v1_20_R1/src/main/kotlin/com/artillexstudios/axminions/nms/v1_20_R1/NMSHandler.kt
new file mode 100644
index 0000000..783c502
--- /dev/null
+++ b/nms/v1_20_R1/src/main/kotlin/com/artillexstudios/axminions/nms/v1_20_R1/NMSHandler.kt
@@ -0,0 +1,23 @@
+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.craftbukkit.v1_20_R1.entity.CraftEntity
+import org.bukkit.entity.Entity
+import org.bukkit.inventory.ItemStack
+
+class NMSHandler : NMSHandler {
+
+ override fun attack(source: Minion, target: Entity) {
+ DamageHandler.damage(source, target)
+ }
+
+ override fun generateRandomFishingLoot(minion: Minion): List {
+ return LootHandler.generateFishingLoot(minion)
+ }
+
+ override fun isAnimal(entity: Entity): Boolean {
+ return (entity as CraftEntity).handle.type.category == MobCategory.CREATURE
+ }
+}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index 9793353..eaae46a 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -12,4 +12,6 @@ plugins {
rootProject.name = 'AxMinions'
include 'api'
include 'common'
+include 'nms'
+include 'nms:v1_20_R1'