Skip to content

Commit

Permalink
Added damage_offhand effect
Browse files Browse the repository at this point in the history
  • Loading branch information
WillFP committed Oct 24, 2023
1 parent 19bada8 commit 9bba4b2
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 131 deletions.
25 changes: 25 additions & 0 deletions core/src/main/kotlin/com/willfp/libreforge/Utils.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
package com.willfp.libreforge

import com.willfp.eco.core.items.Items
import org.bukkit.Bukkit
import org.bukkit.Location
import org.bukkit.Material
import org.bukkit.Sound
import org.bukkit.SoundCategory
import org.bukkit.block.Block
import org.bukkit.entity.Player
import org.bukkit.event.player.PlayerItemBreakEvent
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.Damageable
import kotlin.math.roundToInt

inline fun <reified T : Enum<T>> enumValueOfOrNull(name: String): T? {
Expand Down Expand Up @@ -53,3 +60,21 @@ fun Collection<ItemStack?>.filterNotEmpty() =

internal val ItemStack?.isEcoEmpty: Boolean
get() = Items.isEmpty(this)

fun ItemStack.applyDamage(damage: Int, player: Player?): Boolean {
val meta = this.itemMeta as? Damageable ?: return false
meta.damage += damage
if (meta.damage >= this.type.maxDurability) {
meta.damage = this.type.maxDurability.toInt()
this.itemMeta = meta
if (player != null) {
Bukkit.getPluginManager().callEvent(PlayerItemBreakEvent(player, this))
player.playSound(player.location, Sound.ENTITY_ITEM_BREAK, SoundCategory.BLOCKS, 1f, 1f)
}
this.type = Material.AIR
} else {
this.itemMeta = meta
}

return true
}
Original file line number Diff line number Diff line change
Expand Up @@ -449,5 +449,6 @@ object Effects : Registry<Effect<*>>() {
register(EffectGiveSaturation)
register(EffectSetSaturation)
register(EffectSetFood)
register(EffectDamageOffhand)
}
}
Original file line number Diff line number Diff line change
@@ -1,78 +1,16 @@
package com.willfp.libreforge.effects.impl

import com.willfp.eco.core.config.interfaces.Config
import com.willfp.libreforge.NoCompileData
import com.willfp.eco.util.toSingletonList
import com.willfp.libreforge.arguments
import com.willfp.libreforge.effects.Effect
import com.willfp.libreforge.getIntFromExpression
import com.willfp.libreforge.effects.templates.DamageItemEffect
import com.willfp.libreforge.triggers.TriggerData
import org.bukkit.Bukkit
import org.bukkit.Material
import org.bukkit.Sound
import org.bukkit.SoundCategory
import org.bukkit.entity.Player
import org.bukkit.event.player.PlayerItemBreakEvent
import org.bukkit.event.player.PlayerItemDamageEvent
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.Damageable


object EffectDamageItem : Effect<NoCompileData>("damage_item") {
object EffectDamageItem : DamageItemEffect("damage_item") {
override val isPermanent = false

override val arguments = arguments {
require("damage", "You must specify the amount of damage!")
}

override fun onTrigger(config: Config, data: TriggerData, compileData: NoCompileData): Boolean {
val item = data.foundItem ?: return false
val victim = data.victim

val damage = config.getIntFromExpression("damage", data)

val meta = item.itemMeta ?: return false

if (meta.isUnbreakable || meta !is Damageable) {
return false
}

// Edge cases
if (item.type == Material.CARVED_PUMPKIN || item.type == Material.PLAYER_HEAD) {
return false
}

if (victim is Player) {
@Suppress("DEPRECATION")
val event = PlayerItemDamageEvent(victim, item, damage)
Bukkit.getPluginManager().callEvent(event)
if (!event.isCancelled) {
applyDamage(item, event.damage, victim)
}
} else {
applyDamage(item, damage, null)
}

return true
}

private fun applyDamage(itemStack: ItemStack, amount: Int, player: Player?) {
val meta = itemStack.itemMeta as? Damageable ?: return

meta.damage += amount

if (meta.damage >= itemStack.type.maxDurability) {
meta.damage = itemStack.type.maxDurability.toInt()

itemStack.itemMeta = meta

if (player != null) {
Bukkit.getPluginManager().callEvent(PlayerItemBreakEvent(player, itemStack))
player.playSound(player.location, Sound.ENTITY_ITEM_BREAK, SoundCategory.BLOCKS, 1f, 1f)
}

itemStack.type = Material.AIR
} else {
itemStack.itemMeta = meta
}
override fun getItems(data: TriggerData): List<ItemStack> {
return data.foundItem.toSingletonList()
}
}
Original file line number Diff line number Diff line change
@@ -1,77 +1,18 @@
package com.willfp.libreforge.effects.impl

import com.willfp.eco.core.config.interfaces.Config
import com.willfp.libreforge.NoCompileData
import com.willfp.libreforge.arguments
import com.willfp.libreforge.effects.Effect
import com.willfp.libreforge.getIntFromExpression
import com.willfp.eco.util.toSingletonList
import com.willfp.libreforge.effects.templates.DamageItemEffect
import com.willfp.libreforge.triggers.TriggerData
import com.willfp.libreforge.triggers.TriggerParameter
import org.bukkit.Bukkit
import org.bukkit.Material
import org.bukkit.Sound
import org.bukkit.SoundCategory
import org.bukkit.entity.Player
import org.bukkit.event.player.PlayerItemBreakEvent
import org.bukkit.event.player.PlayerItemDamageEvent
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.Damageable


object EffectDamageMainhand : Effect<NoCompileData>("damage_mainhand") {
object EffectDamageMainhand : DamageItemEffect("damage_mainhand") {
override val parameters = setOf(
TriggerParameter.VICTIM
)

override val arguments = arguments {
require("damage", "You must specify the amount of damage!")
}

override fun onTrigger(config: Config, data: TriggerData, compileData: NoCompileData): Boolean {
val victim = data.victim ?: return false

val damage = config.getIntFromExpression("damage", data)

val equipment = victim.equipment ?: return false

@Suppress("USELESS_ELVIS") // I've had it be null before, spigot sucks.
val item = equipment.itemInMainHand ?: return false

val meta = item.itemMeta as? Damageable ?: return false

if (meta.isUnbreakable) {
return false
}

return if (victim is Player) {
@Suppress("DEPRECATION")
val event = PlayerItemDamageEvent(victim, item, damage)
Bukkit.getPluginManager().callEvent(event)
if (!event.isCancelled) {
applyDamage(item, event.damage, victim)
} else {
false
}
} else {
applyDamage(item, damage, null)
}
}

private fun applyDamage(itemStack: ItemStack, amount: Int, player: Player?): Boolean {
val meta = itemStack.itemMeta as? Damageable ?: return false
meta.damage += amount
if (meta.damage >= itemStack.type.maxDurability) {
meta.damage = itemStack.type.maxDurability.toInt()
itemStack.itemMeta = meta
if (player != null) {
Bukkit.getPluginManager().callEvent(PlayerItemBreakEvent(player, itemStack))
player.playSound(player.location, Sound.ENTITY_ITEM_BREAK, SoundCategory.BLOCKS, 1f, 1f)
}
itemStack.type = Material.AIR
} else {
itemStack.itemMeta = meta
}

return true
override fun getItems(data: TriggerData): List<ItemStack> {
return data.victim?.equipment?.itemInMainHand.toSingletonList()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.willfp.libreforge.effects.impl

import com.willfp.eco.util.toSingletonList
import com.willfp.libreforge.effects.templates.DamageItemEffect
import com.willfp.libreforge.triggers.TriggerData
import com.willfp.libreforge.triggers.TriggerParameter
import org.bukkit.inventory.ItemStack


object EffectDamageOffhand : DamageItemEffect("damage_offhand") {
override val parameters = setOf(
TriggerParameter.VICTIM
)

override fun getItems(data: TriggerData): List<ItemStack> {
return data.victim?.equipment?.itemInOffHand.toSingletonList()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.willfp.libreforge.effects.templates

import com.willfp.eco.core.config.interfaces.Config
import com.willfp.libreforge.NoCompileData
import com.willfp.libreforge.applyDamage
import com.willfp.libreforge.arguments
import com.willfp.libreforge.effects.Effect
import com.willfp.libreforge.getIntFromExpression
import com.willfp.libreforge.triggers.TriggerData
import com.willfp.libreforge.triggers.TriggerParameter
import org.bukkit.Bukkit
import org.bukkit.Material
import org.bukkit.entity.Player
import org.bukkit.event.player.PlayerItemDamageEvent
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.Damageable


abstract class DamageItemEffect(id: String) : Effect<NoCompileData>(id) {
final override val arguments = arguments {
require("damage", "You must specify the amount of damage!")
}

abstract fun getItems(data: TriggerData): List<ItemStack>

final override fun onTrigger(config: Config, data: TriggerData, compileData: NoCompileData): Boolean {
val victim = data.victim ?: return false

val damage = config.getIntFromExpression("damage", data)

val items = getItems(data)
.filterNot { it.type == Material.CARVED_PUMPKIN }
.filterNot { it.type == Material.PLAYER_HEAD }

var success = false

for (item in items) {
val meta = item.itemMeta as? Damageable ?: continue

if (meta.isUnbreakable) {
continue
}

if (victim is Player) {
@Suppress("DEPRECATION")
val event = PlayerItemDamageEvent(victim, item, damage)
Bukkit.getPluginManager().callEvent(event)
if (!event.isCancelled) {
item.applyDamage(event.damage, victim)
success = true
}
} else {
item.applyDamage(damage, null)
success = true
}
}

return success
}
}

0 comments on commit 9bba4b2

Please sign in to comment.