BarbTeam, Lobby related interfaces, "ba-session" working better.

This commit is contained in:
Tooze 2026-01-27 08:05:37 -05:00
parent 094bc4ac6b
commit 0c25abc88a
15 changed files with 977 additions and 504 deletions

View file

@ -33,6 +33,19 @@ class BarbassDevHelper : CommandSet(Privilege.ADMIN) {
player.teleport(Location.create(1885, 5403, 0))
}
define("hch"){ player,args->
val chId = args[1].toIntOrNull()
if (chId != null) {
player.packetDispatch.sendInterfaceConfig(493, chId,true)
}
}
define("vch"){ player,args->
val chId = args[1].toIntOrNull()
if (chId != null) {
player.packetDispatch.sendInterfaceConfig(493, chId,false)
}
}
define("trap"){ player,args->
var thistrap = Location.create(1901, 5474, 0)
var thistrapscen = core.game.node.scenery.Scenery(Scenery.RUNNER_TRAP2_20135, Location(1901, 5474))

View file

@ -32,7 +32,9 @@ class BarbassaultListeners : InteractionListener {
on(Scenery.LADDER_20227, IntType.SCENERY, "Climb-up") { player, _ ->
//Remove Roster/scroll
val loc = Location(2535 , 3572 )
player.inventory.removeAll(Items.SCROLL_10512)
teleport(player, loc) // find ladder code latter
return@on true
}
@ -84,6 +86,8 @@ class BarbassaultListeners : InteractionListener {
Items.NATURE_RUNE_561
//add food
//add ammo
//summoning pouches
)
for (item in player.inventory.toArray()) {
@ -117,7 +121,7 @@ class BarbSelectRole : InterfaceListener {
//Accpting invite text " Your application has been accepted"
//The applicant declined your offer.
//the other player hasn't confirmed their role yet.
//the applicant has chosen a role.0
//the applicant has chosen a role[0]
//You removed the person from the team.
override fun defineInterfaceListeners() {
onOpen(493) { player, _ -> // change this for roles

View file

@ -1,58 +1,70 @@
package content.minigame.barbassault
import content.minigame.barbassault.arena.BarbassaultSession
import content.minigame.barbassault.arena.BarbassaultState
import content.minigame.barbassault.lobby.baSession
import content.minigame.barbassault.activity
import content.minigame.fishingtrawler.FishingTrawlerActivity
import core.api.MapArea
import core.api.sendMessage
import core.game.activity.ActivityManager
import core.game.activity.ActivityPlugin
import core.game.node.entity.player.Player
import core.game.system.task.Pulse
import core.game.world.GameWorld
import core.game.world.map.Location
import core.game.world.map.build.DynamicRegion
import core.game.world.map.zone.ZoneBorders
import core.game.world.map.zone.ZoneRestriction
import core.plugin.Initializable
import core.tools.ticksToSeconds
import core.game.activity.ActivityManager
import core.game.activity.ActivityPlugin
import core.game.world.map.zone.ZoneBorders
import core.tools.colorize
private val sessions = mutableListOf<BarbassaultSession>()
private var activity: BarbassaultActivity? = null
@Initializable
class BarbassaultActivity : ActivityPlugin("barbassault",false,false,true,ZoneRestriction.CANNON,ZoneRestriction.FIRES,ZoneRestriction.FOLLOWERS,ZoneRestriction.RANDOM_EVENTS), MapArea {
class BarbassaultActivity : ActivityPlugin("barbassault",true, true, true,
ZoneRestriction.CANNON,
ZoneRestriction.FIRES,
ZoneRestriction.FOLLOWERS,
ZoneRestriction.RANDOM_EVENTS
) {
init {
activity = this
}
override fun configure() {
GameWorld.Pulser.submit(object : Pulse(10) {
override fun pulse(): Boolean {
sessions.removeIf {
it.state == BarbassaultState.END
}
return false
}
})
}
override fun start(player: Player?, login: Boolean, vararg args: Any?): Boolean {
player ?: return false
//waitingPlayers.add(player)
return true
}
fun addPlayer(player: Player){
}
fun removePlayer(player: Player){
// waitingPlayers.remove(player)
}
override fun newInstance(p: Player?): ActivityPlugin {
ActivityManager.register(this)
return this
}
override fun getSpawnLocation(): Location {
return Location.create(2667, 3161, 0)
return Location.create(2593, 5264, 0)
}
override fun defineAreaBorders(): Array<ZoneBorders> {
return arrayOf(ZoneBorders(2668, 3165, 2675, 3184))
}
override fun getRestrictions(): Array<ZoneRestriction> {
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.TELEPORT)
companion object {
fun createSession(leader: Player): BarbassaultSession {
val activity = ActivityManager.getActivity("barbassault") as BarbassaultActivity
val session = BarbassaultSession(activity)
sessions += session
leader.baSession = session
return session
}
}
}
}

View file

@ -0,0 +1,44 @@
package content.minigame.barbassault.arena
import core.api.MapArea
import core.api.getRegionBorders
import core.game.node.entity.player.Player
import core.game.world.map.build.DynamicRegion
import core.game.world.map.zone.ZoneBorders
import core.game.world.map.zone.ZoneRestriction
class BarbassaultArena(
private val session: BarbassaultSession
) : MapArea {
private lateinit var region: DynamicRegion
fun create() {
region = DynamicRegion.create(BarbassaultGameArea.BA_ARENA.MAIN)
//zone.register(*defineAreaBorders())
}
fun spawnPlayers(players: List<Player>) {
val base = region.baseLocation
players.forEach {
it.properties.teleportLocation =
base.transform(36, 24, 0)
}
}
fun destroy() {
//zone.unregister(*defineAreaBorders())
region.clear()
}
override fun defineAreaBorders(): Array<ZoneBorders> =
arrayOf(getRegionBorders(7509))
override fun getRestrictions(): Array<ZoneRestriction> =
arrayOf(
ZoneRestriction.CANNON,
ZoneRestriction.FIRES,
ZoneRestriction.RANDOM_EVENTS,
ZoneRestriction.TELEPORT
)
}

View file

@ -1,7 +1,10 @@
package content.minigame.barbassault.arena
import content.minigame.barbassault.BarbRole
import content.minigame.barbassault.BarbassaultTut
import content.minigame.barbassault.BarbassaultTut.Companion.TutorialItemSpawn
import content.minigame.barbassault.arena.scenery.DefenderTrap
import content.minigame.barbassault.lobby.baSession
import core.api.*
import core.game.global.action.DropListener
@ -19,6 +22,7 @@ import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import core.game.system.task.Pulse
import core.game.world.GameWorld
import core.game.world.map.Direction
import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders
import core.game.world.update.flag.context.Animation
@ -40,14 +44,32 @@ import org.rs09.consts.Scenery
//sendMessage(player,"The barbarians forbid the use of prayer in their arena as they don't ~ value such methods!")
//should be multicombat
val ATTACKER_ICON = 10556
val DEFENDER_ICON = 10558
val COLLECTOR_ICON = 10557
val HEALER_ICON = 10559
class BarbassaultGameArea : InteractionListener, MapArea {
val ATTACKER_ICON = 10556
val DEFENDER_ICON = 10558
val COLLECTOR_ICON = 10557
val HEALER_ICON = 10559
val ROLE_ICON = intArrayOf(ATTACKER_ICON,DEFENDER_ICON,COLLECTOR_ICON,HEALER_ICON)
val Fix_trap_IDs = intArrayOf(Scenery.RUNNER_TRAP1_20230,Scenery.BROKEN_TRAP0_20231)
val ROLE_ICON = intArrayOf( ATTACKER_ICON, DEFENDER_ICON, COLLECTOR_ICON, HEALER_ICON )
val Fix_trap_IDs = intArrayOf( Scenery.RUNNER_TRAP1_20230, Scenery.BROKEN_TRAP0_20231 )
object BA_ARENA { val MAIN = 7509; val QUEEN = 7508; val all = listOf(MAIN, QUEEN) }
//base.transform(0,0,0)
data class arenaItems(val id: Int,val x: Int, val y: Int, val z: Int)
val arenaItemSpawn: List<arenaItems> = listOf(
arenaItems(Items.HAMMER_2347,32,42,0),
arenaItems(Items.LOGS_11760,30,46,0),
arenaItems(Items.LOGS_11760,29,47,0)
)
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.
@ -80,13 +102,13 @@ class BarbassaultGameArea : InteractionListener, MapArea {
override fun defineListeners() {
on(Fix_trap_IDs, IntType.SCENERY, "Fix") { player, node ->
if (checkHasTools(player)) { return@on true }
if (hasTools(player)) { return@on true }
playerChangeScenery(player,5416,node,Scenery.RUNNER_TRAP2_20135,5,"You fixed the Penance Runner trap.")
return@on true
}
on(Scenery.PENANCE_CAVE_20237, IntType.SCENERY, "block") { player, node ->
if (checkHasTools(player)) { return@on true }
if (hasTools(player)) { return@on true }
playerChangeScenery(player,5417,node,Scenery.PENANCE_CAVE_20238,4)
return@on true
}
@ -97,7 +119,7 @@ class BarbassaultGameArea : InteractionListener, MapArea {
}
on(Scenery.PENANCE_CAVE_20239, IntType.SCENERY, "fix") { player, node ->
if (checkHasTools(player)) { return@on true }
if (hasTools(player)) { return@on true }
playerChangeScenery(player,5417,node,Scenery.PENANCE_CAVE_20238,4)
return@on true
}
@ -142,6 +164,10 @@ class BarbassaultGameArea : InteractionListener, MapArea {
//CATALYTIC_RUNE_12851, ELEMENTAL_RUNE_12850
onUnequip(ROLE_ICON) { player, _ ->
if (player.baSession?.state == BarbassaultState.IN_ARENA){
sendMessage(player, "You can't remove that!") // is there a proper message for this?
return@onUnequip false
}
defineAreaBorders().forEach { border ->
if (border.insideBorder(player)) {
sendMessage(player, "You can't remove that!") // is there a proper message for this?
@ -152,6 +178,9 @@ class BarbassaultGameArea : InteractionListener, MapArea {
}
onEquip(ROLE_ICON) { player, _ ->
if (player.baSession?.state == BarbassaultState.IN_ARENA) {
sendMessage(player, "You can't remove that!")
}
defineAreaBorders().forEach { border ->
if (border.insideBorder(player)) {
sendMessage(player, "You can't remove that!")
@ -184,33 +213,9 @@ class BarbassaultGameArea : InteractionListener, MapArea {
}
}
private fun exitMiniGame(player: Player) {
openOverlay(player,493) // work around to actually close interfaces.
player.interfaceManager.closeOverlay()//maybe im doing this wrong.
removeTimer(player, "teleblock")
val barbassItems = arrayListOf(
Items.WORMS_10515,Items.CRACKERS_10513,Items.TOFU_10514,Items.LOGS_11760,Items.LOGS_11760,Items.HAMMER_2347,Items.DEFENDER_HORN_10538, //Defender Inv Items
Items.HEALING_VIAL_10546,Items.HEALING_VIAL1_10545,Items.HEALING_VIAL2_10544,Items.HEALING_VIAL3_10543,Items.HEALING_VIAL4_10542, //Healer Inv Items
Items.HEALER_HORN_10526,Items.HEALER_HORN_10527,Items.HEALER_HORN_10528,Items.HEALER_HORN_10529,Items.HEALER_HORN_10530,
Items.POISONED_WORMS_10540,Items.POISONED_TOFU_10539,Items.POISONED_MEAT_10541,
)
removeAll(player, barbassItems)
//todo should probably make sure familiars can't smuggle items out
//(player.familiarManager.familiar as? BurdenBeast)?.container?.removeAll(barbassItems)//just in case someone smuggles a pet in.
//award points, set Tp location to next wave
//or lost game Send back to wave room
}
private fun lureDrop(player: Player,item:Item){
//val gi = GroundItemManager.create(GroundItem(item.dropItem,player.location,-1,null))
queueScript(player, strength = QueueStrength.SOFT) {
val current = player.inventory.get(item.slot)
if (current == null || current !== item) {
@ -242,15 +247,6 @@ class BarbassaultGameArea : InteractionListener, MapArea {
return removedAny
}
fun getIconInterfaceId(itemId: Int): Int? {
return when (itemId) {
ATTACKER_ICON -> Components.BARBASSAULT_OVER_ATT_485
COLLECTOR_ICON -> Components.BARBASSAULT_OVER_COL_486
DEFENDER_ICON -> Components.BARBASSAULT_OVER_DEF_487
HEALER_ICON -> Components.BARBASSAULT_OVER_HEAL_488
else -> null
}
}
fun playerChangeScenery(player: Player,anim: Int ,node: Node, newSceneryId: Int, pulseDelay: Int = 3, message: String = "") {
player.animate(Animation(anim))
@ -268,7 +264,7 @@ class BarbassaultGameArea : InteractionListener, MapArea {
}
})
}
fun checkHasTools(player: Player): Boolean{
fun hasTools(player: Player): Boolean{
if (getItemFromEquipment(player, EquipmentSlot.CAPE)?.id != DEFENDER_ICON) {return true}
val requiredItems = listOf(Items.HAMMER_2347, Items.LOGS_11760)
for (item in requiredItems) {
@ -279,26 +275,42 @@ class BarbassaultGameArea : InteractionListener, MapArea {
}
return false
}
fun spawnPartyMembers(){
//1
//2 //3
//5 //4
// party slot effects where you start/spawn
val RedLeader1 = Location.create(1886, 5458, 0)
val RedLeader2 = Location.create(1885, 5457, 0)
val RedLeader3 = Location.create(1887, 5457, 0)
val RedLeader4 = Location.create(1884, 5456, 0)
val RedLeader5 = Location.create(1888, 5456, 0)
}
}
fun exitMiniGame(player: Player) {
// openOverlay(player,493) // work around to actually close interfaces.
//player.interfaceManager.closeOverlay()//maybe im doing this wrong.
removeTimer(player, "teleblock")
object BA_ARENA {
const val MAIN = 7509
const val QUEEN = 7508
val all = listOf(MAIN, QUEEN)
val barbassItems = arrayListOf(
Items.WORMS_10515,Items.CRACKERS_10513,Items.TOFU_10514,Items.LOGS_11760,Items.LOGS_11760,Items.HAMMER_2347,Items.DEFENDER_HORN_10538, //Defender Inv Items
Items.HEALING_VIAL_10546,Items.HEALING_VIAL1_10545,Items.HEALING_VIAL2_10544,Items.HEALING_VIAL3_10543,Items.HEALING_VIAL4_10542, //Healer Inv Items
Items.HEALER_HORN_10526,Items.HEALER_HORN_10527,Items.HEALER_HORN_10528,Items.HEALER_HORN_10529,Items.HEALER_HORN_10530,
Items.POISONED_WORMS_10540,Items.POISONED_TOFU_10539,Items.POISONED_MEAT_10541,
)
removeAll(player, barbassItems)
//todo should probably make sure familiars can't smuggle items out
//(player.familiarManager.familiar as? BurdenBeast)?.container?.removeAll(barbassItems)//just in case someone smuggles a pet in.
//award points, set Tp location to next wave
//or lost game Send back to wave room
}
val BA_ROLE_CAPE = mapOf( BarbRole.ATTACKER to 10556, BarbRole.DEFENDER to 10558, BarbRole.COLLECTOR to 10557, BarbRole.HEALER to 10559 )
fun equipBARoleIcon(player: Player, role: BarbRole) {
val itemId = BA_ROLE_CAPE[role] ?: return
player.equipment.add(Item(itemId),true,false)
//player.getEquipment().add(Item(itemId), true)
}
fun getIconInterfaceId(itemId: Int): Int? {
return when (itemId) {
ATTACKER_ICON -> Components.BARBASSAULT_OVER_ATT_485
COLLECTOR_ICON -> Components.BARBASSAULT_OVER_COL_486
DEFENDER_ICON -> Components.BARBASSAULT_OVER_DEF_487
HEALER_ICON -> Components.BARBASSAULT_OVER_HEAL_488
else -> null
}
}

View file

@ -1,8 +1,13 @@
package content.minigame.barbassault.arena
import content.minigame.barbassault.arena.LureItem
import content.minigame.barbassault.BarbRole
import content.minigame.barbassault.BarbassaultActivity
import content.minigame.barbassault.BarbassaultTut
import content.minigame.barbassault.lobby.BarbTeam
import content.minigame.barbassault.lobby.BarbTeamManager
import content.minigame.barbassault.lobby.SelectRole
import content.minigame.barbassault.lobby.baSession
import core.api.*
import core.game.component.Component
import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
@ -10,114 +15,170 @@ import core.game.system.task.Pulse
import core.game.world.GameWorld
import core.game.world.map.Location
import core.game.world.map.build.DynamicRegion
import core.game.world.map.zone.MapZone
import core.game.world.map.zone.Zone
import core.game.world.map.zone.ZoneBorders
import core.game.world.map.zone.ZoneRestriction
import core.tools.Log
import core.tools.RandomFunction
import core.tools.secondsToTicks
import core.tools.ticksToSeconds
import org.rs09.consts.NPCs
import kotlin.math.ceil
import org.rs09.consts.Music
import org.rs09.consts.Music.ASSAULT_AND_BATTERY_604
import org.rs09.consts.Music.PIRATES_OF_PENANCE_211
import kotlin.math.roundToInt
/*
Player
attribute "baSession" : BarbassaultSession?
state : BarbassaultState (STARTING, IN_ARENA, END)
arena : DynamicRegion / MapArea
lifecycle : start play end
team : BarbTeam?
leader : Player
slots : List<Player>
recruit : PendingRecruit?
player : Player
role : BarbRole?
*/
enum class BarbassaultState { PARTY_CREATION, STARTING, IN_ARENA, COMPLETE, END }
class BarbassaultSession( val activity: BarbassaultActivity ? = null) : MapArea {
constructor(region: DynamicRegion, activity: BarbassaultActivity) : this(activity) {this.region = region; this.base = region.baseLocation}
class BarbassaultSession(val activity: BarbassaultSession? = null) : MapArea {
constructor(region: DynamicRegion, activity: BarbassaultSession) : this(activity) {this.region = region; this.base = region.baseLocation}
var players: ArrayList<Player> = ArrayList()
val LureItemNodes = mutableListOf<LureItem>()
lateinit var region: DynamicRegion
lateinit var base: Location
var isActive = false
val npcs = ArrayList<NPC>()
var inactiveTicks = 0
var timeLeft = secondsToTicks(600)
var state: BarbassaultState = BarbassaultState.PARTY_CREATION
private set
lateinit var team: BarbTeam
fun start(pl: ArrayList<Player>){
region.setMusicId(434)
// region.setMusicId(51)
this.players.addAll(pl)
isActive = true
fun beginStartingPhase() {
if (state != BarbassaultState.PARTY_CREATION) return
GameWorld.Pulser.submit(BarbassPulse(this))
for(player in pl){
//player.interfaceManager.openOverlay(Component(OVERLAY_ID))
//player.interfaceManager.open(Component(TUTORIAL_ID))
//updateOverlay(player)
player.properties.teleportLocation = base.transform(36,24,0)
player.setAttribute("ba-session",this)
registerLogoutListener(player, "ba-logout") {
val session = player.getAttribute<BarbassaultSession?>("ba-session",null) ?: return@registerLogoutListener
player.location = Location.create(2667, 3161, 0) //return to
session.players.remove(player)
player.locks.unlockTeleport()
}
state = BarbassaultState.STARTING
createArena()
startCountdown()
}
private fun enterArena() {
state = BarbassaultState.IN_ARENA
region.setMusicId(ASSAULT_AND_BATTERY_604)
for (player in team.allPlayers()) {
player.baSession?.team?.getRoleForPlayer(player)?.let { equipBARoleIcon(player, it) }
player.properties.teleportLocation = team.spawnLocationFor(player) //base.transform(36, 24, 0)
registerLogoutListener(player, "ba-logout") { handleLogout(player) } //todo make sure this works
}
GameWorld.Pulser.submit(GamePulse())
}
fun endSession() {
if (state == BarbassaultState.END) return
state = BarbassaultState.END
for (player in team.allPlayers()) {
clearLogoutListener(player, "ba-logout")
// player.removeAttribute("ba-session")
player.properties.teleportLocation = Location.create(2593, 5264, 0)
player.interfaceManager.closeOverlay()
}
destroyArena()
}
private fun startCountdown() {
var ticks = secondsToTicks(12)
team.allPlayers().forEach { openOverlay(it, 494);setInterfaceText(it, "60", 494, 0) }
GameWorld.Pulser.submit(object : Pulse(1) {
override fun pulse(): Boolean {
if (state != BarbassaultState.STARTING) return true
ticks--
if (ticks <= 0) {
enterArena()
return true
}
val secondsLeft = ticksToSeconds(ticks)
val display = secondsLeft.toString().padStart(2, '0')
team.allPlayers().forEach {
setInterfaceText(it, display, 494, 0)
// it.sendMessage("Barbarian Assault starts in $display seconds.")
}
return false
}
})
}
private inner class GamePulse : Pulse(1) {
override fun pulse(): Boolean {
if (state != BarbassaultState.IN_ARENA) return true
// TODO: wave logic, timers, win/lose
return false
}
}
private fun createArena() {
region = DynamicRegion.create(BarbassaultGameArea.BA_ARENA.MAIN)
base = region.baseLocation
zone.register(getRegionBorders(region.id))
}
class BarbassPulse(val session: BarbassaultSession) : Pulse(){
var ticks = 0
override fun pulse(): Boolean {
ticks++
session.timeLeft--
//session.zone.unregister(getRegionBorders(session.region.id))
private fun destroyArena() {
if (!this::region.isInitialized) return
zone.unregister(getRegionBorders(region.id))
region.clear()
}
if(session.timeLeft <= 0){
session.isActive = false
for(player in session.players){
player.interfaceManager.closeOverlay()
player.properties.teleportLocation = Location.create(2666, 3162, 0) // return to
// player.incrementAttribute("/save:$STATS_BASE:$FISHING_TRAWLER_GAMES_WON")
player.removeAttribute("ba-session")
clearLogoutListener(player, "ba-logout")
}
session.zone.unregister(getRegionBorders(session.region.id))
}
private fun handleLogout(player: Player) {
team.removePlayer(player)
player.properties.teleportLocation = Location.create(2593, 5264, 0)
player.locks.unlockTeleport()
for(player in session.players){
//session.updateOverlay(player)
if(session.timeLeft <= 1) {
lockInteractions(player, 2)
}
}
return !session.isActive
if (team.allPlayers().isEmpty()) {
endSession()
}
}
fun clearNPCs(){
npcs.forEach {
it.clear()
}
npcs.clear()
}
override fun defineAreaBorders(): Array<ZoneBorders> = emptyArray()
fun initCannons(){
// NPC.create(NPCs.EGG_LAUNCHER_5026, Location.create(1896, 5474, 0), Direction.NORTH),
// NPC.create(NPCs.EGG_LAUNCHER_5026, Location.create(1877, 5474, 0), Direction.NORTH)
for(loc in arrayOf(base.transform(38,17,0),
base.transform(33,18,0))){
val npc = NPC(NPCs.EGG_LAUNCHER_5026)
npc.location = loc
npcs.add(npc)
npc.isRespawn = false
npc.isWalks = false
npc.init()
}
}
override fun defineAreaBorders(): Array<ZoneBorders> {
return arrayOf()
}
override fun getRestrictions(): Array<ZoneRestriction> {
return arrayOf(ZoneRestriction.CANNON, ZoneRestriction.FIRES, ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.TELEPORT)
}
override fun getRestrictions(): Array<ZoneRestriction> = arrayOf(
ZoneRestriction.CANNON,
ZoneRestriction.FIRES,
ZoneRestriction.RANDOM_EVENTS,
ZoneRestriction.TELEPORT
)
override fun areaEnter(entity: Entity) {
super.areaEnter(entity)
log(this::class.java, Log.FINE, "ENTERED BarbAssault")
log(this::class.java, Log.FINE, "ENTERED Barbassault Arena")
val player = entity as? Player ?: return
val wornIconId = getItemFromEquipment(player, EquipmentSlot.CAPE)?.id
val interfaceId = getIconInterfaceId(wornIconId ?: -1)
if (interfaceId != null) {
//sendMessage(player,----- Wave: $Num -----")
openOverlay(player, interfaceId)
}
BarbassaultTut.BarbassTutNPCs.forEach {
npc -> npc.init()
npc.isWalks = false
}
BarbassaultTut.spawnItems()
}
override fun areaLeave(entity: Entity, logout: Boolean) {
super.areaLeave(entity, logout)
log(this::class.java, Log.FINE, "EXITED BarbAssault")
log(this::class.java, Log.FINE, "LEFT Barbassault Arena")
var player = entity as Player
exitMiniGame(player)
removeTimer(player, "teleblock")
}
}

View file

@ -1,6 +1,5 @@
package content.minigame.barbassault.arena.scenery
import content.minigame.barbassault.arena.machines.ItemMachine.Companion.addArrayOfItems
import content.minigame.barbassault.arena.monsters.PENANCE_RUNNER_IDS
import core.api.*
import core.game.node.Node
@ -36,6 +35,7 @@ class DefenderTrap : MapArea {
val TRAP_WEST_ZONE: ZoneBorders = ZoneBorders(1870, 5474, 1872, 5472, 0)
val TRAP_WEST = Location.create(1871, 5473, 0)
val TRAPS_ZONE = arrayOf(TRAP_EAST_ZONE,TRAP_WEST_ZONE)
val Fix_trap_IDs = intArrayOf( Scenery.RUNNER_TRAP1_20230, Scenery.BROKEN_TRAP0_20231 )
val TRAPS = arrayOf(TRAP_WEST,TRAP_EAST)
val playersInArea = mutableListOf<Player>()
@ -63,7 +63,7 @@ class DefenderTrap : MapArea {
fun killRunner(entity: Entity){
entity.sendChat(TRAP_HIT)
entity.startDeath(entity)
var thistrap = Location.create(1901, 5474, 0)
val thistrap = Location.create(1901, 5474, 0)
val scenery = getScenery(thistrap)
//animateScenery(scenery!!, 5076)//5076
@ -97,11 +97,12 @@ class DefenderTrap : MapArea {
sendMessage(player,"Entered Trap Area")
}
}
}
//sendMessage(player,"A Penance Runner broke a trap to the east/west!") //When a runner dies to trap announce to Defenders
//replaceScenery()
//animateScenery
//5076
}

View file

@ -0,0 +1,109 @@
package content.minigame.barbassault.lobby
import content.minigame.barbassault.BarbRole
import content.minigame.barbassault.lobby.BarbTeamManager.abandonTeam
import content.minigame.barbassault.lobby.CurrentTeam.ROLE_MODEL_MAP
import content.minigame.barbassault.lobby.CurrentTeam.modelZoom
import core.api.closeInterface
import core.api.sendMessage
import core.api.setInterfaceModel
import core.api.setInterfaceText
import core.game.component.Component
import core.game.component.ComponentDefinition
import core.game.component.ComponentPlugin
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.plugin.Plugin
@Initializable
class AcceptRoleInterface : ComponentPlugin() {
override fun newInstance(arg: Any?): Plugin<Any> {
ComponentDefinition.forId(AcceptRole.ID).plugin = this
return this
}
override fun handle(player: Player?,component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int ): Boolean {
when (button) {
AcceptRole.AcceptButton, AcceptRole.AcceptButtonText -> { handleAccept(player); return true }
AcceptRole.DeclineButton, AcceptRole.DeclineButtonText -> { handleDecline(player); return true }
}
val slotIndex = AcceptRole.team.indexOfFirst { it.remove == button }
if (slotIndex != -1) { handleRemove(player!!, slotIndex); return true }
return true
}
override fun open(player: Player?, component: Component?) {
super.open(player, component)
var isopen = true
player ?: return
val team = player.baSession?.team
val recruit = team?.recruit?.player
val teamLeader = team?.getLeader()
component?.setCloseEvent{ _, _ -> if (recruit != null && isopen) { closeInterface(recruit); isopen = false }; return@setCloseEvent true }
for (slotIndex in 0 until BarbTeam.MAX_SLOTS) {
val uiSlot = AcceptRole.team[slotIndex]
val partySlot: PartySlot? = team?.getSlot(slotIndex)
val slotPlayer: Player? = partySlot?.player
if (slotPlayer != null) {
val formattedRole = slotPlayer.baSession?.team?.getRoleForPlayer(slotPlayer)?.toString()?.lowercase()?.replaceFirstChar { it.uppercase() }?: AcceptRole.defaultText
val wave = slotPlayer.getAttribute("barbass:wave", 1) ?: 0
setInterfaceText(player, slotPlayer.name.capitalizeWords(), AcceptRole.ID, uiSlot.name )
setInterfaceText(player, formattedRole, AcceptRole.ID, uiSlot.role )
setInterfaceText(player, wave.toString(), AcceptRole.ID, uiSlot.wave )
} else {
setInterfaceText(player, AcceptRole.defaultText, AcceptRole.ID,uiSlot.name )
setInterfaceText(player, AcceptRole.defaultText, AcceptRole.ID,uiSlot.role )
setInterfaceText(player, "0", AcceptRole.ID,uiSlot.wave )
}
}
}
}
private fun handleAccept(player: Player?) {
sendMessage(player!!,"Accepted Clicked")
return
}
private fun handleDecline(player: Player?) {
if (player == null) return
closeInterface(player)
val leader = player.baSession?.team?.getLeader()?.player
if (leader != null && leader != player) {
closeInterface(leader)
}
}
private fun handleRemove(player: Player, slotIndex: Int){
val team = player.baSession?.team
val follower = team?.getSlot(slotIndex)?.player ?: return
val uiSlot = AcceptRole.team[slotIndex]
sendMessage(player,"You removed the person from the team.")
setInterfaceText(player, AcceptRole.defaultText, AcceptRole.ID,uiSlot.name )
setInterfaceText(player, AcceptRole.defaultText, AcceptRole.ID,uiSlot.role )
setInterfaceText(player, "0", AcceptRole.ID,uiSlot.wave )
abandonTeam(follower)
}
object AcceptRole {
const val ID = 492
const val defaultText = "none set"
const val AcceptButtonText = 4
const val DeclineButtonText = 2
const val AcceptButton = 35
const val DeclineButton = 3
data class Slot(val name: Int, val role: Int,val remove: Int, val wave: Int)
val team = listOf(
Slot(15,20,-1,26),
Slot(16,21,47,31),
Slot(17,22,27,32),
Slot(18,23,28,33),
Slot(19,24,29,34),
)
object Status {
const val selectedRole = 6
const val levelRole = 46
}
}

View file

@ -0,0 +1,232 @@
package content.minigame.barbassault.lobby
import content.minigame.barbassault.BarbRole
import content.minigame.barbassault.BarbassaultActivity
import content.minigame.barbassault.arena.BarbassaultSession
import content.minigame.barbassault.arena.BarbassaultState
import core.api.clearLogoutListener
import core.api.sendMessage
import core.game.node.entity.player.Player
import core.game.world.map.Location
/*
Player
attribute "ba-session"
BarbassaultSession : MapArea
team : BarbTeam
slots Players
*/
private const val BA_SESSION_KEY = "ba-session"
var Player.baSession: BarbassaultSession?
get() = getAttribute(BA_SESSION_KEY)
set(value) {
if (value == null) removeAttribute(BA_SESSION_KEY)
else setAttribute(BA_SESSION_KEY, value)
}
/**
private val playerTeams = mutableMapOf<Player, BarbTeam>()
var Player.team: BarbTeam?
get() = playerTeams[this]
set(value) {
if (value == null) playerTeams.remove(this)
else playerTeams[this] = value
}*/
data class PartySlot( val index: Int, val player: Player, var role: BarbRole? = null )
data class PendingRecruit( var player: Player, var role: BarbRole? = null )
private val PartySpawns = arrayOf(30 to 18, 29 to 17, 31 to 17, 28 to 16, 32 to 16)
class BarbTeam(val session: BarbassaultSession, leader: Player) {
companion object {
const val MAX_SLOTS = 5
const val LEADER_SLOT = 0
}
var recruit: PendingRecruit? = null
private val slots: Array<PartySlot?> = arrayOfNulls(MAX_SLOTS)
init {
slots[LEADER_SLOT] = PartySlot(LEADER_SLOT, leader)
}
fun slotOf(player: Player): Int =
slots.indexOfFirst { it?.player == player }
fun getSlot(index: Int): PartySlot? =
slots.getOrNull(index)
fun allPlayers(): List<Player> =
slots.filterNotNull().map { it.player }
fun isLeader(player: Player): Boolean =
slotOf(player) == LEADER_SLOT
fun isFull(): Boolean =
slots.all { it != null }
fun addRecruit(player: Player): Boolean {
recruit = PendingRecruit(player)
return true
}
fun addPlayer(player: Player): Boolean {
if (slotOf(player) != -1) return false
val freeIndex = slots.indexOfFirst { it == null }
if (freeIndex == -1) return false
slots[freeIndex] = PartySlot(freeIndex, player)
return true
}
/** fun removePlayer(player: Player) {
val idx = slotOf(player)
if (idx == -1) return
slots[idx] = null
player.team = null
player.removeAttribute(BA_SESSION_KEY)
clearLogoutListener(player, BA_SESSION_KEY)
//remove from barbsession barbmteam
}*/
fun removePlayer(player: Player) {
val idx = slotOf(player)
if (idx == -1) return
slots[idx] = null
}
fun setRoleForPlayer(player: Player, role: BarbRole): Boolean {
val idx = slotOf(player)
if (idx == -1) return false
slots[idx]?.role = role
allPlayers().forEach { updateRoleAvailabilityFor(it) }
return true
}
fun getRoleForPlayer(player: Player): BarbRole? {
val idx = slotOf(player)
return slots.getOrNull(idx)?.role
}
fun getLeader(): PartySlot? {
return slots[0]
}
fun roleCounts(): RoleCounts {
var att = 0
var def = 0
var coll = 0
var heal = 0
slots.forEach { slot ->
when (slot?.role) {
BarbRole.ATTACKER -> att++
BarbRole.DEFENDER -> def++
BarbRole.COLLECTOR -> coll++
BarbRole.HEALER -> heal++
null -> {}
}
}
return RoleCounts(att, def, coll, heal)
}
fun updateRoleAvailabilityFor(player: Player) {
updateRoleAvailability(roleCounts(),assignedRoleCount(),player )
}
fun assignedRoleCount(): Int =
slots.count { it?.role != null }
fun spawnLocationFor(player: Player): Location {
val idx = slotOf(player)
val (x, y) = PartySpawns[idx]
return session.base.transform(x, y, 0)
}
}
data class RoleCounts(val att: Int, val def: Int, val coll: Int, val heal: Int )
object BarbTeamManager {
fun createTeam(leader: Player): Boolean {
val session = BarbassaultActivity.createSession(leader)
// if (session.team != null) return false
val team = BarbTeam(session, leader)
session.team = team
sendMessage(leader, "TeamCreated")
updateTeam(team)
return true
}
fun disbandTeam(session: BarbassaultSession) {
val team = session.team ?: return
team.allPlayers().forEach {
it.sendMessage("Your leader has left the room and therefore cleared the team!")
it.removeAttribute("ba-session")
updateCurrentTeam(it)
if (session.state == BarbassaultState.STARTING) {
it.properties.teleportLocation = Location.create(2593, 5264, 0)
}
}
session.endSession()
}
fun joinTeam(player: Player, role: BarbRole): Boolean {
val session = player.baSession ?: return false
val team = session.team ?: return false
team.recruit = null
if (!team.addPlayer(player)) {
player.sendMessage("That party is full.")
return false
}
team.setRoleForPlayer(player, role)
team.allPlayers().forEach {
updateCurrentTeam(it)
if (it != player)
it.sendMessage("Your application has been accepted")
}
return true
}
fun abandonTeam(player: Player) {
val session = player.baSession ?: return
val team = session.team ?: return
if (team.isLeader(player)) {
disbandTeam(session)
return
}
team.removePlayer(player)
player.baSession = null
updateCurrentTeam(player)
updateTeam(team)
}
fun updateTeam(team: BarbTeam) {
team.allPlayers().forEach {
updateCurrentTeam(it)
}
}
fun acceptInvite(player: Player, role: BarbRole) {
val session = player.baSession ?: return
val team = session.team ?: return
val recruit = team.recruit ?: return
if (recruit.player != player) return
joinTeam(player, role)
team.recruit = null
}
}
//Leader leaving room and causing disband "Your leader has left the room and therefore cleared the team!"
// //"Your recruiter exited the room."
//Accpting invite text " Your application has been accepted"
//The applicant declined your offer.
//the other player hasn't confirmed their role yet.
//the applicant has chosen a role.0
//You removed the person from the team.

View file

@ -1,28 +1,31 @@
package content.minigame.barbassault.lobby
import content.minigame.barbassault.BarbRole
import content.minigame.barbassault.party.Party
import content.minigame.barbassault.party.PartyHandler
import content.minigame.barbassault.party.PartyService
import content.minigame.barbassault.BarbassaultActivity
import content.minigame.barbassault.arena.BarbassaultSession
import content.minigame.barbassault.arena.BarbassaultState
import content.minigame.barbassault.lobby.BarbTeamManager.abandonTeam
import content.minigame.barbassault.lobby.BarbTeamManager.createTeam
import content.minigame.barbassault.lobby.BarbTeamManager.disbandTeam
import content.minigame.barbassault.lobby.BarbTeamManager.joinTeam
import content.minigame.duel.DuelSession
import core.api.*
import core.game.component.Component
import core.game.interaction.IntType
import core.game.interaction.InteractionListener
import core.game.node.Node
import core.game.node.entity.Entity
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.system.task.Pulse
import core.game.world.GameWorld.ticks
import core.game.world.map.zone.ZoneBorders
import content.minigame.barbassault.arena.BarbassaultSession
import core.game.world.map.build.DynamicRegion
import org.rs09.consts.Items
import org.rs09.consts.Scenery
import org.rs09.consts.Sounds
//"-- Next wave no longer starting"
private var activity: BarbassaultActivity? = null
class BarbassaultLobby : InteractionListener, MapArea {
override fun defineAreaBorders(): Array<ZoneBorders> {
@ -32,16 +35,16 @@ class BarbassaultLobby : InteractionListener, MapArea {
updatePlayerWave(entity)
// openOverlay(entity, 256)
// Components.BARBASSAULT_PLAYERSTAT_490
sendMessage(entity as Player,"Party system is NOT Fully Implemented!!")
}
override fun areaLeave(entity: Entity, logout: Boolean) {
if (entity is Player) {
entity.interfaceManager.closeOverlay()
val barbassItems = intArrayOf(Items.POISONED_WORMS_10540)
//abandonTeam(entity) // Right here, its breaking things
entity.equipment.removeAll(barbassItems)
entity.inventory.removeAll(barbassItems)
}
}
fun updatePlayerWave(entity: Entity) {
@ -67,23 +70,31 @@ class BarbassaultLobby : InteractionListener, MapArea {
//collector 20563 : ch13
//healer 20569 : ch14
override fun defineListeners() {
onUseWithPlayer(Items.SCROLL_10512) { inviter, _, invitee ->
val role = BarbRole.DEFENDER
PartyService.inviteToParty(inviter, invitee as Player, role)
onUseWithPlayer(Items.SCROLL_10512) { leader, _, node ->
val follower = node.asPlayer()
val session = leader.baSession
val team = session?.team
val partyId = inviter.getAttribute<Int>("barbass:party-id")
val party = partyId?.let { PartyHandler.getParty(it) }
if (party != null) {
for (member in party.allMembers()) {
PartyService.updatePartyInterface(member.player)
}
if (team == null) {
leader.sendMessage("No active session found.")
return@onUseWithPlayer false
}
return@onUseWithPlayer true
follower.baSession?.let { return@onUseWithPlayer false } // already on a team
team.recruit = PendingRecruit(follower)
follower.baSession = session
//leader.sendMessage(team.recruit?.player?.username ?: "null")
// joinTeam(follower,BarbRole.DEFENDER)
openInterface(follower, 493)
openInterface(leader, 492)
return@onUseWithPlayer true
}
on(Items.SCROLL_10512, IntType.ITEM, "Read") { player, _ ->
//https://youtu.be/GYh6JPKNOSA?t=233 -- I know 2017, but only example for read scroll iv found.
// ima cry, that YT account got deleted.
// waveAdvance(player)
return@on true
@ -91,43 +102,49 @@ class BarbassaultLobby : InteractionListener, MapArea {
on(Items.SCROLL_10512, IntType.ITEM, "Write-Role") { player, _ ->
//player.interfaceManager.open(Component(493))
//setInterfaceModel(player, 20561, 493, 8,1)
sendDialogueOptions(
player,
"Which role would you like to perform?",
"Attacker", "Defender","Collector","Healer","Cancel")
addDialogueAction(player) { player , buttonId ->
writeRole(player,buttonId)
}
sendDialogueOptions(player, "Which role would you like to perform?","Attacker", "Defender","Collector","Healer","Cancel")
addDialogueAction(player) { _ , buttonId -> writeRole(player,buttonId) }
return@on true
}
on(Items.SCROLL_10512, IntType.ITEM, "Clear") { player, _ ->
val partyId = player.getAttribute<Int>("barbass:party-id") ?: return@on true
val party = PartyHandler.getParty(partyId) ?: return@on true
if (party.getLeader() != player) {
player.sendMessage("Only the party leader can clear the party.")
return@on true
val session = player.baSession
val team = session?.team
if (team != null) {
disbandTeam(session)
createTeam(player)
} else {
createTeam(player)
}
val members = party.allMembers().map { it.player }
for (member in members) {
member.removeAttribute("barbass:party-id")
sendMessage(member,"The party has been cleared.")
closeOverlay(member)
openOverlay(member, 256)
PartyService.updatePartyInterface(member)
}
PartyHandler.removeParty(partyId)
return@on true
}
on(Items.SCROLL_10512, IntType.ITEM, "Destroy") { player, item ->
player.dialogueInterpreter.sendDestroyItem(item.id, item.name)
addDialogueAction(player) { _, button ->
if (button == 3) {
if (removeItem(player, item)) {
playAudio(player, Sounds.DESTROY_OBJECT_2381)
abandonTeam(player)
//updateCurrentTeam(player)
}
}
}
return@on true
}
on(Scenery.LADDER_20193, IntType.SCENERY, "Climb-down") { player, _ ->
val session = player.baSession ?: run {
player.sendMessage("You are not in a session!")
return@on true
}
if (session.state != BarbassaultState.PARTY_CREATION) {
player.sendMessage("Your team is already starting or in the arena!")
return@on true
}
closeOverlay(player) // close party,
openOverlay(player, 494)// open countdown, Make a Count DownHandler
//start a session
// val session = BarbassaultSession(DynamicRegion.create(8011), activity!!)
// session.start(intArrayOf(player))
openOverlay(player, 494)// open countdown,
session.beginStartingPhase()
return@on true
}
on(Scenery.DOOR_20209, IntType.SCENERY, "Pass") { player, node ->
@ -156,7 +173,9 @@ class BarbassaultLobby : InteractionListener, MapArea {
when (buttonId) {
2 -> {
if (player.inventory.add(Item(Items.SCROLL_10512, 1))) {
player.sendMessage("You take scroll from table")
if (createTeam(player)){
player.sendMessage("You take scroll from table")
}
} else {
player.sendMessage("You dont have enough inventory space")
}
@ -213,35 +232,17 @@ class BarbassaultLobby : InteractionListener, MapArea {
else -> null
}
}
fun createPartyAsLeader(leader: Player, role: BarbRole): Int {
val (partyId, party) = PartyHandler.createNewParty()
val success = party.add(leader, role)
sendMessage(leader, "Party created with ID: $partyId")
if (!success) {
PartyHandler.removeParty(partyId)
}
return partyId
}
fun writeRole(player: Player, buttonId: Int) {
if (buttonId == 6) return
val playerRole = getRoleFromButton(buttonId) ?: return
val partyId = player.getAttribute<Int>("barbass:party-id")
val party = partyId?.let { PartyHandler.getParty(it) }
if (party != null) {
val roleCount = party.allMembers().count { it.role == playerRole }
if (roleCount >= 2) {
sendMessage(player,"That role is already full.")
return
}
party.changeRole(player, playerRole)
PartyService.updatePartyInterface(player)
} else {
val newPartyId = createPartyAsLeader(player, playerRole)
PartyService.updatePartyInterface(player)
if (player.baSession?.team != null) {
player.baSession?.team?.setRoleForPlayer(player, playerRole)
BarbTeamManager.updateTeam(player.baSession?.team!!)
sendMessage(player, "You've set your role to ${playerRole.name.lowercase().replaceFirstChar { it.uppercase() }}"
)
}
sendMessage(player,"You've set your role to ${playerRole.name.lowercase().replaceFirstChar { it.uppercase() }}")
}
fun handlePlayerOptionDoor(player: Player, roomRoleOptions:(RoomRole) -> Unit){
@ -285,20 +286,22 @@ class BarbassaultLobby : InteractionListener, MapArea {
val insideRoom = playerLoc.y <= doorLoc.y
val moveY = if (insideRoom) 1 else -1
//ToDo fix walking trough wall when Using door from side.
if (insideRoom) { forceMove(player, playerLoc, doorLoc, 25, 60, null, 819) }
forceMove(player, playerLoc, playerLoc.transform(0, moveY, 0), 25, 60, null, 819) {
if (insideRoom) {
//player.baSession = null
abandonTeam(player)
closeOverlay(player)
PartyService.leaveParty(player)
player.inventory.removeAll(Items.SCROLL_10512)
} else {
openOverlay(player, iface)
player.sendMessage("you enter wave ${BARBWAVEDOOR[node.id]}")
}
}
}
}
fun waveAdvance(player: Player) {
var wave = player.getAttribute("barbass:wave", 1)
val wave = player.getAttribute("barbass:wave", 1)
if (wave in 1..waveLobbies.size) {
val targetLobby = waveLobbies[wave]
teleport(player, targetLobby.randomWalkableLoc)
@ -349,7 +352,8 @@ class BarbassaultLobby : InteractionListener, MapArea {
MAIN_LOBBY
)
val BARBDOORS = intArrayOf( Scenery.DOOR_20199,
val BARBDOORS = intArrayOf(
Scenery.DOOR_20199,
Scenery.DOOR_20200,
Scenery.DOOR_20201,
Scenery.DOOR_20202,
@ -359,7 +363,7 @@ class BarbassaultLobby : InteractionListener, MapArea {
Scenery.DOOR_20206,
Scenery.DOOR_20207,
Scenery.DOOR_20208,
)
)
}
val BARBWAVEDOOR = hashMapOf(
20199 to 1,

View file

@ -0,0 +1,74 @@
package content.minigame.barbassault.lobby
import content.minigame.barbassault.BarbRole
import content.minigame.barbassault.lobby.CurrentTeam.ROLE_MODEL_MAP
import content.minigame.barbassault.lobby.CurrentTeam.modelZoom
import core.api.sendMessage
import core.api.setInterfaceModel
import core.api.setInterfaceText
import core.game.component.Component
import core.game.component.ComponentDefinition
import core.game.component.ComponentPlugin
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.plugin.Initializable
import core.plugin.Plugin
import org.rs09.consts.Items
@Initializable
class CurrentTeamInterface : ComponentPlugin() {
override fun newInstance(arg: Any?): Plugin<Any> {
ComponentDefinition.forId(CurrentTeam.ID).plugin = this
return this
}
override fun handle(player: Player?,component: Component?,opcode: Int,button: Int,slot: Int,itemId: Int ): Boolean {
return true
}
override fun open(player: Player?, component: Component?) {
super.open(player, component)
player ?: return
if(player.inventory.containsItem(Item(Items.SCROLL_10512, 1)) ) {
setInterfaceText(player, player.username, CurrentTeam.ID, CurrentTeam.team[0].name)
//the leader might be able to take scroll between rooms? need Proof
}
}
}
fun updateCurrentTeam(player: Player) {
val team = player.baSession?.team
for (slotIndex in 0 until BarbTeam.MAX_SLOTS) {
val uiSlot = CurrentTeam.team[slotIndex]
val partySlot = team?.getSlot(slotIndex)
val slotPlayer = partySlot?.player
val slotRole = partySlot?.role
val nameText = slotPlayer?.name?.capitalizeWords() ?: CurrentTeam.defaultText
val model = slotRole?.let { ROLE_MODEL_MAP[it] } ?: -1
setInterfaceText(player, nameText, CurrentTeam.ID, uiSlot.name)
setInterfaceModel(player, model, CurrentTeam.ID, uiSlot.role, modelZoom)
}
}
fun String.capitalizeWords(): String = split('_').joinToString("_") { it.replaceFirstChar { c -> c.uppercaseChar() } }
object CurrentTeam {
const val ID = 256
val defaultText = "-----"
val modelZoom = 2372
val ROLE_MODEL_MAP = mapOf(BarbRole.ATTACKER to 20561,BarbRole.COLLECTOR to 20563,BarbRole.DEFENDER to 20566,BarbRole.HEALER to 20569)
data class Slot(val role: Int, val name: Int)
val team = listOf(
Slot(16, 6),
Slot(17, 7),
Slot(18, 8),
Slot(19, 9),
Slot(20, 10)
)
}

View file

@ -0,0 +1,159 @@
package content.minigame.barbassault.lobby
import content.minigame.barbassault.BarbRole
import content.minigame.barbassault.lobby.BarbTeamManager.joinTeam
import core.api.*
import core.game.component.Component
import core.game.component.ComponentDefinition
import core.game.component.ComponentPlugin
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.plugin.Plugin
@Initializable
class RoleSelectInterface : ComponentPlugin() {
override fun open(player: Player?, component: Component?) {
super.open(player, component)
var isopen = true
player ?: return
val team = player.baSession?.team;
if (team != null) { team.updateRoleAvailabilityFor(player) }
component?.setCloseEvent { player, c ->
val leader = team?.getLeader()?.player;
if (leader != null && leader != player && isopen) {
isopen = false
closeInterface(leader)
//if team.recruit not on team, team.recruit?.player?.baSession = null
team.recruit?.player?.baSession = null
team.recruit = null
}
return@setCloseEvent true
}
val leaderData = player.baSession?.team?.getLeader() ?: run {
player.sendMessage("No leader found for your team.")
return
}
setInterfaceText(player, leaderData!!.player.name.capitalizeWords(),SelectRole.ID,SelectRole.Leader.name)
setInterfaceText(player, leaderData.role.toString(),SelectRole.ID,SelectRole.Leader.role)
setInterfaceText(player,"0",SelectRole.ID,SelectRole.Leader.wave)
}
var selectedButton = -1
val roleButtons = mapOf( SelectRole.Att to listOf(8, 9), SelectRole.Def to listOf(10, 11), SelectRole.Col to listOf(12, 13),SelectRole.Heal to listOf(14,15) )
val buttonRoleMap = roleButtons.flatMap { (role, buttons) -> buttons.map { it to role }}.toMap()
val selectRoleToBarbRole = mapOf(SelectRole.Att to BarbRole.ATTACKER,SelectRole.Def to BarbRole.DEFENDER, SelectRole.Col to BarbRole.COLLECTOR, SelectRole.Heal to BarbRole.HEALER )
override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean {
if (player == null) return true
val team = player.baSession?.team;
val pending = team?.recruit ?: return true
when (button) {
SelectRole.AcceptButton, SelectRole.AcceptButtonText -> {
val selectedRole = pending.role
if (selectedRole != null) {
joinTeam(pending.player, selectedRole)
player.sendMessage("You have joined as ${selectedRole.name}.")
team.recruit = null
} else {
player.sendMessage("You must select a role first!")
}
return true
}
SelectRole.DeclineButton, SelectRole.DeclineButtonText -> {
handleDecline(player)
return true
}
}
val clickedSelectRole = buttonRoleMap[button]
if (clickedSelectRole != null && clickedSelectRole.isActive) {
pending.role = selectRoleToBarbRole[clickedSelectRole]
val displayName = pending.role?.name ?: "Unknown"
setInterfaceText(player, displayName, SelectRole.ID, SelectRole.Status.CurrentRole)
selectedButton = button
} else {
}
return true
}
override fun newInstance(arg: Any?): Plugin<Any> {
ComponentDefinition.forId(SelectRole.ID).plugin = this
return this
}
}
fun updateRoleAvailability( counts: RoleCounts, partySize: Int, player: Player ) {
fun canAdd(current: Int, missingRoles: Int): Boolean {
if (partySize >= 5) return false
if (current >= 2) return false
val remainingSlots = 5 - (partySize + 1)
return remainingSlots >= missingRoles
}
val missingRoles = listOf(counts.att, counts.def, counts.coll, counts.heal ).count { it == 0 }
setRoleActive( SelectRole.Att, canAdd( counts.att, if ( counts.att == 0) maxOf(0, missingRoles - 1) else missingRoles ), player )
setRoleActive( SelectRole.Def, canAdd( counts.def, if ( counts.def == 0) maxOf(0, missingRoles - 1) else missingRoles ), player )
setRoleActive( SelectRole.Col, canAdd( counts.coll,if (counts.coll == 0) maxOf(0, missingRoles - 1) else missingRoles ), player )
setRoleActive(SelectRole.Heal, canAdd( counts.heal,if (counts.heal == 0) maxOf(0, missingRoles - 1) else missingRoles ), player )
}
private fun setRoleActive(role: SelectRole.Role, active: Boolean, player: Player) {
role.setActive(active)
setInterfaceModel(player,role.model,SelectRole.ID,role.componentId,0)
setComponentVisibility(player,SelectRole.ID,role.activeChild,!role.isActive)
}
private fun handleAccept(player: Player){
return
}
private fun handleDecline(player: Player) {
closeInterface(player)
val leader = player.baSession?.team?.getLeader()?.player
if (leader != null && leader != player) {
closeInterface(leader)
sendMessage(leader, "The applicant declined your offer.")
}
}
object SelectRole {
const val ID = 493
const val AcceptButton = 16
const val AcceptButtonText = 17
const val DeclineButton = 18
const val DeclineButtonText = 7
class Role(val roleName: String, val componentId: Int, val activeModel: Int, val inactiveModel: Int, val activeChild: Int) {
var isActive: Boolean = false; private set
fun setActive(active: Boolean) { isActive = active }
val model: Int get() = if (isActive) activeModel else inactiveModel
}
val Att = Role("Attacker",8, 20561, 20560, 20)
val Def = Role("Defender",10, 20566, 20567, 55)
val Col = Role("Collector",13, 20563, 20564, 54)
val Heal = Role("Healer", 14, 20569, 20570, 53)
data class Slot(val name: Int, val role: Int, val wave: Int)
val Leader = Slot(28, 33, 39)
val Followers = listOf(
Slot(29, 34, 40),
Slot(30, 35, 41),
Slot(31, 36, 42),
Slot(32, 37, 43),
)
object Status {
const val CurrentRole = 19
const val WaitingForAccept = 22
}
}

View file

@ -1,106 +0,0 @@
package content.minigame.barbassault.party
import content.minigame.barbassault.BarbRole
import core.game.node.entity.player.Player
//todo fix party system. Maybe toss it all away and start over.
data class PartyMember(val player: Player, var role: BarbRole)
class Party(val id: Int) {
companion object {
const val MAX_MEMBERS = 5
const val MAX_PER_ROLE = 2
}
private val slots = MutableList<PartyMember?>(MAX_MEMBERS) { null }
private var leader: Player? = null
fun add(player: Player, role: BarbRole): Boolean {
// Check if player is already in party
if (slots.any { it?.player == player }) return false
// Check if party full
if (slots.count { it != null } >= MAX_MEMBERS) return false
// Check role limit
if (slots.count { it?.role == role } >= MAX_PER_ROLE) return false
// Find first empty slot
val emptyIndex = slots.indexOfFirst { it == null }
if (emptyIndex == -1) return false // no empty slots
slots[emptyIndex] = PartyMember(player, role)
if (leader == null) leader = player
player.setAttribute("barbass:party-id", this.id)
updateInterfaces()
return true
}
fun remove(player: Player): Boolean {
val index = slots.indexOfFirst { it?.player == player }
if (index == -1) return false // not in party
slots[index]?.player?.removeAttribute("barbass:party-id")
slots[index] = null
if (leader == player) {
disband()
} else {
updateInterfaces()
}
return true
}
fun updateInterfaces() {
slots.filterNotNull().forEach {
PartyService.updatePartyInterface(it.player)
}
}
fun disband() {
slots.filterNotNull().forEach {
it.player.removeAttribute("barbass:party-id")
it.player.sendMessage("The party has been disbanded.")
PartyService.updatePartyInterface(it.player)
}
PartyHandler.removeParty(id)
slots.fill(null)
leader = null
}
fun getLeader(): Player? = leader
fun setLeader(player: Player) {
if (slots.any { it?.player == player }) {
leader = player
updateInterfaces()
}
}
fun getRole(player: Player): BarbRole? =
slots.find { it?.player == player }?.role
fun changeRole(player: Player, newRole: BarbRole): Boolean {
val slot = slots.find { it?.player == player } ?: return false
if (slots.count { it?.role == newRole } >= MAX_PER_ROLE) return false
slot.role = newRole
updateInterfaces()
return true
}
fun contains(player: Player): Boolean =
slots.any { it?.player == player }
fun size(): Int = slots.count { it != null }
fun allMembers(): List<PartyMember> = slots.filterNotNull()
fun getSlots(): List<PartyMember?> = slots.toList()
fun clear() {
slots.filterNotNull().forEach {
it.player.removeAttribute("barbass:party-id")
}
slots.fill(null)
leader = null
updateInterfaces()
}
}

View file

@ -1,39 +0,0 @@
package content.minigame.barbassault.party
object PartyHandler {
private val parties = mutableMapOf<Int, Party>()
private val freedIds = ArrayDeque<Int>()
private var nextPartyId = 1
fun createNewParty(): Pair<Int, Party> {
val id = if (freedIds.isNotEmpty()) freedIds.removeFirst() else nextPartyId++
val party = Party(id)
parties[id] = party
return id to party
}
fun getOrCreateParty(id: Int): Party =
parties.getOrPut(id) { Party(id) }
fun getParty(id: Int): Party? = parties[id]
fun removeParty(id: Int) {
if (parties.remove(id) != null) {
freedIds.add(id)
}
}
fun allParties(): Map<Int, Party> = parties.toMap()
fun cleanupOfflineParties() {
val toRemove = parties.filter { (_, party) ->
val leader = party.getLeader()
leader == null || !leader.isActive()
}.keys
for (partyId in toRemove) {
removeParty(partyId)
println("Removed party $partyId because leader was offline or null.")
}
}
}

View file

@ -1,107 +0,0 @@
package content.minigame.barbassault.party
import content.minigame.barbassault.BarbRole
import core.api.sendMessage
import core.api.setInterfaceModel
import core.api.setInterfaceText
import core.game.node.entity.player.Player
class PartyService {
companion object {
fun inviteToParty(inviter: Player, invitee: Player, role: BarbRole) {
val partyId = inviter.getAttribute<Int>("barbass:party-id")
val party = partyId?.let { PartyHandler.getParty(it) }
when {
partyId == null -> sendMessage(inviter, "You're not in a party.")
party == null -> sendMessage(inviter, "Party $partyId not found.")
!party.contains(inviter) -> sendMessage(inviter, "You are not a member of party $partyId.")
invitee.getAttribute<Int>("barbass:party-id") != null -> sendMessage(inviter, "${invitee.name} is already in a party.")
party.size() >= Party.MAX_MEMBERS -> sendMessage(inviter, "Party is full.")
party.allMembers().count { it.role == role } >= Party.MAX_PER_ROLE -> sendMessage(inviter, "Too many players with the role $role.")
!party.add(invitee, role) -> sendMessage(inviter, "Failed to add ${invitee.name} as $role.")
party.getLeader() != inviter -> sendMessage(inviter, "Only the party leader can invite players.")
else -> {
invitee.setAttribute("barbass:party-id", partyId)
val formattedRole = role.name.lowercase().replaceFirstChar { it.uppercase() }
sendMessage(inviter, "${invitee.name} joined your party as $formattedRole.")
}
}
}
fun updatePartyInterface(player: Player) {
val ROLE_MODEL_MAP = mapOf(
BarbRole.ATTACKER to 20561,
BarbRole.COLLECTOR to 20563,
BarbRole.DEFENDER to 20566,
BarbRole.HEALER to 20569
)
val iLeaderText = 6
val iPlayerTextStart = 7
val iModelOffset = 10
val modelZoom = 2372
val iDefaultText = "-----"
val partyId = player.getAttribute<Int>("barbass:party-id") ?: return
val party = PartyHandler.getParty(partyId) ?: return
val members = party.allMembers()
val leader = party.getLeader()
if (leader != null) {
val leaderMember = members.find { it.player == leader }
setInterfaceText(player, leader.username, 256, iLeaderText)
setInterfaceModel(player, ROLE_MODEL_MAP[leaderMember?.role] ?: 20561, 256, iLeaderText + iModelOffset, modelZoom)
} else {
setInterfaceText(player, iDefaultText, 256, iLeaderText)
setInterfaceModel(player, 20561, 256, iLeaderText + iModelOffset, modelZoom)
}
val otherMembers = members.filter { it.player != leader }
for (i in 0 until 4) {
val slotTextId = iPlayerTextStart + i
val slotModelId = slotTextId + iModelOffset
if (i < otherMembers.size) {
val member = otherMembers[i]
setInterfaceText(player, member.player.username, 256, slotTextId)
setInterfaceModel(player, ROLE_MODEL_MAP[member.role] ?: 20561, 256, slotModelId, modelZoom)
} else {
setInterfaceText(player, iDefaultText, 256, slotTextId)
setInterfaceModel(player, -1, 256, slotModelId, modelZoom) // Default to attacker icon for empty
}
}
}
fun leaveParty(player: Player) {
val partyId = player.getAttribute<Int>("barbass:party-id") ?: return
val party = PartyHandler.getParty(partyId) ?: return
if (!party.remove(player)) {
player.sendMessage("Failed to leave the party.")
return
}
player.removeAttribute("barbass:party-id")
player.sendMessage("You have left the party.")
updatePartyInterface(player)
// Update remaining party members
for (member in party.allMembers()) {
updatePartyInterface(member.player)
}
if (party.allMembers().isEmpty()) {
PartyHandler.removeParty(partyId)
}
}
}
}