Fix 9 bugs and features
9 identified bugs have been fixed, aswell as the podium where you would not spawn in the middle and missing messages
This commit is contained in:
@@ -233,9 +233,12 @@ class PodiumManager(
|
||||
val xOff = COLUMN_X_OFFSET[ entry.placement ] ?: return@forEach
|
||||
val height = COLUMN_HEIGHT[ entry.placement ] ?: return@forEach
|
||||
|
||||
val standLoc = center.clone()
|
||||
.add( xOff.toDouble(), height.toDouble(), 0.0 )
|
||||
.apply { yaw = 0f; pitch = 0f }
|
||||
val standLoc = Location(
|
||||
center.world,
|
||||
center.blockX + xOff.toDouble() + 0.5, // Block-Mitte X
|
||||
center.y + height,
|
||||
center.blockZ.toDouble() + 0.5 // Block-Mitte Z
|
||||
).apply { yaw = 0f; pitch = 0f }
|
||||
|
||||
entry.player.teleport( standLoc )
|
||||
entry.player.gameMode = GameMode.ADVENTURE
|
||||
|
||||
@@ -129,10 +129,14 @@ class FeastManager(
|
||||
|
||||
// State erst im nächsten Tick lesen — Block-Commit braucht einen Tick
|
||||
Bukkit.getScheduler().runTaskLater( plugin, { ->
|
||||
val chest = chestBlock.state as? Chest ?: return@runTaskLater
|
||||
val freshBlock = world.getBlockAt( cx, platformY + 1, cz )
|
||||
if ( freshBlock.type != Material.CHEST ) return@runTaskLater
|
||||
|
||||
val chest = freshBlock.state as? Chest ?: return@runTaskLater
|
||||
chest.update( true, false ) // BlockState commiten, bevor Inventar beschrieben wird
|
||||
|
||||
fillChestWithLoot( chest )
|
||||
chest.update( true )
|
||||
}, 1L )
|
||||
}, 2L )
|
||||
}
|
||||
}, 5L )
|
||||
|
||||
@@ -203,11 +207,12 @@ class FeastManager(
|
||||
) {
|
||||
val loot = buildLootTable()
|
||||
val inventory = chest.blockInventory
|
||||
val slots = ( 0 until inventory.size ).shuffled()
|
||||
val slots = ( 0 until inventory.size ).shuffled().toMutableList()
|
||||
|
||||
loot.forEachIndexed { idx, item ->
|
||||
if ( idx < slots.size ) inventory.setItem(slots[ idx ], item )
|
||||
if ( idx < slots.size ) inventory.setItem( slots[ idx ], item )
|
||||
}
|
||||
// kein chest.update() nötig — blockInventory ist eine Live-Referenz
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,7 @@ import club.mcscrims.speedhg.kit.ability.AbilityResult
|
||||
import club.mcscrims.speedhg.kit.ability.ActiveAbility
|
||||
import club.mcscrims.speedhg.kit.ability.PassiveAbility
|
||||
import club.mcscrims.speedhg.kit.listener.KitEventDispatcher.Companion.MAX_KNOCKBACK_HEIGHT_Y
|
||||
import club.mcscrims.speedhg.util.AbilityUtils
|
||||
import club.mcscrims.speedhg.util.ItemBuilder
|
||||
import club.mcscrims.speedhg.util.WorldEditUtils
|
||||
import club.mcscrims.speedhg.util.trans
|
||||
@@ -18,6 +19,7 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent
|
||||
import org.bukkit.event.player.PlayerMoveEvent
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
import org.bukkit.util.Vector
|
||||
import java.util.*
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
@@ -184,11 +186,23 @@ class BlackPantherKit : Kit()
|
||||
player: Player,
|
||||
playstyle: Playstyle
|
||||
) {
|
||||
if ( playstyle != Playstyle.AGGRESSIVE ) return
|
||||
val item = ItemBuilder( Material.BLACK_DYE )
|
||||
.name( aggressiveActive.name )
|
||||
.lore(listOf( aggressiveActive.description ))
|
||||
.build()
|
||||
val item = when( playstyle )
|
||||
{
|
||||
Playstyle.AGGRESSIVE -> {
|
||||
ItemBuilder( Material.BLACK_DYE )
|
||||
.name( aggressiveActive.name )
|
||||
.lore(listOf( aggressiveActive.description ))
|
||||
.build()
|
||||
}
|
||||
|
||||
Playstyle.DEFENSIVE -> {
|
||||
ItemBuilder( Material.FEATHER )
|
||||
.name( defensiveActive.name )
|
||||
.lore(listOf( defensiveActive.description ))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
cachedItems[ player.uniqueId ] = listOf( item )
|
||||
player.inventory.addItem( item )
|
||||
}
|
||||
@@ -230,12 +244,11 @@ class BlackPantherKit : Kit()
|
||||
plugin.languageManager.getRawMessage( player, "kits.height_restriction" )
|
||||
)
|
||||
|
||||
// Werte zum Aktivierungszeitpunkt snapshotten
|
||||
val capturedPushRadius = pushRadius
|
||||
val capturedKnockbackSpeed = pushKnockbackSpeed
|
||||
val capturedKnockbackY = pushKnockbackY
|
||||
val capturedFistModeDurationMs = fistModeDurationMs
|
||||
val capturedProjectileDelay = projectileDelayTicks
|
||||
val capturedPushRadius = pushRadius
|
||||
val capturedKnockbackSpeed = pushKnockbackSpeed
|
||||
val capturedKnockbackY = pushKnockbackY
|
||||
val capturedFistModeDurationMs = fistModeDurationMs
|
||||
val capturedProjectileDelay = projectileDelayTicks
|
||||
|
||||
val enemies = player.world
|
||||
.getNearbyEntities( player.location, capturedPushRadius, capturedPushRadius, capturedPushRadius )
|
||||
@@ -245,6 +258,18 @@ class BlackPantherKit : Kit()
|
||||
if ( enemies.isEmpty() )
|
||||
return AbilityResult.ConditionNotMet( "No enemies within ${capturedPushRadius.toInt()} blocks!" )
|
||||
|
||||
// ── Schockwellen-Partikel am Spieler (Aktivierungs-Burst) ──────────────
|
||||
player.world.spawnParticle(
|
||||
Particle.LARGE_SMOKE,
|
||||
player.location.clone().add( 0.0, 1.0, 0.0 ),
|
||||
30, 1.0, 0.4, 1.0, 0.08
|
||||
)
|
||||
player.world.spawnParticle(
|
||||
Particle.EXPLOSION,
|
||||
player.location.clone().add( 0.0, 0.5, 0.0 ),
|
||||
2, 0.3, 0.2, 0.3, 0.0
|
||||
)
|
||||
|
||||
val pushKey = NamespacedKey( plugin, PUSH_PROJECTILE_KEY )
|
||||
|
||||
enemies.forEach { enemy ->
|
||||
@@ -255,49 +280,116 @@ class BlackPantherKit : Kit()
|
||||
.setY( capturedKnockbackY )
|
||||
|
||||
enemy.velocity = knockDir
|
||||
|
||||
// ── Partikel-Spur von Spieler → Gegner (farbige Dust-Linie) ─────────
|
||||
AbilityUtils.drawColoredParticleLine(
|
||||
player.eyeLocation,
|
||||
enemy.location.clone().add( 0.0, 1.0, 0.0 ),
|
||||
20,
|
||||
Color.fromRGB( 10, 10, 10 ) // Schwarz/Vibranium-Dunkel
|
||||
)
|
||||
|
||||
// ── Aufprall-Burst am Gegner ─────────────────────────────────────────
|
||||
enemy.world.spawnParticle(
|
||||
Particle.CRIT,
|
||||
enemy.location.clone().add( 0.0, 1.0, 0.0 ),
|
||||
10, 0.3, 0.3, 0.3, 0.0
|
||||
20, 0.4, 0.4, 0.4, 0.1
|
||||
)
|
||||
enemy.world.spawnParticle(
|
||||
Particle.LARGE_SMOKE,
|
||||
enemy.location.clone().add( 0.0, 1.0, 0.0 ),
|
||||
8, 0.3, 0.3, 0.3, 0.04
|
||||
)
|
||||
|
||||
Bukkit.getScheduler().runTaskLater( plugin, { ->
|
||||
if ( !player.isOnline ) return@runTaskLater
|
||||
|
||||
val snowball = player.world.spawn( player.eyeLocation, Snowball::class.java )
|
||||
snowball.shooter = player
|
||||
val travelDir = enemy.location.toVector()
|
||||
|
||||
val travelDir = enemy.location.clone().add( 0.0, 1.0, 0.0 )
|
||||
.toVector()
|
||||
.subtract( player.eyeLocation.toVector() )
|
||||
.normalize()
|
||||
.multiply( 1.8 )
|
||||
snowball.velocity = travelDir
|
||||
snowball.persistentDataContainer.set( pushKey, PersistentDataType.BYTE, 1 )
|
||||
|
||||
// ── Partikel-Spur für das Projektil (nachleuchtend) ─────────────
|
||||
AbilityUtils.drawGenericParticleLine(
|
||||
player.eyeLocation,
|
||||
enemy.location.clone().add( 0.0, 1.0, 0.0 ),
|
||||
15,
|
||||
Particle.SOUL_FIRE_FLAME
|
||||
)
|
||||
}, capturedProjectileDelay )
|
||||
}
|
||||
|
||||
fistModeExpiry[ player.uniqueId ] = System.currentTimeMillis() + capturedFistModeDurationMs
|
||||
player.sendActionBar( player.trans( "kits.blackpanther.messages.fist_mode_active" ) )
|
||||
|
||||
player.world.playSound( player.location, Sound.ENTITY_RAVAGER_ROAR, 1f, 1.1f )
|
||||
player.world.playSound( player.location, Sound.ENTITY_RAVAGER_ROAR, 1f, 1.1f )
|
||||
player.world.playSound( player.location, Sound.ENTITY_PLAYER_ATTACK_SWEEP, 0.8f, 0.7f )
|
||||
|
||||
return AbilityResult.Success
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// DEFENSIVE active – no active ability
|
||||
// DEFENSIVE active — Wakanda Leap (neu)
|
||||
// =========================================================================
|
||||
|
||||
private class DefensiveActive : ActiveAbility( Playstyle.DEFENSIVE )
|
||||
private inner class DefensiveActive : ActiveAbility( Playstyle.DEFENSIVE )
|
||||
{
|
||||
private val plugin get() = SpeedHG.instance
|
||||
|
||||
override val kitId: String = "blackpanther"
|
||||
override val name = "None"
|
||||
override val description = "None"
|
||||
override val hardcodedHitsRequired: Int = 0
|
||||
override val triggerMaterial = Material.BARRIER
|
||||
|
||||
override val name: String
|
||||
get() = plugin.languageManager.getDefaultRawMessage( "kits.blackpanther.items.leap.name" )
|
||||
|
||||
override val description: String
|
||||
get() = plugin.languageManager.getDefaultRawMessage( "kits.blackpanther.items.leap.description" )
|
||||
|
||||
override val hardcodedHitsRequired: Int = 10
|
||||
|
||||
override val triggerMaterial: Material
|
||||
get() = Material.FEATHER
|
||||
|
||||
override fun execute(
|
||||
player: Player
|
||||
) = AbilityResult.Success
|
||||
): AbilityResult
|
||||
{
|
||||
if ( player.location.y > MAX_KNOCKBACK_HEIGHT_Y )
|
||||
return AbilityResult.ConditionNotMet(
|
||||
plugin.languageManager.getRawMessage( player, "kits.height_restriction" )
|
||||
)
|
||||
|
||||
// Steil nach oben schleudern — leicht in Blickrichtung geneigt (wie Riptide)
|
||||
val lookDir = player.location.direction.setY( 0.0 ).normalize()
|
||||
val launchVec = Vector( lookDir.x * 0.4, 2.6, lookDir.z * 0.4 )
|
||||
player.velocity = launchVec
|
||||
|
||||
// Fallschaden unterdrücken + Spieler als "in der Luft per Ability" markieren
|
||||
noFallDamagePlayers.add( player.uniqueId )
|
||||
|
||||
player.world.playSound( player.location, Sound.ENTITY_RAVAGER_ROAR, 1f, 1.4f )
|
||||
player.world.playSound( player.location, Sound.ENTITY_PLAYER_ATTACK_SWEEP, 0.8f, 0.6f )
|
||||
player.world.spawnParticle(
|
||||
Particle.LARGE_SMOKE,
|
||||
player.location.clone().add( 0.0, 0.5, 0.0 ),
|
||||
20, 0.3, 0.2, 0.3, 0.07
|
||||
)
|
||||
player.world.spawnParticle(
|
||||
Particle.CRIT,
|
||||
player.location.clone().add( 0.0, 1.0, 0.0 ),
|
||||
12, 0.4, 0.3, 0.4, 0.1
|
||||
)
|
||||
|
||||
player.sendActionBar( player.trans( "kits.blackpanther.messages.wakanda_leap" ) )
|
||||
return AbilityResult.Success
|
||||
}
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
@@ -340,12 +432,11 @@ class BlackPantherKit : Kit()
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// DEFENSIVE passive – Wakanda Forever! (fall-pounce → AOE + crater)
|
||||
// DEFENSIVE passive — Wakanda Forever! (Aufprall-AoE nach Ability-Launch)
|
||||
// =========================================================================
|
||||
|
||||
private inner class DefensivePassive : PassiveAbility( Playstyle.DEFENSIVE )
|
||||
{
|
||||
|
||||
private val plugin get() = SpeedHG.instance
|
||||
|
||||
override val name: String
|
||||
@@ -357,17 +448,16 @@ class BlackPantherKit : Kit()
|
||||
player: Player,
|
||||
event: PlayerMoveEvent
|
||||
) {
|
||||
// Nur feuern wenn Spieler per Ability in der Luft ist
|
||||
if ( !noFallDamagePlayers.contains( player.uniqueId ) ) return
|
||||
// Nur wenn Spieler nach unten bewegt (fällt)
|
||||
if ( event.to.y >= event.from.y ) return
|
||||
|
||||
val capturedPounceMinFall = pounceMinFall
|
||||
if ( player.fallDistance < capturedPounceMinFall ) return
|
||||
|
||||
val blockBelow = event.to.clone().subtract( 0.0, 0.1, 0.0 ).block
|
||||
if ( !blockBelow.type.isSolid ) return
|
||||
|
||||
// ── Aufprall-AoE ────────────────────────────────────────────────────
|
||||
val impactLoc = event.to.clone()
|
||||
|
||||
// Werte zum Aktivierungszeitpunkt snapshotten
|
||||
val capturedPounceRadius = pounceRadius
|
||||
val capturedPounceDamage = pounceDamage
|
||||
|
||||
@@ -378,8 +468,10 @@ class BlackPantherKit : Kit()
|
||||
|
||||
splashTargets.forEach { it.damage( capturedPounceDamage, player ) }
|
||||
|
||||
impactLoc.world.spawnParticle( Particle.EXPLOSION, impactLoc, 3, 0.5, 0.5, 0.5, 0.0 )
|
||||
impactLoc.world.spawnParticle( Particle.LARGE_SMOKE, impactLoc, 20, 1.0, 0.5, 1.0, 0.05 )
|
||||
// ── Partikel & Sounds ────────────────────────────────────────────────
|
||||
impactLoc.world.spawnParticle( Particle.EXPLOSION, impactLoc, 3, 0.5, 0.5, 0.5, 0.0 )
|
||||
impactLoc.world.spawnParticle( Particle.LARGE_SMOKE, impactLoc, 25, 1.2, 0.5, 1.2, 0.06 )
|
||||
impactLoc.world.spawnParticle( Particle.CRIT, impactLoc, 20, 1.0, 0.3, 1.0, 0.15 )
|
||||
impactLoc.world.playSound( impactLoc, Sound.ENTITY_GENERIC_EXPLODE, 1f, 0.7f )
|
||||
impactLoc.world.playSound( impactLoc, Sound.ENTITY_IRON_GOLEM_HURT, 1f, 0.5f )
|
||||
|
||||
@@ -395,7 +487,8 @@ class BlackPantherKit : Kit()
|
||||
mapOf( "count" to splashTargets.size.toString() ) )
|
||||
)
|
||||
|
||||
noFallDamagePlayers.add( player.uniqueId )
|
||||
// Fallschaden wird vom KitEventDispatcher.onLeapFallDamage unterdrückt
|
||||
// (noFallDamagePlayers.remove() passiert dort, NICHT hier)
|
||||
player.fallDistance = 0f
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ class TridentKit : Kit()
|
||||
val nameKey = if ( playstyle == Playstyle.AGGRESSIVE )
|
||||
"kits.trident.items.trident.aggressive.name"
|
||||
else
|
||||
"kits.trident.item.trident.defensive.name"
|
||||
"kits.trident.items.trident.defensive.name"
|
||||
|
||||
val trident = ItemBuilder( Material.TRIDENT )
|
||||
.name( plugin.languageManager.getDefaultRawMessage( nameKey ) )
|
||||
|
||||
@@ -191,8 +191,8 @@ class VenomKit : Kit()
|
||||
|
||||
AbilityUtils.createBeam(
|
||||
player,
|
||||
player.location,
|
||||
player.eyeLocation.toVector(),
|
||||
player.eyeLocation, // Startpunkt = Augenpunkt
|
||||
player.eyeLocation.direction, // Richtungsvektor aus Blickrichtung
|
||||
Particle.DRAGON_BREATH,
|
||||
7.5, 0.1
|
||||
) { target ->
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.bukkit.Bukkit
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.Sound
|
||||
import org.bukkit.attribute.Attribute
|
||||
import org.bukkit.entity.LivingEntity
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.Event
|
||||
import org.bukkit.event.EventHandler
|
||||
@@ -114,10 +115,16 @@ class GameStateListener : Listener {
|
||||
return
|
||||
}
|
||||
|
||||
// BUG 2 FIX: Kein separater Invis-Whitelist-Block mehr.
|
||||
// Beide States (INVINCIBILITY + INGAME) laufen direkt in pickupBlock —
|
||||
// Map-Protection (Diamant, Eisen) ist bereits oben abgehandelt.
|
||||
pickupBlock( event, player )
|
||||
val isAlwaysPickup = alwaysMaterials.containsKey( block.type )
|
||||
val isInvisOnlyPickup = beforeInvisMaterials.containsKey( block.type )
|
||||
|
||||
when {
|
||||
isAlwaysPickup ->
|
||||
pickupBlock( event, player )
|
||||
|
||||
isInvisOnlyPickup && gameManager.currentState == GameState.INVINCIBILITY ->
|
||||
pickupBlock( event, player )
|
||||
}
|
||||
}
|
||||
|
||||
private fun pickupBlock(
|
||||
@@ -135,6 +142,14 @@ class GameStateListener : Listener {
|
||||
}
|
||||
}
|
||||
|
||||
if ( block.type == Material.CACTUS )
|
||||
{
|
||||
activeCactusBreaker[ player.uniqueId ] = player
|
||||
Bukkit.getScheduler().runTask( plugin ) { ->
|
||||
activeCactusBreaker.remove( player.uniqueId )
|
||||
}
|
||||
}
|
||||
|
||||
event.isCancelled = true
|
||||
|
||||
// BUG 1 FIX: !! entfernt → Elvis mit null-Safe-Fallback auf GENERIC_SOUND.
|
||||
@@ -178,38 +193,54 @@ class GameStateListener : Listener {
|
||||
* Kettenreaktion-Drops bekommen soll.
|
||||
*/
|
||||
private val activeMushroomBreaker: MutableMap<UUID, Player> = ConcurrentHashMap()
|
||||
private val activeCactusBreaker: MutableMap<UUID, Player> = ConcurrentHashMap()
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = false)
|
||||
fun onBlockPhysics(
|
||||
event: BlockPhysicsEvent
|
||||
) {
|
||||
val block = event.block
|
||||
if ( block.type != Material.RED_MUSHROOM &&
|
||||
block.type != Material.BROWN_MUSHROOM ) return
|
||||
|
||||
if ( gameManager.currentState != GameState.INVINCIBILITY &&
|
||||
gameManager.currentState != GameState.INGAME ) return
|
||||
|
||||
// Einen Spieler in der Nähe finden der gerade einen Pilz abbaut
|
||||
val harvester = activeMushroomBreaker.values
|
||||
.firstOrNull { it.location.distanceSquared( block.location ) <= 25.0 }
|
||||
?: return // Keine aktive Spieleraktion — normales Physik-Event, ignorieren
|
||||
|
||||
// Block vor dem Pop einsammeln
|
||||
event.isCancelled = true
|
||||
|
||||
val drops = block.getDrops( harvester.inventory.itemInMainHand, harvester )
|
||||
|
||||
if ( !hasInventorySpace( harvester ) )
|
||||
// ── Pilze (bestehende Logik) ──────────────────────────────────────────
|
||||
if ( block.type == Material.RED_MUSHROOM ||
|
||||
block.type == Material.BROWN_MUSHROOM )
|
||||
{
|
||||
drops.forEach { harvester.world.dropItem( block.location, it ) }
|
||||
}
|
||||
else
|
||||
{
|
||||
drops.forEach { harvester.inventory.addItem( it ) }
|
||||
val harvester = activeMushroomBreaker.values
|
||||
.firstOrNull { it.location.distanceSquared( block.location ) <= 25.0 }
|
||||
?: return
|
||||
|
||||
event.isCancelled = true
|
||||
val drops = block.getDrops( harvester.inventory.itemInMainHand, harvester )
|
||||
|
||||
if ( !hasInventorySpace( harvester ) )
|
||||
drops.forEach { harvester.world.dropItem( block.location, it ) }
|
||||
else
|
||||
drops.forEach { harvester.inventory.addItem( it ) }
|
||||
|
||||
block.type = Material.AIR
|
||||
return
|
||||
}
|
||||
|
||||
block.type = Material.AIR
|
||||
// ── Kakteen (NEU) ─────────────────────────────────────────────────────
|
||||
if ( block.type == Material.CACTUS )
|
||||
{
|
||||
val harvester = activeCactusBreaker.values
|
||||
.firstOrNull { it.location.distanceSquared( block.location ) <= 25.0 }
|
||||
?: return
|
||||
|
||||
event.isCancelled = true
|
||||
val drops = block.getDrops( harvester.inventory.itemInMainHand, harvester )
|
||||
|
||||
if ( !hasInventorySpace( harvester ) )
|
||||
drops.forEach { harvester.world.dropItem( block.location, it ) }
|
||||
else
|
||||
drops.forEach { harvester.inventory.addItem( it ) }
|
||||
|
||||
block.type = Material.AIR
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@@ -404,6 +435,9 @@ class GameStateListener : Listener {
|
||||
event: EntitySpawnEvent
|
||||
) {
|
||||
if ( feastStarted ) return
|
||||
// Item-Drops, XP-Orbs, Projekile tc. NICHT blockieren
|
||||
if ( event.entity !is LivingEntity ) return
|
||||
if ( event.entity is Player ) return
|
||||
event.isCancelled = true
|
||||
}
|
||||
|
||||
|
||||
@@ -89,21 +89,24 @@ class GourmetPerk : Perk(), Listener {
|
||||
|
||||
// ── Soup listener ─────────────────────────────────────────────────────────
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
@EventHandler( priority = EventPriority.MONITOR, ignoreCancelled = true )
|
||||
fun onSoupConsume(
|
||||
event: PlayerInteractEvent
|
||||
) {
|
||||
// Nur Rechtsklick — verhindert Trigger beim Schlagen/Links-Klick
|
||||
if ( !event.action.isRightClick ) return
|
||||
if ( event.hand != EquipmentSlot.HAND ) return
|
||||
|
||||
val player = event.player
|
||||
if ( !activePlayers.contains( player.uniqueId ) ) return
|
||||
|
||||
val item = event.item ?: return
|
||||
if ( item.type != Material.MUSHROOM_STEW ) return
|
||||
// Ursprüngliches Item muss MUSHROOM_STEW gewesen sein
|
||||
val originalItem = event.item ?: return
|
||||
if ( originalItem.type != Material.MUSHROOM_STEW ) return
|
||||
|
||||
// Only fire when the item is actually going to be consumed — i.e. when
|
||||
// the player is not at full hunger (vanilla consumption gate).
|
||||
if ( player.foodLevel >= 20 ) return
|
||||
// Nach SoupListener (HIGHEST) ist der Slot eine Bowl, wenn tatsächlich getrunken
|
||||
val currentItem = player.inventory.getItem( event.hand!! )
|
||||
if ( currentItem.type != Material.BOWL ) return
|
||||
|
||||
val dur = durationTicks
|
||||
player.addPotionEffect( PotionEffect( PotionEffectType.REGENERATION, dur, 0, false, true, true ) )
|
||||
|
||||
@@ -599,29 +599,33 @@ kits:
|
||||
curse_received: '<red>🔮 You have been cursed by a Voodoo player!</red>'
|
||||
ability_charged: '<yellow>⚡ Ability recharged!</yellow>'
|
||||
|
||||
# ── Black Panther ─────────────────────────────────────────────────────────────
|
||||
# FIX: Added clarity that AGGRESSIVE is Push + 12 s Vibranium Fists (6.5 dmg/hit).
|
||||
# DEFENSIVE Wakanda pounce now mentions 3-block fall requirement and crater.
|
||||
# ── BlackPanther (neue Defensive-Leap Fähigkeit aus vorherigem Fix) ─────────
|
||||
blackpanther:
|
||||
name: '<gradient:dark_gray:white><bold>Black Panther</bold></gradient>'
|
||||
# Lore-Zeile für DEF aktualisieren:
|
||||
lore:
|
||||
- ' '
|
||||
- '<dark_gray>[AGG]</dark_gray> <gray>Push nearby enemies, then unleash <yellow>6.5 dmg</yellow> fists for <yellow>12 s</yellow>.</gray>'
|
||||
- '<dark_aqua>[DEF]</dark_aqua> <gray>Fall <yellow>3+ blocks</yellow> onto a foe — <red>AOE damage</red> + crater.</gray>'
|
||||
- '<dark_aqua>[DEF]</dark_aqua> <gray>Activate to <yellow>leap skyward</yellow> — land for <red>AOE impact</red> + crater.</gray>'
|
||||
items:
|
||||
push:
|
||||
name: '<gray>⚡ Vibranium Pulse</gray>'
|
||||
description: 'Knock back all nearby enemies and activate 12 s Vibranium Fist Mode'
|
||||
# NEU — Leap-Item für Defensive:
|
||||
leap:
|
||||
name: '<white>⬆ Wakanda Leap</white>'
|
||||
description: 'Launch skyward — land on enemies for AOE damage + crater (fall damage disabled)'
|
||||
passive:
|
||||
aggressive:
|
||||
name: '<gray>Vibranium Fists</gray>'
|
||||
description: '6.5 bare-hand damage for 12 s after activating Push'
|
||||
defensive:
|
||||
name: '<white>Wakanda Forever!</white>'
|
||||
description: 'Fall from 3+ blocks onto an enemy for AOE damage and a crater impact'
|
||||
description: 'Activate Leap, then land on enemies for AOE damage and a crater'
|
||||
messages:
|
||||
fist_mode_active: '<gray>⚡ Vibranium Fists active for <yellow>12 seconds</yellow>!</gray>'
|
||||
wakanda_impact: '<white>⚡ Wakanda Forever! Hit <yellow><count></yellow> enemy(s)!</white>'
|
||||
# NEU:
|
||||
wakanda_leap: '<white>⬆ Wakanda Forever — brace for impact!</white>'
|
||||
ability_charged: '<yellow>⚡ Ability recharged!</yellow>'
|
||||
|
||||
# ── TheWorld ──────────────────────────────────────────────────────────────────
|
||||
@@ -768,11 +772,12 @@ kits:
|
||||
name: '<aqua>Trident Parry</aqua>'
|
||||
description: '20% chance to parry melee attacks: launch attacker back with Slowness I'
|
||||
messages:
|
||||
dive_launched: '<aqua>⚡ Launched! <yellow><charges></yellow> charge(s) remaining.</aqua>'
|
||||
charges_left: '<aqua>⚡ <yellow><charges></yellow> dive charge(s) left!</aqua>'
|
||||
sequence_done: '<gray>Dive sequence complete.</gray>'
|
||||
parry_success: '<aqua>⚡ Parried!</aqua>'
|
||||
parried_by_victim: '<red>⚡ Your attack was parried!</red>'
|
||||
dive_launched: '<aqua>⚡ Launched! Brace for impact!</aqua>'
|
||||
parry_success: '<aqua>🛡 Parried! Attacker bounced back!</aqua>'
|
||||
parried_by_victim: '<red>Your attack was parried!</red>'
|
||||
charges_left: '<aqua>⚡ <yellow><charges></yellow> dive charge(s) remaining!</aqua>'
|
||||
sequence_done: '<gray>Sequence complete — recharging...</gray>'
|
||||
ability_charged: '<yellow>⚡ Ability recharged!</yellow>'
|
||||
|
||||
# ── Blitzcrank ────────────────────────────────────────────────────────────────
|
||||
blitzcrank:
|
||||
|
||||
Reference in New Issue
Block a user