diff --git a/core/src/main/kotlin/com/willfp/libreforge/effects/Effect.kt b/core/src/main/kotlin/com/willfp/libreforge/effects/Effect.kt index 79b61f202..a9dedad19 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/effects/Effect.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/effects/Effect.kt @@ -5,6 +5,8 @@ import com.willfp.eco.core.map.defaultMap import com.willfp.libreforge.Compilable import com.willfp.libreforge.ProvidedHolder import com.willfp.libreforge.applyHolder +import com.willfp.libreforge.mutators.MutatorList +import com.willfp.libreforge.mutators.emptyMutatorList import com.willfp.libreforge.plugin import com.willfp.libreforge.triggers.DispatchedTrigger import com.willfp.libreforge.triggers.Trigger @@ -63,7 +65,13 @@ abstract class Effect( * If the effect supports a certain [trigger]. */ fun supportsTrigger(trigger: Trigger) = - Triggers.withParameters(parameters)(trigger) + Triggers.withParameters(parameters)(trigger, emptyMutatorList()) + + /** + * If the effect supports a certain [trigger] after [mutators] are applied to it. + */ + fun supportsTrigger(trigger: Trigger, mutators: MutatorList) = + Triggers.withParameters(parameters)(trigger, mutators) /** * Enable a permanent effect. diff --git a/core/src/main/kotlin/com/willfp/libreforge/effects/Effects.kt b/core/src/main/kotlin/com/willfp/libreforge/effects/Effects.kt index c9f8b826a..4adfe2238 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/effects/Effects.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/effects/Effects.kt @@ -227,7 +227,7 @@ object Effects : Registry>() { var isInvalid = false for (element in chain) { for (trigger in triggers) { - if (!element.effect.supportsTrigger(trigger)) { + if (!element.effect.supportsTrigger(trigger, mutators)) { isInvalid = true context.log( ConfigViolation( diff --git a/core/src/main/kotlin/com/willfp/libreforge/mutators/Mutator.kt b/core/src/main/kotlin/com/willfp/libreforge/mutators/Mutator.kt index 70a4aa603..3457c65bb 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/mutators/Mutator.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/mutators/Mutator.kt @@ -4,6 +4,7 @@ import com.willfp.eco.core.config.interfaces.Config import com.willfp.libreforge.Compilable import com.willfp.libreforge.effects.RunOrder import com.willfp.libreforge.triggers.TriggerData +import com.willfp.libreforge.triggers.TriggerParameter abstract class Mutator( override val id: String @@ -13,6 +14,20 @@ abstract class Mutator( */ open val runOrder = RunOrder.NORMAL + /** + * The parameter transformers. + */ + protected open val parameterTransformers: Set = emptySet() + + /** + * Transform the parameters. + */ + fun transform(parameters: Set): Set { + return parameterTransformers.fold(parameters) { acc, transformer -> + transformer.transform(acc) + } + } + /** * Mutate the trigger data. * diff --git a/core/src/main/kotlin/com/willfp/libreforge/mutators/MutatorBlock.kt b/core/src/main/kotlin/com/willfp/libreforge/mutators/MutatorBlock.kt index fa333b556..cd3cd12d5 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/mutators/MutatorBlock.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/mutators/MutatorBlock.kt @@ -3,6 +3,7 @@ package com.willfp.libreforge.mutators import com.willfp.eco.core.config.interfaces.Config import com.willfp.libreforge.Compiled import com.willfp.libreforge.triggers.TriggerData +import com.willfp.libreforge.triggers.TriggerParameter /** * A single mutator config block. @@ -14,4 +15,7 @@ class MutatorBlock internal constructor( ): Compiled { fun mutate(data: TriggerData) = mutator.mutate(data, this) + + fun transform(parameters: Set) = + mutator.transform(parameters) } diff --git a/core/src/main/kotlin/com/willfp/libreforge/mutators/MutatorList.kt b/core/src/main/kotlin/com/willfp/libreforge/mutators/MutatorList.kt index 279ab3513..61f3a35a2 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/mutators/MutatorList.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/mutators/MutatorList.kt @@ -2,6 +2,7 @@ package com.willfp.libreforge.mutators import com.willfp.libreforge.DelegatedList import com.willfp.libreforge.triggers.TriggerData +import com.willfp.libreforge.triggers.TriggerParameter /** * A list of mutators. @@ -14,12 +15,19 @@ class MutatorList( } ) { fun mutate(data: TriggerData): TriggerData { - var current = data - - for (block in this) { - current = block.mutate(current) + return this.fold(data) { currentData, block -> + block.mutate(currentData) } + } - return current + fun transform(parameters: Set): Set { + return this.fold(parameters) { currentParameters, block -> + block.transform(currentParameters) + } } } + +/** + * Creates an empty [MutatorList]. + */ +fun emptyMutatorList() = MutatorList(emptyList()) diff --git a/core/src/main/kotlin/com/willfp/libreforge/mutators/TriggerParameterTransformer.kt b/core/src/main/kotlin/com/willfp/libreforge/mutators/TriggerParameterTransformer.kt new file mode 100644 index 000000000..d8e681fcc --- /dev/null +++ b/core/src/main/kotlin/com/willfp/libreforge/mutators/TriggerParameterTransformer.kt @@ -0,0 +1,36 @@ +package com.willfp.libreforge.mutators + +import com.willfp.libreforge.triggers.TriggerParameter + +data class TriggerParameterTransformer( + val parameterIn: TriggerParameter, + val parameterOut: TriggerParameter +) { + fun transform(parameters: Set): Set { + return parameters.fold(mutableSetOf()) { acc, parameter -> + if (parameter == parameterIn) { + acc.apply { + add(parameterIn) + add(parameterOut) + } + } else { + acc.apply { add(parameter) } + } + } + } +} + +class TriggerParameterBuilder { + private val set = mutableSetOf() + + infix fun TriggerParameter.becomes(other: TriggerParameter) { + set += TriggerParameterTransformer(this, other) + } + + internal fun toSet(): Set { + return set + } +} + +fun parameterTransformers(block: TriggerParameterBuilder.() -> Unit): Set = + TriggerParameterBuilder().apply(block).toSet() diff --git a/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorBlockToLocation.kt b/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorBlockToLocation.kt index f229c9233..d9971f22f 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorBlockToLocation.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorBlockToLocation.kt @@ -3,9 +3,15 @@ package com.willfp.libreforge.mutators.impl import com.willfp.eco.core.config.interfaces.Config import com.willfp.libreforge.NoCompileData import com.willfp.libreforge.mutators.Mutator +import com.willfp.libreforge.mutators.parameterTransformers import com.willfp.libreforge.triggers.TriggerData +import com.willfp.libreforge.triggers.TriggerParameter object MutatorBlockToLocation : Mutator("block_to_location") { + override val parameterTransformers = parameterTransformers { + TriggerParameter.LOCATION becomes TriggerParameter.BLOCK + } + override fun mutate(data: TriggerData, config: Config, compileData: NoCompileData): TriggerData { return data.copy( block = data.location?.block diff --git a/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToBlock.kt b/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToBlock.kt index cd5f062b2..6b37e1b07 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToBlock.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToBlock.kt @@ -3,9 +3,16 @@ package com.willfp.libreforge.mutators.impl import com.willfp.eco.core.config.interfaces.Config import com.willfp.libreforge.NoCompileData import com.willfp.libreforge.mutators.Mutator +import com.willfp.libreforge.mutators.TriggerParameterTransformer +import com.willfp.libreforge.mutators.parameterTransformers import com.willfp.libreforge.triggers.TriggerData +import com.willfp.libreforge.triggers.TriggerParameter object MutatorLocationToBlock : Mutator("location_to_block") { + override val parameterTransformers = parameterTransformers { + TriggerParameter.BLOCK becomes TriggerParameter.LOCATION + } + override fun mutate(data: TriggerData, config: Config, compileData: NoCompileData): TriggerData { return data.copy( location = data.block?.location diff --git a/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToCursor.kt b/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToCursor.kt index 061bcc48b..823d04331 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToCursor.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToCursor.kt @@ -4,8 +4,10 @@ import com.willfp.eco.core.config.interfaces.Config import com.willfp.libreforge.NoCompileData import com.willfp.libreforge.arguments import com.willfp.libreforge.mutators.Mutator +import com.willfp.libreforge.mutators.parameterTransformers import com.willfp.libreforge.plugin import com.willfp.libreforge.triggers.TriggerData +import com.willfp.libreforge.triggers.TriggerParameter import org.bukkit.FluidCollisionMode object MutatorLocationToCursor : Mutator("location_to_cursor") { @@ -18,6 +20,11 @@ object MutatorLocationToCursor : Mutator("location_to_cursor") { } } + override val parameterTransformers = parameterTransformers { + TriggerParameter.PLAYER becomes TriggerParameter.LOCATION + TriggerParameter.VICTIM becomes TriggerParameter.LOCATION + } + override fun mutate(data: TriggerData, config: Config, compileData: NoCompileData): TriggerData { val target = config.getString("target") val startingEntity = config.getString("start") diff --git a/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToPlayer.kt b/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToPlayer.kt index d2d58a4fb..0ce870d2a 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToPlayer.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToPlayer.kt @@ -3,9 +3,16 @@ package com.willfp.libreforge.mutators.impl import com.willfp.eco.core.config.interfaces.Config import com.willfp.libreforge.NoCompileData import com.willfp.libreforge.mutators.Mutator +import com.willfp.libreforge.mutators.TriggerParameterTransformer +import com.willfp.libreforge.mutators.parameterTransformers import com.willfp.libreforge.triggers.TriggerData +import com.willfp.libreforge.triggers.TriggerParameter object MutatorLocationToPlayer : Mutator("location_to_player") { + override val parameterTransformers = parameterTransformers { + TriggerParameter.PLAYER becomes TriggerParameter.LOCATION + } + override fun mutate(data: TriggerData, config: Config, compileData: NoCompileData): TriggerData { return data.copy( location = data.player?.location diff --git a/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToProjectile.kt b/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToProjectile.kt index eb3d9b22b..11ed25d2c 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToProjectile.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToProjectile.kt @@ -3,9 +3,15 @@ package com.willfp.libreforge.mutators.impl import com.willfp.eco.core.config.interfaces.Config import com.willfp.libreforge.NoCompileData import com.willfp.libreforge.mutators.Mutator +import com.willfp.libreforge.mutators.parameterTransformers import com.willfp.libreforge.triggers.TriggerData +import com.willfp.libreforge.triggers.TriggerParameter object MutatorLocationToProjectile : Mutator("location_to_projectile") { + override val parameterTransformers = parameterTransformers { + TriggerParameter.PROJECTILE becomes TriggerParameter.LOCATION + } + override fun mutate(data: TriggerData, config: Config, compileData: NoCompileData): TriggerData { return data.copy( location = data.projectile?.location diff --git a/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToVictim.kt b/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToVictim.kt index 6f4f0a0e6..3322208b6 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToVictim.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorLocationToVictim.kt @@ -3,9 +3,15 @@ package com.willfp.libreforge.mutators.impl import com.willfp.eco.core.config.interfaces.Config import com.willfp.libreforge.NoCompileData import com.willfp.libreforge.mutators.Mutator +import com.willfp.libreforge.mutators.parameterTransformers import com.willfp.libreforge.triggers.TriggerData +import com.willfp.libreforge.triggers.TriggerParameter object MutatorLocationToVictim : Mutator("location_to_victim") { + override val parameterTransformers = parameterTransformers { + TriggerParameter.VICTIM becomes TriggerParameter.LOCATION + } + override fun mutate(data: TriggerData, config: Config, compileData: NoCompileData): TriggerData { return data.copy( location = data.victim?.location diff --git a/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorPlayerAsVictim.kt b/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorPlayerAsVictim.kt index ac1eb2112..59f6857ec 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorPlayerAsVictim.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorPlayerAsVictim.kt @@ -3,9 +3,15 @@ package com.willfp.libreforge.mutators.impl import com.willfp.eco.core.config.interfaces.Config import com.willfp.libreforge.NoCompileData import com.willfp.libreforge.mutators.Mutator +import com.willfp.libreforge.mutators.parameterTransformers import com.willfp.libreforge.triggers.TriggerData +import com.willfp.libreforge.triggers.TriggerParameter object MutatorPlayerAsVictim : Mutator("player_as_victim") { + override val parameterTransformers = parameterTransformers { + TriggerParameter.PLAYER becomes TriggerParameter.VICTIM + } + override fun mutate(data: TriggerData, config: Config, compileData: NoCompileData): TriggerData { return data.copy( victim = data.player diff --git a/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorVictimAsPlayer.kt b/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorVictimAsPlayer.kt index d95ba7c69..a014b7165 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorVictimAsPlayer.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorVictimAsPlayer.kt @@ -3,10 +3,16 @@ package com.willfp.libreforge.mutators.impl import com.willfp.eco.core.config.interfaces.Config import com.willfp.libreforge.NoCompileData import com.willfp.libreforge.mutators.Mutator +import com.willfp.libreforge.mutators.parameterTransformers import com.willfp.libreforge.triggers.TriggerData +import com.willfp.libreforge.triggers.TriggerParameter import org.bukkit.entity.Player object MutatorVictimAsPlayer : Mutator("victim_as_player") { + override val parameterTransformers = parameterTransformers { + TriggerParameter.VICTIM becomes TriggerParameter.PLAYER + } + override fun mutate(data: TriggerData, config: Config, compileData: NoCompileData): TriggerData { return data.copy( player = data.victim as? Player diff --git a/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorVictimToOwner.kt b/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorVictimToOwner.kt index dbf0931fc..d4bd8d843 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorVictimToOwner.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/mutators/impl/MutatorVictimToOwner.kt @@ -3,7 +3,9 @@ package com.willfp.libreforge.mutators.impl import com.willfp.eco.core.config.interfaces.Config import com.willfp.libreforge.NoCompileData import com.willfp.libreforge.mutators.Mutator +import com.willfp.libreforge.mutators.parameterTransformers import com.willfp.libreforge.triggers.TriggerData +import com.willfp.libreforge.triggers.TriggerParameter import org.bukkit.entity.LivingEntity import org.bukkit.entity.Tameable diff --git a/core/src/main/kotlin/com/willfp/libreforge/triggers/Triggers.kt b/core/src/main/kotlin/com/willfp/libreforge/triggers/Triggers.kt index 05de644a1..c6fb3d1ec 100644 --- a/core/src/main/kotlin/com/willfp/libreforge/triggers/Triggers.kt +++ b/core/src/main/kotlin/com/willfp/libreforge/triggers/Triggers.kt @@ -1,6 +1,7 @@ package com.willfp.libreforge.triggers import com.willfp.eco.core.registry.Registry +import com.willfp.libreforge.mutators.MutatorList import com.willfp.libreforge.triggers.impl.TriggerAltClick import com.willfp.libreforge.triggers.impl.TriggerBite import com.willfp.libreforge.triggers.impl.TriggerBlockItemDrop @@ -113,9 +114,13 @@ object Triggers : Registry() { /** * Get a predicate requiring certain trigger parameters. */ - fun withParameters(parameters: Set): (Trigger) -> Boolean { - return { - it.parameters.flatMap { param -> param.inheritsFrom.toList().plusElement(param) }.containsAll(parameters) + fun withParameters(parameters: Set): (Trigger, MutatorList) -> Boolean { + return { trigger, mutators -> + trigger.parameters + .flatMap { param -> param.inheritsFrom.toSet().plusElement(param) } + .toSet() + .let { mutators.transform(it) } + .containsAll(parameters) } }