mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2026-08-24 11:55:13 -06:00
Barb Assault:
Reward Interface ( no gamble ) Blackboard Interface Queen help book Commander_Connad Dialog Penance Statues Dialog Private's Dialog Functioning Item Vending Machines Horns cause player to TELL!/Say Penance creatures Started Penance creature configs added Tutorial started ( Needs lots of work ) Game Arena Started ( Needs lots of work ) ContentAPI: added setInterfaceModel
This commit is contained in:
parent
7cf5049687
commit
f2c25bc7ed
33 changed files with 3266 additions and 37 deletions
|
|
@ -45536,8 +45536,6 @@
|
|||
"death_animation": "5937",
|
||||
"name": "Penance Ranger",
|
||||
"defence_level": "1",
|
||||
"safespot": null,
|
||||
"lifepoints": "10",
|
||||
"strength_level": "1",
|
||||
"id": "5229",
|
||||
"aggressive": "true",
|
||||
|
|
@ -45550,7 +45548,23 @@
|
|||
"melee_animation": "5395",
|
||||
"respawn_delay": "60",
|
||||
"defence_animation": "5396",
|
||||
"death_animation": "5937",
|
||||
"death_animation": "5397",
|
||||
"name": "Penance Ranger",
|
||||
"defence_level": "1",
|
||||
"lifepoints": "10",
|
||||
"strength_level": "1",
|
||||
"id": "5230",
|
||||
"aggressive": "true",
|
||||
"range_level": "1",
|
||||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "Shooty-shooty.",
|
||||
"combat_style": "1",
|
||||
"melee_animation": "5395",
|
||||
"respawn_delay": "60",
|
||||
"defence_animation": "5396",
|
||||
"death_animation": "5397",
|
||||
"name": "Penance Ranger",
|
||||
"defence_level": "1",
|
||||
"safespot": null,
|
||||
|
|
@ -81008,11 +81022,25 @@
|
|||
},
|
||||
{
|
||||
"name": "Penance Fighter",
|
||||
"id": "5044"
|
||||
"id": "5044",
|
||||
"combat_audio": "670,672,671",
|
||||
"melee_animation": "5097",
|
||||
"range_animation": "5097",
|
||||
"attack_speed": "4",
|
||||
"defence_animation": "5096",
|
||||
"magic_animation": "5097",
|
||||
"death_animation": "5098"
|
||||
},
|
||||
{
|
||||
"name": "Penance Fighter",
|
||||
"id": "5045"
|
||||
"id": "5045",
|
||||
"combat_audio": "670,672,671",
|
||||
"melee_animation": "5097",
|
||||
"range_animation": "5097",
|
||||
"attack_speed": "4",
|
||||
"defence_animation": "5096",
|
||||
"magic_animation": "5097",
|
||||
"death_animation": "5098"
|
||||
},
|
||||
{
|
||||
"name": "Jack",
|
||||
|
|
@ -81328,131 +81356,287 @@
|
|||
},
|
||||
{
|
||||
"name": "Penance Fighter",
|
||||
"id": "5213"
|
||||
"id": "5213",
|
||||
"combat_audio": "670,672,671",
|
||||
"melee_animation": "5097",
|
||||
"range_animation": "5097",
|
||||
"attack_speed": "4",
|
||||
"defence_animation": "5096",
|
||||
"magic_animation": "5097",
|
||||
"death_animation": "5098"
|
||||
},
|
||||
{
|
||||
"name": "Penance Fighter",
|
||||
"id": "5214"
|
||||
"id": "5214",
|
||||
"combat_audio": "670,672,671",
|
||||
"melee_animation": "5097",
|
||||
"range_animation": "5097",
|
||||
"attack_speed": "4",
|
||||
"defence_animation": "5096",
|
||||
"magic_animation": "5097",
|
||||
"death_animation": "5098"
|
||||
},
|
||||
{
|
||||
"name": "Penance Fighter",
|
||||
"id": "5215"
|
||||
"id": "5215",
|
||||
"combat_audio": "670,672,671",
|
||||
"melee_animation": "5097",
|
||||
"range_animation": "5097",
|
||||
"attack_speed": "4",
|
||||
"defence_animation": "5096",
|
||||
"magic_animation": "5097",
|
||||
"death_animation": "5098"
|
||||
},
|
||||
{
|
||||
"name": "Penance Fighter",
|
||||
"id": "5216"
|
||||
"id": "5216",
|
||||
"combat_audio": "670,672,671",
|
||||
"melee_animation": "5097",
|
||||
"range_animation": "5097",
|
||||
"attack_speed": "4",
|
||||
"defence_animation": "5096",
|
||||
"magic_animation": "5097",
|
||||
"death_animation": "5098"
|
||||
},
|
||||
{
|
||||
"name": "Penance Fighter",
|
||||
"id": "5217"
|
||||
"id": "5217",
|
||||
"combat_audio": "670,672,671",
|
||||
"melee_animation": "5097",
|
||||
"range_animation": "5097",
|
||||
"attack_speed": "4",
|
||||
"defence_animation": "5096",
|
||||
"magic_animation": "5097",
|
||||
"death_animation": "5098"
|
||||
},
|
||||
{
|
||||
"name": "Penance Fighter",
|
||||
"id": "5218"
|
||||
"id": "5218",
|
||||
"combat_audio": "670,672,671",
|
||||
"melee_animation": "5097",
|
||||
"range_animation": "5097",
|
||||
"attack_speed": "4",
|
||||
"defence_animation": "5096",
|
||||
"magic_animation": "5097",
|
||||
"death_animation": "5098"
|
||||
},
|
||||
{
|
||||
"name": "Penance Fighter",
|
||||
"id": "5219"
|
||||
"id": "5219",
|
||||
"combat_audio": "670,672,671",
|
||||
"melee_animation": "5097",
|
||||
"range_animation": "5097",
|
||||
"attack_speed": "4",
|
||||
"defence_animation": "5096",
|
||||
"magic_animation": "5097",
|
||||
"death_animation": "5098"
|
||||
},
|
||||
{
|
||||
"name": "Penance Runner",
|
||||
"id": "5220"
|
||||
"id": "5220",
|
||||
"defence_animation": "5101",
|
||||
"death_animation": "5106"
|
||||
},
|
||||
{
|
||||
"name": "Penance Runner",
|
||||
"id": "5221"
|
||||
"id": "5221",
|
||||
"defence_animation": "5101",
|
||||
"death_animation": "5106"
|
||||
},
|
||||
{
|
||||
"name": "Penance Runner",
|
||||
"id": "5222"
|
||||
"id": "5222",
|
||||
"defence_animation": "5101",
|
||||
"death_animation": "5106"
|
||||
},
|
||||
{
|
||||
"name": "Penance Runner",
|
||||
"id": "5223"
|
||||
"id": "5223",
|
||||
"defence_animation": "5101",
|
||||
"death_animation": "5106"
|
||||
},
|
||||
{
|
||||
"name": "Penance Runner",
|
||||
"id": "5224"
|
||||
"id": "5224",
|
||||
"defence_animation": "5101",
|
||||
"death_animation": "5106"
|
||||
},
|
||||
{
|
||||
"name": "Penance Runner",
|
||||
"id": "5225"
|
||||
"id": "5225",
|
||||
"defence_animation": "5101",
|
||||
"death_animation": "5106"
|
||||
},
|
||||
{
|
||||
"name": "Penance Runner",
|
||||
"id": "5226"
|
||||
"id": "5226",
|
||||
"defence_animation": "5101",
|
||||
"death_animation": "5106"
|
||||
},
|
||||
{
|
||||
"name": "Penance Runner",
|
||||
"id": "5227"
|
||||
"id": "5227",
|
||||
"defence_animation": "5101",
|
||||
"death_animation": "5106"
|
||||
},
|
||||
{
|
||||
"name": "Penance Runner",
|
||||
"id": "5228"
|
||||
"id": "5228",
|
||||
"defence_animation": "5101",
|
||||
"death_animation": "5106"
|
||||
},
|
||||
{
|
||||
"name": "Penance Ranger",
|
||||
"id": "5230"
|
||||
"id": "5230",
|
||||
"combat_style": "1",
|
||||
"melee_animation": "5395",
|
||||
"defence_animation": "5396",
|
||||
"death_animation": "5397",
|
||||
"aggressive": "true"
|
||||
},
|
||||
{
|
||||
"name": "Penance Ranger",
|
||||
"id": "5231"
|
||||
"id": "5231",
|
||||
"combat_style": "1",
|
||||
"melee_animation": "5395",
|
||||
"defence_animation": "5396",
|
||||
"death_animation": "5397",
|
||||
"aggressive": "true"
|
||||
},
|
||||
{
|
||||
"name": "Penance Ranger",
|
||||
"id": "5232"
|
||||
"id": "5232",
|
||||
"combat_style": "1",
|
||||
"melee_animation": "5395",
|
||||
"defence_animation": "5396",
|
||||
"death_animation": "5397",
|
||||
"aggressive": "true"
|
||||
},
|
||||
{
|
||||
"name": "Penance Ranger",
|
||||
"id": "5233"
|
||||
"id": "5233",
|
||||
"combat_style": "1",
|
||||
"melee_animation": "5395",
|
||||
"defence_animation": "5396",
|
||||
"death_animation": "5397",
|
||||
"aggressive": "true"
|
||||
},
|
||||
{
|
||||
"name": "Penance Ranger",
|
||||
"id": "5234"
|
||||
"id": "5234",
|
||||
"combat_style": "1",
|
||||
"melee_animation": "5395",
|
||||
"defence_animation": "5396",
|
||||
"death_animation": "5397",
|
||||
"aggressive": "true"
|
||||
},
|
||||
{
|
||||
"name": "Penance Ranger",
|
||||
"id": "5235"
|
||||
"id": "5235",
|
||||
"combat_style": "1",
|
||||
"melee_animation": "5395",
|
||||
"defence_animation": "5396",
|
||||
"death_animation": "5397",
|
||||
"aggressive": "true"
|
||||
},
|
||||
{
|
||||
"name": "Penance Ranger",
|
||||
"id": "5236"
|
||||
"id": "5236",
|
||||
"combat_style": "1",
|
||||
"melee_animation": "5395",
|
||||
"defence_animation": "5396",
|
||||
"death_animation": "5397",
|
||||
"aggressive": "true"
|
||||
},
|
||||
{
|
||||
"name": "Penance Healer",
|
||||
"id": "5238"
|
||||
"id": "5238",
|
||||
"defence_animation": "5105",
|
||||
"death_animation": "5106",
|
||||
"melee_animation": "5107",
|
||||
"range_animation": "5107",
|
||||
"attack_speed": "4",
|
||||
"magic_animation": "5107"
|
||||
},
|
||||
{
|
||||
"name": "Penance Healer",
|
||||
"id": "5239"
|
||||
"id": "5239",
|
||||
"defence_animation": "5105",
|
||||
"death_animation": "5106",
|
||||
"melee_animation": "5107",
|
||||
"range_animation": "5107",
|
||||
"attack_speed": "4",
|
||||
"magic_animation": "5107"
|
||||
},
|
||||
{
|
||||
"name": "Penance Healer",
|
||||
"id": "5240"
|
||||
"id": "5240",
|
||||
"defence_animation": "5105",
|
||||
"death_animation": "5106",
|
||||
"melee_animation": "5107",
|
||||
"range_animation": "5107",
|
||||
"attack_speed": "4",
|
||||
"magic_animation": "5107"
|
||||
},
|
||||
{
|
||||
"name": "Penance Healer",
|
||||
"id": "5241"
|
||||
"id": "5241",
|
||||
"defence_animation": "5105",
|
||||
"death_animation": "5106",
|
||||
"melee_animation": "5107",
|
||||
"range_animation": "5107",
|
||||
"attack_speed": "4",
|
||||
"magic_animation": "5107"
|
||||
},
|
||||
{
|
||||
"name": "Penance Healer",
|
||||
"id": "5242"
|
||||
"id": "5242",
|
||||
"defence_animation": "5105",
|
||||
"death_animation": "5106",
|
||||
"melee_animation": "5107",
|
||||
"range_animation": "5107",
|
||||
"attack_speed": "4",
|
||||
"magic_animation": "5107"
|
||||
},
|
||||
{
|
||||
"name": "Penance Healer",
|
||||
"id": "5243"
|
||||
"id": "5243",
|
||||
"defence_animation": "5105",
|
||||
"death_animation": "5106",
|
||||
"melee_animation": "5107",
|
||||
"range_animation": "5107",
|
||||
"attack_speed": "4",
|
||||
"magic_animation": "5107"
|
||||
},
|
||||
{
|
||||
"name": "Penance Healer",
|
||||
"id": "5244"
|
||||
"id": "5244",
|
||||
"defence_animation": "5105",
|
||||
"death_animation": "5106",
|
||||
"melee_animation": "5107",
|
||||
"range_animation": "5107",
|
||||
"attack_speed": "4",
|
||||
"magic_animation": "5107"
|
||||
},
|
||||
{
|
||||
"name": "Penance Healer",
|
||||
"id": "5245"
|
||||
"id": "5245",
|
||||
"defence_animation": "5105",
|
||||
"death_animation": "5106",
|
||||
"melee_animation": "5107",
|
||||
"range_animation": "5107",
|
||||
"attack_speed": "4",
|
||||
"magic_animation": "5107"
|
||||
},
|
||||
{
|
||||
"name": "Penance Healer",
|
||||
"id": "5246"
|
||||
"id": "5246",
|
||||
"defence_animation": "5105",
|
||||
"death_animation": "5106",
|
||||
"melee_animation": "5107",
|
||||
"range_animation": "5107",
|
||||
"attack_speed": "4",
|
||||
"magic_animation": "5107"
|
||||
},
|
||||
{
|
||||
"name": "Locust rider",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,378 @@
|
|||
package content.minigame.barbassault
|
||||
|
||||
|
||||
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.game.node.item.Item
|
||||
import core.plugin.Initializable
|
||||
import core.plugin.Plugin
|
||||
import core.tools.*
|
||||
import org.rs09.consts.Components
|
||||
import org.rs09.consts.Items
|
||||
|
||||
@Initializable
|
||||
class BarbRewardInterface : ComponentPlugin() {
|
||||
override fun open(player: Player?, component: Component?) {
|
||||
super.open(player, component)
|
||||
player ?: return
|
||||
updateRewardButtons(player)
|
||||
}
|
||||
var selectedShopButton = -1
|
||||
override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean {
|
||||
//https://youtu.be/AG5Iv-ysAW0?t=11
|
||||
//todo find right values to highlight box blue when selecting.
|
||||
if (button == 213) {
|
||||
player!!.sendMessage("Accepted selection from button: $selectedShopButton")
|
||||
acceptReward(player,selectedShopButton)
|
||||
selectedShopButton = -1
|
||||
return true
|
||||
}
|
||||
selectedShopButton = button
|
||||
updateRewardButtons(player!!, button)
|
||||
return true
|
||||
}
|
||||
override fun newInstance(arg: Any?): Plugin<Any> {
|
||||
ComponentDefinition.forId(Components.BARBASSAULT_REWARD_SHOP_491).plugin = this
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
//may have client side script instead of this.
|
||||
//dumps/scripts/2845.cs2 is for a newer revision with an overhauled interface.
|
||||
|
||||
fun updateRewardButtons(player: Player, selected: Int = -1) {
|
||||
interfaceUpdate(player,selected)
|
||||
|
||||
//points @ bottom
|
||||
val playerPoints = player.getBarbPoints()
|
||||
setInterfaceText(player, playerPoints.atk.toString(), 491, 219)
|
||||
setInterfaceText(player, playerPoints.def.toString(), 491, 220)
|
||||
setInterfaceText(player, playerPoints.col.toString(), 491, 221)
|
||||
setInterfaceText(player, playerPoints.heal.toString(), 491, 222)
|
||||
}
|
||||
|
||||
fun acceptReward(player:Player, selected :Int){
|
||||
if (selected == -1 ) return
|
||||
val reward = barbRewardShop.find { it.buttonChildId == selected } ?: return
|
||||
if (!canBuyReward(player, reward, true)) return
|
||||
|
||||
when {
|
||||
reward.item != null -> { addItem(player, reward.item, 1) }
|
||||
// reward.gamble != null -> { }
|
||||
reward.levelUp != null -> { player.increaseBarbRoleLevel(reward.levelUp) }
|
||||
}
|
||||
removeCost(player, reward)
|
||||
updateRewardButtons(player)
|
||||
}
|
||||
|
||||
fun rollGambleReward(tier: GambleTier): Item {
|
||||
if (tier == GambleTier.HIGH) return Item(Items.DRAGON_CHAINBODY_13481,1)
|
||||
if (tier == GambleTier.MEDIUM) return Item(Items.RUNE_ARROWP_PLUS_5621,52)
|
||||
if (tier == GambleTier.LOW) return Item(Items.UNICORN_HORN_238,10)
|
||||
return Item(Items.FLAX_1779,1)
|
||||
|
||||
}
|
||||
|
||||
fun interfaceUpdate(player: Player, selected: Int) {
|
||||
val playerLevels = player.getBarbLevels()
|
||||
val hasQueenKill = player.hasQueenKill()
|
||||
barbRewardShop.forEach { reward ->
|
||||
val isSelected = reward.buttonChildId == selected
|
||||
val canBuy = canBuyReward(player, reward)
|
||||
val LAVENDER = "<col=D6CCFD>"
|
||||
var costText = reward.rewardCostText.text
|
||||
val nameColor = if (isSelected) BLUE else LAVENDER
|
||||
val resolvedText = if (reward.model != null) {
|
||||
val text = reward.rewardText.resolve(playerLevels).text
|
||||
val model = reward.model.resolve(playerLevels).modelId
|
||||
val perkText = reward.perkText!!.resolve(playerLevels).text
|
||||
|
||||
costText = reward.rewardCostText.resolve(playerLevels).text
|
||||
setInterfaceModel(player, model, 491, reward.model.childId, 2372)
|
||||
setInterfaceText(player, perkText, 491, reward.perkText.childId)
|
||||
text
|
||||
} else {
|
||||
reward.rewardText.text
|
||||
}
|
||||
setInterfaceText(player, nameColor + resolvedText, 491, reward.rewardText.childId)
|
||||
val costColor = if (canBuy) GREEN else RED
|
||||
setInterfaceText(player, costColor + costText, 491, reward.rewardCostText.childId)
|
||||
|
||||
if (reward.queenKillText != null) {
|
||||
val color = if (hasQueenKill) GREEN else RED
|
||||
setInterfaceText(player, color + reward.queenKillText.text, 491, reward.queenKillText.childId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun canBuyReward(player: Player, reward: RewardRow, buying: Boolean = false): Boolean {
|
||||
val points = player.getBarbPoints()
|
||||
val hasQueenKill = player.hasQueenKill()
|
||||
val barbLevels = player.getBarbLevels()
|
||||
val resolvedCost = reward.cost.resolve(barbLevels)
|
||||
|
||||
fun requireQueenKill(base: Boolean): Boolean {
|
||||
return if (buying && reward.queenKillText != null) base && hasQueenKill else base
|
||||
}
|
||||
return when (resolvedCost) {
|
||||
is RewardCost.AllRoles -> requireQueenKill(
|
||||
points.atk >= resolvedCost.amountPerRole &&
|
||||
points.def >= resolvedCost.amountPerRole &&
|
||||
points.col >= resolvedCost.amountPerRole &&
|
||||
points.heal >= resolvedCost.amountPerRole
|
||||
)
|
||||
is RewardCost.AnyRole -> requireQueenKill( listOf( points.atk, points.def, points.col, points.heal).any { it >= resolvedCost.minimum })
|
||||
is RewardCost.Coins -> requireQueenKill(inInventory(player, 995, resolvedCost.amount))
|
||||
is RewardCost.Specific -> {
|
||||
if (isBarbRewardMaxed(reward,barbLevels)) return false
|
||||
requireQueenKill(
|
||||
points.atk >= resolvedCost.required.atk &&
|
||||
points.def >= resolvedCost.required.def &&
|
||||
points.col >= resolvedCost.required.col &&
|
||||
points.heal >= resolvedCost.required.heal
|
||||
)
|
||||
}
|
||||
is RewardCost.Dynamic -> TODO()
|
||||
}
|
||||
}
|
||||
fun isBarbRewardMaxed(reward: RewardRow, barbLevels: BarbAssaultLevels): Boolean {
|
||||
val text = reward.rewardText.text.lowercase()
|
||||
return when {
|
||||
"attacker" in text -> barbLevels.atk >= 5
|
||||
"defender" in text -> barbLevels.def >= 5
|
||||
"collector" in text -> barbLevels.col >= 5
|
||||
"healer" in text -> barbLevels.heal >= 5
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
fun removeCost(player: Player, reward: RewardRow) {
|
||||
val barbLevels = player.getBarbLevels()
|
||||
val resolvedCost = reward.cost.resolve(barbLevels)
|
||||
|
||||
when (resolvedCost) {
|
||||
is RewardCost.AllRoles -> {
|
||||
if (reward.queenKillText != null) { setAttribute(player,"barbass:queen-kill", 0)}
|
||||
player.removeBarbPoints(BarbAssaultPoints(resolvedCost.amountPerRole, resolvedCost.amountPerRole, resolvedCost.amountPerRole, resolvedCost.amountPerRole))
|
||||
}
|
||||
is RewardCost.AnyRole -> { closeInterface(player);gambleDialogReward(player,resolvedCost.minimum) } //player.removeBarbPoints(BarbAssaultPoints(cost.minimum, cost.minimum, cost.minimum, cost.minimum))
|
||||
is RewardCost.Coins -> {
|
||||
if (reward.queenKillText != null) { setAttribute(player,"barbass:queen-kill", 0)}
|
||||
removeItem(player, Item(Items.COINS_995, resolvedCost.amount), Container.INVENTORY)
|
||||
}
|
||||
is RewardCost.Specific -> player.removeBarbPoints(resolvedCost.required)
|
||||
else -> return
|
||||
}
|
||||
}
|
||||
//https://youtu.be/KKUbBrJBab0?t=44
|
||||
fun gambleDialogReward(player: Player, cost: Int) {
|
||||
var costChoice: BarbRole? = null
|
||||
//todo Finish Gamble reward
|
||||
/*openDialogue(player, object : DialogueFile() {
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
// this.npc = NPC( NPCs.COMMANDER_CONNAD_5029)
|
||||
when (stage) {
|
||||
0 -> {sendDialogueOptions(player,"Which points would you like to spend?", "Attacker Honor Points","Defender Honor Points","Collector Honor Points","Healer Honor Points")
|
||||
addDialogueAction(player) { player , buttonId ->
|
||||
when(buttonId) {
|
||||
2 -> {costChoice = BarbRole.ATTACKER; stage++}
|
||||
3 -> {costChoice = BarbRole.DEFENDER; stage++}
|
||||
4 -> {costChoice = BarbRole.COLLECTOR; stage++}
|
||||
5 -> {costChoice = BarbRole.HEALER; stage++}
|
||||
}
|
||||
//return@addDialogueAction
|
||||
} }
|
||||
|
||||
2 -> sendNPCDialogue(player,NPCs.COMMANDER_CONNAD_5029,"Gamble you say! Let me take something from my big bag of prizes!").also { stage++}
|
||||
3 -> npc("What can i find!").also { stage++ }
|
||||
4 -> npc("Ah, found something!").also { stage++ }
|
||||
5 -> npc("You've got...").also { stage++ }
|
||||
6 -> sendItemDialogue(player,995,"ItemName!").also{end()}
|
||||
}
|
||||
}
|
||||
}).also {
|
||||
val barbPoints = player.getBarbPoints()
|
||||
|
||||
val costPointsSelected = when (costChoice) {
|
||||
BarbRole.ATTACKER -> BarbAssaultPoints(atk = cost)
|
||||
BarbRole.COLLECTOR -> BarbAssaultPoints(col = cost)
|
||||
BarbRole.DEFENDER -> BarbAssaultPoints(def = cost)
|
||||
BarbRole.HEALER -> BarbAssaultPoints(heal = cost)
|
||||
else -> {return}
|
||||
}
|
||||
|
||||
if (barbPoints.hasEnough(costPointsSelected)) {
|
||||
player.removeBarbPoints(costPointsSelected)
|
||||
} else {
|
||||
player.sendMessage("You don't have enough ${costChoice!!.name.lowercase()} points to gamble.")
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
data class InterfaceModel( val childId: Int, val modelId: Int, val dynamicModelId: ((playerLevel: BarbAssaultLevels) -> Int)? = null) {
|
||||
fun resolve(playerLevel: BarbAssaultLevels): InterfaceModel {
|
||||
val resolvedID = dynamicModelId?.invoke(playerLevel) ?: modelId
|
||||
return InterfaceModel(childId, resolvedID, null)
|
||||
}
|
||||
}
|
||||
data class InterfaceText( val childId: Int, val text: String, val dynamicText: ((playerLevel: BarbAssaultLevels) -> String)? = null) {
|
||||
fun resolve(playerLevel: BarbAssaultLevels): InterfaceText {
|
||||
val resolvedText = dynamicText?.invoke(playerLevel) ?: text
|
||||
return InterfaceText(childId, resolvedText, null)
|
||||
}
|
||||
}
|
||||
sealed class RewardCost {
|
||||
data class Specific(val required: BarbAssaultPoints) : RewardCost()
|
||||
data class AllRoles(val amountPerRole: Int) : RewardCost()
|
||||
data class AnyRole(val minimum: Int) : RewardCost()
|
||||
data class Coins(val amount: Int) : RewardCost()
|
||||
data class Dynamic(val generator: (BarbAssaultLevels) -> RewardCost) : RewardCost()
|
||||
|
||||
fun resolve(levels: BarbAssaultLevels): RewardCost = when (this) {
|
||||
is Dynamic -> generator(levels)
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
data class RewardRow(
|
||||
val buttonChildId: Int,
|
||||
val model : InterfaceModel? = null,
|
||||
val rewardText: InterfaceText,
|
||||
val perkText: InterfaceText? = null,
|
||||
val rewardCostText: InterfaceText,
|
||||
val queenKillText: InterfaceText? = null,
|
||||
val cost: RewardCost,
|
||||
val item: Int? = null,
|
||||
val levelUp: BarbRole? = null,
|
||||
val gamble: GambleTier? = null
|
||||
)
|
||||
enum class GambleTier {LOW, MEDIUM, HIGH }
|
||||
//https://youtu.be/DZ9FqGFFVDw?t=4 -- 2009
|
||||
//https://youtu.be/md3naJdy2MM?t=67 -- 2008
|
||||
//https://youtu.be/u69JPBlDtVc?t=21 -- 2007
|
||||
/*
|
||||
Level | Honour Points | Collector | Healer | Attacker | Defender
|
||||
------|---------------|------------------------------------------|-------------|-----------|-------------------
|
||||
1 | Start level | Bag holds 2 eggs | Heals 10 hp | +1 Damage | Lure 4 spaces
|
||||
2 | 200 | Bag holds 4 eggs + Egg conversion | Heals 15 hp | +2 Damage | Lure 5 spaces
|
||||
3 | 300 | Bag holds 6 eggs + Conversion chance 40% | Heals 20 hp | +3 Damage | Lure 6 spaces
|
||||
4 | 400 | Bag holds 7 eggs + Conversion chance 60% | Heals 25 hp | +4 Damage | Lure 8 spaces
|
||||
5 | 500 | Bag holds 8 eggs + Conversion chance 80% | Heals 35 hp | +5 Damage | Lure 10 spaces
|
||||
*/
|
||||
|
||||
val barbRewardShop = listOf(
|
||||
RewardRow(81,
|
||||
model = InterfaceModel(80,20522){ level -> (20521 + level.atk).coerceIn(20522,20525) },
|
||||
rewardText = InterfaceText(82, "Attacker level up to 2"){ level -> if (level.atk >= 5) "Attacker level up complete" else "Attacker level up to ${level.atk + 1}"},
|
||||
rewardCostText = InterfaceText(83, "200 Attacker points"){ level -> if (level.atk >= 5) " - Mastered - " else "${level.atk + 1}00 Attacker points"},
|
||||
perkText = InterfaceText(85, "+2 bonus damage") { level -> if (level.atk >= 5) " - Mastered - " else "+${level.atk + 1} bonus damage" },
|
||||
cost = RewardCost.Dynamic { level -> RewardCost.Specific(BarbAssaultPoints((level.atk + 1) * 100, 0, 0, 0))},
|
||||
levelUp = BarbRole.ATTACKER
|
||||
),
|
||||
RewardRow(90,
|
||||
model = InterfaceModel(89,20526){ level -> (20525 + level.col).coerceIn(20526,20529) },
|
||||
rewardText = InterfaceText(91, "Collector level up to 2"){ level -> if (level.col >= 5) "Collector level up complete" else "Collector level up to ${level.col + 1}"},
|
||||
rewardCostText = InterfaceText(92, "200 Collector points"){ level -> if (level.col >= 5) " - Mastered - " else "${level.col + 1}00 Collector points"},
|
||||
perkText = InterfaceText(94, "Egg conversion") { level -> if (level.col <= 1) "Egg conversion" else if (level.col in 2..4) "Egg convert success ${(level.col - 2) * 20 + 40}%" else " - Mastered - " },
|
||||
cost = RewardCost.Dynamic { level -> RewardCost.Specific(BarbAssaultPoints(0, (level.col + 1) * 100, 0, 0))},
|
||||
levelUp = BarbRole.COLLECTOR
|
||||
),
|
||||
RewardRow(97,
|
||||
model = InterfaceModel(96,20531){ level -> (20530 + level.def).coerceIn(20531,20534) },
|
||||
rewardText = InterfaceText(98, "Defender level up to 2"){ level -> if (level.def >= 5) "Defender level up complete" else "Defender level up to ${level.def + 1}"},
|
||||
rewardCostText = InterfaceText(99, "200 Defender points"){ level -> if (level.def >= 5) " - Mastered - " else "${level.def + 1}00 Defender points"},
|
||||
perkText = InterfaceText(101, "Lure range 5") { level -> when (level.def) { 0, 1 -> "Lure range 5"; 2 -> "Lure range 6"; 3 -> "Lure range 8"; 4 -> "Lure range 10"; else -> " - Mastered - " } },
|
||||
cost = RewardCost.Dynamic { level -> RewardCost.Specific(BarbAssaultPoints(0, 0, (level.def + 1) * 100, 0))},
|
||||
levelUp = BarbRole.DEFENDER
|
||||
),
|
||||
RewardRow(104,
|
||||
model = InterfaceModel(103,20538){ level -> (20537 + level.heal).coerceIn(20538,20541) },
|
||||
rewardText = InterfaceText(105, "Healer level up to 2"){ level -> if (level.heal >= 5) "Healer level up complete" else "Healer level up to ${level.heal + 1}"},
|
||||
rewardCostText = InterfaceText(106, "200 Defender points"){ level -> if (level.heal >= 5) " - Mastered - " else "${level.heal + 1}00 Healer points"},
|
||||
perkText = InterfaceText(108, "Heal 15 points") { level -> when (level.heal) { 0, 1 -> "Heal 15 points"; 2 -> "Heal 20 points"; 3 -> "Heal 25 points"; 4 -> "Heal 35 points"; else -> " - Mastered - " } },
|
||||
cost = RewardCost.Dynamic { level -> RewardCost.Specific(BarbAssaultPoints(0, 0, 0, (level.heal + 1) * 100))},
|
||||
levelUp = BarbRole.HEALER
|
||||
),
|
||||
|
||||
RewardRow(111,
|
||||
rewardText = InterfaceText(112, "Penance Fighter hat"),
|
||||
rewardCostText = InterfaceText(113, "275 points in each role"),
|
||||
queenKillText = InterfaceText(229, "Kill Queen"),
|
||||
cost = RewardCost.AllRoles(275),
|
||||
item = Items.FIGHTER_HAT_10548
|
||||
),
|
||||
RewardRow(118,
|
||||
rewardText = InterfaceText(119, "Penance Ranger hat"),
|
||||
rewardCostText = InterfaceText(120, "275 points in each role"),
|
||||
queenKillText = InterfaceText(228, "Kill Queen"),
|
||||
cost = RewardCost.AllRoles(275),
|
||||
item = Items.RANGER_HAT_10550
|
||||
),
|
||||
RewardRow(125,
|
||||
rewardText = InterfaceText(126, "Penance Runner hat"),
|
||||
rewardCostText = InterfaceText(127, "275 points in each role"),
|
||||
queenKillText = InterfaceText(227, "Kill Queen"),
|
||||
cost = RewardCost.AllRoles(275),
|
||||
item = Items.RUNNER_HAT_10549
|
||||
),
|
||||
RewardRow(132,
|
||||
rewardText = InterfaceText(133, "Penance Healer hat"),
|
||||
rewardCostText = InterfaceText(134, "275 points in each role"),
|
||||
queenKillText = InterfaceText(226, "Kill Queen"),
|
||||
cost = RewardCost.AllRoles(275),
|
||||
item = Items.HEALER_HAT_10547
|
||||
),
|
||||
RewardRow(139,
|
||||
rewardText = InterfaceText(140, "Penance torso"),
|
||||
rewardCostText = InterfaceText(141, "375 points in each role"),
|
||||
queenKillText = InterfaceText(225, "Kill Queen"),
|
||||
cost = RewardCost.AllRoles(375),
|
||||
item = Items.FIGHTER_TORSO_10551
|
||||
),
|
||||
RewardRow(146,
|
||||
rewardText = InterfaceText(147, "Penance skirt"),
|
||||
rewardCostText = InterfaceText(148, "375 points in each role"),
|
||||
queenKillText = InterfaceText(224, "Kill Queen"),
|
||||
cost = RewardCost.AllRoles(375),
|
||||
item = Items.PENANCE_SKIRT_10555
|
||||
),
|
||||
RewardRow(153,
|
||||
rewardText = InterfaceText(154, "Penance boots"),
|
||||
rewardCostText = InterfaceText(155, "100 points in each role"),
|
||||
cost = RewardCost.AllRoles(100),
|
||||
item = Items.RUNNER_BOOTS_10552
|
||||
),
|
||||
RewardRow(160,
|
||||
rewardText = InterfaceText(161, "Penance gloves"),
|
||||
rewardCostText = InterfaceText(162, "150 points in each role"),
|
||||
cost = RewardCost.AllRoles(150),
|
||||
item = Items.PENANCE_GLOVES_10553
|
||||
),
|
||||
RewardRow(167,
|
||||
rewardText = InterfaceText(168, "Granite body"),
|
||||
rewardCostText = InterfaceText(169, "95,000 coins"),
|
||||
queenKillText = InterfaceText(230, "Kill Queen"),
|
||||
cost = RewardCost.Coins(95000),
|
||||
item = Items.GRANITE_BODY_10564
|
||||
),
|
||||
RewardRow(174,
|
||||
rewardText = InterfaceText(175, "Gamble points - low items"),
|
||||
rewardCostText = InterfaceText(176, "200 points (any role)"),
|
||||
cost = RewardCost.AnyRole(200),
|
||||
gamble = GambleTier.LOW
|
||||
),
|
||||
RewardRow(181,
|
||||
rewardText = InterfaceText(182, "Gamble points - medium items"),
|
||||
rewardCostText = InterfaceText(183, "400 points (any role)"),
|
||||
cost = RewardCost.AnyRole(400),
|
||||
gamble = GambleTier.MEDIUM
|
||||
),
|
||||
RewardRow(188,
|
||||
rewardText = InterfaceText(189, "Gamble points - high items"),
|
||||
rewardCostText = InterfaceText(190, "500 points (any role)"),
|
||||
queenKillText = InterfaceText(223, "Kill Queen"),
|
||||
cost = RewardCost.AnyRole(500),
|
||||
gamble = GambleTier.HIGH
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
package content.minigame.barbassault
|
||||
|
||||
import core.api.*
|
||||
import core.game.component.Component
|
||||
import core.game.node.entity.player.Player
|
||||
import org.rs09.consts.Components
|
||||
|
||||
data class RoleChildIds(
|
||||
val chpId: Int,
|
||||
val levelId: Int,
|
||||
val rewardNextLevelId: Int,
|
||||
val pointsNextLevelId: Int
|
||||
)
|
||||
data class RoleDisplayValues(
|
||||
val chpId: Int,
|
||||
val levelId: Int,
|
||||
val rewardNextLevelId: Int,
|
||||
val pointsNextLevelId: Int,
|
||||
val rewardText: String,
|
||||
val pointsText: String
|
||||
)
|
||||
|
||||
data class RewardInfo(
|
||||
val reward: String,
|
||||
val pointsToNextLevel: String
|
||||
)
|
||||
|
||||
class BarbassBlackBoard {
|
||||
companion object {
|
||||
const val PLAYER_NAME = 19
|
||||
const val CURRENT_WAVE = 25
|
||||
|
||||
val roleComponents: Map<BarbRole, RoleChildIds> = mapOf(
|
||||
BarbRole.ATTACKER to RoleChildIds(20,15,27,10),
|
||||
BarbRole.DEFENDER to RoleChildIds(21,16,28,11),
|
||||
BarbRole.COLLECTOR to RoleChildIds(22,17,29,12),
|
||||
BarbRole.HEALER to RoleChildIds(23,18,30,13)
|
||||
)
|
||||
|
||||
fun getRewardInfo(role: BarbRole, level: Int): RewardInfo {
|
||||
val reward = when (role) {
|
||||
BarbRole.ATTACKER -> when (level) {
|
||||
1 -> "+2 bonus damage"
|
||||
2 -> "+3 bonus damage"
|
||||
3 -> "+4 bonus damage"
|
||||
4 -> "+5 bonus damage"
|
||||
else -> " - Mastered - "
|
||||
}
|
||||
|
||||
BarbRole.DEFENDER -> when (level) {
|
||||
1 -> "Lure range 5"
|
||||
2 -> "Lure range 6"
|
||||
3 -> "Lure range 8"
|
||||
4 -> "Lure range 10"
|
||||
else -> " - Mastered - "
|
||||
}
|
||||
|
||||
BarbRole.COLLECTOR -> when (level) { //is this the right info for 2009?
|
||||
1 -> "Bag holds 4 eggs"
|
||||
2 -> "Bag holds 6 eggs"
|
||||
3 -> "Bag holds 7 eggs"
|
||||
4 -> "Bag holds 8 eggs"
|
||||
else -> " - Mastered - "
|
||||
}
|
||||
|
||||
BarbRole.HEALER -> when (level) {
|
||||
1 -> "Heal 15 points"
|
||||
2 -> "Heal 20 points"
|
||||
3 -> "Heal 25 points"
|
||||
4 -> "Heal 35 points"
|
||||
else -> " - Mastered - "
|
||||
}
|
||||
}
|
||||
|
||||
val points = getPointsTillNextLevel(level)
|
||||
return RewardInfo(reward, points)
|
||||
}
|
||||
|
||||
fun getPointsTillNextLevel(level: Int): String {
|
||||
return when (level) {
|
||||
1 -> "200"
|
||||
2 -> "300"
|
||||
3 -> "400"
|
||||
4 -> "500"
|
||||
else -> "---"
|
||||
}
|
||||
}
|
||||
fun getAllRoleValues(role: BarbRole, level: Int): RoleDisplayValues {
|
||||
val ids = roleComponents[role]
|
||||
val rewardInfo = getRewardInfo(role, level)
|
||||
|
||||
return RoleDisplayValues(
|
||||
ids!!.chpId, ids.levelId, ids.rewardNextLevelId, ids.pointsNextLevelId,
|
||||
rewardInfo.reward, rewardInfo.pointsToNextLevel
|
||||
)
|
||||
}
|
||||
|
||||
fun updateBlackBoard(player: Player) {
|
||||
val wave = player.getAttribute("barbass:wave", 1)
|
||||
player.interfaceManager.open(Component(Components.BARBASSAULT_PLAYERSTAT_490))
|
||||
setInterfaceText(player, player.username, Components.BARBASSAULT_PLAYERSTAT_490, PLAYER_NAME)
|
||||
setInterfaceText(player, wave.toString(), Components.BARBASSAULT_PLAYERSTAT_490, CURRENT_WAVE)
|
||||
|
||||
val playerLevel = player.getBarbLevels()
|
||||
val playerPoints = player.getBarbPoints()
|
||||
|
||||
for (role in BarbRole.values()) {
|
||||
val level = when (role) {
|
||||
BarbRole.ATTACKER -> playerLevel.atk
|
||||
BarbRole.DEFENDER -> playerLevel.def
|
||||
BarbRole.COLLECTOR -> playerLevel.col
|
||||
BarbRole.HEALER -> playerLevel.heal
|
||||
}
|
||||
val points = when (role) {
|
||||
BarbRole.ATTACKER -> playerPoints.atk
|
||||
BarbRole.DEFENDER -> playerPoints.def
|
||||
BarbRole.COLLECTOR -> playerPoints.col
|
||||
BarbRole.HEALER -> playerPoints.heal
|
||||
}
|
||||
val roleValues = getAllRoleValues(role, level)
|
||||
|
||||
setInterfaceText(player, points.toString(), 490, roleValues.chpId)
|
||||
setInterfaceText(player, level.toString(), 490, roleValues.levelId)
|
||||
setInterfaceText(player, roleValues.rewardText, 490, roleValues.rewardNextLevelId)
|
||||
setInterfaceText(player, roleValues.pointsText, 490, roleValues.pointsNextLevelId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
package content.minigame.barbassault
|
||||
|
||||
import core.api.sendMessage
|
||||
|
||||
import core.game.node.item.Item
|
||||
import core.game.system.command.Privilege
|
||||
import core.game.system.command.sets.CommandSet
|
||||
import core.game.world.map.Location
|
||||
import core.plugin.Initializable
|
||||
import org.rs09.consts.Items
|
||||
|
||||
@Initializable
|
||||
class BarbassDevHelper : CommandSet(Privilege.ADMIN) {
|
||||
override fun defineCommands() {
|
||||
define ("maxbarbpts") { player,_ ->
|
||||
player.addBarbPoints(BarbAssaultPoints(500, 500, 500,500))
|
||||
}
|
||||
define ("rstbarbpts") { player,_ ->
|
||||
player.setBarbPoints(BarbAssaultPoints(0, 0, 0,0))
|
||||
}
|
||||
define ("rstbarblvl") { player,_ ->
|
||||
player.setBarbLevels(BarbAssaultLevels(0, 0, 0,0))
|
||||
}
|
||||
define("barbgame"){ player,_->
|
||||
player.teleport(Location.create(1886, 5467, 0))
|
||||
}
|
||||
define("barbqueen"){ player,_->
|
||||
player.teleport(Location.create(1885, 5403, 0))
|
||||
}
|
||||
|
||||
define("rolekit", Privilege.ADMIN, "<role> <level>", "Gives Barbarian Assault kit") { player, args ->
|
||||
data class RoleKit(
|
||||
val horns: IntArray? = null,
|
||||
val bags: IntArray? = null,
|
||||
val extraItems: List<Int> = emptyList()
|
||||
)
|
||||
val roleKits = mapOf(
|
||||
"healer" to RoleKit(
|
||||
horns = intArrayOf(Items.HEALER_HORN_10526,Items.HEALER_HORN_10527,Items.HEALER_HORN_10528,Items.HEALER_HORN_10529,Items.HEALER_HORN_10530 ),
|
||||
extraItems = listOf(10559,Items.HEALING_VIAL_10546, Items.POISONED_WORMS_10540, Items.POISONED_TOFU_10539,Items.POISONED_MEAT_10541)
|
||||
),
|
||||
"attacker" to RoleKit(
|
||||
horns = intArrayOf(Items.ATTACKER_HORN_10516,Items.ATTACKER_HORN_10517,Items.ATTACKER_HORN_10518,Items.ATTACKER_HORN_10519,Items.ATTACKER_HORN_10520),
|
||||
extraItems = listOf(10556)
|
||||
),
|
||||
"defender" to RoleKit(
|
||||
horns = intArrayOf(Items.DEFENDER_HORN_10538),
|
||||
extraItems = listOf(10558,Items.DEFENDER_HORN_10538,Items.WORMS_10515,Items.CRACKERS_10513,Items.TOFU_10514)
|
||||
),
|
||||
"collector" to RoleKit(
|
||||
horns = intArrayOf(Items.COLLECTION_BAG_10521, Items.COLLECTION_BAG_10522, Items.COLLECTION_BAG_10523, Items.COLLECTION_BAG_10524, Items.COLLECTION_BAG_10525),
|
||||
extraItems = listOf(10557,Items.COLLECTOR_HORN_10560)
|
||||
)
|
||||
)
|
||||
|
||||
if (args.size < 3) {
|
||||
sendMessage(player,"Usage: ::rolekit <healer|attacker|collector|defender> <level 1-5>")
|
||||
return@define
|
||||
}
|
||||
|
||||
val roleName = args[1].lowercase()
|
||||
val level = args[2].toIntOrNull()
|
||||
if (level == null || level !in 1..5) {
|
||||
sendMessage(player,"Invalid level. Use a number between 1 and 5.")
|
||||
return@define
|
||||
}
|
||||
val role = roleKits[roleName]
|
||||
if (role == null) {
|
||||
sendMessage(player,"Unknown role: $roleName. Use healer, attacker, defender, or collector.")
|
||||
return@define
|
||||
}
|
||||
player.inventory.add(Item(role.horns?.get(level - 1) ?:1 ))
|
||||
role.extraItems.forEach { player.inventory.add(Item(it)) }
|
||||
sendMessage(player,"Gave $roleName kit for level $level.")
|
||||
}
|
||||
}
|
||||
}
|
||||
176
Server/src/main/content/minigame/barbassault/Barbassault.kt
Normal file
176
Server/src/main/content/minigame/barbassault/Barbassault.kt
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
package content.minigame.barbassault
|
||||
|
||||
import core.game.node.entity.player.Player
|
||||
|
||||
enum class BarbRole { ATTACKER, DEFENDER, COLLECTOR, HEALER }
|
||||
data class BarbAssaultPoints( val atk: Int = 0, val col: Int = 0, val def: Int = 0, val heal: Int = 0) {
|
||||
val total: Int get() = atk + col + def + heal
|
||||
fun hasEnough(cost: BarbAssaultPoints): Boolean = atk >= cost.atk && col >= cost.col && def >= cost.def && heal >= cost.heal
|
||||
operator fun minus(other: BarbAssaultPoints): BarbAssaultPoints = BarbAssaultPoints(atk - other.atk,col - other.col,def - other.def,heal - other.heal).clamped()
|
||||
operator fun plus(other: BarbAssaultPoints): BarbAssaultPoints = BarbAssaultPoints(atk + other.atk,col + other.col,def + other.def,heal + other.heal).clamped()
|
||||
fun clamped(): BarbAssaultPoints = BarbAssaultPoints(atk.coerceIn(0, 500), col.coerceIn(0, 500), def.coerceIn(0, 500), heal.coerceIn(0, 500) )
|
||||
}
|
||||
/**
|
||||
* Retrieves the player's current Barbarian Assault points.
|
||||
*
|
||||
* @return [BarbAssaultPoints] representing the player's stored points in each role:
|
||||
* - `atk`: Attacker points
|
||||
* - `col`: Collector points
|
||||
* - `def`: Defender points
|
||||
* - `heal`: Healer points
|
||||
*
|
||||
* Example usage:
|
||||
* ```
|
||||
* val points = player.getBarbPoints()
|
||||
* println("Attacker points: ${points.atk}")
|
||||
* ```
|
||||
*/
|
||||
fun Player.getBarbPoints(): BarbAssaultPoints = BarbAssaultPoints(
|
||||
getAttribute("barbass:atk-points", 0),
|
||||
getAttribute("barbass:col-points", 0),
|
||||
getAttribute("barbass:def-points", 0),
|
||||
getAttribute("barbass:heal-points", 0)
|
||||
)
|
||||
/**
|
||||
* Sets the player's Barbarian Assault role points, clamping each to the allowed range (0 to 500)
|
||||
* and saving them to persistent storage.
|
||||
*
|
||||
* @param points [BarbAssaultPoints] containing the new point values for each role:
|
||||
* - `atk`: Attacker points
|
||||
* - `col`: Collector points
|
||||
* - `def`: Defender points
|
||||
* - `heal`: Healer points
|
||||
*
|
||||
* Example usage:
|
||||
* ```
|
||||
* val newPoints = BarbAssaultPoints(atk = 120, col = 80, def = 200, heal = 0)
|
||||
* player.setBarbPoints(newPoints)
|
||||
* ```
|
||||
*/
|
||||
fun Player.setBarbPoints(points: BarbAssaultPoints) {
|
||||
val rolePoints = points.clamped()
|
||||
setAttribute("/save:barbass:atk-points", rolePoints.atk)
|
||||
setAttribute("/save:barbass:col-points", rolePoints.col)
|
||||
setAttribute("/save:barbass:def-points", rolePoints.def)
|
||||
setAttribute("/save:barbass:heal-points", rolePoints.heal)
|
||||
}
|
||||
/**
|
||||
* Adds Barbarian Assault points to the player.
|
||||
*
|
||||
* @param additional The points to be added to the player's current Barbarian Assault points.
|
||||
* Values will be automatically clamped between 0 and 500.
|
||||
*
|
||||
* Example usage:
|
||||
* ```
|
||||
* // Give the player 30 attacker points and 10 collector points
|
||||
* player.addBarbPoints(BarbAssaultPoints(atk = 30, col = 10, def = 0, heal = 0))
|
||||
* ```
|
||||
*/
|
||||
fun Player.addBarbPoints(additional: BarbAssaultPoints) {
|
||||
setBarbPoints(getBarbPoints() + additional)
|
||||
}
|
||||
/**
|
||||
* Removes Barbarian Assault points from the player.
|
||||
*
|
||||
* @param toRemove The points to be subtracted from the player's current Barbarian Assault points.
|
||||
* Values will be clamped so that no role goes below 0.
|
||||
*
|
||||
* Example usage:
|
||||
* ```
|
||||
* // Remove 15 attacker points and 5 defender points
|
||||
* player.removeBarbPoints(BarbAssaultPoints(atk = 15, col = 0, def = 5, heal = 0))
|
||||
* ```
|
||||
*/
|
||||
fun Player.removeBarbPoints(toRemove: BarbAssaultPoints) {
|
||||
setBarbPoints(getBarbPoints() - toRemove)
|
||||
}
|
||||
|
||||
data class BarbAssaultLevels(val atk: Int, val col: Int, val def: Int, val heal: Int) {
|
||||
fun clamped(): BarbAssaultLevels = BarbAssaultLevels(
|
||||
atk.coerceIn(1, 5), col.coerceIn(1, 5), def.coerceIn(1, 5), heal.coerceIn(1, 5)
|
||||
)
|
||||
}
|
||||
|
||||
fun Player.hasQueenKill(): Boolean = getAttribute("barbass:queen-kill", 0) > 0
|
||||
/**
|
||||
* Retrieves the player's Barbarian Assault role levels from their saved attributes.
|
||||
* Defaults to level 1 for any role if not previously set.
|
||||
*
|
||||
* @return [BarbAssaultLevels] containing the level for each role:
|
||||
* - `atk`: Attacker level
|
||||
* - `col`: Collector level
|
||||
* - `def`: Defender level
|
||||
* - `heal`: Healer level
|
||||
*
|
||||
* Example usage:
|
||||
* ```
|
||||
* val levels = player.getBarbLevels()
|
||||
* println("Attacker Level: ${levels.atk}")
|
||||
* ```
|
||||
*/
|
||||
fun Player.getBarbLevels(): BarbAssaultLevels = BarbAssaultLevels(
|
||||
getAttribute("barbass:atk-level", 1),
|
||||
getAttribute("barbass:col-level", 1),
|
||||
getAttribute("barbass:def-level", 1),
|
||||
getAttribute("barbass:heal-level", 1)
|
||||
)
|
||||
/**
|
||||
* Sets the player's Barbarian Assault role levels and saves them to persistent attributes.
|
||||
*
|
||||
* @param levels The [BarbAssaultLevels] object containing levels for each role:
|
||||
* - `atk`: Attacker level (1–5)
|
||||
* - `col`: Collector level (1–5)
|
||||
* - `def`: Defender level (1–5)
|
||||
* - `heal`: Healer level (1–5)
|
||||
*
|
||||
* Example usage:
|
||||
* ```
|
||||
* val newLevels = BarbAssaultLevels(atk = 2, col = 1, def = 3, heal = 1)
|
||||
* player.setBarbLevels(newLevels)
|
||||
* ```
|
||||
*/
|
||||
fun Player.setBarbLevels(levels: BarbAssaultLevels) {
|
||||
setAttribute("/save:barbass:atk-level", levels.atk)
|
||||
setAttribute("/save:barbass:col-level", levels.col)
|
||||
setAttribute("/save:barbass:def-level", levels.def)
|
||||
setAttribute("/save:barbass:heal-level", levels.heal)
|
||||
}
|
||||
/**
|
||||
* Increases the level of the specified Barbarian Assault role by 1, up to a maximum of 5.
|
||||
*
|
||||
* Only one role can be increased at a time. The result is clamped to ensure the level does not exceed 5.
|
||||
*
|
||||
* @param role The [BarbRole] to increase the level of. Must be one of:
|
||||
* - `BarbRole.ATTACKER`
|
||||
* - `BarbRole.COLLECTOR`
|
||||
* - `BarbRole.DEFENDER`
|
||||
* - `BarbRole.HEALER`
|
||||
*
|
||||
* Example usage:
|
||||
* ```
|
||||
* player.increaseBarbRoleLevel(BarbRole.ATTACKER)
|
||||
* ```
|
||||
*/
|
||||
fun Player.increaseBarbRoleLevel(role: BarbRole) {
|
||||
val current = getBarbLevels()
|
||||
val newLevels = when (role) {
|
||||
BarbRole.ATTACKER -> current.copy(atk = current.atk + 1)
|
||||
BarbRole.COLLECTOR -> current.copy(col = current.col + 1)
|
||||
BarbRole.DEFENDER -> current.copy(def = current.def + 1)
|
||||
BarbRole.HEALER -> current.copy(heal = current.heal + 1)
|
||||
}.clamped()
|
||||
setBarbLevels(newLevels)
|
||||
}
|
||||
fun BarbAssaultLevels.getLevel(role: BarbRole): Int = when (role) {
|
||||
BarbRole.ATTACKER -> atk
|
||||
BarbRole.COLLECTOR -> col
|
||||
BarbRole.DEFENDER -> def
|
||||
BarbRole.HEALER -> heal
|
||||
}
|
||||
|
||||
fun BarbAssaultPoints.getPoints(role: BarbRole): Int = when (role) {
|
||||
BarbRole.ATTACKER -> atk
|
||||
BarbRole.COLLECTOR -> col
|
||||
BarbRole.DEFENDER -> def
|
||||
BarbRole.HEALER -> heal
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
package content.minigame.barbassault
|
||||
|
||||
|
||||
import content.minigame.barbassault.BarbassBlackBoard.Companion.updateBlackBoard
|
||||
import core.api.*
|
||||
import core.game.component.Component
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.InterfaceListener
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.world.map.Location
|
||||
import org.rs09.consts.Components
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
import org.rs09.consts.Scenery
|
||||
|
||||
const val BARBASSAULT_ACCEPT_ROLE_492 = 492
|
||||
const val BARBASSAULT_SELECT_ROLE_493 = 493
|
||||
|
||||
class BarbassaultListeners : InteractionListener {
|
||||
//CommandSet(Privilege.ADMIN)
|
||||
|
||||
override fun defineListeners() {
|
||||
on(Scenery.LADDER_20226, IntType.SCENERY, "Climb-down") { player, _ ->
|
||||
// if (GameWorld.settings?.enable_barbassault != true) return@on false
|
||||
if (joinError(player)) return@on true
|
||||
val loc = Location(2593 , 5261 )
|
||||
teleport(player, loc) // find ladder code latter
|
||||
return@on true
|
||||
|
||||
}
|
||||
on(Scenery.LADDER_20227, IntType.SCENERY, "Climb-up") { player, _ ->
|
||||
//Remove Roster/scroll
|
||||
val loc = Location(2535 , 3572 )
|
||||
teleport(player, loc) // find ladder code latter
|
||||
return@on true
|
||||
|
||||
}
|
||||
on(Scenery.BLACKBOARD_20134, IntType.SCENERY, "Read") { player, _ ->
|
||||
//emote 5354
|
||||
//Remove Roster/scroll
|
||||
// openOverlay(player, Components.BARBASSAULT_PLAYERSTAT_490)
|
||||
updateBlackBoard(player)
|
||||
return@on true
|
||||
|
||||
}
|
||||
on(NPCs.COMMANDER_CONNAD_5029, IntType.NPC, "Get-rewards") { player, _ ->
|
||||
setVarbit(player, 3256, 200)
|
||||
player.interfaceManager.open(Component(Components.BARBASSAULT_REWARD_SHOP_491))
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(NPCs.CAPTAIN_CAIN_5030, IntType.NPC, "Tutorial") { player, _ ->
|
||||
player.interfaceManager.open(Component(Components.BARBASSAULT_TUTORIAL_496))
|
||||
return@on true
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private fun capeCheck(player: Player): String? {
|
||||
val wornCape = getItemFromEquipment(player, EquipmentSlot.CAPE)?.id ?: -1
|
||||
|
||||
if (wornCape != -1) return "No CAPES!!!" // find correct message
|
||||
return null
|
||||
}
|
||||
private fun forbiddenItemsCheck(player: Player): String? {
|
||||
val forbiddenRunes = setOf(
|
||||
Items.AIR_RUNE_556,
|
||||
Items.FIRE_RUNE_554,
|
||||
Items.EARTH_RUNE_557,
|
||||
Items.WATER_RUNE_555,
|
||||
Items.BLOOD_RUNE_565,
|
||||
Items.BODY_RUNE_559,
|
||||
Items.CHAOS_RUNE_562,
|
||||
Items.COSMIC_RUNE_564,
|
||||
Items.ASTRAL_RUNE_9075,
|
||||
Items.DEATH_RUNE_560,
|
||||
Items.LAVA_RUNE_4699,
|
||||
Items.MUD_RUNE_4698,
|
||||
Items.SMOKE_RUNE_4697,
|
||||
Items.STEAM_RUNE_4694,
|
||||
Items.SOUL_RUNE_566,
|
||||
Items.NATURE_RUNE_561
|
||||
//add food
|
||||
//add ammo
|
||||
)
|
||||
|
||||
for (item in player.inventory.toArray()) {
|
||||
if (item != null) {
|
||||
if (item.id in forbiddenRunes) {
|
||||
return "no outside runes"
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
private fun familiarCheck(player: Player): String? {
|
||||
// if has pet or familiar, not allowed to enter.
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private fun joinError(player: Player): Boolean {
|
||||
val errorMessage = capeCheck(player) ?: forbiddenItemsCheck(player) ?: familiarCheck(player) ?: return false
|
||||
player.sendMessage(errorMessage).also { return true }
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
class BarbSelectRole : InterfaceListener {
|
||||
//Team related
|
||||
//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.
|
||||
override fun defineInterfaceListeners() {
|
||||
onOpen(493) { player, _ -> // change this for roles
|
||||
val lines: Array<String> = player.getAttribute("ifaces:220:lines", arrayOf())
|
||||
for(i in 0 until Math.min(lines.size, 15)) {
|
||||
setInterfaceText(player, lines[i], 220, i+1)
|
||||
//setInterfaceText(player, "${i}", 220, i+1)
|
||||
}
|
||||
return@onOpen true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package content.minigame.barbassault
|
||||
|
||||
import core.api.produceGroundItem
|
||||
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 org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
|
||||
class BarbassaultTut {
|
||||
companion object {
|
||||
data class TutorialItemSpawn(val itemId: Int, val location: Location)
|
||||
val BarbassTutItems: List<TutorialItemSpawn> = listOf(
|
||||
TutorialItemSpawn(Items.LOGS_11760, Location.create(1885, 5487, 0)),
|
||||
TutorialItemSpawn(Items.LOGS_11760, Location.create(1886, 5486, 0)),
|
||||
TutorialItemSpawn(Items.HAMMER_2347, Location.create(1888, 5482, 0))
|
||||
)
|
||||
val BarbassTutNPCs: List<NPC> = listOf(
|
||||
NPC.create(NPCs.PENANCE_RANGER_5041, Location.create(1874, 5485, 0), Direction.SOUTH),
|
||||
NPC.create(NPCs.PENANCE_FIGHTER_5040, Location.create(1880, 5486, 0), Direction.SOUTH),
|
||||
NPC.create(NPCs.PENANCE_HEALER_5043, Location.create(1892, 5486, 0), Direction.SOUTH),
|
||||
NPC.create(NPCs.PENANCE_RUNNER_5042, Location.create(1898, 5485, 0), Direction.SOUTH),
|
||||
|
||||
NPC.create(NPCs.MAJOR_DEFEND_5037, Location.create(1891, 5466, 0), Direction.SOUTH),
|
||||
NPC.create(NPCs.MAJOR_HEAL_5038, Location.create(1882, 5466, 0), Direction.SOUTH),
|
||||
NPC.create(NPCs.MAJOR_ATTACK_5035, Location.create(1882, 5477, 0), Direction.SOUTH),
|
||||
NPC.create(NPCs.MAJOR_COLLECT_5036, Location.create(1891, 5477, 0), Direction.SOUTH),
|
||||
|
||||
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)
|
||||
)
|
||||
|
||||
fun spawnItems() {
|
||||
val groundItems = GroundItemManager.getItems()
|
||||
BarbassTutItems.forEach { (id, loc) ->
|
||||
if (groundItems.none { it.id == id && it.location == loc && !it.isRemoved })
|
||||
produceGroundItem(null, id, 1, loc).apply { forceVisible = true }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
https://www.youtube.com/watch?v=2A5hMOm0TMY
|
||||
[CAPTAIN_CAIN_5030]: option [ Tutorial]
|
||||
|
||||
|
||||
|
||||
*/
|
||||
112
Server/src/main/content/minigame/barbassault/CommanderConnad.kt
Normal file
112
Server/src/main/content/minigame/barbassault/CommanderConnad.kt
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
package content.minigame.barbassault
|
||||
|
||||
import core.api.addItem
|
||||
import core.api.freeSlots
|
||||
import core.api.openInterface
|
||||
import core.game.dialogue.DialoguePlugin
|
||||
import core.game.dialogue.FacialExpression
|
||||
import core.game.dialogue.Topic
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.item.Item
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.Components
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
|
||||
@Initializable
|
||||
class CommanderConnad(player: Player? = null) : DialoguePlugin(player) {
|
||||
override fun newInstance(player: Player?): DialoguePlugin {
|
||||
return CommanderConnad(player)
|
||||
}
|
||||
override fun open(vararg args: Any?): Boolean {
|
||||
//todo check if completed tut with Captain
|
||||
stage = 5
|
||||
handle(0,0)
|
||||
return true
|
||||
}
|
||||
override fun handle(componentID: Int, buttonID: Int): Boolean {
|
||||
val barbasspoints = player.getBarbPoints()
|
||||
|
||||
val displayName = player.name.replaceFirstChar { it.uppercaseChar() }
|
||||
|
||||
when (stage) {
|
||||
0 -> playerl(FacialExpression.FRIENDLY, "Hello?").also { stage++ }
|
||||
1 -> npcl(FacialExpression.FRIENDLY, "Sorry soldier, you don't have permission to speak with me yet. Go and talk to the Captain.").also { stage = END_DIALOGUE }
|
||||
|
||||
5 -> playerl(FacialExpression.FRIENDLY, " I believe you might be able to reward me for my progress in this arena?.").also { stage++ }
|
||||
6 -> npcl(FacialExpression.FRIENDLY,"Well that depends upon your skill levels for each role.").also { stage++ }
|
||||
7 -> npcl(FacialExpression.ASKING,"What's your name soldier?").also { stage++ }
|
||||
8 -> playerl(FacialExpression.FRIENDLY, "${displayName}, Sir!").also { stage++ }
|
||||
9 -> npcl(FacialExpression.FRIENDLY," Okay. What exactly do you want to know, ${displayName}?").also { stage++ }
|
||||
10 -> showTopics(
|
||||
Topic(FacialExpression.ASKING,"Can I trade some of my points?",15),
|
||||
Topic(FacialExpression.ASKING,"What points do I have so far, sir?",25),
|
||||
Topic(FacialExpression.ASKING,"Could I have a 'Queen Help' book?", queenBookStage(player)),
|
||||
Topic(FacialExpression.ASKING,"Could I have my current wave reset to one?", areWaveOne(player)),
|
||||
Topic(FacialExpression.FRIENDLY,"That is all, sir.",100)
|
||||
)
|
||||
|
||||
//Open RewardInterface
|
||||
15-> npcl(FacialExpression.FRIENDLY,"Of course.").also { stage++ }
|
||||
16 -> {
|
||||
end()
|
||||
openInterface(player,Components.BARBASSAULT_REWARD_SHOP_491)
|
||||
}
|
||||
//Point Check
|
||||
25 -> npcl(FacialExpression.FRIENDLY,"Let me check...").also { stage = getBarbPointStage(player,barbasspoints.total) }
|
||||
26 -> npcl(FacialExpression.FRIENDLY,"You have absolutely no points, whatsoever. Best you get back into that arena!").also { stage = 10 }
|
||||
27 -> npcl(FacialExpression.FRIENDLY,"You have: ${barbasspoints.atk} Attacker Honour Points, ${barbasspoints.def} Defender Honour Points, ${barbasspoints.col} Collector Honour Points and ${barbasspoints.heal} Healer Honour Points.").also { stage = 10 }
|
||||
|
||||
//Get Queen book.
|
||||
50 -> npcl(FacialExpression.FRIENDLY,"By all means.").also {
|
||||
addItem(player, Items.QUEEN_HELP_BOOK_10562, 1)
|
||||
stage = 10
|
||||
}
|
||||
//Already have Queen book
|
||||
51 -> npcl(FacialExpression.ANNOYED,"You already have one!").also { stage++ }
|
||||
52 -> playerl(FacialExpression.WORRIED,"Oh yes, sorry.").also { stage = 10}
|
||||
|
||||
//not enough Inventory Space
|
||||
53 -> playerl(FacialExpression.WORRIED,"Oh, no. Wait, I don't have enough space to carry one.").also { stage++ }
|
||||
54 -> npcl(FacialExpression.FRIENDLY,"Well, you can come back and get one at any time from me.").also { stage = 10 }
|
||||
//Already have QueenBook
|
||||
75 -> npcl(FacialExpression.ANNOYED," You do realise that you're already on wave one?").also { stage++ }
|
||||
76 -> playerl(FacialExpression.WORRIED,"Ah. Yes. Sorry about that.").also { stage = END_DIALOGUE}
|
||||
//todo find Correct Dialog for wave reset
|
||||
77 -> npcl(FacialExpression.ASKING,"I can change it down to wave 1, Are you sure you want that?").also { stage++ }
|
||||
78 -> showTopics(
|
||||
Topic(FacialExpression.FRIENDLY, "Yes, reset my wave to one.",79),
|
||||
Topic(FacialExpression.FRIENDLY, "No, I want to stay on wave ${player!!.getAttribute<Int>("barbass:wave")}.",10)
|
||||
)
|
||||
79 -> {
|
||||
npcl(FacialExpression.ASKING,"Very well.").also { stage = END_DIALOGUE }
|
||||
player.setAttribute("/save:barbass:wave", 1)
|
||||
}
|
||||
//END
|
||||
100 -> npcl(FacialExpression.FRIENDLY,"Very well, on your way.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
return true
|
||||
}
|
||||
private fun getBarbPointStage(player: Player, total: Int): Int {
|
||||
if (total == 0 ) return 26
|
||||
return 27
|
||||
}
|
||||
private fun queenBookStage(player: Player?): Int {
|
||||
if (freeSlots(player!!) == 0) return 53
|
||||
if (player.hasItem(Item(Items.QUEEN_HELP_BOOK_10562))) return 51
|
||||
return 50
|
||||
}
|
||||
private fun areWaveOne(player: Player?): Int {
|
||||
val currentWave = player!!.getAttribute<Int>("barbass:wave")
|
||||
if (currentWave != 1) return 77
|
||||
return 75
|
||||
}
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.COMMANDER_CONNAD_5029)
|
||||
}
|
||||
}
|
||||
|
||||
//[COMMANDER_CONNAD_5029] Dialog: https://www.youtube.com/watch?v=wb1InggbaZc
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package content.minigame.barbassault
|
||||
|
||||
import core.api.openDialogue
|
||||
import core.api.sendDialogue
|
||||
import core.game.dialogue.DialogueFile
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import org.rs09.consts.Scenery
|
||||
|
||||
class PenanceStatueDialogues : InteractionListener {
|
||||
val statueToDialogId = mapOf(
|
||||
Scenery.PENANCE_FIGHTER_STATUE_20164 to 1,
|
||||
Scenery.PENANCE_HEALER_STATUE_20165 to 5,
|
||||
Scenery.PENANCE_RANGER_STATUE_20167 to 10,
|
||||
Scenery.PENANCE_RUNNER_STATUE_20166 to 15,
|
||||
Scenery.PENANCE_QUEEN_SPAWN_STATUE_20168 to 20
|
||||
)
|
||||
val STATUES: IntArray = statueToDialogId.keys.toIntArray()
|
||||
|
||||
override fun defineListeners() {
|
||||
on(STATUES, IntType.SCENERY, "Inspect") { player, node ->
|
||||
openDialogue(player, object : DialogueFile() {
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (stage) {
|
||||
0 -> sendDialogue(player, "There seems to be a plaque on the statue. It says:").also { stage = statueToDialogId[node.id] ?: -1 }
|
||||
//FIGHTER STATUE
|
||||
1 -> sendDialogue(player, "'The Penance Fighter - With the single goal to attack all that may threaten its Queen, this monster uses it's giant claws to shred its prey, and can only be stopped with brute force. Sharing the telekinetic trait of the other Penance monsters, the Penance Fighter can anticipate and adapt to").also { stage++ }
|
||||
2 -> sendDialogue(player, "defend itself. Bearing this in mind, it's important when fighting this monster to change attack style periodically to ensure damage is dealt. Most combatants will be glad to notice this creature (like the other Penance) has only one eye, and hence its depth perception is not all that it could be! Otherwise, those claws would soon destroy the most").also { stage++ }
|
||||
3 -> sendDialogue(player, "experienced of warriors!'").also { stage = 26 }
|
||||
//HEALER STATUE
|
||||
5 -> sendDialogue(player,"'The Penance Healer - This monster could have arguably been called a 'Penance Poisoner', for it has a dual role - both healing other Penance and poisoning any creature it sees as a threat. It performs these roles with equal importance and switches from one to the other as soon as it has the").also { stage++ }
|
||||
6 -> sendDialogue(player,"chance of finding a target. The best way to stop a Penance Healer is fighting it at its own game. The Penance Healer is partial to food, which it uses to create its own chemicals for curing and poisoning. As a result it has to be very careful what it eats, and has a mechanism by which it will be immune to certain types of poisonous foods at").also { stage++ }
|
||||
7 -> sendDialogue(player,"different times. With this information in mind, it is in fact possible to poison the Penance Healer by using the right type of food at the right time.'").also { stage = 26 }
|
||||
//RANGER STATUE
|
||||
10 -> sendDialogue(player,"'The Penance Ranger - These creatures store a highly corrosive liquid in the abdomen at the base of their bodies. It is believed that this was initially used for breaking up food matter to be passed on to the Queen for digestion. With the increase of easily digestible food sources (e.g. 'daring'").also { stage++ }
|
||||
11 -> sendDialogue(player,"adventurers), this functionality has been removed. It now seems to be used for offensive means in the form of projectiles. The only way to defeat this monster is to confront it with brute force, as it has no convenient weakness. That being said, the Penance Ranger can anticipate and adapt to attacks using the telekenisis common between").also { stage++ }
|
||||
12 -> sendDialogue(player,"all Penance, and hence, when taking on this monster, it is important to change attack style periodically to perform damage.'").also { stage = 26 }
|
||||
//RUNNER STATUE
|
||||
15 -> sendDialogue(player,"'The Penance Runner - These creatures are attracted to the scent of their Queen - charging to her aid in the hope of creating a barrier to protect her from threat. Their slender legs aid in motion, and their bulky bodies are effective shields and a strong barrier when linked together. And so,").also { stage++ }
|
||||
16 -> sendDialogue(player,"they are willing to waste their own lives in the simple interest of protecting their Queen. Using this interesting trait against them, Penance Runners are lured in the arena by the exit cave, which is doused with this scent. This is used to test combatants in how many Penance Runners manage to get past and how many are stopped").also { stage++ }
|
||||
17 -> sendDialogue(player,"with the use of the traps. Penance Runners are an energetic group, and therefore take any opportunity to eat and restore energy. With this in mind, laying down food within smelling distance of the Runners will lure them along. However, they are not stupid, and look for different food to ensure they are not so easily tricked... Hence,").also { stage++ }
|
||||
18 -> sendDialogue(player,"giving them the wrong food will send them running back to their caves. It's an interesting evolutionary trait, which is transmitted telepathically between Penance Runners... One which we carefully intercept.'").also { stage = 26 }
|
||||
//QUEENSPAWN STATUE
|
||||
20 -> sendDialogue(player,"'The Penance Spawn - You're only likely to see these creatures in close proximity to their creator - the dreaded Penance Queen. All Penance begin their lives in this form, mutating into the seperate classes of Penance depending on the lack or abundance of other classes in the local environment.").also { stage++ }
|
||||
21 -> sendDialogue(player,"Through telepathic communication, the Queen is able to determine the number of each class of Penance (Fighter, Ranger, Healer or Runner) and communicate to her spawn the form they should take on to fill any gaps in numbers. If the spawn receives no communication from a Queen, it turns into a Queen itself, because").also { stage++ }
|
||||
22 -> sendDialogue(player,"of the evident neccessity of such a role. These spawn will attack on sight, but a few hits by any means should stop these slimy creatures.'").also { stage = 26 }
|
||||
//END OF DIALOGUE
|
||||
26 -> end()
|
||||
}
|
||||
}
|
||||
})
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package content.minigame.barbassault
|
||||
|
||||
import content.global.handlers.iface.BookInterface
|
||||
import content.global.handlers.iface.BookLine
|
||||
import content.global.handlers.iface.Page
|
||||
import content.global.handlers.iface.PageSet
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.node.entity.player.Player
|
||||
import org.rs09.consts.Items
|
||||
|
||||
class QueenHelpBook : InteractionListener {
|
||||
companion object {
|
||||
private val TITLE = "Queen Help"
|
||||
private val CONTENTS = arrayOf(
|
||||
PageSet(
|
||||
Page( //1
|
||||
BookLine("<col=ff0000>1) <col=0b5394>Collector: <col=000000>Pick up ", 55),
|
||||
BookLine("yellow egg. pass to", 56),
|
||||
BookLine("healer.", 57),
|
||||
|
||||
BookLine("Take omega egg from", 58),
|
||||
BookLine("Defender. Load in to ", 59),
|
||||
BookLine("turret.", 60),
|
||||
|
||||
BookLine("<col=ff0000>2) <col=0b5394>Healer:<col=000000> Take yellow", 62),
|
||||
BookLine("egg from Collector.", 63),
|
||||
BookLine("Poison egg in pool. Pass", 64),
|
||||
BookLine("to Attacker.", 65),
|
||||
|
||||
),
|
||||
Page( //2
|
||||
BookLine("", 66),
|
||||
BookLine("<col=ff0000>3)<col=0b5394> Attacker:<col=000000> Take", 67),
|
||||
BookLine("poisoned, yellow egg from", 68),
|
||||
BookLine("healer Add spikes from", 69),
|
||||
BookLine("mushroom. Pass to", 70),
|
||||
BookLine("Defender.", 70),
|
||||
BookLine("", 72),
|
||||
BookLine("<col=ff0000>4)<col=0b5394> Defender:<col=000000> Take ", 73),
|
||||
BookLine("poisoned, spiked, yellow", 74),
|
||||
BookLine("from Attacker. Dunk", 75),
|
||||
BookLine("in lava. Pass to Collector.", 76),
|
||||
BookLine("", 77),
|
||||
BookLine("", 78)
|
||||
)
|
||||
)
|
||||
|
||||
)
|
||||
private fun display(player: Player, pageNum: Int, buttonID: Int) : Boolean {
|
||||
BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
on(Items.QUEEN_HELP_BOOK_10562, IntType.ITEM, "read") { player, _ ->
|
||||
BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display)
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//[QUEEN_HELP_BOOK_10562] // https://www.youtube.com/watch?v=r1x8xbz3JAA
|
||||
|
|
@ -0,0 +1,249 @@
|
|||
package content.minigame.barbassault.arena
|
||||
|
||||
import core.api.*
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.node.entity.Entity
|
||||
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.zone.ZoneBorders
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.tools.Log
|
||||
import org.rs09.consts.Components
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.Scenery
|
||||
|
||||
//HAMMER_2347
|
||||
//LOGS_11760 use these loggs
|
||||
//1889 5407 - Barb assualt QUEEN area -- 7508
|
||||
//1891 5465 - barb assualt AREA under
|
||||
|
||||
//queen spawn in Location.create(1884, 5405, 0)
|
||||
|
||||
//No prayers
|
||||
//sendMessage(player,"The barbarians forbid the use of prayer in their arena as they don't ~ value such methods!")
|
||||
|
||||
//should be multicombat
|
||||
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)
|
||||
|
||||
|
||||
override fun defineAreaBorders(): Array<ZoneBorders> {
|
||||
//block standard teleports.
|
||||
return arrayOf(getRegionBorders(7509))
|
||||
}
|
||||
override fun areaEnter(entity: Entity) {
|
||||
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) {
|
||||
val player = entity as? Player ?: return
|
||||
|
||||
closeOverlay(player)
|
||||
exitMiniGame(player)
|
||||
log(this::class.java, Log.FINE, "EXITED BARBASS")
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
|
||||
on(Scenery.LADDER_20194, IntType.SCENERY, "Climb-up") { player, _ ->
|
||||
sendDialogueOptions(player, "Are you sure you want to leave?", "Yes", "No")
|
||||
addDialogueAction(player) { _, buttonId ->
|
||||
if (buttonId == 2) {
|
||||
//endGame
|
||||
teleport(player, Location(2593 , 5261 ))
|
||||
|
||||
}
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
on(Scenery.HEALER_SPRING_20150, IntType.SCENERY, "Drink-from") { player, _ ->
|
||||
if (getItemFromEquipment(player, EquipmentSlot.CAPE)?.id == 10559) {
|
||||
player.animate(Animation(5407))
|
||||
player.lock(5)
|
||||
GameWorld.Pulser.submit(object : Pulse(3, player) {
|
||||
override fun pulse(): Boolean {
|
||||
heal(player, 25)
|
||||
player.unlock()
|
||||
sendMessage(player,"You've been healed \$Healed hitpoints.")
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
return@on true
|
||||
|
||||
}
|
||||
on(Scenery.HEALER_SPRING_20150, IntType.SCENERY, "Take-from") { player, _ ->
|
||||
//emote 5400
|
||||
/* HEALING_VIAL_10546 -- empty
|
||||
HEALING_VIAL1_10545 // 1
|
||||
HEALING_VIAL2_10544
|
||||
HEALING_VIAL3_10543
|
||||
HEALING_VIAL4_10542 // 4
|
||||
*/
|
||||
|
||||
return@on true
|
||||
|
||||
}
|
||||
|
||||
//CATALYTIC_RUNE_12851, ELEMENTAL_RUNE_12850
|
||||
|
||||
onUnequip(ROLE_ICON) { player, _ ->
|
||||
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
|
||||
}
|
||||
|
||||
onEquip(ROLE_ICON) { player, _ ->
|
||||
defineAreaBorders().forEach { border ->
|
||||
if (border.insideBorder(player)) {
|
||||
sendMessage(player, "You can't remove that!")
|
||||
// return@onUnequip false
|
||||
}
|
||||
}
|
||||
return@onEquip true
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
}
|
||||
|
||||
fun removeAll(player: Player, items: List<Int>, container: Container = Container.INVENTORY): Boolean {
|
||||
var removedAny = false
|
||||
items.forEach { id ->
|
||||
if (removeAll(player, id, container)) {
|
||||
removedAny = true
|
||||
}
|
||||
}
|
||||
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 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)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
484 = horn of glory!
|
||||
Barricaded entrances will only slow down, not stop, Penance from entering the battlefield.
|
||||
Players are allowed to use normal potions; however, potions mixed using Barbarian training may not be brought into the arena.
|
||||
Every team member will lose points when a runner makes it to the end,
|
||||
The only combat experience you will get here is the base experience for a magic spell using the runes given to you by the attacker machine.
|
||||
//You can stand in front of the lure cave to block runners from passing by. (Note that a runner can get through if you are walked on by another player)
|
||||
|
||||
[DEFENDER_HORN_10538]
|
||||
[COLLECTOR_HORN_10560]
|
||||
Collector Level 1 = [COLLECTION_BAG_10521] - Bag holds 2 eggs
|
||||
Collector Level 2 = [COLLECTION_BAG_10522] - Bag holds 4 eggs + Egg conversion
|
||||
Collector Level 3 = [COLLECTION_BAG_10523] - Bag holds 6 eggs + 40% conversion
|
||||
Collector Level 4 = [COLLECTION_BAG_10524] - Bag holds 7 eggs + 60% conversion
|
||||
Collector Level 5 = [COLLECTION_BAG_10525] - Bag holds 8 eggs + 80% conversion
|
||||
|
||||
Attacker Level 1 = [ATTACKER_HORN_10516] - +1 Damage
|
||||
Attacker Level 2 = [ATTACKER_HORN_10517] - +2 Damage
|
||||
Attacker Level 3 = [ATTACKER_HORN_10518] - +3 Damage
|
||||
Attacker Level 4 = [ATTACKER_HORN_10519] - +4 Damage
|
||||
Attacker Level 5 = [ATTACKER_HORN_10520] - +5 Damage
|
||||
|
||||
Healer Level 1 = [HEALER_HORN_10526] - Heals 10 hp
|
||||
Healer Level 2 = [HEALER_HORN_10527] - Heals 15 hp
|
||||
Healer Level 3 = [HEALER_HORN_10528] - Heals 20 hp
|
||||
Healer Level 4 = [HEALER_HORN_10529] - Heals 25 hp
|
||||
Healer Level 5 = [HEALER_HORN_10530] - Heals 35 hp
|
||||
|
||||
HEALING_VIAL_10546
|
||||
HEALING_VIAL1_10545
|
||||
HEALING_VIAL2_10544
|
||||
HEALING_VIAL3_10543
|
||||
HEALING_VIAL4_10542
|
||||
|
||||
| Level | Honour Points | Defender |
|
||||
|-------|----------------|----------------|
|
||||
| 1 | Start level | Lure 4 spaces |
|
||||
| 2 | 200 | Lure 5 spaces |
|
||||
| 3 | 300 | Lure 6 spaces |
|
||||
| 4 | 400 | Lure 8 spaces |
|
||||
| 5 | 500 | Lure 10 spaces |
|
||||
|-------|----------------|----------------|
|
||||
RUNNER_TRAP2_20135
|
||||
RUNNER_TRAP1_20230
|
||||
BROKEN_TRAP0_20231
|
||||
|
||||
Only normal Magics can damage.
|
||||
we use these runes in barb assault.
|
||||
[ATTACKER_ITEM_MACHINE_20241]
|
||||
Options[ Take-runes, Take-arrows(300 of each)
|
||||
CATALYTIC_RUNE_12851, ELEMENTAL_RUNE_12850
|
||||
|
||||
https://youtu.be/_EipqTK3Qak?t=68
|
||||
Blocking off entrance, does NOT STOP runners entering, only slows
|
||||
|
||||
|
||||
Announce in game room when All of a monster has been killed
|
||||
" All of the $PENANCE Name have been killed!
|
||||
|
||||
* */
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package content.minigame.barbassault.arena
|
||||
|
||||
import core.api.*
|
||||
import core.game.node.entity.player.Player
|
||||
import org.rs09.consts.Items
|
||||
|
||||
object HornHelper {
|
||||
fun getAttackerHorn(player: Player): AttackerHorn? {
|
||||
return AttackerHorn.values().firstOrNull { inInventory(player, it.itemId) }
|
||||
}
|
||||
|
||||
fun getHealerHorn(player: Player): HealerHorn? {
|
||||
return HealerHorn.values().firstOrNull { inInventory(player, it.itemId) }
|
||||
}
|
||||
|
||||
fun getCollectorBag(player: Player): CollectionBag? {
|
||||
return CollectionBag.values().firstOrNull { inInventory(player, it.itemId) }
|
||||
}
|
||||
}
|
||||
enum class AttackerHorn(val itemId: Int) {
|
||||
LEVEL_ONE(Items.ATTACKER_HORN_10516),
|
||||
LEVEL_TWO(Items.ATTACKER_HORN_10517),
|
||||
LEVEL_THREE(Items.ATTACKER_HORN_10518),
|
||||
LEVEL_FOUR(Items.ATTACKER_HORN_10519),
|
||||
LEVEL_FIVE(Items.ATTACKER_HORN_10520);
|
||||
|
||||
companion object {
|
||||
private val map = values().associateBy(AttackerHorn::itemId)
|
||||
|
||||
fun fromId(id: Int): AttackerHorn? = map[id]
|
||||
}
|
||||
}
|
||||
enum class HealerHorn(val itemId: Int) {
|
||||
LEVEL_ONE(Items.HEALER_HORN_10526),
|
||||
LEVEL_TWO(Items.HEALER_HORN_10527),
|
||||
LEVEL_THREE(Items.HEALER_HORN_10528),
|
||||
LEVEL_FOUR(Items.HEALER_HORN_10529),
|
||||
LEVEL_FIVE(Items.HEALER_HORN_10530);
|
||||
|
||||
companion object {
|
||||
private val map = values().associateBy(HealerHorn::itemId)
|
||||
|
||||
fun fromId(id: Int): HealerHorn? = map[id]
|
||||
}
|
||||
}
|
||||
enum class CollectionBag(val itemId: Int) {
|
||||
LEVEL_ONE(Items.COLLECTION_BAG_10521),
|
||||
LEVEL_TWO(Items.COLLECTION_BAG_10522),
|
||||
LEVEL_THREE(Items.COLLECTION_BAG_10523),
|
||||
LEVEL_FOUR(Items.COLLECTION_BAG_10524),
|
||||
LEVEL_FIVE(Items.COLLECTION_BAG_10525);
|
||||
|
||||
companion object {
|
||||
private val map = values().associateBy(CollectionBag::itemId)
|
||||
|
||||
fun fromId(id: Int): CollectionBag? = map[id]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
package content.minigame.barbassault.arena
|
||||
|
||||
import core.api.sendChat
|
||||
import core.api.sendMessage
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import org.rs09.consts.Items
|
||||
|
||||
class HornListeners : InteractionListener {
|
||||
val ATTACKER_HORNS = intArrayOf(Items.ATTACKER_HORN_10516,Items.ATTACKER_HORN_10517,Items.ATTACKER_HORN_10518,Items.ATTACKER_HORN_10519,Items.ATTACKER_HORN_10520)
|
||||
val TELL_RED = "Collector: Red Eggs!"
|
||||
val TELL_GREEN = "Collector: Green Eggs!"
|
||||
val TELL_BLUE = "Collector: Blue Eggs!"
|
||||
|
||||
val TELL_PTOFU = "Healer: Poison tofo!"
|
||||
val TELL_PWORMS = "Healer: Poison worms!"
|
||||
val TELL_PMEAT = "Healer: Poison meat!"
|
||||
|
||||
val TELL_STYLE1 = "Attacker: Controlled/Bronze/Wind!"
|
||||
val TELL_STYLE2 = "Attacker: Accurate/Iron/Water!"
|
||||
val TELL_STYLE3 = "Attacker: Aggressive/Steel/Earth!"
|
||||
val TELL_STYLE4 = "Attacker: Defensive/Mithril/Fire!"
|
||||
|
||||
val HEALER_HORNS = intArrayOf(Items.HEALER_HORN_10526,Items.HEALER_HORN_10527,Items.HEALER_HORN_10528,Items.HEALER_HORN_10529,Items.HEALER_HORN_10530 )
|
||||
val TELL_TOFU = "Defender: Drop Tofu!"
|
||||
val TELL_CRACKERS= "Defender: Drop Crackers!"
|
||||
val TELL_WORMS = "Defender: Drop Worms!"
|
||||
|
||||
val ALL_HORNS = intArrayOf(Items.COLLECTOR_HORN_10560,Items.DEFENDER_HORN_10538) + HEALER_HORNS + ATTACKER_HORNS
|
||||
val TELL_MEDIC = "Medic!!"
|
||||
|
||||
override fun defineListeners() {
|
||||
on(ALL_HORNS, IntType.ITEM, "Medic") { player, _ ->
|
||||
sendChat(player,TELL_MEDIC)
|
||||
return@on true
|
||||
}
|
||||
on(ALL_HORNS, IntType.ITEM, "Drop") { player, _ ->
|
||||
sendMessage(player,"I need that!") // not authentic
|
||||
return@on false
|
||||
}
|
||||
|
||||
//ATTACKER
|
||||
on(ATTACKER_HORNS, IntType.ITEM, "Tell-red") { player, _ ->
|
||||
sendChat(player,TELL_RED)
|
||||
return@on true
|
||||
}
|
||||
on(ATTACKER_HORNS, IntType.ITEM, "Tell-green") { player, _ ->
|
||||
sendChat(player,TELL_GREEN)
|
||||
return@on true
|
||||
}
|
||||
on(ATTACKER_HORNS, IntType.ITEM, "Tell-blue") { player, _ ->
|
||||
sendChat(player,TELL_BLUE)
|
||||
return@on true
|
||||
}
|
||||
|
||||
//DEFENDER
|
||||
on(Items.DEFENDER_HORN_10538, IntType.ITEM, "Tell-tofu") { player, _ ->
|
||||
sendChat(player,TELL_PTOFU)
|
||||
return@on true
|
||||
}
|
||||
on(Items.DEFENDER_HORN_10538, IntType.ITEM, "Tell-worms") { player, _ ->
|
||||
sendChat(player,TELL_PWORMS)
|
||||
return@on true
|
||||
}
|
||||
on(Items.DEFENDER_HORN_10538, IntType.ITEM, "Tell-meat") { player, _ ->
|
||||
sendChat(player,TELL_PMEAT)
|
||||
return@on true
|
||||
}
|
||||
|
||||
//COLLECTOR
|
||||
on(Items.COLLECTOR_HORN_10560, IntType.ITEM, "Tell-style1") { player, _ ->
|
||||
sendChat(player,TELL_STYLE1)
|
||||
return@on true
|
||||
}
|
||||
on(Items.COLLECTOR_HORN_10560, IntType.ITEM, "Tell-style2") { player, _ ->
|
||||
sendChat(player,TELL_STYLE2)
|
||||
return@on true
|
||||
}
|
||||
on(Items.COLLECTOR_HORN_10560, IntType.ITEM, "Tell-style3") { player, _ ->
|
||||
sendChat(player,TELL_STYLE3)
|
||||
return@on true
|
||||
}
|
||||
on(Items.COLLECTOR_HORN_10560, IntType.ITEM, "Tell-style4") { player, _ ->
|
||||
sendChat(player,TELL_STYLE4)
|
||||
return@on true
|
||||
}
|
||||
|
||||
//HEALER
|
||||
on(HEALER_HORNS, IntType.ITEM, "Tell-tofu") { player, _ ->
|
||||
sendChat(player,TELL_TOFU)
|
||||
return@on true
|
||||
}
|
||||
on(HEALER_HORNS, IntType.ITEM, "Tell-crackers") { player, _ ->
|
||||
sendChat(player,TELL_CRACKERS)
|
||||
return@on true
|
||||
}
|
||||
on(HEALER_HORNS, IntType.ITEM, "tell-worms") { player, _ ->
|
||||
sendChat(player,TELL_WORMS)
|
||||
return@on true
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package content.minigame.barbassault.arena
|
||||
|
||||
class WaveCompleteInterface {
|
||||
}
|
||||
|
||||
/*
|
||||
[TITLE] bold/ Wave Complete!
|
||||
bold/ Reward:
|
||||
Bold/ The Queen is dead!
|
||||
|
||||
Reward:
|
||||
80 Attacker Points
|
||||
5 Defender Points
|
||||
5 Collector Points
|
||||
5 Healer Points
|
||||
The option to send your points
|
||||
for
|
||||
special armour and gambling
|
||||
options,
|
||||
which you should use before
|
||||
defeating the queen again.
|
||||
|
||||
advance break down -->
|
||||
https://youtu.be/OjkLXOQVWEQ?t=113
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package content.minigame.barbassault.arena.machines
|
||||
|
||||
import core.api.EquipmentSlot
|
||||
import core.api.getItemFromEquipment
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.Scenery
|
||||
import core.api.sendMessage
|
||||
|
||||
|
||||
class AttackerMachine: InteractionListener {
|
||||
|
||||
val TAKE_ARROWS = intArrayOf(Items.BRONZE_ARROW_882, Items.IRON_ARROW_884,Items.STEEL_ARROW_886,Items.MITHRIL_ARROW_888)
|
||||
val TAKE_RUNES = intArrayOf(Items.AIR_RUNE_556,Items.WATER_RUNE_555,Items.EARTH_RUNE_557,Items.FIRE_RUNE_554,
|
||||
Items.MIND_RUNE_558,Items.CHAOS_RUNE_562, Items.DEATH_RUNE_560,Items.BLOOD_RUNE_565)
|
||||
|
||||
//val TAKE_RUNES = intArrayOf(Items.CATALYTIC_RUNE_12851,Items.ELEMENTAL_RUNE_12850)
|
||||
//suppose to use Catalyic and Elemental runes
|
||||
|
||||
//should probably make sure familiars can't smuggle items out
|
||||
|
||||
override fun defineListeners() {
|
||||
on(Scenery.ATTACKER_ITEM_MACHINE_20241, IntType.SCENERY, "Take-runes") { player, node ->
|
||||
if (getItemFromEquipment(player, EquipmentSlot.CAPE)?.id == 10556) {
|
||||
ItemMachine.handleAddItemMachine(player, node, TAKE_RUNES, 300)
|
||||
sendMessage(player,"You take a selection of runes from the dispenser.")
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
on(Scenery.ATTACKER_ITEM_MACHINE_20241, IntType.SCENERY, "Take-arrows") { player, node ->
|
||||
if (getItemFromEquipment(player, EquipmentSlot.CAPE)?.id == 10556) {
|
||||
ItemMachine.handleAddItemMachine(player, node, TAKE_ARROWS, 300)
|
||||
sendMessage(player,"You take a selection of arrows from the dispenser.")
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package content.minigame.barbassault.arena.machines
|
||||
|
||||
import core.api.EquipmentSlot
|
||||
import core.api.getItemFromEquipment
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import org.rs09.consts.Scenery
|
||||
|
||||
class CollectorMachine : InteractionListener {
|
||||
|
||||
override fun defineListeners() {
|
||||
on(Scenery.DEFENDER_ITEM_MACHINE_20242, IntType.SCENERY, "Convert") { player, _ ->
|
||||
if (getItemFromEquipment(player, EquipmentSlot.CAPE)?.id == 10557) {
|
||||
//Items.RED_EGG_10532
|
||||
//Items.BLUE_EGG_10533
|
||||
//Items.GREEN_EGG_10531
|
||||
//uhhhhhh
|
||||
//more research is needed.
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package content.minigame.barbassault.arena.machines
|
||||
|
||||
import core.api.EquipmentSlot
|
||||
import core.api.getItemFromEquipment
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.Scenery
|
||||
|
||||
class DefenderMachine :InteractionListener {
|
||||
val TAKE_WORMS = Items.WORMS_10515
|
||||
val TAKE_CRACKERS = Items.CRACKERS_10513
|
||||
val TAKE_TOFU = Items.TOFU_10514
|
||||
val baseItems = intArrayOf(TAKE_WORMS, TAKE_CRACKERS, TAKE_TOFU)
|
||||
val STOCK_UP = IntArray(11 * baseItems.size) { i -> baseItems[i % baseItems.size] }
|
||||
|
||||
|
||||
override fun defineListeners() {
|
||||
on(Scenery.DEFENDER_ITEM_MACHINE_20242, IntType.SCENERY, "Stock-up") { player, node ->
|
||||
if (getItemFromEquipment(player, EquipmentSlot.CAPE)?.id == 10558) {
|
||||
ItemMachine.handleAddItemMachine(player, node, STOCK_UP, 1)
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
on(Scenery.DEFENDER_ITEM_MACHINE_20242, IntType.SCENERY, "Take-crackers") { player, node ->
|
||||
if (getItemFromEquipment(player, EquipmentSlot.CAPE)?.id == 10558) {
|
||||
ItemMachine.handleAddItemMachine(player, node, intArrayOf(TAKE_CRACKERS), 5)
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
on(Scenery.DEFENDER_ITEM_MACHINE_20242, IntType.SCENERY, "Take-tofu") { player, node ->
|
||||
if (getItemFromEquipment(player, EquipmentSlot.CAPE)?.id == 10558) {
|
||||
ItemMachine.handleAddItemMachine(player, node, intArrayOf(TAKE_TOFU), 5)
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
on(Scenery.DEFENDER_ITEM_MACHINE_20242, IntType.SCENERY, "Take-worms") { player, node ->
|
||||
if (getItemFromEquipment(player, EquipmentSlot.CAPE)?.id == 10558) {
|
||||
ItemMachine.handleAddItemMachine(player, node, intArrayOf(TAKE_WORMS), 5)
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
[DEFENDER_ITEM_MACHINE_20242]
|
||||
Options[ Stock-up, Take-crackers, Take-tofu, Take-worms]
|
||||
take items gives 5,
|
||||
stock up alternates crackers tofu worms
|
||||
CRACKERS_10513, TOFU_10514, WORMS_10515
|
||||
|
||||
*/
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package content.minigame.barbassault.arena.machines
|
||||
|
||||
|
||||
import core.api.EquipmentSlot
|
||||
import core.api.getItemFromEquipment
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.Scenery
|
||||
|
||||
class HealerMachine : InteractionListener {
|
||||
val ALL_HEALER_VAILS = intArrayOf(Items.HEALING_VIAL_10546,Items.HEALING_VIAL1_10545,Items.HEALING_VIAL2_10544,Items.HEALING_VIAL3_10543,Items.HEALING_VIAL4_10542)
|
||||
val TAKE_VAIL = Items.HEALING_VIAL4_10542
|
||||
val TAKE_WORMS = Items.POISONED_WORMS_10540
|
||||
val TAKE_TOFU = Items.POISONED_TOFU_10539
|
||||
val TAKE_MEAT = Items.POISONED_MEAT_10541
|
||||
|
||||
val baseItems = intArrayOf(TAKE_WORMS, TAKE_TOFU, TAKE_MEAT)
|
||||
val STOCK_UP = IntArray(11 * baseItems.size) { i -> baseItems[i % baseItems.size] }
|
||||
|
||||
|
||||
override fun defineListeners() {
|
||||
on(Scenery.HEALER_ITEM_MACHINE_20243, IntType.SCENERY, "Stock-up") { player, node ->
|
||||
if (getItemFromEquipment(player, EquipmentSlot.CAPE)?.id == 10559) {
|
||||
//todo only allowed to have one vial
|
||||
ItemMachine.handleAddItemMachine(player, node, STOCK_UP, 1)
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
on(Scenery.HEALER_ITEM_MACHINE_20243, IntType.SCENERY, "Take-vail") { player, node ->
|
||||
if (getItemFromEquipment(player, EquipmentSlot.CAPE)?.id == 10559) {
|
||||
//todo only allowed to have one vial
|
||||
ItemMachine.handleAddItemMachine(player, node, intArrayOf(TAKE_VAIL), 1)
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
on(Scenery.HEALER_ITEM_MACHINE_20243, IntType.SCENERY, "Take-worms") { player, node ->
|
||||
if (getItemFromEquipment(player, EquipmentSlot.CAPE)?.id == 10559) {
|
||||
ItemMachine.handleAddItemMachine(player, node, intArrayOf(TAKE_WORMS), 5)
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
on(Scenery.HEALER_ITEM_MACHINE_20243, IntType.SCENERY, "Take-tofu") { player, node ->
|
||||
if (getItemFromEquipment(player, EquipmentSlot.CAPE)?.id == 10559) {
|
||||
ItemMachine.handleAddItemMachine(player, node, intArrayOf(TAKE_TOFU), 5)
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
on(Scenery.HEALER_ITEM_MACHINE_20243, IntType.SCENERY, "Take-meat") { player, node ->
|
||||
if (getItemFromEquipment(player, EquipmentSlot.CAPE)?.id == 10559) {
|
||||
ItemMachine.handleAddItemMachine(player, node, intArrayOf(TAKE_MEAT), 5)
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* [HEALER_ITEM_MACHINE_20243]
|
||||
Options[ Stock-up, Take-vail, Take-tofu, Take-worms, Tale-meat]
|
||||
Take item gives 5!
|
||||
Stock-up gives vial and alternating tofo-worms-meat till full
|
||||
POISONED_TOFU_10539,POISONED_MEAT_10541,POISONED_WORMS_10540
|
||||
*/
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package content.minigame.barbassault.arena.machines
|
||||
|
||||
import core.api.addItem
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.GameWorld
|
||||
import core.game.world.update.flag.context.Animation
|
||||
|
||||
class ItemMachine {
|
||||
companion object {
|
||||
fun handleAddItemMachine(player: Player,node: Node, items: IntArray, amount: Int)
|
||||
{
|
||||
player.animate(Animation(5419)) // find right animation
|
||||
player.lock(5) //
|
||||
|
||||
GameWorld.Pulser.submit(object : Pulse(3, player) {
|
||||
override fun pulse(): Boolean {
|
||||
//sendMessage(player,"You fill up your inventory with food from the dispenser") //defender
|
||||
//sendMessage(player,"You fill up your inventory with poisoned food from the dispenser")// healer
|
||||
//todo send right message depending on role
|
||||
addArrayOfItems(player,items,amount)
|
||||
player.unlock()
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun addArrayOfItems(player: Player, ids: IntArray, amount: Int) {
|
||||
ids.forEach { id -> addItem(player,id,amount) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package content.minigame.barbassault.arenas.monsters
|
||||
|
||||
import content.minigame.barbassault.arena.HornHelper
|
||||
import core.api.*
|
||||
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.npc.NPCBehavior
|
||||
import core.game.node.entity.player.Player
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
val PENANCE_FIGHTER_IDS = listOf(
|
||||
NPCs.PENANCE_FIGHTER_5040,
|
||||
NPCs.PENANCE_FIGHTER_5044,
|
||||
NPCs.PENANCE_FIGHTER_5045,
|
||||
NPCs.PENANCE_FIGHTER_5213,
|
||||
NPCs.PENANCE_FIGHTER_5214,
|
||||
NPCs.PENANCE_FIGHTER_5215,
|
||||
NPCs.PENANCE_FIGHTER_5216,
|
||||
NPCs.PENANCE_FIGHTER_5217,
|
||||
NPCs.PENANCE_FIGHTER_5218,
|
||||
NPCs.PENANCE_FIGHTER_5219)
|
||||
|
||||
class PenanceFighterNPC : NPCBehavior(*PENANCE_FIGHTER_IDS.toIntArray()) {
|
||||
override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean {
|
||||
if (attacker is Player && getItemFromEquipment(attacker, EquipmentSlot.CAPE)?.id != 10556) {
|
||||
sendMessage(attacker,"These Penance are immune to your attacks.")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
|
||||
return 0.0
|
||||
}
|
||||
override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) {
|
||||
val firstBefore = state.estimatedHit
|
||||
state.estimatedHit = firstBefore + (HornHelper.getAttackerHorn(attacker as Player)?.ordinal?.plus(1) ?: 0) +1
|
||||
|
||||
}
|
||||
override fun onCreation (self: NPC) {
|
||||
self.setAttribute("agg_radius",2)
|
||||
self.isWalks = true
|
||||
self.isNeverWalks = false
|
||||
self.walkRadius = 64
|
||||
self.isAggressive = true
|
||||
self.isRespawn = false
|
||||
|
||||
self.definition.combatDistance = 1
|
||||
self.properties.combatPulse.style = CombatStyle.MELEE
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//Shrink death 5098
|
||||
//Fighter_Attack_5097
|
||||
//5096 take hit
|
||||
//5095_Move
|
||||
//9094_Idle
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package content.minigame.barbassault.arena.monsters
|
||||
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.npc.NPCBehavior
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
val PENANCE_HEALER_IDS = listOf(
|
||||
NPCs.PENANCE_HEALER_5043,
|
||||
NPCs.PENANCE_HEALER_5238,
|
||||
NPCs.PENANCE_HEALER_5239,
|
||||
NPCs.PENANCE_HEALER_5240,
|
||||
NPCs.PENANCE_HEALER_5241,
|
||||
NPCs.PENANCE_HEALER_5242,
|
||||
NPCs.PENANCE_HEALER_5243,
|
||||
NPCs.PENANCE_HEALER_5244,
|
||||
NPCs.PENANCE_HEALER_5245,
|
||||
NPCs.PENANCE_HEALER_5246
|
||||
)
|
||||
class PenanceHealerNPC : NPCBehavior(*PENANCE_HEALER_IDS.toIntArray()) {
|
||||
override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
|
||||
return 0.0
|
||||
}
|
||||
|
||||
//sendMessage(player,"that's the wrong type of poisoned food to use! Penalty!")
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Can only heal Penance Runners
|
||||
Can only be Poisoned by Healer roll
|
||||
Poisoned tofu/Poisoned worms/Poisoned meat announced by Defender
|
||||
|
||||
poisoned food will cause a total of 54 damage over time.
|
||||
First spawn = will target visible player then target visible Penance Runner,heal it to full health. repeat
|
||||
No runners = Randomly Roam
|
||||
|
||||
Poisoned tofu = 10539
|
||||
Poisoned worms = 10540
|
||||
Poisoned meat = 10541
|
||||
|
||||
Healer emote:
|
||||
healer_Idle_5104
|
||||
healer_hit_5105
|
||||
healer_Death_5106
|
||||
Healer_attack_5107?
|
||||
*/
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package content.minigame.barbassault.arena.monsters
|
||||
|
||||
import core.api.sendMessage
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.combat.CombatStyle
|
||||
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
|
||||
|
||||
class PenanceQueenNPC : NPCBehavior(NPCs.PENANCE_QUEEN_5247){
|
||||
override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean {
|
||||
if (attacker is Player ) {
|
||||
sendMessage(attacker,"Only an Omega Egg can hurt the queen!")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
|
||||
return 0.0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
queen emote:
|
||||
queen_hit_5408+
|
||||
queen_move_5409
|
||||
queen_Idle_5410
|
||||
queen_attack_5411
|
||||
queen_Death_5412
|
||||
queen_attack2_5413
|
||||
queen_Spawnin_5414
|
||||
*/
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package content.minigame.barbassault.arena.monsters
|
||||
|
||||
import core.api.*
|
||||
import core.api.getItemFromEquipment
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.combat.CombatStyle
|
||||
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
|
||||
//20730 = rangers cast
|
||||
val PENANCE_RANGER_IDS = listOf(
|
||||
NPCs.PENANCE_RANGER_5041,
|
||||
NPCs.PENANCE_RANGER_5229,
|
||||
NPCs.PENANCE_RANGER_5230,
|
||||
NPCs.PENANCE_RANGER_5231,
|
||||
NPCs.PENANCE_RANGER_5232,
|
||||
NPCs.PENANCE_RANGER_5233,
|
||||
NPCs.PENANCE_RANGER_5234,
|
||||
NPCs.PENANCE_RANGER_5235,
|
||||
NPCs.PENANCE_RANGER_5236,
|
||||
NPCs.PENANCE_RANGER_5237
|
||||
)
|
||||
class PenanceRangerNPC : NPCBehavior(*PENANCE_RANGER_IDS.toIntArray()) {
|
||||
override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean {
|
||||
if (attacker is Player && getItemFromEquipment(attacker, EquipmentSlot.CAPE)?.id != 10556) {
|
||||
sendMessage(attacker, "These Penance are immune to your attacks.")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
|
||||
return 0.0
|
||||
}
|
||||
override fun onCreation (self: NPC) {
|
||||
self.setAttribute("agg_radius",2)
|
||||
self.isWalks = true
|
||||
self.isNeverWalks = false
|
||||
self.walkRadius = 64
|
||||
self.isAggressive = true
|
||||
|
||||
self.definition.combatDistance = 8
|
||||
self.properties.combatPulse.style = CombatStyle.RANGE
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Combat-style/arrow-type/magic-spell announced by Collector
|
||||
* Controlled/Bullet/Wind
|
||||
* Accurate/Field/Water
|
||||
* Aggressive/Blunt/Earth
|
||||
* Defensive/Barbed/Fire
|
||||
* Poisons (from both weapons and green eggs)
|
||||
* Egg fired from the Egg Launcher
|
||||
* Recoil damage from any player
|
||||
*/
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package content.minigame.barbassault.arena.monsters
|
||||
|
||||
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
|
||||
|
||||
val PENANCE_RUNNER_IDS = listOf(
|
||||
NPCs.PENANCE_RUNNER_5042,
|
||||
NPCs.PENANCE_RUNNER_5220,
|
||||
NPCs.PENANCE_RUNNER_5221,
|
||||
NPCs.PENANCE_RUNNER_5222,
|
||||
NPCs.PENANCE_RUNNER_5223,
|
||||
NPCs.PENANCE_RUNNER_5224,
|
||||
NPCs.PENANCE_RUNNER_5225,
|
||||
NPCs.PENANCE_RUNNER_5226,
|
||||
NPCs.PENANCE_RUNNER_5227,
|
||||
NPCs.PENANCE_RUNNER_5228,
|
||||
)
|
||||
class PenanceRunnerNPC : NPCBehavior(*PENANCE_RANGER_IDS.toIntArray()) {
|
||||
val GOOD_EAT = "Chomp, chomp"
|
||||
val BAD_EAT = "Blurghh"
|
||||
val TRAP_HIT = "Urghhh!"
|
||||
|
||||
override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
|
||||
return 0.0
|
||||
}
|
||||
override fun onCreation(self: NPC) {
|
||||
self.isWalks = true
|
||||
self.walkRadius = 22
|
||||
}
|
||||
|
||||
fun seekFood(){
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//good food dropped stays "good"
|
||||
//bad food dropped stays bad
|
||||
/*
|
||||
Runner emote
|
||||
Runner_death_5103
|
||||
Runner_trap_Death_ 5102
|
||||
runner_hit_5101
|
||||
runner_Move_5100
|
||||
runner_Idle 5099
|
||||
*/
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package content.minigame.barbassault.arena.monsters
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.npc.NPCBehavior
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
|
||||
class PenanceSpawnNPC : NPCBehavior(NPCs.QUEEN_SPAWN_5248) {
|
||||
override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
|
||||
return 0.0
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package content.minigame.barbassault.arena.scenery
|
||||
|
||||
import content.minigame.barbassault.arena.monsters.PENANCE_RUNNER_IDS
|
||||
import core.api.*
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
|
||||
|
||||
// RUNNER_TRAP2_20135
|
||||
// RUNNER_TRAP1_20230
|
||||
// BROKEN_TRAP0_20231
|
||||
//Trap East Location.create(1901, 5474, 0)
|
||||
//trap west Location.create(1871, 5473, 0)
|
||||
|
||||
//emote 5365 maybe
|
||||
//emote 5416 long
|
||||
//emote 5416 long
|
||||
//emote 5417 block wall
|
||||
|
||||
//trap only kills if Runner eats GOOD bait.
|
||||
//If runner eats bad bait they escape
|
||||
class DefenderTrap : MapArea {
|
||||
val GOOD_EAT = "Chomp, chomp"
|
||||
val BAD_EAT = "Blurghh"
|
||||
val TRAP_HIT = "Urghhh!"
|
||||
val TRAP_EAST_ZONE: ZoneBorders = ZoneBorders(1900, 5475, 1902, 5473, 0)
|
||||
val TRAP_EAST = Location.create(1901, 5474, 0)
|
||||
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 TRAPS = arrayOf(TRAP_WEST,TRAP_EAST)
|
||||
val playersInArea = mutableListOf<Player>()
|
||||
|
||||
override fun defineAreaBorders(): Array<ZoneBorders> {
|
||||
return TRAPS_ZONE
|
||||
}
|
||||
override fun areaEnter(entity: Entity) {
|
||||
if (PENANCE_RUNNER_IDS.contains(entity.id)) {
|
||||
killRunner(entity)
|
||||
updateTrap(entity.location)
|
||||
sendMessageArea()
|
||||
}
|
||||
|
||||
val player = entity as? Player ?: return
|
||||
playersInArea.add(player)
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun areaLeave(entity: Entity, logout: Boolean) {
|
||||
val player = entity as? Player ?: return
|
||||
playersInArea.remove(player)
|
||||
}
|
||||
|
||||
fun killRunner(entity: Entity){
|
||||
|
||||
}
|
||||
|
||||
fun updateTrap(location: Location) {
|
||||
if (TRAPS.contains(location)){
|
||||
|
||||
}
|
||||
}
|
||||
fun sendMessageArea(){
|
||||
playersInArea.forEach { player ->
|
||||
sendMessage(player,"Entered Trap Area")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//you fixed the Penance Runner trap.
|
||||
//sendMessage(player,"A Penance Runner broke a trap to the east/west!") //When a runner dies to trap announce to Defenders
|
||||
//replaceScenery()
|
||||
//animateScenery
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package content.minigame.barbassault.arena.scenery
|
||||
|
||||
class EggCannon {
|
||||
|
||||
///stun(entity: Entity, ticks: Int)
|
||||
///isStunned(entity: Entity)
|
||||
//applyPoison (entity: Entity, source: Entity, severity: Int)
|
||||
//isPoisoned (entity: Entity) : Boolean
|
||||
//spawnProjectile
|
||||
//face()
|
||||
|
||||
//error message CHATBOX "[bold]all of the _PENANCE_ have been killed!"
|
||||
//error messageif out of range CHATBOX "There are no targetable _PENANCE_ within fireing range."
|
||||
|
||||
}
|
||||
//emote 5428 maybe
|
||||
/* GOLD I TELL YOU GOLD!!!!
|
||||
https://youtu.be/_EipqTK3Qak?t=106
|
||||
|
||||
//egg explosion 20727
|
||||
|
||||
shoot option when no eggs in hoper =
|
||||
MEssage chatbox-> There are no egs in the hopper.
|
||||
|
||||
Look-in ->
|
||||
The hopper contains
|
||||
0 poison egs, 0 explosive eggs
|
||||
and 0 stun eggs.
|
||||
|
||||
stun eggs
|
||||
explosive eggs
|
||||
poison eggs
|
||||
messages
|
||||
You load the hopper.
|
||||
You cant load any more /Egg_type/s.
|
||||
|
||||
*/
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
package content.minigame.barbassault.arena.scenery
|
||||
|
||||
import core.api.sendMessage
|
||||
import core.game.component.Component
|
||||
import core.game.component.ComponentDefinition
|
||||
import core.game.component.ComponentPlugin
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.node.entity.player.Player
|
||||
import core.plugin.Plugin
|
||||
import org.rs09.consts.Components
|
||||
import org.rs09.consts.Scenery
|
||||
|
||||
class HornOfGlory : ComponentPlugin() , InteractionListener {
|
||||
companion object {
|
||||
val QUEEN_ARRIVE = "The Queen has arrived and you can no longer use the horn of glory!"
|
||||
//attacker
|
||||
val CONTROLED_BRONZE_WIND = 0
|
||||
val ACCURATE_IRON_WATER = 1
|
||||
val AGGRISSIVE_STEEL_EARTH = 2
|
||||
val DEFENSIVE_MITHRIL_FIRE = 3
|
||||
//defender
|
||||
val FOOD_TOFU = 0
|
||||
val FOOD_CRACKERS = 1
|
||||
val FOOD_WORMS = 2
|
||||
//collector
|
||||
val RED_EGG = 0
|
||||
val GREEN_EGG = 1
|
||||
val BLUE_EGG = 2
|
||||
//healer
|
||||
val POISON_TOFU = 0
|
||||
val POISON_WORMS = 1
|
||||
val POISON_MEAT = 2
|
||||
|
||||
val CALL_BUTTON = mapOf(
|
||||
16 to CONTROLED_BRONZE_WIND,
|
||||
17 to ACCURATE_IRON_WATER,
|
||||
18 to AGGRISSIVE_STEEL_EARTH,
|
||||
19 to DEFENSIVE_MITHRIL_FIRE,
|
||||
|
||||
20 to FOOD_TOFU,
|
||||
22 to FOOD_CRACKERS,
|
||||
21 to FOOD_WORMS,
|
||||
|
||||
13 to RED_EGG,
|
||||
14 to GREEN_EGG,
|
||||
15 to BLUE_EGG,
|
||||
|
||||
23 to POISON_TOFU,
|
||||
24 to POISON_WORMS,
|
||||
25 to POISON_MEAT
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
override fun newInstance(arg: Any?): Plugin<Any> {
|
||||
ComponentDefinition.forId(Components.BARBASSAULT_HORN_484).plugin = this
|
||||
return this
|
||||
}
|
||||
|
||||
override fun handle(
|
||||
player: Player?,
|
||||
component: Component?,
|
||||
opcode: Int,
|
||||
button: Int,
|
||||
slot: Int,
|
||||
itemId: Int
|
||||
): Boolean {
|
||||
sendMessage(player!!,"Button " +button )
|
||||
return true
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
on(Scenery.HORN_OF_GLORY_20247, IntType.SCENERY, "Call") { player, _ ->
|
||||
//emote 5438
|
||||
player.interfaceManager.open(Component(484))
|
||||
return@on true
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,403 @@
|
|||
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 core.api.*
|
||||
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 org.rs09.consts.Items
|
||||
import org.rs09.consts.Scenery
|
||||
|
||||
|
||||
//"-- Next wave no longer starting"
|
||||
|
||||
class BarbassaultLobby : InteractionListener, MapArea {
|
||||
|
||||
override fun defineAreaBorders(): Array<ZoneBorders> {
|
||||
return areaBorders
|
||||
}
|
||||
override fun areaEnter(entity: Entity) {
|
||||
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)
|
||||
|
||||
entity.equipment.removeAll(barbassItems)
|
||||
entity.inventory.removeAll(barbassItems)
|
||||
}
|
||||
}
|
||||
fun updatePlayerWave(entity: Entity) {
|
||||
val player = entity as? Player ?: return
|
||||
val location = player.location
|
||||
|
||||
if (QUICK_START.insideBorder(location)) {
|
||||
entity.setAttribute("/save:barbass:wave", 1)
|
||||
return
|
||||
}
|
||||
for ((index, lobby) in waveLobbies.withIndex()) {
|
||||
if (lobby.insideBorder(location)) {
|
||||
if (lobby != MAIN_LOBBY) { // MAIN_LOBBY should not assign a wave number
|
||||
entity.setAttribute("/save:barbass:wave", index + 1)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//attacker 20561 : ch8
|
||||
//defender 20566 : ch10
|
||||
//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)
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
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.
|
||||
// waveAdvance(player)
|
||||
|
||||
return@on true
|
||||
}
|
||||
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)
|
||||
}
|
||||
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 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(Scenery.LADDER_20193, IntType.SCENERY, "Climb-down") { player, _ ->
|
||||
closeOverlay(player) // close party,
|
||||
openOverlay(player, 494)// open countdown, Make a Count DownHandler
|
||||
return@on true
|
||||
}
|
||||
on(Scenery.DOOR_20209, IntType.SCENERY, "Pass") { player, node ->
|
||||
if (!QUICK_START.insideBorder(player.location)){
|
||||
player.setAttribute("/save:barbass:wave", 1)
|
||||
handlePlayerOptionDoor(player) { role ->
|
||||
player.sendMessage("You are a ${role.name.lowercase().replaceFirstChar { it.uppercase() }}.")
|
||||
handleWaveDoor(player, node, 489)
|
||||
}
|
||||
}else {
|
||||
handleWaveDoor(player, node, 489)
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(BARBDOORS, IntType.SCENERY, "Pass") { player, node ->
|
||||
handleWaveDoor(player, node,256)
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(Scenery.SCROLL_TABLE_20149, IntType.SCENERY, "Take-from") { player, _ ->
|
||||
if(!player.inventory.containsItem(Item(Items.SCROLL_10512, 1)) ) {
|
||||
//do you wish to take a scroll? yes ? no
|
||||
sendDialogueOptions(player, "Take a recruitment scroll?", "Yes", "No")
|
||||
addDialogueAction(player) { _, buttonId ->
|
||||
when (buttonId) {
|
||||
2 -> {
|
||||
if (player.inventory.add(Item(Items.SCROLL_10512, 1))) {
|
||||
player.sendMessage("You take scroll from table")
|
||||
} else {
|
||||
player.sendMessage("You dont have enough inventory space")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
player.sendMessage("You already have a scroll")
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
//DOOR_20209
|
||||
// [Title][red] "Which role would you like to perform?"
|
||||
// [0] "Attacker"
|
||||
// [1] "Defender"
|
||||
// [2] "Collector"
|
||||
// [3] "Healer"
|
||||
// [4] "I'll be any role!"
|
||||
|
||||
/*private val pulse = object : Pulse(1) {
|
||||
override fun pulse(): Boolean {
|
||||
ticks++
|
||||
//setInterfaceText(player, ticks.toString(),494,0)
|
||||
// for people in party update our time to next wave start
|
||||
// maybe this is not the right way to do it?
|
||||
if (ticks >= 500) {
|
||||
ticks = 400
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
*/
|
||||
enum class RoomRole {
|
||||
ATTACKER, DEFENDER, COLLECTOR, HEALER, ANYROLE
|
||||
}
|
||||
|
||||
|
||||
fun getModelFromButton(button: Int): Int {
|
||||
return when (button) {
|
||||
2 -> 20561
|
||||
3 -> 20566
|
||||
4 -> 20563
|
||||
5 -> 20569
|
||||
else -> 0 // Unknown or no match
|
||||
}
|
||||
}
|
||||
fun getRoleFromButton(button: Int): BarbRole? {
|
||||
return when (button) {
|
||||
2 -> BarbRole.ATTACKER
|
||||
3 -> BarbRole.DEFENDER
|
||||
4 -> BarbRole.COLLECTOR
|
||||
5 -> BarbRole.HEALER
|
||||
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)
|
||||
}
|
||||
sendMessage(player,"You've set your role to ${playerRole.name.lowercase().replaceFirstChar { it.uppercase() }}")
|
||||
}
|
||||
|
||||
fun handlePlayerOptionDoor(player: Player, roomRoleOptions:(RoomRole) -> Unit){
|
||||
sendDialogueOptions(
|
||||
player,
|
||||
"Which role would you like to perform?",
|
||||
"Attacker", "Defender","Collector","Healer","I'll be any role!")
|
||||
addDialogueAction(player) { _, buttonId ->
|
||||
val role = when (buttonId) {
|
||||
2 -> RoomRole.ATTACKER
|
||||
3 -> RoomRole.DEFENDER
|
||||
4 -> RoomRole.COLLECTOR
|
||||
5 -> RoomRole.HEALER
|
||||
6 -> RoomRole.ANYROLE
|
||||
else -> RoomRole.ANYROLE
|
||||
}
|
||||
roomRoleOptions(role)
|
||||
}
|
||||
}
|
||||
fun handleWriteRole(player: Player){
|
||||
sendDialogueOptions(
|
||||
player,
|
||||
"Which role do you wish to be?",
|
||||
"Attacker", "Defender","Collector","Healer","Cancel")
|
||||
addDialogueAction(player) { _, buttonId ->
|
||||
when (buttonId) {
|
||||
2 -> BarbRole.ATTACKER
|
||||
3 -> BarbRole.DEFENDER
|
||||
4 -> BarbRole.COLLECTOR
|
||||
5 -> BarbRole.HEALER
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
fun handleWaveDoor(player: Player, node: Node,iface: Int){
|
||||
val doorLoc = node.location
|
||||
val playerLoc = player.location
|
||||
var wave = player.getAttribute("barbass:wave", 1)
|
||||
if (wave == BARBWAVEDOOR[node.id]) {
|
||||
val insideRoom = playerLoc.y <= doorLoc.y
|
||||
val moveY = if (insideRoom) 1 else -1
|
||||
//ToDo fix walking trough wall when Using door from side.
|
||||
forceMove(player, playerLoc, playerLoc.transform(0, moveY, 0), 25, 60, null, 819) {
|
||||
if (insideRoom) {
|
||||
closeOverlay(player)
|
||||
PartyService.leaveParty(player)
|
||||
} else {
|
||||
openOverlay(player, iface)
|
||||
|
||||
player.sendMessage("you enter wave ${BARBWAVEDOOR[node.id]}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fun waveAdvance(player: Player) {
|
||||
var 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 {
|
||||
// Locations
|
||||
val QUICK_START: ZoneBorders = ZoneBorders(2595, 5278, 2610, 5271, 0)
|
||||
val MAIN_LOBBY: ZoneBorders = ZoneBorders(2588, 5266, 2597, 5261, 0)
|
||||
|
||||
val WAVE_LOBBY1: ZoneBorders = ZoneBorders(2576, 5298, 2583, 5291, 0)
|
||||
val WAVE_LOBBY2: ZoneBorders = ZoneBorders(2584, 5298, 2591, 5291, 0)
|
||||
|
||||
val WAVE_LOBBY3: ZoneBorders = ZoneBorders(2595, 5298, 2602, 5291, 0)
|
||||
val WAVE_LOBBY4: ZoneBorders = ZoneBorders(2603, 5298, 2610, 5291, 0)
|
||||
|
||||
|
||||
val WAVE_LOBBY5: ZoneBorders = ZoneBorders(2576, 5288, 2583, 5281, 0)
|
||||
val WAVE_LOBBY6: ZoneBorders = ZoneBorders(2584, 5288, 2591, 5281, 0)
|
||||
|
||||
val WAVE_LOBBY7: ZoneBorders = ZoneBorders(2595, 5288, 2602, 5281, 0)
|
||||
val WAVE_LOBBY8: ZoneBorders = ZoneBorders(2603, 5288, 2610, 5281, 0)
|
||||
|
||||
val WAVE_LOBBY9: ZoneBorders = ZoneBorders(2576, 5278, 2583, 5271, 0)
|
||||
val WAVE_LOBBY10: ZoneBorders = ZoneBorders(2584, 5278, 2591, 5271, 0)
|
||||
|
||||
val areaBorders = arrayOf(
|
||||
QUICK_START,
|
||||
WAVE_LOBBY1,
|
||||
WAVE_LOBBY2,
|
||||
WAVE_LOBBY3,
|
||||
WAVE_LOBBY4,
|
||||
WAVE_LOBBY5,
|
||||
WAVE_LOBBY6,
|
||||
WAVE_LOBBY7,
|
||||
WAVE_LOBBY8,
|
||||
WAVE_LOBBY9,
|
||||
WAVE_LOBBY10
|
||||
)
|
||||
val waveLobbies = listOf(
|
||||
WAVE_LOBBY1, WAVE_LOBBY2, WAVE_LOBBY3, WAVE_LOBBY4,
|
||||
WAVE_LOBBY5, WAVE_LOBBY6, WAVE_LOBBY7, WAVE_LOBBY8,
|
||||
WAVE_LOBBY9, WAVE_LOBBY10,
|
||||
MAIN_LOBBY
|
||||
)
|
||||
|
||||
val BARBDOORS = intArrayOf( Scenery.DOOR_20199,
|
||||
Scenery.DOOR_20200,
|
||||
Scenery.DOOR_20201,
|
||||
Scenery.DOOR_20202,
|
||||
Scenery.DOOR_20203,
|
||||
Scenery.DOOR_20204,
|
||||
Scenery.DOOR_20205,
|
||||
Scenery.DOOR_20206,
|
||||
Scenery.DOOR_20207,
|
||||
Scenery.DOOR_20208,
|
||||
)
|
||||
}
|
||||
val BARBWAVEDOOR = hashMapOf(
|
||||
20199 to 1,
|
||||
20200 to 2,
|
||||
20201 to 3,
|
||||
20202 to 4,
|
||||
20203 to 5,
|
||||
20204 to 6,
|
||||
20205 to 7,
|
||||
20206 to 8,
|
||||
20207 to 9,
|
||||
20208 to 10,
|
||||
20209 to 1)
|
||||
|
||||
// override fun tick() {
|
||||
// TODO("Not yet implemented")
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
PRIVATE_PALDO_5031 -- Big axe barb at entrance to main lobby
|
||||
PRIVATE_PALDON_5034 -- sword -- Above wave 7 and 8 Source:https://youtu.be/VPlIYB1h9KM?t=340
|
||||
PRIVATE_PENDRON_5032 -- Mace -- Above arrow Guessing
|
||||
PRIVATE_PIERREB_5033 -- bowman -- Above wave 9 and 10 Source:https://youtu.be/XHp7g7dz12M?t=83
|
||||
|
||||
|
||||
DOOR_20209
|
||||
[Title][red] "Which role would you like to perform?"
|
||||
[0] "Attacker"
|
||||
[1] "Defender"
|
||||
[2] "Collector"
|
||||
[3] "Healer"
|
||||
[4] "I'll be any role!"
|
||||
SCROLL_10512 -- LeaderScroll
|
||||
QUEEN_HELP_BOOK_10562 -- Get from cain and POH bookcase
|
||||
1889 5407 - Barb assualt QUEEN area
|
||||
1891 5465 - barb assualt AREA under
|
||||
*/
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package content.minigame.barbassault
|
||||
|
||||
import core.api.animate
|
||||
import core.api.sendMessage
|
||||
import core.game.dialogue.DialoguePlugin
|
||||
import core.game.dialogue.FacialExpression
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
@Initializable
|
||||
class PrivatesDialogues(player: Player? = null) : DialoguePlugin(player){
|
||||
|
||||
val NPCtoDialogStage = mapOf(
|
||||
NPCs.PRIVATE_PALDON_5034 to 1,
|
||||
NPCs.PRIVATE_PALDO_5031 to 6,
|
||||
NPCs.PRIVATE_PIERREB_5033 to 11,
|
||||
NPCs.PRIVATE_PENDRON_5032 to 20,
|
||||
|
||||
)
|
||||
val PRIVATES: IntArray = NPCtoDialogStage.keys.toIntArray()
|
||||
|
||||
override fun newInstance(player: Player?): DialoguePlugin {
|
||||
return PrivatesDialogues(player)
|
||||
}
|
||||
|
||||
override fun open(vararg args: Any?): Boolean {
|
||||
val currentNPC = args[0] as NPC
|
||||
npc = currentNPC
|
||||
stage = NPCtoDialogStage[currentNPC.id] ?: -1
|
||||
sendMessage(player, stage.toString())
|
||||
handle(0,0)
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
override fun handle(componentID: Int, buttonID: Int): Boolean {
|
||||
when (stage) {
|
||||
//PRIVATE_PALDON
|
||||
1 -> playerl(FacialExpression.FRIENDLY, "Hi.").also { stage++ }
|
||||
2 -> npcl(FacialExpression.ANNOYED, "Shhh. Don't talk to me.").also { stage++ }
|
||||
3 -> playerl(FacialExpression.THINKING, "What? Why?").also { stage++ }
|
||||
4 -> npcl(FacialExpression.AFRAID, "If I'm seen slacking off by talking to you, I'll be in deep trouble!").also { stage++ }
|
||||
5 -> playerl(FacialExpression.WORRIED, "Oh... Sorry.").also { stage = END_DIALOGUE}
|
||||
//PRIVATE_PALDO
|
||||
6 -> playerl(FacialExpression.FRIENDLY, "Hi, soldier..").also { stage++ }
|
||||
7 -> npcl(FacialExpression.FRIENDLY, "Why, hello there!").also { stage++ }
|
||||
8 -> playerl(FacialExpression.THINKING, "You seem like a jolly chap.").also { stage++ }
|
||||
9 -> npcl(FacialExpression.FRIENDLY, "And why not? 'Tis a greeeaat day!").also { stage++ }
|
||||
10 -> playerl(FacialExpression.FRIENDLY, "Well, I suppose it is.").also { stage = END_DIALOGUE }
|
||||
//PRIVATE_PIERREB
|
||||
11 -> playerl(FacialExpression.ASKING, "Hello. So you're just a private?").also { stage++ }
|
||||
12 -> npcl(FacialExpression.ANGRY, "Show some respect! It's more than you'll achieve.").also { stage++}
|
||||
13 -> playerl(FacialExpression.ANNOYED, "I beg to differ. I'm in perfect shape!").also { stage++ }
|
||||
14 -> npcl(FacialExpression.ANGRY, "Prove it!").also { stage++}
|
||||
15 -> playerl(FacialExpression.ASKING, "How?").also { stage++ }
|
||||
16 -> npcl(FacialExpression.ANGRY, "Give me five star-jumps!").also {
|
||||
animate(player, Animation(2761))
|
||||
stage++
|
||||
}
|
||||
17 -> npcl(FacialExpression.ANGRY, "Five sit-ups.").also {
|
||||
animate(player, Animation(2763))
|
||||
stage++
|
||||
}
|
||||
18 -> npcl(FacialExpression.ANGRY, "Run on the spot!").also {
|
||||
animate(player, Animation(2764))
|
||||
stage++
|
||||
}
|
||||
19 -> npcl(FacialExpression.THINKING, "Okay. Maybe you have what it takes. Best you speak with the captain.").also { stage = END_DIALOGUE }
|
||||
//PRIVATE_PENDRON
|
||||
20 -> playerl(FacialExpression.FRIENDLY, "Hi there.").also { stage++ }
|
||||
21 -> npcl(FacialExpression.ASKING, "Don't suppose you've seen a battleaxe around here?").also { stage++ }
|
||||
22 -> playerl(FacialExpression.FRIENDLY, "A battleaxe? Nope, afraid not.").also { stage++ }
|
||||
23 -> npcl(FacialExpression.WORRIED, "the captain is going to kill me if he finds out I've lost my weapon.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
return true
|
||||
}
|
||||
override fun getIds(): IntArray {
|
||||
return PRIVATES
|
||||
}
|
||||
|
||||
}
|
||||
106
Server/src/main/content/minigame/barbassault/party/Party.kt
Normal file
106
Server/src/main/content/minigame/barbassault/party/Party.kt
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
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()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
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.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue