From d76f0bb8e131fbf9f301e64ad3201b4fc9cc98b3 Mon Sep 17 00:00:00 2001 From: Tooze Date: Mon, 20 Apr 2026 22:32:41 -0400 Subject: [PATCH] Egg Cannon Fires! --- .../barbassault/arena/BarbassaultGameArea.kt | 16 --- .../barbassault/arena/BarbassaultSession.kt | 20 ++-- .../barbassault/arena/Npcs/PenanceHelper.kt | 34 ++++-- .../barbassault/arena/scenery/EggHopper.kt | 101 +++++++++--------- 4 files changed, 88 insertions(+), 83 deletions(-) diff --git a/Server/src/main/content/minigame/barbassault/arena/BarbassaultGameArea.kt b/Server/src/main/content/minigame/barbassault/arena/BarbassaultGameArea.kt index 0cf3aa7ef..70c43f04e 100644 --- a/Server/src/main/content/minigame/barbassault/arena/BarbassaultGameArea.kt +++ b/Server/src/main/content/minigame/barbassault/arena/BarbassaultGameArea.kt @@ -369,22 +369,6 @@ object BarbAssaultCombat { } } -object BAGraphics { - - const val GREEN_LARGE_EXPLOSION_867 = 867 - const val RED_LARGE_EXPLOSION_868 = 868 - const val BLUE_LARGE_EXPLOSION_869 = 869 - - const val GREEN_EGG_BREAK_873 = 873 - const val RED_EGG_BREAK_874 = 874 - const val BLUE_EGG_BREAK_875 = 875 - - const val PENANCE_HEALER_BAD_BREATH_863 = 863 - const val PENANCE_HEALER_GOOD_BREATH_864 = 864 - - const val GREEN_LARGE_EXPLOSION2_876 = 876 - -} diff --git a/Server/src/main/content/minigame/barbassault/arena/BarbassaultSession.kt b/Server/src/main/content/minigame/barbassault/arena/BarbassaultSession.kt index 4ef1fa0b4..2b893eaa7 100644 --- a/Server/src/main/content/minigame/barbassault/arena/BarbassaultSession.kt +++ b/Server/src/main/content/minigame/barbassault/arena/BarbassaultSession.kt @@ -37,12 +37,13 @@ import org.rs09.consts.NPCs enum class BarbassaultState { PARTY_CREATION, STARTING, IN_ARENA,FORFEIT, COMPLETE,DEATH, END } class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutListener, MapArea { - constructor(region: DynamicRegion, activity: BarbassaultActivity) : this(activity) {this.region = region; this.base = region.baseLocation} + //constructor(region: DynamicRegion, activity: BarbassaultActivity) : this(activity) {this.region = region; this.base = region.baseLocation} lateinit var region: DynamicRegion lateinit var base: Location - var currentWave = 1 - var state: BarbassaultState = BarbassaultState.PARTY_CREATION + lateinit var currentWaveDefinition: WaveDefinition lateinit var team: BarbTeam + + var state: BarbassaultState = BarbassaultState.PARTY_CREATION val sessionNpcs = mutableListOf() val BAgroundItems = mutableListOf() val eggHopper = EggHopper.EggHopper() @@ -50,14 +51,15 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutLi var eggCannonNpcEast: NPC? = null val scoreManager = BarbScoreManager() val eventBus = BarbAssEventBus() - val npcCaps = SpawnCaps(4,4,2,2)//wave 1 - private val countDoown = if(GameWorld.settings?.isDevMode == true) 4 else 60 + + private val countDoown = if(GameWorld.settings?.isDevMode == true) 10 else 60 private var countdownPulse: Pulse? = null fun beginStartingPhase(quickStart: Boolean = false) { if (state != BarbassaultState.PARTY_CREATION) return state = BarbassaultState.STARTING + currentWaveDefinition = getWaveDefinition(team.wave) createArena() startCountdown(quickStart) } @@ -83,7 +85,7 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutLi registerLogoutListener(player, "ba-logout") { handleLogout(player) } } - GameWorld.Pulser.submit(GamePulse()) + Pulser.submit(GamePulse()) } fun endSession() { @@ -302,11 +304,7 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutLi zone.cleanItems(player,ALL_BARBASS_ITEMS) clearLogoutListener(player, "ba-logout") player.fullRestore() - destroyArena() - } - fun getMonstersForWave(){ - } fun sessionNPCSpawn(id: Int, location: Location, direction: Direction, vararg objects: Any): NPC? { val npc = NPC.create(id, location, direction, *objects) @@ -318,7 +316,7 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutLi fun spawnEggCannons() { eggCannonNpcWest = sessionNPCSpawn( NPCs.EGG_LAUNCHER_5026, base.transform(21, 34, 0), Direction.NORTH ) //eggCannonNpcWest?. - if (currentWave == 10) return + if (team.wave == 10) return eggCannonNpcEast = sessionNPCSpawn( NPCs.EGG_LAUNCHER_5026, base.transform(40, 34, 0), Direction.NORTH ) } diff --git a/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceHelper.kt b/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceHelper.kt index 7d92835fb..ff642747e 100644 --- a/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceHelper.kt +++ b/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceHelper.kt @@ -2,7 +2,6 @@ package content.minigame.barbassault.arena.Npcs import content.minigame.barbassault.baSession -import core.api.hasLineOfSight import core.api.produceGroundItem import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player @@ -34,7 +33,6 @@ fun dropPenanceEggCluster(killer: Player, npc: NPC) { /** * Finds the closest visible player to the given NPC within a specified range. - * Filters out invisible players and those without line of sight. * * @param npc The NPC used as the search origin. * @param range Maximum distance to search for players. @@ -46,7 +44,6 @@ fun findClosestPlayerFromNPC(npc: NPC,range:Int = 14): Player? { for (player in RegionManager.getLocalPlayers(npc, range)) { if (player.isInvisible) continue - if (!hasLineOfSight(npc, player)) continue val dist = npc.location.getDistance(player.location) if (dist < bestDistance) { @@ -59,20 +56,18 @@ fun findClosestPlayerFromNPC(npc: NPC,range:Int = 14): Player? { /** * Finds the closest NPC matching the given target NPC within a range, - * ensuring there is line of sight between the source NPC and the target. * * @param targetNPC The specific NPC being searched for. * @param npc The source NPC performing the search. * @param range Maximum search radius. * @return The closest matching NPC if found and visible, otherwise null. */ -fun findClosestTargetNPCFromNPC(targetNPC:NPC,npc: NPC,range:Int = 14): NPC? { +fun findClosestTargetNPCIDFromNPC(targetNPC: Int?, npc: NPC, range: Int = 14): NPC? { var closest: NPC? = null var bestDistance = Double.MAX_VALUE for (foundNpc in RegionManager.getLocalNpcs(npc, range)) { - if (targetNPC != foundNpc) continue - if (!hasLineOfSight(npc, foundNpc)) continue + if (targetNPC != foundNpc.id) continue val dist = npc.location.getDistance(foundNpc.location) if (dist < bestDistance) { @@ -97,7 +92,6 @@ fun findClosestNPCIDFromPlayer(player: Player, targetNPC: Int, range: Int = 14): for (npc in RegionManager.getLocalNpcs(player, range)) { if (npc.id != targetNPC) continue - if (!hasLineOfSight(player, npc)) continue val dist = player.location.getDistance(npc.location) if (dist < bestDistance) { @@ -108,4 +102,28 @@ fun findClosestNPCIDFromPlayer(player: Player, targetNPC: Int, range: Int = 14): return closest } +object BAGraphics { + + const val GREEN_LARGE_EXPLOSION_867 = 867 + const val RED_LARGE_EXPLOSION_868 = 868 + const val BLUE_LARGE_EXPLOSION_869 = 869 + + const val GREEN_EGG_BREAK_873 = 873 + const val RED_EGG_BREAK_874 = 874 + const val BLUE_EGG_BREAK_875 = 875 + + const val PENANCE_HEALER_BAD_BREATH_863 = 863 + const val PENANCE_HEALER_GOOD_BREATH_864 = 864 + + const val GREEN_LARGE_EXPLOSION2_876 = 876 + const val RED_EGG_EXPLOSION_975 = 975 + const val GREEN_EGG_PROJECTILE_977 = 977 + const val RED_EGG_PROJECTILE_978 = 978 + const val Blue_EGG_PROJECTILE_978 = 979 + const val YELLOW_EGG_PROJECTILE_980 = 980 + const val STUNN_BIRDYS_981 = 981 + + +} + diff --git a/Server/src/main/content/minigame/barbassault/arena/scenery/EggHopper.kt b/Server/src/main/content/minigame/barbassault/arena/scenery/EggHopper.kt index c339faac7..df4fb663e 100644 --- a/Server/src/main/content/minigame/barbassault/arena/scenery/EggHopper.kt +++ b/Server/src/main/content/minigame/barbassault/arena/scenery/EggHopper.kt @@ -1,17 +1,23 @@ package content.minigame.barbassault.arena.scenery import content.minigame.barbassault.BarbRole +import content.minigame.barbassault.arena.Npcs.BAGraphics.Blue_EGG_PROJECTILE_978 +import content.minigame.barbassault.arena.Npcs.BAGraphics.GREEN_EGG_PROJECTILE_977 +import content.minigame.barbassault.arena.Npcs.BAGraphics.RED_EGG_PROJECTILE_978 import content.minigame.barbassault.arena.Npcs.findClosestNPCIDFromPlayer -import content.minigame.barbassault.arena.Npcs.findClosestTargetNPCFromNPC +import content.minigame.barbassault.arena.Npcs.findClosestTargetNPCIDFromNPC +import content.minigame.barbassault.arena.PenanceType import content.minigame.barbassault.baSession import core.api.* import core.game.component.CloseEvent import core.game.component.Component import core.game.component.ComponentDefinition import core.game.component.ComponentPlugin +import core.game.node.entity.Entity import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.game.node.item.Item +import core.game.world.update.flag.context.Animation import core.plugin.Initializable import core.plugin.Plugin import org.rs09.consts.Items @@ -88,6 +94,11 @@ class EggHopper : ComponentPlugin() { fun consumeBlue(): Boolean { if (blue <= 0) return false; blue--; return true } fun consumeYellow(): Boolean { if (yellow <= 0) return false; yellow--; return true } } + enum class EggType( val consume: EggHopper.() -> Boolean, val action: String,val key: String) { + GREEN({ consumeGreen() }, "poison","green"), RED({ consumeRed() }, "explosive", "red"), BLUE({ consumeBlue() }, "stun", "blue"); + fun tryConsume(hopper: EggHopper): Boolean = hopper.consume() + } + override fun newInstance(arg: Any?): Plugin { ComponentDefinition.forId(EggTurret.ID).plugin = this ComponentDefinition.forId(EggTurret.ID).isWalkable = false; @@ -122,49 +133,33 @@ class EggHopper : ComponentPlugin() { } return true } - val PENANCE_HEALER_IDS = listOf( - NPCs.PENANCE_HEALER_5245, - NPCs.PENANCE_HEALER_5246 - ) - fun shootNormalEggs(button: Int,player: Player?) { + + fun shootNormalEggs(button: Int, player: Player?) { player ?: return - val eggHopper = player.baSession?.eggHopper - val penanceSets = listOf( - "Penance Healer" to EggTurret.pHealerBtns, // PENANCE_HEALER_IDS - "Penance Runner" to EggTurret.pRunnerBtns, // PENANCE_RUNNER_IDS - "Penance Fighter" to EggTurret.pFighterBtns, // PENANCE_FIGHTER_IDS - "Penance Ranger" to EggTurret.pRangerBtns // PENANCE_RANGER_IDS - ) - for ((name, colors) in penanceSets) { - when(button) { - colors.green -> { - if (!eggHopper?.consumeGreen()!!) { - sendMessage(player, "There are no green eggs in the hopper.") - return - } - sendMessage(player, "Shoot poison at $name."); - //fireEgg(player: Player,npc: NPC) - return - } - colors.red -> { - if (!eggHopper?.consumeRed()!!) { - sendMessage(player, "There are no red eggs in the hopper.") - return - } - sendMessage(player, "Shoot Explosive at $name.") - return - } - colors.blue -> { - if (!eggHopper?.consumeBlue()!!) { - sendMessage(player, "There are no blue eggs in the hopper.") - return - } - sendMessage(player, "Shoot Stun at $name.") - return - } + val hopper = player.baSession?.eggHopper ?: return + + val (type, eggType) = listOf( + PenanceType.HEALER to EggTurret.pHealerBtns, + PenanceType.RUNNER to EggTurret.pRunnerBtns, + PenanceType.FIGHTER to EggTurret.pFighterBtns, + PenanceType.RANGER to EggTurret.pRangerBtns + ).firstNotNullOfOrNull { (type, colors) -> + when (button) { + colors.GREEN -> type to EggType.GREEN + colors.RED -> type to EggType.RED + colors.BLUE -> type to EggType.BLUE + else -> null } - updateCannonUI(player) + } ?: return + + if (!eggType.tryConsume(hopper)) { + sendMessage(player, "There are no ${eggType.key} eggs in the hopper.") + return } + + sendMessage(player, "Shoot ${eggType.action} at $type.") + fireEgg(player, type, eggType) + updateCannonUI(player) } fun updateCannonUI(player: Player?){ @@ -173,7 +168,7 @@ class EggHopper : ComponentPlugin() { val penances = listOf( EggTurret.pHealer, EggTurret.pRunner, EggTurret.pRanger, EggTurret.pFighter ) penances.forEach { penance -> - val colors = listOf( "green" to penance.green,"red" to penance.red, "blue" to penance.blue) + val colors = listOf( "green" to penance.GREEN,"red" to penance.RED, "blue" to penance.BLUE) colors.forEach { (colorName, componentId) -> val value = when(colorName) { "green" -> eggHopper.green @@ -229,6 +224,7 @@ class EggHopper : ComponentPlugin() { sendMessage(player,"You load the hopper.") removeItem(player, Item(itemId, added)) } + //if hopper full messsage "You can't load any more $eggType eggs." } fun showEggHopperCount(player: Player?){ player ?: return @@ -240,12 +236,21 @@ class EggHopper : ComponentPlugin() { } - fun fireEgg(player: Player,npc: NPC){ - val session = player.baSession + //error message CHATBOX "[bold]all of the _PENANCE_ have been killed!" + fun fireEgg(player: Player, type: PenanceType, eggType: EggType){ + val npcId = player.baSession?.currentWaveDefinition?.npcIds?.get(type) val eggCannon = findClosestNPCIDFromPlayer(player,NPCs.EGG_LAUNCHER_5026,2) - val target = findClosestTargetNPCFromNPC(npc, eggCannon as NPC ) - // - eggCannon.attack(target) + val target = findClosestTargetNPCIDFromNPC(npcId, eggCannon as NPC ,14) + + if (target == null) {sendMessage(player,"There are no targetable Penance ${type.name} within firing range.") ;return} + //queueScript { } + player.animate(Animation(5428)) + eggCannon.face(target) + eggCannon.animate(Animation(5426)) + + if (eggType.key == "green" ){ spawnProjectile(eggCannon,target as Entity,GREEN_EGG_PROJECTILE_977) } + if (eggType.key == "red" ){ spawnProjectile(eggCannon,target as Entity,RED_EGG_PROJECTILE_978) } + if (eggType.key == "blue" ){ spawnProjectile(eggCannon,target as Entity,Blue_EGG_PROJECTILE_978) } } } @@ -253,7 +258,7 @@ class EggHopper : ComponentPlugin() { -data class EggColors(val green: Int, val red: Int, val blue: Int) +data class EggColors(val GREEN: Int, val RED: Int, val BLUE: Int) object EggTurret { const val ID = 495 val pHealer = EggColors(57, 58, 59)