Pennance Spawns can be delayed by Blocked tunnels

This commit is contained in:
Tooze 2026-05-22 17:38:00 -04:00
parent b361c2b2c1
commit 832e52904c
4 changed files with 77 additions and 30 deletions

View file

@ -57,11 +57,11 @@ class BADevHelper : CommandSet(Privilege.ADMIN) {
return@define
}
define("spawnwave"){ player,_->
getBASession(player)?.spawnNpcWave()
getBASession(player)?.forceWaveSpawn()
return@define
}
define("spawnwaveforce"){ player,_->
getBASession(player)?.spawnNpcWave(true)
getBASession(player)?.forceWaveSpawn(true)
return@define
}
define("babot"){ player,_->

View file

@ -101,13 +101,16 @@ class BarbassaultArenaListener : InteractionListener {
}
on(Scenery.PENANCE_CAVE_20237, IntType.SCENERY, "block") { player, node ->
//restrict to role
if (hasTools(player)) { return@on true }
playerChangeScenery(player,5417,node,Scenery.PENANCE_CAVE_20238,4)
getBASession(player)?.setCaveBlocked(node,true)
return@on true
}
on(Scenery.PENANCE_CAVE_20238, IntType.SCENERY, "demolish") { player, node ->
playerChangeScenery(player,5418,node,Scenery.PENANCE_CAVE_20239,5)
getBASession(player)?.setCaveBlocked(node,false)
return@on true
}

View file

@ -20,6 +20,7 @@ import content.minigame.barbassault.getBAWave
import content.minigame.barbassault.lobby.*
import content.minigame.barbassault.lobby.BALobby.Companion.waveLobbies
import core.api.*
import core.game.node.Node
import core.game.node.entity.Entity
import core.game.node.entity.impl.PulseManager
import core.game.node.entity.npc.NPC
@ -43,7 +44,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) }
data class PenanceNpcTunnel( val type: PenanceType, val caveLocation: Location, val spawnOffset: Location, val direction: Direction)
data class ArenaSpawnItems(val id: Int, val location: Location)
class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, MapArea {
@ -57,7 +58,12 @@ class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, M
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,47,0,Direction.SOUTH), PenanceNpcTunnel(PenanceType.RANGER,18,46,0,Direction.SOUTH) )
var npcTunnel: List<PenanceNpcTunnel> = listOf(
PenanceNpcTunnel(PenanceType.RUNNER,location(0,0,0),location(42,46,0),Direction.SOUTH),
PenanceNpcTunnel(PenanceType.HEALER,location(0,0,0),location(36,47,0),Direction.SOUTH),
PenanceNpcTunnel(PenanceType.FIGHTER,location(0,0,0),location(24,47,0),Direction.SOUTH),
PenanceNpcTunnel(PenanceType.RANGER,location(0,0,0),location(18,46,0),Direction.SOUTH) )
private val caveBlocked = mutableMapOf<PenanceType, Boolean>()
val BAgroundItems = mutableListOf<BAGroundSpawn>()
val arenaSpawnItems: List<ArenaSpawnItems> = listOf(ArenaSpawnItems(Items.HAMMER_2347,location(32,42,0)),ArenaSpawnItems(Items.LOGS_11760,location(30,46,0)),ArenaSpawnItems(Items.LOGS_11760,location(29,47,0)))
@ -65,6 +71,7 @@ class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, M
val eggHopper = EggCannon.EggHopper()
var eggCannonNpcWest: NPC? = null
var eggCannonNpcEast: NPC? = null
val scoreManager = BarbScoreManager()
val eventBus = BarbAssEventBus()
@ -72,6 +79,7 @@ class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, M
private var countdownPulse: Pulse? = null
fun beginStartingPhase(quickStart: Boolean = false) {
if (state != BarbassaultState.PARTY_CREATION) return
state = BarbassaultState.STARTING
@ -179,26 +187,40 @@ class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, M
tracker.healerStats.wrongPoisonUsed++
}
}
fun setCaveBlocked(node: Node, blocked: Boolean) {
val tunnel = npcTunnel.firstOrNull { t -> base.transform(t.caveLocation) == node.location } ?: return
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++ }
if (blocked) {
caveBlocked[tunnel.type] = true
} else {
caveBlocked.remove(tunnel.type)
}
}
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
fun isCaveBlocked(type: PenanceType): Boolean {
return caveBlocked[type] == true
}
fun forceWaveSpawn(force: Boolean = false){
tryPenanceSpawn(PenanceType.RANGER,force)
tryPenanceSpawn(PenanceType.FIGHTER,force)
tryPenanceSpawn(PenanceType.RUNNER,force)
tryPenanceSpawn(PenanceType.HEALER,force)
}
fun tryPenanceSpawn(type: PenanceType, force: Boolean = false): Boolean {
val current = currentNPCCount[type]
val cap = currentWaveDefinition.caps[type]
val npcId = currentWaveDefinition.npcIds[type] ?: return false
var thisNpc = sessionNPCSpawn(npcId, location(30,31,0), spawn.direction)
thisNpc?.location = base.transform(spawn.toLocation())
thisNpc?.setAttribute(BA_SESSION_KEY, this)
increment()
if (!force && current >= cap) return false
val spawn = npcTunnel.firstOrNull { it.type == type } ?: return false
val npc = sessionNPCSpawn(npcId, location(30, 31, 0), spawn.direction)
npc?.location = base.transform(spawn.spawnOffset)
npc?.setAttribute(BA_SESSION_KEY, this)
currentNPCCount[type]++
return isCaveBlocked(type)
}
fun tryGroundItemSpawn(){
@ -274,16 +296,21 @@ class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, M
private var roleCallTicks = baseCallTicks
private var baseSpawnTicks = secondsToTicks(6)
private var waveSpawnTicks = baseSpawnTicks
private var waveSpawnTicks = SpawnCaps( baseSpawnTicks, baseSpawnTicks, baseSpawnTicks, baseSpawnTicks )
private var groundSpawnTicks = baseSpawnTicks
override fun pulse(): Boolean {
when(state){
BarbassaultState.IN_ARENA -> {
eventBus.processEvents()
roleCallTicks--; waveSpawnTicks--; groundSpawnTicks--
if (roleCallTicks <= 0) { rollNewRoleCalls(); roleCallTicks = baseCallTicks }
if (waveSpawnTicks <= 0 ){ spawnNpcWave(); waveSpawnTicks = baseSpawnTicks }
roleCallTicks--; groundSpawnTicks--
if (roleCallTicks <= 0) { rollNewRoleCalls(); roleCallTicks = baseCallTicks }
for (type in PenanceType.values()) {
waveSpawnTicks[type]--
if (waveSpawnTicks[type] <= 0) { waveSpawnTicks[type] = if (tryPenanceSpawn(type)) baseSpawnTicks * 2 else baseSpawnTicks
}
}
}
BarbassaultState.FORFEIT -> { endGame("left"); return true }
@ -356,9 +383,8 @@ class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, M
override fun areaEnter(entity: Entity) {
log(this::class.java, Log.FINE, "ENTERED Barbassault Arena")
val player = entity as? Player ?: return
log(this::class.java, Log.FINE, "ENTERED Barbassault Arena")
val waveNum = getBAWave(player)
val wornIconId = getItemFromEquipment(player, EquipmentSlot.CAPE)?.id
val interfaceId = getIconInterfaceId(wornIconId ?: -1)
@ -372,10 +398,10 @@ class BarbassaultSession( val activity: BAActivity ? = null) :LogoutListener, M
}
override fun areaLeave(entity: Entity, logout: Boolean) {
log(this::class.java, Log.FINE, "LEFT Barbassault Arena")
super.areaLeave(entity, logout)
var player = entity as Player
//exitMiniGame(player)
val player = entity as? Player ?: return
log(this::class.java, Log.FINE, "LEFT Barbassault Arena")
removeTimer(player, "teleblock")
zone.cleanItems(player,ALL_BARBASS_ITEMS)
clearLogoutListener(player, "ba-logout")

View file

@ -12,7 +12,25 @@ 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(var rangers: Int, var fighters: Int, var runners: Int, var healers: Int)
data class SpawnCaps(var rangers: Int, var fighters: Int, var runners: Int, var healers: Int) {
operator fun get(type: PenanceType): Int =
when (type) {
PenanceType.RANGER -> rangers
PenanceType.FIGHTER -> fighters
PenanceType.RUNNER -> runners
PenanceType.HEALER -> healers
else -> {0}
}
operator fun set(type: PenanceType, value: Int) {
when (type) {
PenanceType.RANGER -> rangers = value
PenanceType.FIGHTER -> fighters = value
PenanceType.RUNNER -> runners = value
PenanceType.HEALER -> healers = value
else -> {0}
}
}
}
private val waves = listOf(
WaveDefinition( //Wave tut
SpawnCaps(rangers = 1, fighters = 1, runners = 1, healers = 1),