Lots of things

This commit is contained in:
AverageGithub 2025-01-23 16:04:22 +01:00
parent f532ed81a5
commit 887acb6bf8
25 changed files with 918 additions and 101 deletions

BIN
.build.gradle.swp Normal file

Binary file not shown.

View File

@ -7,7 +7,7 @@ plugins {
} }
group = 'com.artillexstudios.axminions' group = 'com.artillexstudios.axminions'
version = '1.0.12' version = '1.0.13'
repositories { repositories {
mavenCentral() mavenCentral()
@ -29,6 +29,8 @@ dependencies {
implementation project(path: ":nms:v1_20_R3", configuration: "reobf") implementation project(path: ":nms:v1_20_R3", configuration: "reobf")
implementation project(path: ":nms:v1_20_R4", configuration: "reobf") implementation project(path: ":nms:v1_20_R4", configuration: "reobf")
implementation project(path: ":nms:v1_21_R1", configuration: "reobf") implementation project(path: ":nms:v1_21_R1", configuration: "reobf")
implementation project(path: ":nms:v1_21_R2", configuration: "reobf")
// implementation project(path: ":nms:v1_21_R3", configuration: "reobf")
} }
allprojects { allprojects {
@ -133,8 +135,11 @@ allprojects {
compileOnly 'com.bgsoftware:WildStackerAPI:2023.2' compileOnly 'com.bgsoftware:WildStackerAPI:2023.2'
compileOnly 'net.essentialsx:EssentialsX:2.19.0' compileOnly 'net.essentialsx:EssentialsX:2.19.0'
compileOnly 'com.github.Gypopo:EconomyShopGUI-API:1.7.0' compileOnly 'com.github.Gypopo:EconomyShopGUI-API:1.7.0'
compileOnly 'com.github.brcdev-minecraft:shopgui-api:3.0.0' compileOnly 'com.github.brcdev-minecraft:shopgui-api:3.0.0'
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.1.0-SNAPSHOT' compileOnly('com.sk89q.worldguard:worldguard-bukkit:7.0.1') {
exclude module: "org.spigotmc"
exclude module: "org.bukkit"
}
compileOnly 'com.bgsoftware:SuperiorSkyblockAPI:2023.2' compileOnly 'com.bgsoftware:SuperiorSkyblockAPI:2023.2'
compileOnly 'world.bentobox:bentobox:1.24.0-SNAPSHOT' compileOnly 'world.bentobox:bentobox:1.24.0-SNAPSHOT'
compileOnly 'com.github.TechFortress:GriefPrevention:16.18' compileOnly 'com.github.TechFortress:GriefPrevention:16.18'
@ -144,11 +149,13 @@ allprojects {
compileOnly 'com.github.LoneDev6:api-itemsadder:3.6.1' compileOnly 'com.github.LoneDev6:api-itemsadder:3.6.1'
compileOnly 'com.palmergames.bukkit.towny:towny:0.100.1.0' compileOnly 'com.palmergames.bukkit.towny:towny:0.100.1.0'
implementation platform('com.intellectualsites.bom:bom-newest:1.35') implementation platform('com.intellectualsites.bom:bom-newest:1.35')
implementation("com.artillexstudios.axapi:axapi:1.4.322:all") implementation("com.artillexstudios.axapi:axapi:1.4.507:all")
implementation("com.zaxxer:HikariCP:5.1.0") implementation("com.zaxxer:HikariCP:5.1.0")
implementation("org.bstats:bstats-bukkit:3.0.2") implementation("org.bstats:bstats-bukkit:3.0.2")
compileOnly 'org.black_ixx:playerpoints:3.2.6' compileOnly 'org.black_ixx:playerpoints:3.2.6'
compileOnly 'com.github.Maxlego08:zShop-API:3.0.5' // compileOnly('com.github.Maxlego08:zShop-API:3.0.5') {
// exclude module: "zMenu-API"
// }
compileOnly 'me.clip:placeholderapi:2.11.5' compileOnly 'me.clip:placeholderapi:2.11.5'
} }
} }

View File

@ -3,7 +3,7 @@ package com.artillexstudios.axminions
import com.artillexstudios.axapi.AxPlugin import com.artillexstudios.axapi.AxPlugin
import com.artillexstudios.axapi.data.ThreadedQueue import com.artillexstudios.axapi.data.ThreadedQueue
import com.artillexstudios.axapi.scheduler.Scheduler import com.artillexstudios.axapi.scheduler.Scheduler
import com.artillexstudios.axapi.utils.FeatureFlags import com.artillexstudios.axapi.utils.featureflags.FeatureFlags
import com.artillexstudios.axminions.api.AxMinionsAPI import com.artillexstudios.axminions.api.AxMinionsAPI
import com.artillexstudios.axminions.api.AxMinionsAPIImpl import com.artillexstudios.axminions.api.AxMinionsAPIImpl
import com.artillexstudios.axminions.api.config.Config import com.artillexstudios.axminions.api.config.Config
@ -62,9 +62,9 @@ class AxMinionsPlugin : AxPlugin() {
manager.loadLibrary(h2) manager.loadLibrary(h2)
} }
override fun updateFlags() { override fun updateFlags(flags: FeatureFlags) {
FeatureFlags.PACKET_ENTITY_TRACKER_ENABLED.set(true) flags.PACKET_ENTITY_TRACKER_ENABLED.set(true)
FeatureFlags.USE_LEGACY_HEX_FORMATTER.set(true) flags.USE_LEGACY_HEX_FORMATTER.set(true)
} }
override fun load() { override fun load() {
@ -74,6 +74,7 @@ class AxMinionsPlugin : AxPlugin() {
override fun enable() { override fun enable() {
Metrics(this, 19043) Metrics(this, 19043)
com.artillexstudios.axapi.metrics.AxMetrics(5).start()
AxMinionsPlugin.config = Config(File(dataFolder, "config.yml"), getResource("config.yml")!!) AxMinionsPlugin.config = Config(File(dataFolder, "config.yml"), getResource("config.yml")!!)
messages = Messages(File(dataFolder, "messages.yml"), getResource("messages.yml")!!) messages = Messages(File(dataFolder, "messages.yml"), getResource("messages.yml")!!)

View File

@ -14,7 +14,7 @@ import com.artillexstudios.axminions.integrations.prices.CMIIntegration
import com.artillexstudios.axminions.integrations.prices.EconomyShopGUIIntegration import com.artillexstudios.axminions.integrations.prices.EconomyShopGUIIntegration
import com.artillexstudios.axminions.integrations.prices.EssentialsIntegration import com.artillexstudios.axminions.integrations.prices.EssentialsIntegration
import com.artillexstudios.axminions.integrations.prices.ShopGUIPlusIntegration import com.artillexstudios.axminions.integrations.prices.ShopGUIPlusIntegration
import com.artillexstudios.axminions.integrations.prices.ZShopIntegration //import com.artillexstudios.axminions.integrations.prices.ZShopIntegration
import com.artillexstudios.axminions.integrations.protection.BentoBoxIntegration import com.artillexstudios.axminions.integrations.protection.BentoBoxIntegration
import com.artillexstudios.axminions.integrations.protection.GriefPreventionIntegration import com.artillexstudios.axminions.integrations.protection.GriefPreventionIntegration
import com.artillexstudios.axminions.integrations.protection.IridiumSkyBlockIntegration import com.artillexstudios.axminions.integrations.protection.IridiumSkyBlockIntegration
@ -108,11 +108,11 @@ class Integrations : Integrations {
.sendMessage(StringUtils.formatToString("<#33FF33>[AxMinions] Hooked into EconomyShopGUI!"))} .sendMessage(StringUtils.formatToString("<#33FF33>[AxMinions] Hooked into EconomyShopGUI!"))}
} }
"zshop" -> { // "zshop" -> {
if (isPluginLoaded("zShop")) { // if (isPluginLoaded("zShop")) {
register(ZShopIntegration()) // register(ZShopIntegration())
} // }
} // }
} }
when (Config.ECONOMY_HOOK().lowercase(Locale.ENGLISH)) { when (Config.ECONOMY_HOOK().lowercase(Locale.ENGLISH)) {

View File

@ -7,25 +7,43 @@ import com.artillexstudios.axminions.api.events.MinionKillEntityEvent
import com.artillexstudios.axminions.api.utils.fastFor import com.artillexstudios.axminions.api.utils.fastFor
import com.artillexstudios.axminions.api.warnings.Warnings import com.artillexstudios.axminions.api.warnings.Warnings
import com.artillexstudios.axminions.nms.NMSHandler import com.artillexstudios.axminions.nms.NMSHandler
import dev.rosewood.rosestacker.api.RoseStackerAPI
import com.artillexstudios.axminions.integrations.stacker.RoseStackerIntegration
import org.bukkit.Bukkit import org.bukkit.Bukkit
import java.util.concurrent.ThreadLocalRandom import java.util.concurrent.ThreadLocalRandom
import java.util.Random
import org.bukkit.entity.Item import org.bukkit.entity.Item
import org.bukkit.entity.LivingEntity import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
import org.bukkit.event.EventPriority
import org.bukkit.event.Listener import org.bukkit.event.Listener
import org.bukkit.event.entity.EntityDamageByEntityEvent import org.bukkit.event.entity.EntityDamageByEntityEvent
class MinionDamageListener : Listener { class MinionDamageListener : Listener {
private val random = Random()
@EventHandler @EventHandler
fun onMinionKillEntityEvent(event: MinionKillEntityEvent) { fun onMinionKillEntityEvent(event: MinionKillEntityEvent) {
val minion = event.minion
val entitySize = AxMinionsPlugin.integrations.getStackerIntegration().getStackSize(event.target) val entitySize = AxMinionsPlugin.integrations.getStackerIntegration().getStackSize(event.target)
if (AxMinionsPlugin.integrations.getStackerIntegration() is RoseStackerIntegration && entitySize > 1) {
// chance can be 0.01 = 1% or 0.1 = 10% or 1 = 100%
val chance = minion.getType().getDouble("chance-kill-stacked-amount", minion.getLevel())
val amount = minion.getType().getLong("stacked-amount", minion.getLevel())
val stackedEntity = RoseStackerAPI.getInstance().getStackedEntity(event.target)!!
val amountToKill = (if (entitySize > amount) amount else entitySize) as Long
if (random.nextDouble() <= chance) {
stackedEntity.killPartialStack(null, (amountToKill as Number).toInt())
minion.setActions((minion.getActionAmount() + (amountToKill - 1L) as Long) as Long)
}
} else {
event.minion.setActions(event.minion.getActionAmount() + entitySize)
}
event.minion.setActions(event.minion.getActionAmount() + entitySize)
val coerced = (event.minion.getStorage() + ThreadLocalRandom.current().nextInt(1, 4) * entitySize).coerceIn( val coerced = (event.minion.getStorage() + ThreadLocalRandom.current().nextInt(1, 4) * entitySize).coerceIn(
0.0, 0.0,
event.minion.getType().getLong("storage", event.minion.getLevel()).toDouble() event.minion.getType().getLong("storage", event.minion.getLevel()).toDouble()
) )
event.minion.setStorage(coerced) event.minion.setStorage(coerced)
@ -53,12 +71,6 @@ class MinionDamageListener : Listener {
@EventHandler @EventHandler
fun onEntityDamageByEntityEvent(event: EntityDamageByEntityEvent) { fun onEntityDamageByEntityEvent(event: EntityDamageByEntityEvent) {
if (event.damager.uniqueId == NMSHandler.get().getAnimalUUID() && event.entity is Player) {
event.isCancelled = true
event.damage = 0.0
return
}
val entity = event.entity val entity = event.entity
if (entity is LivingEntity) { if (entity is LivingEntity) {
if (event.damager.uniqueId == NMSHandler.get().getAnimalUUID() && event.finalDamage > entity.health) { if (event.damager.uniqueId == NMSHandler.get().getAnimalUUID() && event.finalDamage > entity.health) {
@ -66,4 +78,19 @@ class MinionDamageListener : Listener {
} }
} }
} }
@EventHandler(priority = EventPriority.MONITOR)
fun onEntityDamageByEntityEvente(event: EntityDamageByEntityEvent) {
if (event.damager.uniqueId != NMSHandler.get().getAnimalUUID()) {
return
}
if (event.entity is Player) {
event.isCancelled = true
event.damage = 0.0
return
}
event.isCancelled = false
}
} }

View File

@ -195,63 +195,128 @@ class MinionInventoryListener : Listener {
player.giveExp(stored.toInt()) player.giveExp(stored.toInt())
minion.setStorage(0.0) minion.setStorage(0.0)
} }
AxMinionsPlugin.dataQueue.submit {
AxMinionsPlugin.dataHandler.saveMinion(minion)
}
} }
"charge" -> { "charge" -> {
val chargeSeconds = (minion.getCharge() - System.currentTimeMillis()) / 1000
if ((Config.MAX_CHARGE() * 60) - chargeSeconds < Config.MINIMUM_CHARGE()) { if (event.isShiftClick) {
player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.CHARGE_NOT_ENOUGH_TIME_PASSED())) while (true) {
return val chargeSeconds = (minion.getCharge() - System.currentTimeMillis()) / 1000
}
var chargeAmount = Config.CHARGE_AMOUNT() if ((Config.MAX_CHARGE() * 60) - chargeSeconds < Config.MINIMUM_CHARGE()) {
var itemCharge = false player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.CHARGE_NOT_ENOUGH_TIME_PASSED()))
val section = Config.CHARGE_ITEMS() return
}
for (key in section.keys) { var chargeAmount = Config.CHARGE_AMOUNT()
val item = ItemBuilder(section.getSection(key.toString())).get() var itemCharge = false
if (player.inventory.containsAtLeast(item, 1)) { val section = Config.CHARGE_ITEMS()
itemCharge = true
chargeAmount = section.getSection(key.toString()).getInt("charge") for (key in section.keys) {
player.inventory.removeItem(item) val item = ItemBuilder(section.getSection(key.toString())).get()
break if (player.inventory.containsAtLeast(item, 1)) {
itemCharge = true
chargeAmount = section.getSection(key.toString()).getInt("charge")
player.inventory.removeItem(item)
break
}
}
if (Config.CHARGE_PRICE() <= 0 && !itemCharge) {
player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.CHARGE_FAIL()))
return
}
if (!itemCharge) {
if ((AxMinionsPlugin.integrations.getEconomyIntegration()?.getBalance(player)
?: return) < Config.CHARGE_PRICE()
) {
player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.CHARGE_FAIL()))
return
}
AxMinionsPlugin.integrations.getEconomyIntegration()?.let {
minion.getOwner()?.let { player ->
it.takeBalance(player, Config.CHARGE_PRICE())
}
}
}
if (chargeSeconds + chargeAmount > Config.MAX_CHARGE() * 60L) {
minion.setCharge(System.currentTimeMillis() + Config.MAX_CHARGE() * 60L * 1000L)
return
}
if (minion.getCharge() < System.currentTimeMillis()) {
minion.setCharge(System.currentTimeMillis() + chargeAmount * 1000)
} else {
minion.setCharge(minion.getCharge() + chargeAmount * 1000)
}
if (Messages.CHARGE().isNotBlank()) {
player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.CHARGE()))
}
} }
} } else {
val chargeSeconds = (minion.getCharge() - System.currentTimeMillis()) / 1000
if (Config.CHARGE_PRICE() <= 0 && !itemCharge) { if ((Config.MAX_CHARGE() * 60) - chargeSeconds < Config.MINIMUM_CHARGE()) {
player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.CHARGE_FAIL())) player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.CHARGE_NOT_ENOUGH_TIME_PASSED()))
return return
} }
if (!itemCharge) { var chargeAmount = Config.CHARGE_AMOUNT()
if ((AxMinionsPlugin.integrations.getEconomyIntegration()?.getBalance(player) var itemCharge = false
?: return) < Config.CHARGE_PRICE() val section = Config.CHARGE_ITEMS()
) {
for (key in section.keys) {
val item = ItemBuilder(section.getSection(key.toString())).get()
if (player.inventory.containsAtLeast(item, 1)) {
itemCharge = true
chargeAmount = section.getSection(key.toString()).getInt("charge")
player.inventory.removeItem(item)
break
}
}
if (Config.CHARGE_PRICE() <= 0 && !itemCharge) {
player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.CHARGE_FAIL())) player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.CHARGE_FAIL()))
return return
} }
AxMinionsPlugin.integrations.getEconomyIntegration()?.let { if (!itemCharge) {
minion.getOwner()?.let { player -> if ((AxMinionsPlugin.integrations.getEconomyIntegration()?.getBalance(player)
it.takeBalance(player, Config.CHARGE_PRICE()) ?: return) < Config.CHARGE_PRICE()
) {
player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.CHARGE_FAIL()))
return
}
AxMinionsPlugin.integrations.getEconomyIntegration()?.let {
minion.getOwner()?.let { player ->
it.takeBalance(player, Config.CHARGE_PRICE())
}
} }
} }
}
if (chargeSeconds + chargeAmount > Config.MAX_CHARGE() * 60L) { if (chargeSeconds + chargeAmount > Config.MAX_CHARGE() * 60L) {
minion.setCharge(System.currentTimeMillis() + Config.MAX_CHARGE() * 60L * 1000L) minion.setCharge(System.currentTimeMillis() + Config.MAX_CHARGE() * 60L * 1000L)
return return
} }
if (minion.getCharge() < System.currentTimeMillis()) { if (minion.getCharge() < System.currentTimeMillis()) {
minion.setCharge(System.currentTimeMillis() + chargeAmount * 1000) minion.setCharge(System.currentTimeMillis() + chargeAmount * 1000)
} else { } else {
minion.setCharge(minion.getCharge() + chargeAmount * 1000) minion.setCharge(minion.getCharge() + chargeAmount * 1000)
} }
if (Messages.CHARGE().isNotBlank()) { if (Messages.CHARGE().isNotBlank()) {
player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.CHARGE())) player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.CHARGE()))
}
} }
} }
} }

View File

@ -133,12 +133,16 @@ class Minion(
) )
if (event.isAttack) { if (event.isAttack) {
if (ownerUUID == event.player.uniqueId) { if (event.player.inventory.firstEmpty() == -1) {
breakMinion(event)
} else if ((canBuildAt && !Config.ONLY_OWNER_BREAK()) || event.player.hasPermission("axminions.*")) {
breakMinion(event)
} else {
broken.set(false) broken.set(false)
} else {
if (ownerUUID == event.player.uniqueId) {
breakMinion(event)
} else if ((canBuildAt && !Config.ONLY_OWNER_BREAK()) || event.player.hasPermission("axminions.*")) {
breakMinion(event)
} else {
broken.set(false)
}
} }
} else { } else {
if (ownerUUID == event.player.uniqueId) { if (ownerUUID == event.player.uniqueId) {
@ -263,6 +267,22 @@ class Minion(
this.level + 1 this.level + 1
).toString() ).toString()
) )
val chanceKillStackedAmount = Placeholder.parsed("chance_kill_stacked_amount", type.getDouble("chance-kill-stacked-amount", this.level).toString())
val nextChanceKillStackedAmount = Placeholder.parsed(
"next_chance_kill_stacked_amount",
if (type.hasReachedMaxLevel(this)) Messages.UPGRADES_MAX_LEVEL_REACHED() else type.getDouble(
"chance-kill-stacked-amount",
this.level + 1
).toString()
)
val stackedAmount = Placeholder.parsed("stacked_amount", type.getDouble("stacked-amount", this.level).toString())
val nextStackedAmount = Placeholder.parsed(
"next_stacked_amount",
if (type.hasReachedMaxLevel(this)) Messages.UPGRADES_MAX_LEVEL_REACHED() else type.getDouble(
"stacked-amount",
this.level + 1
).toString()
)
val extra = Placeholder.parsed("extra", type.getDouble("extra", this.level).toString()) val extra = Placeholder.parsed("extra", type.getDouble("extra", this.level).toString())
val nextExtra = Placeholder.parsed( val nextExtra = Placeholder.parsed(
"next_extra", "next_extra",
@ -321,7 +341,11 @@ class Minion(
actions, actions,
multiplier, multiplier,
nextMultiplier, nextMultiplier,
nextStorage nextStorage,
chanceKillStackedAmount,
nextChanceKillStackedAmount,
stackedAmount,
nextStackedAmount
).get() ).get()
val meta = item.itemMeta!! val meta = item.itemMeta!!

View File

@ -147,8 +147,10 @@ class CrafterMinionType : MinionType("crafter", AxMinionsPlugin.INSTANCE.getReso
val amt = next.value - recipeChoice.itemStack.amount val amt = next.value - recipeChoice.itemStack.amount
if (amt == 0) { if (amt == 0) {
iterator.remove() iterator.remove()
} else if (amt > 0) {
next.setValue(amt)
} else { } else {
next.setValue(amount) return false
} }
} }
} }
@ -178,8 +180,10 @@ class CrafterMinionType : MinionType("crafter", AxMinionsPlugin.INSTANCE.getReso
val amt = next.value - recipeChoice.value.itemStack.amount val amt = next.value - recipeChoice.value.itemStack.amount
if (amt == 0) { if (amt == 0) {
iterator.remove() iterator.remove()
} else if (amt > 0) {
next.setValue(amt)
} else { } else {
next.setValue(amount) return false
} }
} }
} }

View File

@ -110,7 +110,7 @@ class MinerMinionType : MinionType("miner", AxMinionsPlugin.INSTANCE.getResource
if (possible) { if (possible) {
minion.addToContainerOrDrop( minion.addToContainerOrDrop(
gen.generator.drawGeneratedObject().customDrops?.item ?: return@fastFor gen.lastGeneratedObject.customDrops?.item?.clone() ?: return@fastFor
) )
gen.scheduleGeneratorRegeneration() gen.scheduleGeneratorRegeneration()
return@fastFor return@fastFor
@ -158,7 +158,7 @@ class MinerMinionType : MinionType("miner", AxMinionsPlugin.INSTANCE.getResource
if (possible) { if (possible) {
minion.addToContainerOrDrop( minion.addToContainerOrDrop(
gen.generator.drawGeneratedObject().customDrops?.item ?: return@fastFor gen.lastGeneratedObject.customDrops?.item?.clone() ?: return@fastFor
) )
gen.scheduleGeneratorRegeneration() gen.scheduleGeneratorRegeneration()
return@fastFor return@fastFor
@ -192,7 +192,11 @@ class MinerMinionType : MinionType("miner", AxMinionsPlugin.INSTANCE.getResource
} }
} }
} else { } else {
LocationUtils.getAllBlocksInRadius(minion.getLocation(), minion.getRange(), false) val locCopy = minion.getLocation().clone()
locCopy.setX(locCopy.getBlockX().toDouble())
locCopy.setY(locCopy.getBlockY().toDouble())
locCopy.setZ(locCopy.getBlockZ().toDouble())
LocationUtils.getAllBlocksInRadius(locCopy, minion.getRange(), false)
.fastFor { location -> .fastFor { location ->
if (AxMinionsPlugin.integrations.kGeneratorsIntegration) { if (AxMinionsPlugin.integrations.kGeneratorsIntegration) {
val gen = Main.getPlacedGenerators().getLoaded(location) val gen = Main.getPlacedGenerators().getLoaded(location)
@ -201,7 +205,7 @@ class MinerMinionType : MinionType("miner", AxMinionsPlugin.INSTANCE.getResource
if (possible) { if (possible) {
minion.addToContainerOrDrop( minion.addToContainerOrDrop(
gen.generator.drawGeneratedObject().customDrops?.item ?: return@fastFor gen.lastGeneratedObject.customDrops?.item?.clone() ?: return@fastFor
) )
gen.scheduleGeneratorRegeneration() gen.scheduleGeneratorRegeneration()
return@fastFor return@fastFor
@ -236,7 +240,11 @@ class MinerMinionType : MinionType("miner", AxMinionsPlugin.INSTANCE.getResource
"line" -> { "line" -> {
faces.fastFor { faces.fastFor {
LocationUtils.getAllBlocksFacing(minion.getLocation(), minion.getRange(), it).fastFor { location -> val locCopy = minion.getLocation().clone()
locCopy.setX(locCopy.getBlockX().toDouble())
locCopy.setY(locCopy.getBlockY().toDouble())
locCopy.setZ(locCopy.getBlockZ().toDouble())
LocationUtils.getAllBlocksFacing(locCopy, minion.getRange(), it).fastFor { location ->
if (AxMinionsPlugin.integrations.kGeneratorsIntegration) { if (AxMinionsPlugin.integrations.kGeneratorsIntegration) {
if (Config.DEBUG()) { if (Config.DEBUG()) {
println("KGenerators integration!") println("KGenerators integration!")
@ -253,7 +261,7 @@ class MinerMinionType : MinionType("miner", AxMinionsPlugin.INSTANCE.getResource
println("Not possible") println("Not possible")
} }
minion.addToContainerOrDrop( minion.addToContainerOrDrop(
gen.generator.drawGeneratedObject().customDrops?.item ?: return@fastFor gen.lastGeneratedObject.customDrops?.item?.clone() ?: return@fastFor
) )
gen.scheduleGeneratorRegeneration() gen.scheduleGeneratorRegeneration()
return@fastFor return@fastFor
@ -291,7 +299,11 @@ class MinerMinionType : MinionType("miner", AxMinionsPlugin.INSTANCE.getResource
} }
"face" -> { "face" -> {
LocationUtils.getAllBlocksFacing(minion.getLocation(), minion.getRange(), minion.getDirection().facing) val locCopy = minion.getLocation().clone()
locCopy.setX(locCopy.getBlockX().toDouble())
locCopy.setY(locCopy.getBlockY().toDouble())
locCopy.setZ(locCopy.getBlockZ().toDouble())
LocationUtils.getAllBlocksFacing(locCopy, minion.getRange(), minion.getDirection().facing)
.fastFor { location -> .fastFor { location ->
if (AxMinionsPlugin.integrations.kGeneratorsIntegration) { if (AxMinionsPlugin.integrations.kGeneratorsIntegration) {
val gen = Main.getPlacedGenerators().getLoaded(location) val gen = Main.getPlacedGenerators().getLoaded(location)
@ -300,7 +312,7 @@ class MinerMinionType : MinionType("miner", AxMinionsPlugin.INSTANCE.getResource
if (possible) { if (possible) {
minion.addToContainerOrDrop( minion.addToContainerOrDrop(
gen.generator.drawGeneratedObject().customDrops?.item ?: return@fastFor gen.lastGeneratedObject.customDrops?.item?.clone() ?: return@fastFor
) )
gen.scheduleGeneratorRegeneration() gen.scheduleGeneratorRegeneration()
return@fastFor return@fastFor

Binary file not shown.

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

17
gradlew vendored
View File

@ -83,7 +83,8 @@ done
# This is normally unused # This is normally unused
# shellcheck disable=SC2034 # shellcheck disable=SC2034
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045 # shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #( '' | soft) :;; #(
*) *)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045 # shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac
@ -201,11 +202,11 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command; # Collect all arguments for the java command:
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# shell script including quotes and variable substitutions, so put them in # and any embedded shellness will be escaped.
# double quotes to make sure that they get re-expanded; and # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# * put everything else in single quotes, so that it's not re-expanded. # treated as '${Hostname}' itself on the command line.
set -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \

20
gradlew.bat vendored
View File

@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute if %ERRORLEVEL% equ 0 goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail
@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail

View File

@ -1,5 +1,5 @@
plugins { plugins {
id("io.papermc.paperweight.userdev") version "1.7.1" apply false id("io.papermc.paperweight.userdev") version "2.0.0-beta.8" apply false
} }
group = "com.artillexstudios.axminions" group = "com.artillexstudios.axminions"
@ -10,4 +10,4 @@ subprojects {
compileOnly project(":common") compileOnly project(":common")
compileOnly project(":api") compileOnly project(":api")
} }
} }

View File

@ -6,7 +6,7 @@ group = 'com.artillexstudios.axminions.nms'
version = '1.0-SNAPSHOT' version = '1.0-SNAPSHOT'
dependencies { dependencies {
paperweight.paperDevBundle("1.20.5-R0.1-SNAPSHOT") paperweight.paperDevBundle("1.20.6-R0.1-SNAPSHOT")
} }
kotlin { kotlin {

24
nms/v1_21_R2/build.gradle Normal file
View File

@ -0,0 +1,24 @@
plugins {
id("io.papermc.paperweight.userdev")
}
group = 'com.artillexstudios.axminions.nms'
version = '1.0-SNAPSHOT'
dependencies {
paperweight.paperDevBundle("1.21.3-R0.1-SNAPSHOT")
}
kotlin {
jvmToolchain(21)
}
tasks {
build {
dependsOn(reobfJar)
}
reobfJar {
mustRunAfter(shadowJar)
}
}

View File

@ -0,0 +1,224 @@
package com.artillexstudios.axminions.nms.v1_21_R2
import com.artillexstudios.axminions.api.events.PreMinionDamageEntityEvent
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.entity.EntityType
import net.minecraft.world.entity.EquipmentSlot
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.animal.Fox
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 org.bukkit.Bukkit
import org.bukkit.craftbukkit.CraftWorld
import org.bukkit.craftbukkit.entity.CraftEntity
import org.bukkit.craftbukkit.inventory.CraftItemStack
import org.bukkit.enchantments.Enchantment
import org.bukkit.entity.Entity
import org.bukkit.entity.Player
import net.minecraft.world.entity.EquipmentSlotGroup
import net.minecraft.world.entity.ai.attributes.Attributes
import net.minecraft.core.component.DataComponents
import net.minecraft.core.Holder
import net.minecraft.resources.ResourceKey
import net.minecraft.world.entity.ai.attributes.Attribute
import java.util.*
object DamageHandler {
private var DUMMY_ENTITY = Fox(EntityType.FOX, (Bukkit.getWorlds().get(0) as CraftWorld).handle)
private var minion: Minion? = null
fun getUUID(): UUID {
return DUMMY_ENTITY.uuid
}
fun getMinion(): Minion? {
return minion
}
fun damage(source: Minion, entity: Entity) {
val nmsEntity = (entity as CraftEntity).handle
synchronized(DUMMY_ENTITY) {
this.minion = source
var f = 1
val nmsItem: ItemStack
if (source.getTool() == null) {
nmsItem = ItemStack.EMPTY
} else {
nmsItem = CraftItemStack.asNMSCopy(source.getTool())
nmsItem.get(DataComponents.ATTRIBUTE_MODIFIERS)?.forEach(EquipmentSlotGroup.MAINHAND) { h: Holder<Attribute>, m ->
if (h.unwrapKey().orElseThrow() == Attributes.ATTACK_DAMAGE.unwrapKey().orElseThrow()) {
f += m.amount().toInt()
}
}
}
DUMMY_ENTITY.setItemSlot(EquipmentSlot.MAINHAND, nmsItem)
if (!nmsEntity.isAttackable || entity is Player) return
val f2 = 1.0f
val damageSource = nmsEntity.damageSources().noAggroMobAttack(DUMMY_ENTITY)
var f1 = EnchantmentHelper.modifyDamage(
nmsEntity.level() as ServerLevel,
nmsItem,
nmsEntity,
damageSource,
f.toFloat()
)
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.igniteForSeconds(1f, false)
}
}
val event = PreMinionDamageEntityEvent(source, entity as org.bukkit.entity.LivingEntity, f.toDouble())
Bukkit.getPluginManager().callEvent(event)
if (event.isCancelled) {
return
}
val flag5 = nmsEntity.hurtServer((source.getLocation().world as CraftWorld).handle as ServerLevel, damageSource, 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) getSweepingDamageRatio(sweep) else 0.0f * f
val list: List<LivingEntity> = (source.getLocation().world as CraftWorld).handle
.getEntitiesOfClass(LivingEntity::class.java, nmsEntity.boundingBox.inflate(1.0, 0.25, 1.0))
.filter { it !is Player }
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 = PreMinionDamageEntityEvent(
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.hurtServer((source.getLocation().world as CraftWorld).handle as ServerLevel, nmsEntity.damageSources().noAggroMobAttack(DUMMY_ENTITY), 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
)
}
}
if (nmsEntity is LivingEntity) {
val f5: Float = f3 - nmsEntity.health
if (j > 0) {
nmsEntity.igniteForSeconds(j * 4f, 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()
}
}
}
this.minion = null
}
}
fun getSweepingDamageRatio(level: Int): Float {
return 1.0f - 1.0f / (level + 1).toFloat()
}
}

View File

@ -0,0 +1,39 @@
package com.artillexstudios.axminions.nms.v1_21_R2
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.Location
import org.bukkit.craftbukkit.CraftWorld
import org.bukkit.craftbukkit.inventory.CraftItemStack
import org.bukkit.inventory.ItemStack
object LootHandler {
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 {
CraftItemStack.asNMSCopy(minion.getTool())
}
val level = (minion.getLocation().world as CraftWorld).handle
val lootparams = LootParams.Builder(level).withParameter(
LootContextParams.ORIGIN, Vec3(waterLocation.x, waterLocation.y, waterLocation.z)
).withParameter(LootContextParams.TOOL, nmsItem).withOptionalParameter(LootContextParams.THIS_ENTITY, null)
.create(LootContextParamSets.FISHING)
val lootTable = MinecraftServer.getServer().reloadableRegistries().getLootTable(BuiltInLootTables.FISHING);
return lootTable.getRandomItems(lootparams).stream().map { original: net.minecraft.world.item.ItemStack? ->
CraftItemStack.asBukkitCopy(
original
)
}.toList()
}
}

View File

@ -0,0 +1,49 @@
package com.artillexstudios.axminions.nms.v1_21_R2
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.block.Block
import org.bukkit.craftbukkit.block.CraftBlock
import org.bukkit.craftbukkit.block.CraftBlockState
import org.bukkit.craftbukkit.entity.CraftEntity
import org.bukkit.craftbukkit.inventory.CraftItemStack
import org.bukkit.craftbukkit.util.CraftLocation
import org.bukkit.entity.Entity
import org.bukkit.inventory.ItemStack
import java.util.*
class NMSHandler : NMSHandler {
override fun attack(source: Minion, target: Entity) {
DamageHandler.damage(source, target)
}
override fun generateRandomFishingLoot(minion: Minion, waterLocation: Location): List<ItemStack> {
return LootHandler.generateFishingLoot(minion, waterLocation)
}
override fun isAnimal(entity: Entity): Boolean {
return (entity as CraftEntity).handle.type.category == MobCategory.CREATURE
}
override fun getAnimalUUID(): UUID {
return DamageHandler.getUUID()
}
override fun getMinion(): Minion? {
return DamageHandler.getMinion()
}
override fun getExp(block: Block, itemStack: ItemStack): Int {
val craftBlock = block as CraftBlock
return craftBlock.nms.block.getExpDrop(
(block.state as CraftBlockState).handle,
craftBlock.handle.minecraftWorld,
CraftLocation.toBlockPosition(block.location),
CraftItemStack.asNMSCopy(itemStack),
true
)
}
}

26
nms/v1_21_R3/build.gradle Normal file
View File

@ -0,0 +1,26 @@
plugins {
id("io.papermc.paperweight.userdev")
}
group = 'com.artillexstudios.axminions.nms'
version = '1.0-SNAPSHOT'
dependencies {
paperweight.paperDevBundle("1.21.4-R0.1-SNAPSHOT")
}
kotlin {
jvmToolchain(21)
}
configurations.all { resolutionStrategy { { details -> if (details.getSelected() != details.getRequested()) { details.useVersion(details.getSelected().toString()) } } } }
tasks {
build {
dependsOn(reobfJar)
}
reobfJar {
mustRunAfter(shadowJar)
}
}

View File

@ -0,0 +1,224 @@
package com.artillexstudios.axminions.nms.v1_21_R3
import com.artillexstudios.axminions.api.events.PreMinionDamageEntityEvent
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.entity.EntityType
import net.minecraft.world.entity.EquipmentSlot
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.animal.Fox
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 org.bukkit.Bukkit
import org.bukkit.craftbukkit.CraftWorld
import org.bukkit.craftbukkit.entity.CraftEntity
import org.bukkit.craftbukkit.inventory.CraftItemStack
import org.bukkit.enchantments.Enchantment
import org.bukkit.entity.Entity
import org.bukkit.entity.Player
import net.minecraft.world.entity.EquipmentSlotGroup
import net.minecraft.world.entity.ai.attributes.Attributes
import net.minecraft.core.component.DataComponents
import net.minecraft.core.Holder
import net.minecraft.resources.ResourceKey
import net.minecraft.world.entity.ai.attributes.Attribute
import java.util.*
object DamageHandler {
private var DUMMY_ENTITY = Fox(EntityType.FOX, (Bukkit.getWorlds().get(0) as CraftWorld).handle)
private var minion: Minion? = null
fun getUUID(): UUID {
return DUMMY_ENTITY.uuid
}
fun getMinion(): Minion? {
return minion
}
fun damage(source: Minion, entity: Entity) {
val nmsEntity = (entity as CraftEntity).handle
synchronized(DUMMY_ENTITY) {
this.minion = source
var f = 1
val nmsItem: ItemStack
if (source.getTool() == null) {
nmsItem = ItemStack.EMPTY
} else {
nmsItem = CraftItemStack.asNMSCopy(source.getTool())
nmsItem.get(DataComponents.ATTRIBUTE_MODIFIERS)?.forEach(EquipmentSlotGroup.MAINHAND) { h: Holder<Attribute>, m ->
if (h.unwrapKey().orElseThrow() == Attributes.ATTACK_DAMAGE.unwrapKey().orElseThrow()) {
f += m.amount().toInt()
}
}
}
DUMMY_ENTITY.setItemSlot(EquipmentSlot.MAINHAND, nmsItem)
if (!nmsEntity.isAttackable || entity is Player) return
val f2 = 1.0f
val damageSource = nmsEntity.damageSources().noAggroMobAttack(DUMMY_ENTITY)
var f1 = EnchantmentHelper.modifyDamage(
nmsEntity.level() as ServerLevel,
nmsItem,
nmsEntity,
damageSource,
f.toFloat()
)
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.igniteForSeconds(1f, false)
}
}
val event = PreMinionDamageEntityEvent(source, entity as org.bukkit.entity.LivingEntity, f.toDouble())
Bukkit.getPluginManager().callEvent(event)
if (event.isCancelled) {
return
}
val flag5 = nmsEntity.hurtServer((source.getLocation().world as CraftWorld).handle as ServerLevel, damageSource, 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) getSweepingDamageRatio(sweep) else 0.0f * f
val list: List<LivingEntity> = (source.getLocation().world as CraftWorld).handle
.getEntitiesOfClass(LivingEntity::class.java, nmsEntity.boundingBox.inflate(1.0, 0.25, 1.0))
.filter { it !is Player }
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 = PreMinionDamageEntityEvent(
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.hurtServer((source.getLocation().world as CraftWorld).handle as ServerLevel, nmsEntity.damageSources().noAggroMobAttack(DUMMY_ENTITY), 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
)
}
}
if (nmsEntity is LivingEntity) {
val f5: Float = f3 - nmsEntity.health
if (j > 0) {
nmsEntity.igniteForSeconds(j * 4f, 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()
}
}
}
this.minion = null
}
}
fun getSweepingDamageRatio(level: Int): Float {
return 1.0f - 1.0f / (level + 1).toFloat()
}
}

View File

@ -0,0 +1,39 @@
package com.artillexstudios.axminions.nms.v1_21_R3
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.Location
import org.bukkit.craftbukkit.CraftWorld
import org.bukkit.craftbukkit.inventory.CraftItemStack
import org.bukkit.inventory.ItemStack
object LootHandler {
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 {
CraftItemStack.asNMSCopy(minion.getTool())
}
val level = (minion.getLocation().world as CraftWorld).handle
val lootparams = LootParams.Builder(level).withParameter(
LootContextParams.ORIGIN, Vec3(waterLocation.x, waterLocation.y, waterLocation.z)
).withParameter(LootContextParams.TOOL, nmsItem).withOptionalParameter(LootContextParams.THIS_ENTITY, null)
.create(LootContextParamSets.FISHING)
val lootTable = MinecraftServer.getServer().reloadableRegistries().getLootTable(BuiltInLootTables.FISHING);
return lootTable.getRandomItems(lootparams).stream().map { original: net.minecraft.world.item.ItemStack? ->
CraftItemStack.asBukkitCopy(
original
)
}.toList()
}
}

View File

@ -0,0 +1,49 @@
package com.artillexstudios.axminions.nms.v1_21_R3
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.block.Block
import org.bukkit.craftbukkit.block.CraftBlock
import org.bukkit.craftbukkit.block.CraftBlockState
import org.bukkit.craftbukkit.entity.CraftEntity
import org.bukkit.craftbukkit.inventory.CraftItemStack
import org.bukkit.craftbukkit.util.CraftLocation
import org.bukkit.entity.Entity
import org.bukkit.inventory.ItemStack
import java.util.*
class NMSHandler : NMSHandler {
override fun attack(source: Minion, target: Entity) {
DamageHandler.damage(source, target)
}
override fun generateRandomFishingLoot(minion: Minion, waterLocation: Location): List<ItemStack> {
return LootHandler.generateFishingLoot(minion, waterLocation)
}
override fun isAnimal(entity: Entity): Boolean {
return (entity as CraftEntity).handle.type.category == MobCategory.CREATURE
}
override fun getAnimalUUID(): UUID {
return DamageHandler.getUUID()
}
override fun getMinion(): Minion? {
return DamageHandler.getMinion()
}
override fun getExp(block: Block, itemStack: ItemStack): Int {
val craftBlock = block as CraftBlock
return craftBlock.nms.block.getExpDrop(
(block.state as CraftBlockState).handle,
craftBlock.handle.minecraftWorld,
CraftLocation.toBlockPosition(block.location),
CraftItemStack.asNMSCopy(itemStack),
true
)
}
}

View File

@ -22,5 +22,7 @@ include 'nms:v1_20_R3'
include 'nms:v1_20_R4' include 'nms:v1_20_R4'
include 'nms:v1_21_R1' include 'nms:v1_21_R1'
include 'nms:v1_18_R2' include 'nms:v1_18_R2'
include 'nms:v1_21_R2'
//include 'nms:v1_21_R3'
findProject(':nms:v1_18_R2')?.name = 'v1_18_R2' findProject(':nms:v1_18_R2')?.name = 'v1_18_R2'