wave spawning based on wave caps in WaveDefinition

This commit is contained in:
Tooze 2026-05-16 23:54:35 -04:00
parent f3e84836c6
commit 380bd6e0fd
10 changed files with 53 additions and 26 deletions

View file

@ -1,5 +1,6 @@
package content.minigame.barbassault
import content.minigame.barbassault.arena.Npcs.dropPenanceEggCluster
import content.minigame.barbassault.bots.BarbassBot
import content.minigame.barbassault.lobby.BarbassaultLobby
import core.api.*
@ -21,7 +22,7 @@ class BarbassDevHelper : CommandSet(Privilege.ADMIN) {
return@define
}
define ("setbarbwave") { player,args ->
player.setAttribute("/save:barbass:wave", args[1].toIntOrNull())
player.setBarbWave(args[1].toInt())
return@define
}
@ -45,7 +46,18 @@ class BarbassDevHelper : CommandSet(Privilege.ADMIN) {
define("defgear"){ player,_->
player.equipment.replace(Item(954),2)
return@define
}
define("eggloot"){ player,_->
dropPenanceEggCluster(player)
return@define
}
define("spawnwave"){ player,_->
player.baSession?.spawnNpcWave()
return@define
}
define("spawnwaveforce"){ player,_->
player.baSession?.spawnNpcWave(true)
return@define
}
define("babot"){ player,_->
if (babotcount >= 25) {

View file

@ -67,17 +67,6 @@ class BarbassaultGameArea : InteractionListener, MapArea {
EggCannonLoc(EggCannonSide.WEST, 21, 34, 0, Direction.SOUTH),
EggCannonLoc(EggCannonSide.EAST, 40, 34, 0, Direction.SOUTH) )
enum class pennanceNPC { RUNNER, HEALER, FIGHTER, RANGER }
data class npcSpawnLoc(val tunnel:pennanceNPC, val x: Int,val y: Int,val z: Int,val direction: Direction)
val npcSpawns: List<npcSpawnLoc> = listOf(
npcSpawnLoc(pennanceNPC.RUNNER,42,45,0,Direction.SOUTH),
npcSpawnLoc(pennanceNPC.HEALER,36,46,0,Direction.SOUTH),
npcSpawnLoc(pennanceNPC.FIGHTER,24,46,0,Direction.SOUTH),
npcSpawnLoc(pennanceNPC.RANGER,36,46,0,Direction.SOUTH),
)
override fun defineAreaBorders(): Array<ZoneBorders> {
//block standard teleports.
BarbassaultTut.BarbassTutNPCs.forEach {

View file

@ -11,7 +11,6 @@ import content.minigame.barbassault.getBarbWave
import content.minigame.barbassault.lobby.*
import core.api.*
import core.game.node.entity.Entity
import core.game.node.entity.combat.CombatStyle
import core.game.node.entity.impl.PulseManager
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
@ -24,7 +23,6 @@ import core.game.world.map.Direction
import core.game.world.map.Location
import core.game.world.map.build.DynamicRegion
import core.game.world.map.zone.*
import core.game.world.update.flag.context.Graphics
import core.tools.Log
import core.tools.secondsToTicks
import core.tools.ticksToSeconds
@ -35,6 +33,7 @@ import org.rs09.consts.NPCs
enum class BarbassaultState { PARTY_CREATION, STARTING, IN_ARENA,FORFEIT, COMPLETE,DEATH, END }
data class PenanceNpcTunnel(val type:PenanceType, val x: Int,val y: Int,val z: Int,val direction: Direction) { fun toLocation(): Location = Location(x, y, z) }
class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutListener, MapArea {
//constructor(region: DynamicRegion, activity: BarbassaultActivity) : this(activity) {this.region = region; this.base = region.baseLocation}
@ -45,6 +44,13 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutLi
var state: BarbassaultState = BarbassaultState.PARTY_CREATION
val sessionNpcs = mutableListOf<NPC>()
var currentNPCCount = SpawnCaps(0,0,0,0)
val npcTunnel: List<PenanceNpcTunnel> = listOf(
PenanceNpcTunnel(PenanceType.RUNNER,42,46,0,Direction.SOUTH),
PenanceNpcTunnel(PenanceType.HEALER,36,47,0,Direction.SOUTH),
PenanceNpcTunnel(PenanceType.FIGHTER,24,46,0,Direction.SOUTH),
PenanceNpcTunnel(PenanceType.RANGER,18,46,0,Direction.SOUTH),
)
val BAgroundItems = mutableListOf<GroundItem>()
val eggHopper = EggCannon.EggHopper()
var eggCannonNpcWest: NPC? = null
@ -136,7 +142,6 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutLi
Pulser.submit(countdownPulse!!)
}
private fun InitEvents(){
eventBus.register(BarbAssEvent.NPCDied::class.java) { event ->
val tracker = scoreManager.trackerFor(event.killer)
val npcRoleType = event.npc.getAttribute<BarbRole>("barbass-role")
@ -163,10 +168,29 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutLi
tracker.healerStats.wrongPoisonUsed++
}
}
fun forfeit(){
state = BarbassaultState.FORFEIT
fun spawnNpcWave(force: Boolean = false) {
val caps = currentWaveDefinition.caps
val npcIds = currentWaveDefinition.npcIds
tryPenanceSpawn(PenanceType.RANGER, currentNPCCount.rangers, caps.rangers, npcIds, force) { currentNPCCount.rangers++ }
tryPenanceSpawn(PenanceType.FIGHTER, currentNPCCount.fighters, caps.fighters, npcIds,force) { currentNPCCount.fighters++ }
tryPenanceSpawn(PenanceType.RUNNER, currentNPCCount.runners, caps.runners,npcIds,force) { currentNPCCount.runners++ }
tryPenanceSpawn(PenanceType.HEALER, currentNPCCount.healers, caps.healers, npcIds,force) { currentNPCCount.healers++ }
}
fun tryPenanceSpawn(type: PenanceType,current: Int,cap: Int,npcIds: Map<PenanceType, Int>, force: Boolean, increment: () -> Unit) {
if (!force && current >= cap) { return }
val npcId = npcIds[type] ?: return
val spawn = npcTunnel.firstOrNull { it.type == type } ?: return
var thisNpc = sessionNPCSpawn(npcId, base.transform(30,31,0), spawn.direction)
thisNpc?.location = base.transform(spawn.toLocation())
increment()
}
fun forfeit(){ state = BarbassaultState.FORFEIT }
fun isInBarbAssaultGame() = state == BarbassaultState.IN_ARENA
fun endGame(endReason: String){
@ -309,7 +333,6 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutLi
fun sessionNPCSpawn(id: Int, location: Location, direction: Direction, vararg objects: Any): NPC? {
val npc = NPC.create(id, location, direction, *objects)
npc.init()
sessionNpcs.add(npc)
return npc
}

View file

@ -60,7 +60,7 @@ class PenanceFighterNPC : NPCBehavior(*PENANCE_FIGHTER_IDS.toIntArray()) {
self.isWalks = true
// self.isNeverWalks = false
self.properties.isNPCWalkable = false
self.walkRadius = 64
self.walkRadius = 24
self.isAggressive = true
self.isRespawn = false

View file

@ -29,6 +29,8 @@ class PenanceHealerNPC : NPCBehavior(*PENANCE_HEALER_IDS.toIntArray()) {
override fun onCreation (self: NPC) {
self.setAttribute("barbass-role", BarbRole.HEALER)
self.isWalks = true
self.walkRadius = 24
}
//sendMessage(player,"that's the wrong type of poisoned food to use! Penalty!")

View file

@ -8,8 +8,9 @@ import core.game.node.entity.player.Player
import core.game.world.map.RegionManager
import org.rs09.consts.Items
fun dropPenanceEggCluster(killer: Player, npc: NPC) {
val tiles = npc.dropLocation.get3x3Tiles().shuffled()
fun dropPenanceEggCluster(killer: Player, npc: NPC? = null) {
val center = npc?.dropLocation ?: killer.location
val tiles = center.get3x3Tiles().shuffled()
val eggs = listOf( Items.RED_EGG_10532, Items.RED_EGG_10532,
Items.BLUE_EGG_10533, Items.BLUE_EGG_10533,

View file

@ -50,7 +50,7 @@ class PenanceRangerNPC : NPCBehavior(*PENANCE_RANGER_IDS.toIntArray()) {
self.setAttribute("agg_radius",6)
self.isWalks = true
self.isNeverWalks = false
self.walkRadius = 64
self.walkRadius = 24
self.isAggressive = true
self.definition.combatGraphics[1] = Graphics(866, 25, 0)
self.setAttribute("barbass-role",BarbRole.ATTACKER)

View file

@ -36,7 +36,7 @@ class PenanceRunnerNPC : NPCBehavior(*PENANCE_RUNNER_IDS.toIntArray()) {
}
override fun onCreation(self: NPC) {
self.isWalks = true
self.walkRadius = 22
self.walkRadius = 24
self.destinationFlag
self.setAttribute("barbass-role", BarbRole.DEFENDER)

View file

@ -12,7 +12,7 @@ fun getWaveDefinition(index: Int): WaveDefinition {
data class WaveDefinition( val caps: SpawnCaps, val npcIds: Map<PenanceType, Int> )
enum class PenanceType { HEALER, RUNNER, FIGHTER, RANGER, QUEEN }
data class SpawnCaps(val rangers: Int, val fighters: Int, val runners: Int, val healers: Int)
data class SpawnCaps(var rangers: Int, var fighters: Int, var runners: Int, var healers: Int)
private val waves = listOf(
WaveDefinition( //Wave tut
SpawnCaps(rangers = 1, fighters = 1, runners = 1, healers = 1),

View file

@ -232,7 +232,7 @@ class EggCannon : ComponentPlugin() {
val target = findClosestTargetNPCIDFromNPC(npcId, eggCannon as NPC ,14)
val hopper = player.baSession?.eggHopper ?: return
if (target == null) { sendDialogueLines(player,"There are no targetable Penance ${type.name} within firing range.") ;return}
if (target == null) { sendDialogueLines(player,"There are no targetable Penance ${type.name.lowercase().replaceFirstChar { it.uppercase() }} within firing range.") ;return}
if (!eggType.tryConsume(hopper)) {
sendMessage(player, "There are no ${eggType.name.lowercase()} eggs in the hopper.")
return