A little bit all over.

This commit is contained in:
Tooze 2026-02-08 23:10:34 -05:00
parent 2bb7a9812c
commit c646238715
10 changed files with 264 additions and 26 deletions

View file

@ -32,6 +32,11 @@ class BarbassDevHelper : CommandSet(Privilege.ADMIN) {
define("barbqueen"){ player,_->
player.teleport(Location.create(1885, 5403, 0))
}
//nods to the defender guide I found, as "suggested" defender gear.
define("defgear"){ player,_->
player.equipment.replace(Item(954),2)
}
define("hch"){ player,args->
val chId = args[1].toIntOrNull()

View file

@ -2,6 +2,7 @@ package content.minigame.barbassault.arena
import content.minigame.barbassault.lobby.BarbTeam
import core.game.node.entity.player.Player
//https://www.youtube.com/watch?v=OJ2BDEM03Dw
class BarbScoreManager {
@ -20,11 +21,12 @@ class BarbScoreManager {
fun personal(player: Player, caps: SpawnCaps): RoleScore {
return trackerFor(player).toScoreboard(caps)
}
fun team(team: BarbTeam, caps: SpawnCaps): RoleScore {
//val caps = session.currentWaveCaps()
//val teamScore = session.scoreManager.team(caps)
fun team(caps: SpawnCaps): RoleScore {
var total = RoleScore.ZERO
for (player in team.allPlayers()) {
total = total.add(trackerFor(player).toScoreboard(caps))
for (tracker in allTrackers()) {
total = total.add(tracker.toScoreboard(caps))
}
return total
}
@ -46,9 +48,19 @@ data class ScoreTracker(var attackerStats: AttackerStats = AttackerStats(), var
}
fun toScoreboard(caps: SpawnCaps): RoleScore = BarbAssaultScoreBuilder.build(this, caps)
}
//Wave spawn counts // may pull from wave to count table latter
val waveCaps = listOf( //i should put this somewhere else
SpawnCaps(4,4,2,2), //wave1
SpawnCaps(4,5,3,3),
SpawnCaps(6,5,4,3),
SpawnCaps(6,6,4,4),
SpawnCaps(6,6,5,5),
SpawnCaps(7,6,6,6),
SpawnCaps(7,7,6,7),
SpawnCaps(8,7,7,7),
SpawnCaps(8,8,9,8) // wave 9
)
data class SpawnCaps(val rangers: Int, val fighters: Int, val runners: Int, val healers: Int)
data class RoleScore(val rangersKilled: Int, val fightersKilled: Int, val incorrectStylePenalty: Int,
data class RoleScore(val rangersKilled: Int, val fightersKilled: Int, val incorrectStylePenalty: Int,
val eggsScore: Int,
val runnersKilledScore: Int, val runnersPastPenalty: Int,
val healersKilledScore: Int, val hitpointsHealedScore: Int, val wrongPoisonPenalty: Int )

View file

@ -0,0 +1,36 @@
package content.minigame.barbassault.arena
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
sealed class BarbAssEvent {
data class NPCDied(val npc: NPC, val killer: Player) : BarbAssEvent()
data class EggCollected(val player: Player, val count: Int) : BarbAssEvent()
data class HitpointsHealed(val player: Player, val amount: Int) : BarbAssEvent()
data class WrongPoisonUsed(val player: Player) : BarbAssEvent()
}
class BarbAssEventBus {
private val listeners = mutableMapOf<Class<out BarbAssEvent>, MutableList<(BarbAssEvent) -> Unit>>()
private val pendingEvents = mutableListOf<BarbAssEvent>()
fun <T : BarbAssEvent> register(eventType: Class<T>, listener: (T) -> Unit) {
listeners.computeIfAbsent(eventType) { mutableListOf() }.add { listener(it as T) }
}
fun emit(event: BarbAssEvent) {
pendingEvents.add(event)
}
fun processEvents() {
for (event in pendingEvents) {
listeners[event::class.java]?.forEach { it.invoke(event) }
}
pendingEvents.clear()
}
fun clear() {
listeners.clear()
}
}

View file

@ -5,6 +5,7 @@ import content.minigame.barbassault.BarbassaultActivity
import content.minigame.barbassault.arena.scenery.EggCannon
import content.minigame.barbassault.arena.scenery.GloryHorn
import content.minigame.barbassault.lobby.BarbTeam
import content.minigame.barbassault.lobby.BarbassaultLobby
import content.minigame.barbassault.lobby.baSession
import core.api.*
import core.game.node.entity.Entity
@ -23,6 +24,7 @@ import core.tools.Log
import core.tools.secondsToTicks
import core.tools.ticksToSeconds
import org.rs09.consts.Components
import org.rs09.consts.Items
import org.rs09.consts.Music.ASSAULT_AND_BATTERY_604
import org.rs09.consts.NPCs
@ -42,7 +44,7 @@ Player
enum class BarbassaultState { PARTY_CREATION, STARTING, IN_ARENA,FORFEIT, COMPLETE, END }
class BarbassaultSession( val activity: BarbassaultActivity ? = null) : MapArea {
class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutListener, MapArea {
constructor(region: DynamicRegion, activity: BarbassaultActivity) : this(activity) {this.region = region; this.base = region.baseLocation}
lateinit var region: DynamicRegion
@ -55,6 +57,10 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) : MapArea
val groundItems = mutableListOf<GroundItem>()
val eggHopper = EggCannon.EggHopper()
val scoreManager = BarbScoreManager()
val eventBus = BarbAssEventBus()
val npcCaps = SpawnCaps(4,4,2,2)//wave 1
fun beginStartingPhase() {
if (state != BarbassaultState.PARTY_CREATION) return
@ -64,6 +70,7 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) : MapArea
}
private fun enterArena() {
state = BarbassaultState.IN_ARENA
region.setMusicId(ASSAULT_AND_BATTERY_604)
@ -90,6 +97,13 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) : MapArea
// https://www.youtube.com/watch?v=vYKbHNZn80w
destroyArena()
}
override fun logout(player: Player) {
if (!defineAreaBorders().any { it.insideBorder(player.location) }) {
return
}
player.properties.teleportLocation = Location.create(2593, 5264, 0)
}
private fun startCountdown() {
var ticks = secondsToTicks(12)
@ -120,20 +134,60 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) : MapArea
}
})
}
private fun InitEvents(){
eventBus.register(BarbAssEvent.NPCDied::class.java) { event ->
val tracker = scoreManager.trackerFor(event.killer)
val npcRoleType = event.npc.getAttribute<BarbRole>("barbass-role")
when (npcRoleType) {
BarbRole.ATTACKER -> tracker.attackerStats.rangersKilled++
BarbRole.DEFENDER -> tracker.defenderStats.runnersKilled++
BarbRole.HEALER -> tracker.healerStats.healersKilled++
else -> {}
}
}
eventBus.register(BarbAssEvent.EggCollected::class.java) { event ->
val tracker = scoreManager.trackerFor(event.player)
tracker.collectorStats.eggsCollected += event.count
}
eventBus.register(BarbAssEvent.HitpointsHealed::class.java) { event ->
val tracker = scoreManager.trackerFor(event.player)
tracker.healerStats.hitpointsReplenished += event.amount
}
eventBus.register(BarbAssEvent.WrongPoisonUsed::class.java) { event ->
val tracker = scoreManager.trackerFor(event.player)
tracker.healerStats.wrongPoisonUsed++
}
}
private inner class GamePulse : Pulse(1) {
private var roleCallTicks = secondsToTicks(30)
private var waveSpawns = secondsToTicks(6)
override fun pulse(): Boolean {
if (state != BarbassaultState.IN_ARENA) return true
if (state == BarbassaultState.FORFEIT){
eventBus.clear()
scoreManager.resetAll()
BarbassaultLobby.TeamToLobby(team,team.wave)
}
if (state == BarbassaultState.COMPLETE){
//advance to next wave lobby!
BarbassaultLobby.TeamToLobby(team,team.wave+1)
}
eventBus.processEvents()
roleCallTicks--
if (roleCallTicks <= 0) {
rollNewRoleCalls()
roleCallTicks = secondsToTicks(30)
}
// TODO: wave logic, timers, win/lose
// reSpawnItems
return false
}
}
@ -142,21 +196,31 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) : MapArea
region = DynamicRegion.create(BarbassaultGameArea.BA_ARENA.MAIN)
base = region.baseLocation
zone.register(getRegionBorders(region.id))
region.toggleMulticombat()
spawnEggCannons()
}
private fun destroyArena() {
if (!this::region.isInitialized) return
if (!this::region.isInitialized) return
zone.unregister(getRegionBorders(region.id))
region.clear()
region.flagInactive()
}
private fun handleLogout(player: Player) {
state = BarbassaultState.FORFEIT
zone.cleanItems(player,arrayOf(Item(ATTACKER_ICON),Item(DEFENDER_ICON),Item(COLLECTOR_ICON),Item(HEALER_ICON)))
region.remove(player)
team.removePlayer(player)
player.properties.teleportLocation = Location.create(2593, 5264, 0)
player.locks.unlockTeleport()
// player.properties.teleportLocation = Location.create(2593, 5264, 0)
player.location = Location.create(2593, 5264, 0)
if (team.allPlayers().isEmpty()) {
player.properties.teleportLocation = Location.create(2593, 5264, 0)
endSession()
}
}
@ -170,6 +234,7 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) : MapArea
ZoneRestriction.TELEPORT
)
override fun areaEnter(entity: Entity) {
log(this::class.java, Log.FINE, "ENTERED Barbassault Arena")
@ -186,13 +251,20 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) : MapArea
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)
removeTimer(player, "teleblock")
zone.cleanItems(player,arrayOf(Item(ATTACKER_ICON),Item(DEFENDER_ICON),Item(COLLECTOR_ICON),Item(HEALER_ICON)))
//region.remove(player)
clearLogoutListener(player, "ba-logout")
destroyArena()
}
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

@ -1,7 +1,11 @@
package content.minigame.barbassault.arenas.monsters
import content.minigame.barbassault.BarbRole
import content.minigame.barbassault.arena.BaHornSystem
import content.minigame.barbassault.arena.BarbAssEvent
import content.minigame.barbassault.lobby.baSession
import core.api.*
import core.game.container.impl.EquipmentContainer
import core.game.node.entity.Entity
import core.game.node.entity.combat.BattleState
import core.game.node.entity.combat.CombatStyle
@ -34,10 +38,60 @@ class PenanceFighterNPC : NPCBehavior(*PENANCE_FIGHTER_IDS.toIntArray()) {
return 0.0
}
override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) {
attacker as Player
val firstBefore = state.estimatedHit
//I should set a value in my players session instead of scanning the inventory every time for a horn.
state.estimatedHit = firstBefore + (BaHornSystem.HornHelper.getAttackerHorn(attacker as Player)?.ordinal?.plus(1) ?: 0) +1
//I should read my players level instead of scanning the inventory every time for a horn.
var toDamage = firstBefore + (BaHornSystem.HornHelper.getAttackerHorn(attacker)?.ordinal?.plus(1) ?: 0) +1
//if wrong attack recoil 1 damage to player.
val attackStyle = attacker.properties.attackStyle.style
val combatType = state.style
when (combatType) {
CombatStyle.MELEE -> {
when (attackStyle) {
0 -> sendMessage(attacker, "Melee: Accurate")
1 -> sendMessage(attacker, "Melee: Aggressive")
2 -> sendMessage(attacker, "Melee: Controlled")
3 -> sendMessage(attacker, "Melee: Defensive")
else -> {
toDamage = 0
sendMessage(attacker, "Melee: Unknown style")
}
}
}
CombatStyle.RANGE -> {
val arrows = attacker.equipment.get(EquipmentContainer.SLOT_ARROWS).name
sendMessage(attacker, "Ranged attack, Arrows: $arrows")
val ammunitionID = state.ammunition.itemId
when(ammunitionID){
882 -> "bronze"
884 -> "iron"
886 -> "steel"
888 -> "mithril"
else -> {
toDamage = 0
sendMessage(attacker,"Only allowed to use provided arrows.")}
}
}
CombatStyle.MAGIC -> {
val castSpell = state.spell.spellId
when(castSpell){
1,10,24,45 -> sendMessage(attacker, "Magic spell: Air")
4,14,27,48 -> sendMessage(attacker, "Magic spell: Water")
6,17,66,52 -> sendMessage(attacker, "Magic spell: Earth")
8,20,38,55 -> sendMessage(attacker, "Magic spell: Fire")
else -> {
toDamage = 0
}
}
}
}
state.estimatedHit = toDamage
}
override fun onCreation (self: NPC) {
self.setAttribute("agg_radius",2)
@ -47,10 +101,20 @@ class PenanceFighterNPC : NPCBehavior(*PENANCE_FIGHTER_IDS.toIntArray()) {
self.isAggressive = true
self.isRespawn = false
self.setAttribute("barbass-role", BarbRole.ATTACKER)
self.definition.combatDistance = 1
self.properties.combatPulse.style = CombatStyle.MELEE
}
override fun onDeathFinished(self: NPC, killer: Entity) {
super.onDeathFinished(self, killer)
val player = killer as? Player ?: return
val session = player.baSession ?: return
session.eventBus.emit(BarbAssEvent.NPCDied(self,player))
}
}
//Shrink death 5098

View file

@ -1,8 +1,12 @@
package content.minigame.barbassault.arena.monsters
import content.minigame.barbassault.BarbRole
import content.minigame.barbassault.arena.BarbAssEvent
import content.minigame.barbassault.lobby.baSession
import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC
import core.game.node.entity.npc.NPCBehavior
import core.game.node.entity.player.Player
import org.rs09.consts.NPCs
val PENANCE_HEALER_IDS = listOf(
@ -22,8 +26,20 @@ class PenanceHealerNPC : NPCBehavior(*PENANCE_HEALER_IDS.toIntArray()) {
return 0.0
}
override fun onCreation (self: NPC) {
self.setAttribute("barbass-role", BarbRole.HEALER)
}
//sendMessage(player,"that's the wrong type of poisoned food to use! Penalty!")
override fun onDeathFinished(self: NPC, killer: Entity) {
super.onDeathFinished(self, killer)
val player = killer as? Player ?: return
val session = player.baSession ?: return
session.eventBus.emit(BarbAssEvent.NPCDied(self,player))
}
}
/*

View file

@ -8,6 +8,7 @@ import core.game.node.entity.npc.NPCBehavior
import core.game.node.entity.player.Player
import org.rs09.consts.NPCs
//.configureBossData()
class PenanceQueenNPC : NPCBehavior(NPCs.PENANCE_QUEEN_5247){
override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean {
if (attacker is Player ) {
@ -19,6 +20,7 @@ class PenanceQueenNPC : NPCBehavior(NPCs.PENANCE_QUEEN_5247){
override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
return 0.0
}
}

View file

@ -1,5 +1,8 @@
package content.minigame.barbassault.arena.monsters
import content.minigame.barbassault.BarbRole
import content.minigame.barbassault.arena.BarbAssEvent
import content.minigame.barbassault.lobby.baSession
import core.api.*
import core.api.getItemFromEquipment
import core.game.node.entity.Entity
@ -40,10 +43,20 @@ class PenanceRangerNPC : NPCBehavior(*PENANCE_RANGER_IDS.toIntArray()) {
self.walkRadius = 64
self.isAggressive = true
self.setAttribute("barbass-role",BarbRole.ATTACKER)
self.definition.combatDistance = 8
self.properties.combatPulse.style = CombatStyle.RANGE
}
override fun onDeathFinished(self: NPC, killer: Entity) {
super.onDeathFinished(self, killer)
val player = killer as? Player ?: return
val session = player.baSession ?: return
session.eventBus.emit(BarbAssEvent.NPCDied(self,player))
}
}

View file

@ -1,14 +1,17 @@
package content.minigame.barbassault.arena.monsters
import content.minigame.barbassault.BarbRole
import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC
import core.game.node.entity.npc.NPCBehavior
import core.game.world.map.Location
import org.rs09.consts.NPCs
import content.minigame.barbassault.arena.*
import content.minigame.barbassault.lobby.baSession
import core.api.forceWalk
import core.api.removeGroundItem
import core.api.sendChat
import core.game.node.entity.player.Player
import core.game.node.item.GroundItem
import core.game.node.item.GroundItemManager
@ -38,6 +41,8 @@ class PenanceRunnerNPC : NPCBehavior(*PENANCE_RUNNER_IDS.toIntArray()) {
self.walkRadius = 22
self.destinationFlag
self.setAttribute("barbass-role", BarbRole.DEFENDER)
}
override fun tick(self: NPC): Boolean {
@ -59,8 +64,13 @@ class PenanceRunnerNPC : NPCBehavior(*PENANCE_RUNNER_IDS.toIntArray()) {
fun seekFood(){
}
override fun onDeathFinished(self: NPC, killer: Entity) {
super.onDeathFinished(self, killer)
val player = killer as? Player ?: return
val session = player.baSession ?: return
session.eventBus.emit(BarbAssEvent.NPCDied(self,player))
}
}

View file

@ -23,8 +23,9 @@ import org.rs09.consts.Items
import org.rs09.consts.Scenery
import org.rs09.consts.Sounds
//https://www.youtube.com/watch?v=0d5I97HLUEs ending of video shows we are allowed capes in lap but not wave rooms
//"-- Next wave no longer starting"
// The game ended early because one of your team-mated died.
private var activity: BarbassaultActivity? = null
class BarbassaultLobby : InteractionListener, MapArea {
@ -302,18 +303,25 @@ class BarbassaultLobby : InteractionListener, MapArea {
}
}
}
fun waveAdvance(player: Player) {
val wave = player.getAttribute("barbass:wave", 1)
if (wave in 1..waveLobbies.size) {
val targetLobby = waveLobbies[wave]
teleport(player, targetLobby.randomWalkableLoc)
if (wave == 10) {player.setAttribute("/save:barbass:wave", 1)}
} else {
println("Invalid wave number: $wave")
}
}
companion object {
fun TeamToLobby(team: BarbTeam, wave: Int) {
if (wave in 1..waveLobbies.size) {
val targetLobby = waveLobbies[wave]
for (player in team.allPlayers()) {
teleport(player, targetLobby.randomWalkableLoc)
}
}
}
fun waveAdvance(player: Player) {
val wave = player.getAttribute("barbass:wave", 1)
if (wave in 1..waveLobbies.size) {
if (wave == 10) {player.setAttribute("/save:barbass:wave", 1)}
} else {
println("Invalid wave number: $wave")
}
}
// Locations
val QUICK_START: ZoneBorders = ZoneBorders(2595, 5278, 2610, 5271, 0)
val MAIN_LOBBY: ZoneBorders = ZoneBorders(2588, 5266, 2597, 5261, 0)