diff --git a/Server/src/main/content/minigame/barbassault/BarbassDevHelper.kt b/Server/src/main/content/minigame/barbassault/BarbassDevHelper.kt index bb3f65c4a..f80ad4c71 100644 --- a/Server/src/main/content/minigame/barbassault/BarbassDevHelper.kt +++ b/Server/src/main/content/minigame/barbassault/BarbassDevHelper.kt @@ -51,6 +51,11 @@ class BarbassDevHelper : CommandSet(Privilege.ADMIN) { dropPenanceEggCluster(player) return@define } + define("cleanfloor"){ player,_-> + val session = player.baSession ?: return@define + session.clearGroundItems() + return@define + } define("spawnwave"){ player,_-> player.baSession?.spawnNpcWave() return@define diff --git a/Server/src/main/content/minigame/barbassault/BarbassaultTut.kt b/Server/src/main/content/minigame/barbassault/BarbassaultTut.kt index b4415c333..943388af1 100644 --- a/Server/src/main/content/minigame/barbassault/BarbassaultTut.kt +++ b/Server/src/main/content/minigame/barbassault/BarbassaultTut.kt @@ -1,16 +1,44 @@ package content.minigame.barbassault +import core.api.MapArea +import core.api.getRegionBorders +import core.api.log import core.api.produceGroundItem +import core.game.node.entity.Entity import core.game.node.entity.npc.NPC -import core.game.node.item.GroundItem import core.game.node.item.GroundItemManager import core.game.world.map.Direction import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.tools.Log import org.rs09.consts.Items import org.rs09.consts.NPCs -class BarbassaultTut { +class BarbassaultTut: MapArea { + + override fun defineAreaBorders(): Array { + //block standard teleports. + BarbassTutNPCs.forEach { + npc -> npc.init() + npc.isWalks = false + + } + spawnItems() + return arrayOf(getRegionBorders(7509)) + } + override fun areaEnter(entity: Entity) { + //todo move tut maparea to barbtut + log(this::class.java, Log.FINE, "ENTERED BARBASS TUT") + } + + + override fun areaLeave(entity: Entity, logout: Boolean) { + //val player = entity as? Player ?: return + log(this::class.java, Log.FINE, "EXITED BARBASS TUT") + } + + companion object { data class TutorialItemSpawn(val itemId: Int, val location: Location) val BarbassTutItems: List = listOf( diff --git a/Server/src/main/content/minigame/barbassault/arena/BarbassaultActivity.kt b/Server/src/main/content/minigame/barbassault/arena/BarbassaultActivity.kt index 201f77c6f..da9ec181a 100644 --- a/Server/src/main/content/minigame/barbassault/arena/BarbassaultActivity.kt +++ b/Server/src/main/content/minigame/barbassault/arena/BarbassaultActivity.kt @@ -27,12 +27,7 @@ import org.rs09.consts.Items private val sessions = mutableListOf() private var activity: BarbassaultActivity? = null @Initializable -open class BarbassaultActivity : ActivityPlugin("barbassault",false, true, true, - ZoneRestriction.CANNON, - ZoneRestriction.FIRES, - ZoneRestriction.FOLLOWERS, - ZoneRestriction.RANDOM_EVENTS -) { +open class BarbassaultActivity : ActivityPlugin("barbassault",false, true, true,ZoneRestriction.CANNON,ZoneRestriction.FIRES,ZoneRestriction.FOLLOWERS,ZoneRestriction.RANDOM_EVENTS) { init { activity = this } @@ -74,7 +69,6 @@ open class BarbassaultActivity : ActivityPlugin("barbassault",false, true, true, } if (e is NPC) { // dropPenanceEggCluster(e) - //GroundItemManager.create(Item(Items.RED_EGG_10532, 1), e.location).apply { forceVisible = true } } return false } diff --git a/Server/src/main/content/minigame/barbassault/arena/BarbassaultGameArea.kt b/Server/src/main/content/minigame/barbassault/arena/BarbassaultArenaListener.kt similarity index 88% rename from Server/src/main/content/minigame/barbassault/arena/BarbassaultGameArea.kt rename to Server/src/main/content/minigame/barbassault/arena/BarbassaultArenaListener.kt index 063517678..26c9df496 100644 --- a/Server/src/main/content/minigame/barbassault/arena/BarbassaultGameArea.kt +++ b/Server/src/main/content/minigame/barbassault/arena/BarbassaultArenaListener.kt @@ -1,9 +1,9 @@ package content.minigame.barbassault.arena import content.minigame.barbassault.BarbRole -import content.minigame.barbassault.BarbassaultTut import content.minigame.barbassault.arena.BaHornSystem.HornHelper.getHealerHorn import content.minigame.barbassault.arena.BarbassaultSession.AttackerStyle +import content.minigame.barbassault.arena.scenery.All_Eggs import content.minigame.barbassault.arena.scenery.EggCannon import content.minigame.barbassault.arena.scenery.EggCannon.Companion.loadEggHopper import content.minigame.barbassault.arena.scenery.EggCannon.Companion.loadHopperEggs @@ -17,21 +17,20 @@ import core.game.global.action.DropListener 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.combat.BattleState import core.game.node.entity.combat.CombatStyle import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.game.node.item.GroundItem +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.GameWorld.Pulser 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 -import core.tools.Log +import core.game.worldevents.holiday.easter.EasterEvent.Companion.BUN_EARS import org.rs09.consts.Items import org.rs09.consts.Scenery @@ -48,45 +47,12 @@ val ATTACKER_ICON = 10556 val DEFENDER_ICON = 10558 val COLLECTOR_ICON = 10557 val HEALER_ICON = 10559 -class BarbassaultGameArea : InteractionListener, MapArea { +class BarbassaultArenaListener : InteractionListener { 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 = listOf( - arenaItems(Items.HAMMER_2347,32,42,0), - arenaItems(Items.LOGS_11760,30,46,0), - arenaItems(Items.LOGS_11760,29,47,0) - ) - - enum class EggCannonSide { WEST, EAST } - data class EggCannonLoc( val side: EggCannonSide, val x: Int, val y: Int, val z: Int, val direction: Direction ) - val eggCannons: List = listOf( - EggCannonLoc(EggCannonSide.WEST, 21, 34, 0, Direction.SOUTH), - EggCannonLoc(EggCannonSide.EAST, 40, 34, 0, Direction.SOUTH) ) - - override fun defineAreaBorders(): Array { - //block standard teleports. - BarbassaultTut.BarbassTutNPCs.forEach { - npc -> npc.init() - npc.isWalks = false - - } - BarbassaultTut.spawnItems() - return arrayOf(getRegionBorders(7509)) - } - override fun areaEnter(entity: Entity) { - //todo move tut maparea to barbtut - log(this::class.java, Log.FINE, "ENTERED BARBASS TUT") - } - - - override fun areaLeave(entity: Entity, logout: Boolean) { - //val player = entity as? Player ?: return - log(this::class.java, Log.FINE, "EXITED BARBASS TUT") - } override fun defineListeners() { //Wrong food message "That's the wrong type of poisoned food to use! Penalty!" @@ -198,12 +164,6 @@ class BarbassaultGameArea : InteractionListener, MapArea { 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? - return@onUnequip false - } - } return@onUnequip true } @@ -212,22 +172,14 @@ class BarbassaultGameArea : InteractionListener, MapArea { sendMessage(player, "You can't remove that!") return@onEquip false } - defineAreaBorders().forEach { border -> - if (border.insideBorder(player)) { - sendMessage(player, "You can't remove that!") - // return@onUnequip false - } - } return@onEquip true } on(LureItems, IntType.GROUNDITEM, "Take") { player, node -> //if (getItemFromEquipment(player, EquipmentSlot.CAPE)?.id != DEFENDER_ICON) { return@on false } // only a defender can interact with lure food. val groundLureItem = findClosestLure(node.location) - if (groundLureItem == null) return@on true removeLure(groundLureItem) - return@on true } on(LureItems, IntType.ITEM, "Drop") { player, node -> @@ -246,6 +198,19 @@ class BarbassaultGameArea : InteractionListener, MapArea { //delete from ground as runner "eats" return@on true } + on(All_Eggs, IntType.GROUNDITEM, "Take") { player, node -> + if (node !is GroundItem) return@on true + + node.isActive = false + GroundItemManager.destroy(node) + val session = player.baSession ?: return@on true + session.BAgroundItems.remove(node) + + + addItemOrDrop(player, node.id) // no room, lets just redrop it, what COULD GO WRONG + + return@on true + } } fun playerChangeScenery(player: Player,anim: Int ,node: Node, newSceneryId: Int, pulseDelay: Int = 3, message: String = "") { @@ -253,7 +218,7 @@ class BarbassaultGameArea : InteractionListener, MapArea { player.animate(Animation(anim)) player.lock(pulseDelay) //if trap send message "You fixed the Penance Runner trap." - GameWorld.Pulser.submit(object : Pulse(pulseDelay, player) { + Pulser.submit(object : Pulse(pulseDelay, player) { override fun pulse(): Boolean { player.unlock() val scenryNode = node as core.game.node.scenery.Scenery diff --git a/Server/src/main/content/minigame/barbassault/arena/BarbassaultSession.kt b/Server/src/main/content/minigame/barbassault/arena/BarbassaultSession.kt index 43b0367d2..b069c6e4d 100644 --- a/Server/src/main/content/minigame/barbassault/arena/BarbassaultSession.kt +++ b/Server/src/main/content/minigame/barbassault/arena/BarbassaultSession.kt @@ -9,13 +9,15 @@ import content.minigame.barbassault.baSession import content.minigame.barbassault.getBarbLevels import content.minigame.barbassault.getBarbWave import content.minigame.barbassault.lobby.* +import content.minigame.barbassault.lobby.BarbassaultLobby.Companion.waveLobbies import core.api.* import core.game.node.entity.Entity import core.game.node.entity.impl.PulseManager import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player -import core.game.node.item.GroundItem +import core.game.node.item.GroundItemManager import core.game.node.item.Item +import core.game.system.config.GroundSpawnLoader import core.game.system.task.Pulse import core.game.world.GameWorld import core.game.world.GameWorld.Pulser @@ -34,6 +36,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 ArenaSpawnItems(val id: Int, val location: Location) class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutListener, MapArea { //constructor(region: DynamicRegion, activity: BarbassaultActivity) : this(activity) {this.region = region; this.base = region.baseLocation} @@ -43,15 +46,14 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutLi lateinit var team: BarbTeam var state: BarbassaultState = BarbassaultState.PARTY_CREATION + val sessionNpcs = mutableListOf() var currentNPCCount = SpawnCaps(0,0,0,0) - val npcTunnel: List = 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), - ) - val BAgroundItems = mutableListOf() + val npcTunnel: List = 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) ) + + val BAgroundItems = mutableListOf() + val arenaSpawnItems: List = 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))) + val eggHopper = EggCannon.EggHopper() var eggCannonNpcWest: NPC? = null var eggCannonNpcEast: NPC? = null @@ -92,6 +94,7 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutLi } Pulser.submit(GamePulse()) + tryGroundItemSpawn() } fun endSession() { @@ -184,11 +187,26 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutLi val npcId = npcIds[type] ?: return val spawn = npcTunnel.firstOrNull { it.type == type } ?: return - var thisNpc = sessionNPCSpawn(npcId, base.transform(30,31,0), spawn.direction) + var thisNpc = sessionNPCSpawn(npcId, location(30,31,0), spawn.direction) thisNpc?.location = base.transform(spawn.toLocation()) increment() } + fun tryGroundItemSpawn(){ + val leader = team.getLeader()?.player ?: return + val groundItems = GroundItemManager.getItems() + + arenaSpawnItems.forEach { spawnItem -> + val spawnLoc = spawnItem.location + val alreadyExists = groundItems.any { it.id == spawnItem.id && it.location == spawnLoc && !it.isRemoved } + if (!alreadyExists) { + val thisGroundItem = produceGroundSpawnItem(6,Item(spawnItem.id, 1),spawnLoc) //produceGroundItem(leader, spawnItem.id, 1, spawnLoc).apply { + sendMessage(leader, "spawned item: $spawnLoc") + } + } + } + + fun forfeit(){ state = BarbassaultState.FORFEIT } fun isInBarbAssaultGame() = state == BarbassaultState.IN_ARENA @@ -215,27 +233,25 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutLi BarbTeamManager.updateTeam(player.baSession?.team!!) } } + //MAIN GAME LOOP private inner class GamePulse : Pulse(1) { - private var roleCallTicks = secondsToTicks(30) - private var waveSpawnTicks = secondsToTicks(6) + private val baseCallTicks = secondsToTicks(30) + private var roleCallTicks = baseCallTicks + + private var baseSpawnTicks = secondsToTicks(6) + private var waveSpawnTicks = baseSpawnTicks + private var groundSpawnTicks = baseSpawnTicks override fun pulse(): Boolean { - //log(this.javaClass, Log.FINE,state.toString()) when(state){ BarbassaultState.IN_ARENA -> { - eventBus.processEvents() // process events such as npc died to scoring + eventBus.processEvents() + roleCallTicks--; waveSpawnTicks--; groundSpawnTicks-- + if (roleCallTicks <= 0) { rollNewRoleCalls(); roleCallTicks = baseCallTicks } + if (waveSpawnTicks <= 0 ){ spawnNpcWave(); waveSpawnTicks = baseSpawnTicks } + - roleCallTicks-- - waveSpawnTicks-- - if (roleCallTicks <= 0) { - rollNewRoleCalls() - roleCallTicks = secondsToTicks(30) - } - if (waveSpawnTicks <= 0 ){ - spawnNpcWave() - waveSpawnTicks = secondsToTicks(6) - } } - BarbassaultState.FORFEIT -> {endGame("left"); return true} + BarbassaultState.FORFEIT -> { endGame("left"); return true } BarbassaultState.COMPLETE -> { log(this.javaClass, Log.FINE,state.toString()) BarbassaultLobby.TeamToLobby(team,team.wave+1) @@ -257,7 +273,7 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutLi } private fun createArena() { - region = DynamicRegion.create(BarbassaultGameArea.BA_ARENA.MAIN) + region = DynamicRegion.create(BarbassaultArenaListener.BA_ARENA.MAIN) base = region.baseLocation zone.zoneType = ZoneType.SAFE.id region.regionZones.add(RegionZone(activity!!, region.borders)) //DONT FORGET THIS STUPID! @@ -283,7 +299,8 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutLi team.removePlayer(player) player.locks.unlockTeleport() - player.location = Location.create(2593, 5264, 0) + player.location = waveLobbies[team.wave].randomWalkableLoc + //player.location = Location.create(2593, 5264, 0) if (team.allPlayers().isEmpty()) { // might be redundant player.properties.teleportLocation = Location.create(2593, 5264, 0) @@ -331,11 +348,17 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutLi destroyArena() } fun sessionNPCSpawn(id: Int, location: Location, direction: Direction, vararg objects: Any): NPC? { - val npc = NPC.create(id, location, direction, *objects) + val npc = NPC.create(id, base.transform(location), direction, *objects) npc.init() sessionNpcs.add(npc) return npc } + fun produceGroundSpawnItem(rate:Int,item: Item,location: Location): SessionGroundSpawn { + val thisGroundItem = SessionGroundSpawn(this,rate,item,location) + thisGroundItem.init() + return thisGroundItem + } + fun spawnEggCannons() { eggCannonNpcWest = sessionNPCSpawn( NPCs.EGG_LAUNCHER_5026, base.transform(21, 34, 0), Direction.NORTH ) //eggCannonNpcWest?. @@ -343,8 +366,16 @@ class BarbassaultSession( val activity: BarbassaultActivity ? = null) :LogoutLi eggCannonNpcEast = sessionNPCSpawn( NPCs.EGG_LAUNCHER_5026, base.transform(40, 34, 0), Direction.NORTH ) } - private fun clearGroundItems(){ + fun clearGroundItems(){ //BAgroundItems + //thisGroundItem.isActive = false + BAgroundItems.forEach { item -> + item.isActive = false + item.setRespawnRate(-1) + item.isAutoSpawn = false + GroundItemManager.destroy(item) + } + } private fun giveRoleItems(player: Player, role: BarbRole) { diff --git a/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceHelper.kt b/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceHelper.kt index 0d1b63129..d44ede145 100644 --- a/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceHelper.kt +++ b/Server/src/main/content/minigame/barbassault/arena/Npcs/PenanceHelper.kt @@ -3,28 +3,28 @@ package content.minigame.barbassault.arena.Npcs import content.minigame.barbassault.baSession import core.api.produceGroundItem +import core.api.sendMessage import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player +import core.game.node.item.Item import core.game.world.map.RegionManager import org.rs09.consts.Items fun dropPenanceEggCluster(killer: Player, npc: NPC? = null) { val center = npc?.dropLocation ?: killer.location + val session = killer.baSession ?: return val tiles = center.get3x3Tiles().shuffled() val eggs = listOf( Items.RED_EGG_10532, Items.RED_EGG_10532, - Items.BLUE_EGG_10533, Items.BLUE_EGG_10533, - Items.GREEN_EGG_10531, Items.GREEN_EGG_10531) + Items.BLUE_EGG_10533, Items.BLUE_EGG_10533, + Items.GREEN_EGG_10531, Items.GREEN_EGG_10531) for (i in eggs.indices) { val tile = tiles[i] - val egg = produceGroundItem(killer, eggs[i], 1, tile).apply { - //todo Find way to make eggs not decay and visible to all - decayTime = 100 - forceVisible = true - isRemainPrivate = false - } - killer.baSession?.BAgroundItems?.add(egg) + val thisGroundItem = session.produceGroundSpawnItem(60,Item(eggs[i],1),tile) + thisGroundItem.init() + sendMessage(killer, tile.toString()) + } } diff --git a/Server/src/main/content/minigame/barbassault/arena/SessionGroundSpawn.kt b/Server/src/main/content/minigame/barbassault/arena/SessionGroundSpawn.kt new file mode 100644 index 000000000..384ae9352 --- /dev/null +++ b/Server/src/main/content/minigame/barbassault/arena/SessionGroundSpawn.kt @@ -0,0 +1,60 @@ +package content.minigame.barbassault.arena +import core.game.node.item.GroundItem +import core.game.node.item.GroundItemManager +import core.game.system.task.Pulse +import core.game.node.item.Item +import core.game.world.GameWorld + +import core.game.world.map.Location + +class SessionGroundSpawn(private var session: BarbassaultSession, private var respawnRate: Int, item: Item?,location: Location?) : GroundItem(item, session.base.transform(location)) { + private var active = true + private var autoSpawn = true + + override fun toString(): String { + return "SessionGroundSpawn [name=$name, respawnRate=$respawnRate, loc=$location]" + } + + fun init(): GroundItem { + session.BAgroundItems.add(this) + return GroundItemManager.create(this) + } + + override fun isActive(): Boolean { + return active + } + + override fun setActive(value: Boolean) { + active = value + } + + override fun isPrivate(): Boolean { + return false + } + + override fun isAutoSpawn(): Boolean { + return autoSpawn + } + + fun setAutoSpawn(value: Boolean) { + autoSpawn = value + } + + override fun respawn() { + if (!autoSpawn || respawnRate < 0) { + return + } + GameWorld.Pulser.submit(object : Pulse(respawnRate) { + override fun pulse(): Boolean { + val thisGroundItem = GroundItemManager.create(this@SessionGroundSpawn) + return true + } + }) + } + + fun setRespawnRate(rate: Int) { + respawnRate = rate + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/barbassault/arena/scenery/EggCannon.kt b/Server/src/main/content/minigame/barbassault/arena/scenery/EggCannon.kt index 5165b4b26..fb31446a6 100644 --- a/Server/src/main/content/minigame/barbassault/arena/scenery/EggCannon.kt +++ b/Server/src/main/content/minigame/barbassault/arena/scenery/EggCannon.kt @@ -30,6 +30,8 @@ import org.rs09.consts.NPCs // half -> EGG_HOPPER_20265 // full -> EGG_HOPPER_20266 //varbit 3268 +val All_Eggs = intArrayOf(Items.GREEN_EGG_10531,Items.RED_EGG_10532,Items.BLUE_EGG_10533) + @Initializable class EggCannon : ComponentPlugin() {