Egg Cannon Fires!

This commit is contained in:
Tooze 2026-04-20 22:32:41 -04:00
parent ab0c3c81b2
commit d76f0bb8e1
4 changed files with 88 additions and 83 deletions

View file

@ -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
}

View file

@ -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<NPC>()
val BAgroundItems = mutableListOf<GroundItem>()
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 )
}

View file

@ -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
}

View file

@ -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<Any> {
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)