forked from 2009Scape/Server
Merge pull request 'Updating from 2009scape' (#2) from 2009Scape/Server:master into master
Reviewed-on: #2
This commit is contained in:
commit
793acecf2e
31 changed files with 1340 additions and 1321 deletions
|
|
@ -58878,5 +58878,19 @@
|
|||
"maxAmount": "1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"default": [
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "1.0",
|
||||
"id": "592",
|
||||
"maxAmount": "1"
|
||||
}
|
||||
],
|
||||
"charm": [],
|
||||
"ids": "8127",
|
||||
"description": "Dark energy core",
|
||||
"main": []
|
||||
}
|
||||
]
|
||||
|
|
@ -2079,6 +2079,18 @@
|
|||
"region": "12880",
|
||||
"id": "441"
|
||||
},
|
||||
{
|
||||
"region": "12888",
|
||||
"id": "445"
|
||||
},
|
||||
{
|
||||
"region": "12889",
|
||||
"id": "445"
|
||||
},
|
||||
{
|
||||
"region": "12890",
|
||||
"id": "445"
|
||||
},
|
||||
{
|
||||
"region": "12944",
|
||||
"id": "606"
|
||||
|
|
@ -2199,6 +2211,18 @@
|
|||
"region": "13142",
|
||||
"id": "459"
|
||||
},
|
||||
{
|
||||
"region": "13144",
|
||||
"id": "445"
|
||||
},
|
||||
{
|
||||
"region": "13145",
|
||||
"id": "445"
|
||||
},
|
||||
{
|
||||
"region": "13146",
|
||||
"id": "445"
|
||||
},
|
||||
{
|
||||
"region": "13199",
|
||||
"id": "388"
|
||||
|
|
@ -2271,6 +2295,18 @@
|
|||
"region": "13373",
|
||||
"id": "586"
|
||||
},
|
||||
{
|
||||
"region": "13400",
|
||||
"id": "445"
|
||||
},
|
||||
{
|
||||
"region": "13401",
|
||||
"id": "445"
|
||||
},
|
||||
{
|
||||
"region": "13402",
|
||||
"id": "445"
|
||||
},
|
||||
{
|
||||
"region": "13456",
|
||||
"id": "452"
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import content.global.ame.events.evilbob.EvilBobNPC
|
|||
import content.global.ame.events.evilchicken.EvilChickenNPC
|
||||
import content.global.ame.events.freakyforester.FreakyForesterNPC
|
||||
import content.global.ame.events.genie.GenieNPC
|
||||
import content.global.ame.events.pillory.PilloryNPC
|
||||
import content.global.ame.events.rickturpentine.RickTurpentineNPC
|
||||
import content.global.ame.events.rivertroll.RiverTrollRENPC
|
||||
import content.global.ame.events.rockgolem.RockGolemRENPC
|
||||
|
|
@ -52,6 +53,7 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n
|
|||
RICK_TURPENTINE(npc = RickTurpentineNPC(), loot = CERTER.loot),
|
||||
SURPRISE_EXAM(npc = MysteriousOldManNPC(), type = "sexam"),
|
||||
FREAKY_FORESTER(npc = FreakyForesterNPC(), skillIds = intArrayOf(Skills.WOODCUTTING)),
|
||||
PILLORY(npc = PilloryNPC(), skillIds = intArrayOf(Skills.THIEVING)),
|
||||
TREE_SPIRIT(npc = TreeSpiritRENPC(), skillIds = intArrayOf(Skills.WOODCUTTING)),
|
||||
RIVER_TROLL(RiverTrollRENPC(), skillIds = intArrayOf(Skills.FISHING)),
|
||||
ROCK_GOLEM(RockGolemRENPC(), skillIds = intArrayOf(Skills.MINING)),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,220 @@
|
|||
package content.global.ame.events.pillory
|
||||
|
||||
import content.global.ame.RandomEvents
|
||||
import core.api.*
|
||||
import core.game.dialogue.FacialExpression
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.interaction.InterfaceListener
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import core.game.world.map.zone.ZoneRestriction
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import org.rs09.consts.NPCs
|
||||
import org.rs09.consts.Scenery
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
/**
|
||||
* Pillory Unlocking Interface PILLORY_189
|
||||
*
|
||||
* https://www.youtube.com/watch?v=caWn7pE2mkE
|
||||
* https://www.youtube.com/watch?v=TMVR5cZZwZ0
|
||||
* https://www.youtube.com/watch?v=Ym9LCDP-Q74
|
||||
* https://www.youtube.com/watch?v=_vn0QZTtI6U (Failure)
|
||||
* https://www.youtube.com/watch?v=zmXDikQIua4
|
||||
*
|
||||
* Child IDs
|
||||
* 4 - Rotating Lock Model
|
||||
* 5 6 7 - Swinging Keys Models
|
||||
* 8 9 10 - Buttons for the Swinging Keys Models
|
||||
* 11 12 13 14 15 16 - Padlocks at the Top
|
||||
* 17 18 19 20 21 22 - Padlocks stars? Model 15272, Anim 4135
|
||||
*
|
||||
* Model IDs
|
||||
* Using the amazeballs ::listifmodels
|
||||
* 9749, 9750, 9751, 9752 - Swinging Keys Models
|
||||
* 9753, 9754, 9755, 9756 - Rotating Lock Models
|
||||
* 9757 9758 locked unlock
|
||||
*/
|
||||
class PilloryInterface : InterfaceListener, InteractionListener, MapArea {
|
||||
companion object {
|
||||
const val PILLORY_LOCK_INTERFACE = 189
|
||||
const val PILLORY_ATRRIBUTE_RETURN_LOC = "/save:original-loc"
|
||||
const val PILLORY_ATTRIBUTE_EVENT_KEYS = "pillory:event-keys"
|
||||
const val PILLORY_ATTRIBUTE_EVENT_LOCK = "pillory:event-lock"
|
||||
const val PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT = "/save:pillory:target-correct"
|
||||
const val PILLORY_ATRRIBUTE_CORRECT_COUNTER = "/save:pillory:num-correct"
|
||||
|
||||
val LOCATIONS = arrayOf(
|
||||
// Varrock Cages
|
||||
Location(3226, 3407, 0),
|
||||
Location(3228, 3407, 0),
|
||||
Location(3230, 3407, 0),
|
||||
// Seers Village Cages
|
||||
Location(2681, 3489, 0),
|
||||
Location(2683, 3489, 0),
|
||||
Location(2685, 3489, 0),
|
||||
// Yannile Cages
|
||||
Location(2604, 3105, 0),
|
||||
Location(2606, 3105, 0),
|
||||
Location(2608, 3105, 0),
|
||||
)
|
||||
|
||||
fun initPillory(player: Player) {
|
||||
setAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, 3)
|
||||
setAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 0)
|
||||
player.dialogueInterpreter.sendPlainMessage(true, "", "Solve the pillory puzzle to be returned to where you came from.")
|
||||
}
|
||||
|
||||
fun randomPillory(player: Player) {
|
||||
// Shuffle all 4 kinds of keys in, pick 3 for the keys, pick 1 from the 3 as the lock.
|
||||
val keys = (0..3).toIntArray().let{ keys -> keys.shuffle(); return@let keys }
|
||||
val lock = intArrayOf(keys[1], keys[2], keys[3]).random() // Last 3 as there are 4 keys. key[0] is fallback.
|
||||
|
||||
setAttribute(player, PILLORY_ATTRIBUTE_EVENT_KEYS, keys)
|
||||
setAttribute(player, PILLORY_ATTRIBUTE_EVENT_LOCK, lock)
|
||||
|
||||
player.packetDispatch.sendModelOnInterface(9753 + lock, PILLORY_LOCK_INTERFACE, 4, 0)
|
||||
player.packetDispatch.sendModelOnInterface(9749 + keys[1], PILLORY_LOCK_INTERFACE, 5, 0)
|
||||
player.packetDispatch.sendModelOnInterface(9749 + keys[2], PILLORY_LOCK_INTERFACE, 6, 0)
|
||||
player.packetDispatch.sendModelOnInterface(9749 + keys[3], PILLORY_LOCK_INTERFACE, 7, 0)
|
||||
|
||||
val numberToGetCorrect = getAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, 3)
|
||||
val correctCount = getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 0)
|
||||
for (i in 1.. 6) {
|
||||
// Set if lock is red or green.
|
||||
if (i <= correctCount) {
|
||||
player.packetDispatch.sendModelOnInterface(9758, PILLORY_LOCK_INTERFACE, 10 + i, 0)
|
||||
} else {
|
||||
player.packetDispatch.sendModelOnInterface(9757, PILLORY_LOCK_INTERFACE, 10 + i, 0)
|
||||
}
|
||||
// Set if hide or show lock.
|
||||
player.packetDispatch.sendInterfaceConfig(PILLORY_LOCK_INTERFACE, 10 + i, i > numberToGetCorrect)
|
||||
}
|
||||
}
|
||||
|
||||
fun selectedKey(player: Player, buttonID: Int) {
|
||||
val keys = getAttribute(player, PILLORY_ATTRIBUTE_EVENT_KEYS, intArrayOf(0, 0, 0))
|
||||
val lock = getAttribute(player, PILLORY_ATTRIBUTE_EVENT_LOCK, -1)
|
||||
if (keys[buttonID] == lock) {
|
||||
// CORRECT ANSWER
|
||||
setAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 0) + 1)
|
||||
if (getAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, 3) <= getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, -1)) {
|
||||
player.dialogueInterpreter.sendPlainMessage(true, "", "You've escaped!")
|
||||
sendMessage(player, "You've escaped!")
|
||||
removeAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT)
|
||||
removeAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER)
|
||||
closeInterface(player)
|
||||
queueScript(player, 0, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
lock(player, 6)
|
||||
sendGraphics(Graphics(1576, 0, 0), player.location)
|
||||
animate(player,8939)
|
||||
playAudio(player, Sounds.TELEPORT_ALL_200)
|
||||
return@queueScript delayScript(player, 3)
|
||||
}
|
||||
1 -> {
|
||||
val loot = RandomEvents.CERTER.loot!!.roll(player)[0]
|
||||
addItemOrDrop(player, loot.id, loot.amount)
|
||||
teleport(player, getAttribute(player, PILLORY_ATRRIBUTE_RETURN_LOC, Location.create(3222, 3218, 0)))
|
||||
sendGraphics(Graphics(1577, 0, 0), player.location)
|
||||
animate(player,8941)
|
||||
removeAttribute(player, PILLORY_ATRRIBUTE_RETURN_LOC)
|
||||
closeInterface(player)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
randomPillory(player)
|
||||
player.dialogueInterpreter.sendPlainMessage(
|
||||
true,
|
||||
"",
|
||||
"Correct!",
|
||||
"" + getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 0) + " down, " +
|
||||
(getAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, 3) - getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 0)) + " to go!")
|
||||
// Animation for the star, but it doesn't work.
|
||||
player.packetDispatch.sendInterfaceConfig(PILLORY_LOCK_INTERFACE, 16 + getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 1), false)
|
||||
sendAnimationOnInterface(player, 4135, PILLORY_LOCK_INTERFACE, 16 + getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 1))
|
||||
} else {
|
||||
// WRONG ANSWER
|
||||
player.dialogueInterpreter.close()
|
||||
player.dialogueInterpreter.sendDialogues(NPCs.TRAMP_2794 , FacialExpression.OLD_ANGRY1, "Bah, that's not right.","Use the key that matches the hole", "in the spinning lock.")
|
||||
if (getAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, 0) < 6) {
|
||||
setAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, getAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, 0) + 1)
|
||||
}
|
||||
setAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 0)
|
||||
closeInterface(player)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineInterfaceListeners() {
|
||||
on(PILLORY_LOCK_INTERFACE){ player, component, opcode, buttonID, slot, itemID ->
|
||||
when (buttonID) {
|
||||
8 -> selectedKey(player, 1)
|
||||
9 -> selectedKey(player, 2)
|
||||
10 -> selectedKey(player, 3)
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
|
||||
onOpen(PILLORY_LOCK_INTERFACE){ player, component ->
|
||||
return@onOpen true
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
on(Scenery.CAGE_6836, IntType.SCENERY, "unlock") { player, node ->
|
||||
if (player.location in LOCATIONS) { // When you aren't inside.
|
||||
randomPillory(player)
|
||||
openInterface(player, PILLORY_LOCK_INTERFACE)
|
||||
player.dialogueInterpreter.sendPlainMessage(true, "", "Pick the <col=8A0808>swinging key</col> that matches the", "hole in the <col=8A0808>spinning lock</col>.")
|
||||
} else {
|
||||
sendMessage(player, "You can't unlock the pillory, you'll let all the prisoners out!")
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineAreaBorders(): Array<ZoneBorders> {
|
||||
return arrayOf(
|
||||
// Varrock Cages
|
||||
ZoneBorders(3226, 3407, 3226, 3407),
|
||||
ZoneBorders(3228, 3407, 3228, 3407),
|
||||
ZoneBorders(3230, 3407, 3230, 3407),
|
||||
// Seers Village Cages
|
||||
ZoneBorders(2681, 3489, 2681, 3489),
|
||||
ZoneBorders(2683, 3489, 2683, 3489),
|
||||
ZoneBorders(2685, 3489, 2685, 3489),
|
||||
// Yannile Cages
|
||||
ZoneBorders(2604, 3105, 2604, 3105),
|
||||
ZoneBorders(2606, 3105, 2606, 3105),
|
||||
ZoneBorders(2608, 3105, 2608, 3105),
|
||||
)
|
||||
}
|
||||
|
||||
override fun getRestrictions(): Array<ZoneRestriction> {
|
||||
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT)
|
||||
}
|
||||
|
||||
override fun areaEnter(entity: Entity) {
|
||||
if (entity is Player) {
|
||||
entity.interfaceManager.removeTabs(0, 1, 2, 3, 4, 5, 6, 12)
|
||||
}
|
||||
}
|
||||
|
||||
override fun areaLeave(entity: Entity, logout: Boolean) {
|
||||
if (entity is Player) {
|
||||
entity.interfaceManager.restoreTabs()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package content.global.ame.events.pillory
|
||||
|
||||
import content.global.ame.RandomEventNPC
|
||||
import core.api.*
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.system.timer.impl.AntiMacro
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import org.rs09.consts.NPCs
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
// "::revent [-p] <lt>player name<gt> [-e <lt>event name<gt>]"
|
||||
class PilloryNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.PILLORY_GUARD_2791) {
|
||||
|
||||
override fun init() {
|
||||
super.init()
|
||||
sendChat("${player.username}, you're under arrest!")
|
||||
face(player)
|
||||
player.dialogueInterpreter.sendPlainMessage(true, "", "Solve the pillory puzzle to be returned to where you came from.")
|
||||
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
lock(player, 6)
|
||||
sendGraphics(Graphics(1576, 0, 0), player.location)
|
||||
animate(player,8939)
|
||||
playAudio(player, Sounds.TELEPORT_ALL_200)
|
||||
return@queueScript delayScript(player, 3)
|
||||
}
|
||||
1 -> {
|
||||
if (getAttribute<Location?>(player, PilloryInterface.PILLORY_ATRRIBUTE_RETURN_LOC, null) == null) {
|
||||
setAttribute(player, PilloryInterface.PILLORY_ATRRIBUTE_RETURN_LOC, player.location)
|
||||
}
|
||||
PilloryInterface.initPillory(player)
|
||||
teleport(player, PilloryInterface.LOCATIONS.random()) // 9 random spots!
|
||||
AntiMacro.terminateEventNpc(player)
|
||||
sendGraphics(Graphics(1577, 0, 0), player.location)
|
||||
animate(player,8941)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun talkTo(npc: NPC) {
|
||||
//player.dialogueInterpreter.open(FreakyForesterDialogue(),npc)
|
||||
}
|
||||
}
|
||||
|
|
@ -59,7 +59,7 @@ public enum BuildHotspot {
|
|||
DINING_BENCH_1(15300, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_MID_ANIM, Decoration.BENCH_WOODEN, Decoration.BENCH_OAK, Decoration.BENCH_CARVED_OAK, Decoration.BENCH_TEAK, Decoration.BENCH_CARVED_TEAK, Decoration.BENCH_MAHOGANY, Decoration.BENCH_GILDED),
|
||||
DINING_BENCH_2(15299, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_MID_ANIM, Decoration.BENCH_WOODEN, Decoration.BENCH_OAK, Decoration.BENCH_CARVED_OAK, Decoration.BENCH_TEAK, Decoration.BENCH_CARVED_TEAK, Decoration.BENCH_MAHOGANY,Decoration.BENCH_GILDED),
|
||||
ROPE_BELL_PULL(15304, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.ROPE_PULL, Decoration.BELL_PULL, Decoration.FANCY_BELL_PULL),
|
||||
WALL_DECORATION(15303, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DECORATION, Decoration.TEAK_DECORATION, Decoration.GILDED_DECORATION),
|
||||
WALL_DECORATION(15303, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DECORATION, Decoration.TEAK_DECORATION, Decoration.GILDED_DECORATION),
|
||||
|
||||
/**
|
||||
* Low-level Work shop hotspots.
|
||||
|
|
@ -67,11 +67,11 @@ public enum BuildHotspot {
|
|||
REPAIR(15448, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.REPAIR_BENCH, Decoration.WHETSTONE, Decoration.ARMOUR_STAND),
|
||||
WORKBENCH(15439, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.WORKBENCH_WOODEN, Decoration.WORKBENCH_OAK,Decoration.WORKBENCH_STEEL_FRAME, Decoration.WORKBENCH_WITH_VICE,Decoration.WORKBENCH_WITH_LATHE),
|
||||
CRAFTING(15441, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.CRAFTING_TABLE_1, Decoration.CRAFTING_TABLE_2,Decoration.CRAFTING_TABLE_3, Decoration.CRAFTING_TABLE_4),
|
||||
TOOL1(15443, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2, Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4, Decoration.TOOL_STORE_5),
|
||||
TOOL2(15444, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
|
||||
TOOL3(15445, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
|
||||
TOOL4(15446, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
|
||||
TOOL5(15447, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
|
||||
TOOL1(15443, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2, Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4, Decoration.TOOL_STORE_5),
|
||||
TOOL2(15444, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
|
||||
TOOL3(15445, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
|
||||
TOOL4(15446, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
|
||||
TOOL5(15447, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
|
||||
HERALDRY(15450, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.PLUMING_STAND, Decoration.SHIELD_EASEL,Decoration.BANNER_EASEL),
|
||||
|
||||
/**
|
||||
|
|
@ -188,20 +188,10 @@ public enum BuildHotspot {
|
|||
MAP(15396, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.SMALL_MAP, Decoration.MEDIUM_MAP, Decoration.LARGE_MAP),
|
||||
BOOKCASE2(15397, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.WOODEN_BOOKCASE, Decoration.OAK_BOOKCASE, Decoration.MAHOGANY_BOOKCASE),
|
||||
|
||||
/**
|
||||
* Manegerie Hotspots
|
||||
*/
|
||||
OBELISK(44911, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.MINI_OBELISK),
|
||||
PET_FEEDER(44910, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.OAK_PET_FEEDER, Decoration.TEAK_PET_FEEDER, Decoration.MAHOGANY_PET_FEEDER),
|
||||
PET_HOUSE(44909, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.OAK_PET_HOUSE, Decoration.TEAK_PET_HOUSE, Decoration.MAHOGANY_PET_HOUSE, Decoration.CONSECRATED_PET_HOUSE, Decoration.DESECRATED_PET_HOUSE, Decoration.NATURAL_PET_HOUSE),
|
||||
HABITAT_1(44907, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.GARDEN_HABITAT, Decoration.JUNGLE_HABITAT, Decoration.DESERT_HABITAT, Decoration.POLAR_HABITAT, Decoration.VOLCANIC_HABITAT),
|
||||
HABITAT_2(44908, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.GARDEN_HABITAT, Decoration.JUNGLE_HABITAT, Decoration.DESERT_HABITAT, Decoration.POLAR_HABITAT, Decoration.VOLCANIC_HABITAT),
|
||||
|
||||
|
||||
/**
|
||||
* Combat room hotspots.
|
||||
*/
|
||||
WALL_DECORATION2(15297, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DECORATION, Decoration.TEAK_DECORATION, Decoration.GILDED_DECORATION),
|
||||
WALL_DECORATION2(15297, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DECORATION, Decoration.TEAK_DECORATION, Decoration.GILDED_DECORATION),
|
||||
STORAGE_SPACE(15296, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.GLOVE_RACK, Decoration.WEAPONS_RACK, Decoration.EXTRA_WEAPONS_RACK),
|
||||
CR_RING(15277, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_RING, Decoration.FENCING_RING, Decoration.COMBAT_RING, Decoration.NOTHING, Decoration.NOTHING2),
|
||||
CR_CORNER(15278, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_RING, Decoration.FENCING_RING, Decoration.COMBAT_RING, Decoration.NOTHING, Decoration.NOTHING2),
|
||||
|
|
@ -238,7 +228,7 @@ public enum BuildHotspot {
|
|||
LECTERN(15420, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.OAK_LECTERN, Decoration.EAGLE_LECTERN, Decoration.DEMON_LECTERN, Decoration.TEAK_EAGLE_LECTERN, Decoration.TEAK_DEMON_LECTERN, Decoration.MAHOGANY_EAGLE_LECTERN, Decoration.MAHOGANY_DEMON_LECTERN),
|
||||
CRYSTAL_BALL(15422, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.CRYSTAL_BALL, Decoration.ELEMENTAL_SPHERE, Decoration.CRYSTAL_OF_POWER),
|
||||
BOOKCASE3(15425, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.WOODEN_BOOKCASE, Decoration.OAK_BOOKCASE, Decoration.MAHOGANY_BOOKCASE),
|
||||
WALL_CHART(15423, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.ALCHEMICAL_CHART, Decoration.ASTRONOMICAL_CHART, Decoration.INFERNAL_CHART),
|
||||
WALL_CHART(15423, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.ALCHEMICAL_CHART, Decoration.ASTRONOMICAL_CHART, Decoration.INFERNAL_CHART),
|
||||
TELESCOPE(15424, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.TELESCOPE1, Decoration.TELESCOPE2, Decoration.TELESCOPE3),
|
||||
|
||||
/**
|
||||
|
|
@ -394,7 +384,6 @@ public enum BuildHotspot {
|
|||
linkedHotspots.add(new BuildHotspot[] { PRISON, PRISON_DOOR });
|
||||
linkedHotspots.add(new BuildHotspot[] { DUNGEON_DOOR_LEFT, DUNGEON_DOOR_RIGHT });
|
||||
linkedHotspots.add(new BuildHotspot[] { DUNGEON_DOOR_LEFT2, DUNGEON_DOOR_RIGHT2 });
|
||||
linkedHotspots.add(new BuildHotspot[] { HABITAT_1, HABITAT_2 });
|
||||
linkedHotspots.add(new BuildHotspot[] { SMALL_PLANT_1, SMALL_PLANT1 });
|
||||
linkedHotspots.add(new BuildHotspot[] { SHELVES, SHELVES_2 });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ public final class BuildingUtils {
|
|||
*/
|
||||
public static void removeDecoration(Player player, Scenery object) {
|
||||
if (object.getId() == Decoration.PORTAL.getObjectId() && player.getHouseManager().getPortalAmount() <= 1) {
|
||||
player.getPacketDispatch().sendMessage("You need atleast one portal, how else would you leave your house?");
|
||||
sendMessage(player, "You need at least one portal, how else would you leave your house?");
|
||||
return;
|
||||
}
|
||||
Location l = object.getLocation();
|
||||
|
|
@ -369,6 +369,10 @@ public final class BuildingUtils {
|
|||
if (objectId == object.getId() && hotspot.getCurrentX() == l.getChunkOffsetX() && hotspot.getCurrentY() == l.getChunkOffsetY()) {
|
||||
player.animate(REMOVE_ANIMATION);
|
||||
removeDecoration(player, region, room, hotspot, object, style);
|
||||
Decoration decoration = Decoration.forObjectId(object.getId());
|
||||
for (Item item : decoration.getRefundItems()) {
|
||||
addItemOrDrop(player, item.getId(), item.getAmount());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -4,8 +4,10 @@ import core.api.playGlobalAudio
|
|||
import core.api.teleport
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.item.Item
|
||||
import core.game.node.scenery.Scenery
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Animation
|
||||
|
|
@ -27,27 +29,31 @@ class MountedGlory : InteractionListener {
|
|||
)
|
||||
|
||||
override fun defineListeners() {
|
||||
on(MOUNTED_GLORY, IntType.SCENERY, "Edgeville") { player, _ ->
|
||||
mountedGloryTeleport(player,0)
|
||||
on(MOUNTED_GLORY, IntType.SCENERY, "Edgeville") { player, `object` ->
|
||||
mountedGloryAction(player, `object`, 0)
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(MOUNTED_GLORY, IntType.SCENERY, "Karamja") { player, _ ->
|
||||
mountedGloryTeleport(player,1)
|
||||
on(MOUNTED_GLORY, IntType.SCENERY, "Karamja") { player, `object` ->
|
||||
mountedGloryAction(player, `object`, 1)
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(MOUNTED_GLORY, IntType.SCENERY, "Draynor Village") { player, _ ->
|
||||
mountedGloryTeleport(player,2)
|
||||
on(MOUNTED_GLORY, IntType.SCENERY, "Draynor Village") { player, `object` ->
|
||||
mountedGloryAction(player, `object`, 2)
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(MOUNTED_GLORY, IntType.SCENERY, "Al Kharid") { player, _ ->
|
||||
mountedGloryTeleport(player,3)
|
||||
on(MOUNTED_GLORY, IntType.SCENERY, "Al Kharid") { player, `object` ->
|
||||
mountedGloryAction(player, `object`, 3)
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
private fun mountedGloryTeleport(player : Player, int : Int) {
|
||||
private fun mountedGloryAction(player : Player, `object` : Node, int : Int) {
|
||||
if (player.houseManager.isBuildingMode) {
|
||||
player.dialogueInterpreter.open("con:removedec", `object` as Scenery)
|
||||
return
|
||||
}
|
||||
if (!player.zoneMonitor.teleport(1, Item(Items.AMULET_OF_GLORY_1704))) {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,25 +26,31 @@ class TelescopePlugin : OptionHandler() {
|
|||
}
|
||||
|
||||
override fun handle(player: Player?, node: Node?, option: String?): Boolean {
|
||||
val obj = node?.asScenery() as Scenery
|
||||
val star = ShootingStarPlugin.getStar()
|
||||
val delay: Int = 25000 + (25000 / 3)
|
||||
val timeLeft = delay - star.ticks
|
||||
val fakeTimeLeftBecauseFuckPlayers = TimeUnit.MILLISECONDS.toMinutes(timeLeft * 600L) + if(RandomFunction.random(0,100) % 2 == 0) 2 else -2
|
||||
val obj = node?.asScenery() as Scenery
|
||||
val window = when (obj.id) {
|
||||
13657 -> 9
|
||||
13658 -> 2
|
||||
else -> 24
|
||||
}
|
||||
val fakeTimeLeft = RandomFunction.random(-window, window+1) + TimeUnit.MILLISECONDS.toMinutes(timeLeft * 600L)
|
||||
player?.lock()
|
||||
player?.animate(ANIMATION)
|
||||
player?.interfaceManager?.open(Component(782)).also { player?.unlock()
|
||||
Pulser.submit(object : Pulse(2, player) {
|
||||
override fun pulse(): Boolean {
|
||||
if (obj.isActive) {
|
||||
player?.dialogueInterpreter?.sendDialogue("You see a shooting star! The star looks like it will land","in about $fakeTimeLeftBecauseFuckPlayers minutes!")
|
||||
player?.interfaceManager?.open(Component(782)).also {
|
||||
player?.unlock()
|
||||
Pulser.submit(object : Pulse(2, player) {
|
||||
override fun pulse(): Boolean {
|
||||
if (obj.isActive) {
|
||||
player?.dialogueInterpreter?.sendDialogue("You see a shooting star! The star looks like it will land","in about $fakeTimeLeft minutes!")
|
||||
return true
|
||||
}
|
||||
return true
|
||||
}
|
||||
return true
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -1,104 +0,0 @@
|
|||
package content.global.skill.magic.lunar;
|
||||
|
||||
import core.game.node.entity.combat.spell.MagicSpell;
|
||||
import core.game.node.entity.combat.spell.Runes;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.Entity;
|
||||
import core.game.node.entity.combat.spell.SpellType;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.system.task.Pulse;
|
||||
import core.game.world.GameWorld;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.game.world.update.flag.context.Graphics;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Represents the dream magic spell.
|
||||
* @author 'Vexia
|
||||
* @version 1.0
|
||||
*/
|
||||
@Initializable
|
||||
public final class DreamSpell extends MagicSpell {
|
||||
|
||||
/**
|
||||
* Represents the starting animation.
|
||||
*/
|
||||
private static final Animation START = Animation.create(6295);
|
||||
|
||||
/**
|
||||
* Represents the dreaming animation.
|
||||
*/
|
||||
private static final Animation DREAMING = Animation.create(6296);
|
||||
|
||||
/**
|
||||
* Represents the end animation.
|
||||
*/
|
||||
private static final Animation END = Animation.create(6297);
|
||||
|
||||
/**
|
||||
* Represents the graphics of this spell.
|
||||
*/
|
||||
private static final Graphics GRAPHIC = new Graphics(1056);
|
||||
|
||||
/**
|
||||
* Constructs a new {@code CureOtherSpell} {@code Object}.
|
||||
*/
|
||||
public DreamSpell() {
|
||||
super(SpellBook.LUNAR, 79, 82, null, null, null, new Item[] { new Item(Runes.COSMIC_RUNE.getId(), 1), new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.BODY_RUNE.getId(), 5) });
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
|
||||
SpellBook.LUNAR.register(10, this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cast(Entity entity, Node target) {
|
||||
final Player p = (Player) entity;
|
||||
if (p.getSkills().getLifepoints() == p.getSkills().getStaticLevel(Skills.HITPOINTS)) {
|
||||
p.getPacketDispatch().sendMessage("You have no need to cast this spell since your hitpoints are already full.");
|
||||
return false;
|
||||
}
|
||||
if (!meetsRequirements(entity, true, true)) {
|
||||
return false;
|
||||
}
|
||||
p.animate(START);
|
||||
p.lock();
|
||||
GameWorld.getPulser().submit(new Pulse(4, p) {
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
p.animate(DREAMING);
|
||||
p.graphics(GRAPHIC);
|
||||
p.unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
p.getPulseManager().run(new Pulse(18, p) {
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
p.graphics(GRAPHIC);
|
||||
p.getSkills().heal(1);
|
||||
if (p.getSkills().getLifepoints() == p.getSkills().getStaticLevel(Skills.HITPOINTS)) {
|
||||
stop();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
super.stop();
|
||||
p.graphics(new Graphics(-1));
|
||||
p.animate(END);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ import content.global.skill.magic.spellconsts.Lunar
|
|||
import core.api.*
|
||||
import core.game.component.CloseEvent
|
||||
import core.game.component.Component
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.combat.ImpactHandler
|
||||
import core.game.node.entity.npc.NPC
|
||||
|
|
@ -169,9 +170,10 @@ class LunarListeners : SpellListener("lunar"), Commands {
|
|||
}
|
||||
|
||||
// Level 79
|
||||
/**
|
||||
* Dream
|
||||
*/
|
||||
onCast(Lunar.DREAM, NONE) { player, _ ->
|
||||
requires(player, 79, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.BODY_RUNE_559, 5), Item(Items.COSMIC_RUNE_564, 1)))
|
||||
dream(player)
|
||||
}
|
||||
|
||||
// Level 80
|
||||
onCast(Lunar.STRING_JEWELLERY, NONE) { player, _ ->
|
||||
|
|
@ -576,9 +578,38 @@ class LunarListeners : SpellListener("lunar"), Commands {
|
|||
}
|
||||
|
||||
// Level 79
|
||||
/**
|
||||
* Dream
|
||||
*/
|
||||
private fun dream(player: Player) {
|
||||
if(player.skills.lifepoints >= getStatLevel(player, Skills.HITPOINTS)) {
|
||||
sendMessage(player, "You have no need to cast this spell since your hitpoints are already full.")
|
||||
return
|
||||
}
|
||||
|
||||
animate(player, Animations.LUNAR_SPELLBOOK_DREAM_START_6295)
|
||||
delayEntity(player, 4)
|
||||
queueScript(player, 4, QueueStrength.WEAK) { stage: Int ->
|
||||
when(stage) {
|
||||
0 -> {
|
||||
animate(player, Animations.LUNAR_SPELLBOOK_DREAM_MID_6296)
|
||||
sendGraphics(Graphics.LUNAR_SPELLBOOK_DREAM_1056, player.location)
|
||||
playAudio(player, Sounds.LUNAR_SLEEP_3619)
|
||||
return@queueScript delayScript(player, 5)
|
||||
}
|
||||
else -> {
|
||||
sendGraphics(Graphics.LUNAR_SPELLBOOK_DREAM_1056, player.location)
|
||||
// This heals 2 HP every min. Naturally you heal 1 for a total of 3
|
||||
// The script steps every 5 ticks and we want 50 ticks before a heal
|
||||
if (stage.mod(10) == 0){
|
||||
heal(player, 1)
|
||||
if(player.skills.lifepoints >= getStatLevel(player, Skills.HITPOINTS)) {
|
||||
animate(player, Animations.LUNAR_SPELLBOOK_DREAM_END_6297)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
}
|
||||
return@queueScript delayScript(player, 5)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun stringJewellery(player: Player) {
|
||||
val playerJewellery = ArrayDeque<Item>()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package content.global.skill.runecrafting
|
||||
|
||||
import core.api.*
|
||||
import core.game.container.Container
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
|
|
@ -7,109 +8,131 @@ import core.game.node.item.Item
|
|||
import org.json.simple.JSONArray
|
||||
import org.json.simple.JSONObject
|
||||
import org.rs09.consts.Items
|
||||
import core.tools.colorize
|
||||
|
||||
/**
|
||||
* A class for managing rune pouches.
|
||||
* @param player the player this manager instance belongs to.
|
||||
* @author Ceikry
|
||||
* @author Ceikry, Player Name
|
||||
*/
|
||||
class PouchManager(val player: Player) {
|
||||
|
||||
val pouches = mapOf(
|
||||
Items.SMALL_POUCH_5509 to RCPouch(3,1),
|
||||
Items.MEDIUM_POUCH_5510 to RCPouch(6,25),
|
||||
Items.LARGE_POUCH_5512 to RCPouch(9,50),
|
||||
Items.GIANT_POUCH_5514 to RCPouch(12,75)
|
||||
Items.SMALL_POUCH_5509 to RCPouch(3, 3, 1),
|
||||
Items.MEDIUM_POUCH_5510 to RCPouch(6, 264, 25),
|
||||
Items.LARGE_POUCH_5512 to RCPouch(9, 186, 50),
|
||||
Items.GIANT_POUCH_5514 to RCPouch(12,140, 75)
|
||||
)
|
||||
|
||||
/**
|
||||
* Method to add essence to a pouch
|
||||
* @param pouchId the id of the pouch we are adding to
|
||||
* @param itemId the item ID of the pouch we are adding to
|
||||
* @param amount the amount of essence to add
|
||||
* @param essence the ID of the essence item we are trying to add
|
||||
* @author Ceikry
|
||||
* @author Ceikry, Player Name
|
||||
*/
|
||||
fun addToPouch(pouchId: Int, amount: Int, essence: Int){
|
||||
if(!checkRequirement(pouchId)){
|
||||
player.sendMessage(colorize("%RYou lack the required level to use this pouch."))
|
||||
fun addToPouch(itemId: Int, amount: Int, essence: Int) {
|
||||
val pouchId = if (isDecayedPouch(itemId)) itemId - 1 else itemId
|
||||
if (!checkRequirement(pouchId)) {
|
||||
sendMessage(player, "You lack the required level to use this pouch.")
|
||||
return
|
||||
}
|
||||
var amt = amount
|
||||
val pouch = pouches[pouchId]
|
||||
val otherEssence = when(essence){
|
||||
val otherEssence = when(essence) {
|
||||
Items.RUNE_ESSENCE_1436 -> Items.PURE_ESSENCE_7936
|
||||
Items.PURE_ESSENCE_7936 -> Items.RUNE_ESSENCE_1436
|
||||
else -> 0
|
||||
}
|
||||
pouch ?: return
|
||||
if(amount > pouch.container.freeSlots()){
|
||||
if (amount > pouch.container.freeSlots()) {
|
||||
amt = pouch.container.freeSlots()
|
||||
}
|
||||
if(amt == 0){
|
||||
player.sendMessage("This pouch is already full.")
|
||||
if (amt == pouch.container.freeSlots()) {
|
||||
sendMessage(player, "Your pouch is full.") //https://www.youtube.com/watch?v=wbYtRwODKTo
|
||||
}
|
||||
if(pouch.container.contains(otherEssence,1)){
|
||||
player.sendMessage("You can only store one type of essence in each pouch.")
|
||||
if (pouch.container.contains(otherEssence,1)) {
|
||||
sendMessage(player, "You can only store one type of essence in each pouch.")
|
||||
return
|
||||
}
|
||||
player.inventory.remove(Item(essence,amt))
|
||||
pouch.container.add(Item(essence,amt))
|
||||
}
|
||||
|
||||
var disappeared = false
|
||||
if (itemId != Items.SMALL_POUCH_5509) {
|
||||
pouch.charges -= amt
|
||||
}
|
||||
if (pouch.charges <= 0) {
|
||||
pouch.currentCap -= when (pouchId) {
|
||||
Items.MEDIUM_POUCH_5510 -> 1
|
||||
Items.LARGE_POUCH_5512 -> 2
|
||||
Items.GIANT_POUCH_5514 -> 3
|
||||
else /*small pouch*/ -> 0
|
||||
}
|
||||
if (pouch.currentCap <= 0) {
|
||||
// The pouch will disappear: https://runescape.wiki/w/Runecrafting_pouches?oldid=708494, https://oldschool.runescape.wiki/w/Essence_pouch
|
||||
// "Degraded pouches will continue to degrade and lose essence capacity until they disappear or are repaired." implies that this is the end result of a gradual decay process
|
||||
if (removeItem(player, itemId)) {
|
||||
disappeared = true
|
||||
sendMessage(player, "Your pouch has degraded completely.")
|
||||
// Reset the pouch for when the player obtains a new one
|
||||
pouch.currentCap = pouch.capacity
|
||||
pouch.charges = pouch.maxCharges
|
||||
pouch.remakeContainer()
|
||||
}
|
||||
} else {
|
||||
if (!isDecayedPouch(itemId)) {
|
||||
val slot = player.inventory.getSlot(Item(itemId))
|
||||
replaceSlot(player, slot, Item(itemId + 1))
|
||||
}
|
||||
sendMessage(player, "Your pouch has decayed through use.") //https://www.youtube.com/watch?v=FUcPYrgPUlQ
|
||||
pouch.charges = 9 * pouch.currentCap //implied by multiple contemporaneous sources, quantified only by https://oldschool.runescape.wiki/w/Large_pouch
|
||||
pouch.remakeContainer()
|
||||
if (amt > pouch.currentCap) {
|
||||
amt = pouch.currentCap
|
||||
}
|
||||
}
|
||||
}
|
||||
val essItem = Item(essence, amt)
|
||||
if (!disappeared && removeItem(player, essItem)) {
|
||||
pouch.container.add(essItem)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to withdraw rune essence from a pouch.
|
||||
* @param pouchId the item ID of the pouch to withdraw from
|
||||
* @author Ceikry
|
||||
* @param itemId the item ID of the pouch to withdraw from
|
||||
* @author Ceikry, Player Name
|
||||
*/
|
||||
fun withdrawFromPouch(pouchId: Int){
|
||||
fun withdrawFromPouch(itemId: Int) {
|
||||
val pouchId = if (isDecayedPouch(itemId)) itemId - 1 else itemId
|
||||
val pouch = pouches[pouchId]
|
||||
pouch ?: return
|
||||
val playerFree = player.inventory.freeSlots()
|
||||
val playerFree = freeSlots(player)
|
||||
var amount = pouch.currentCap - pouch.container.freeSlots()
|
||||
if (amount > playerFree) amount = playerFree
|
||||
player.debug("$amount")
|
||||
if(amount == 0) return
|
||||
val essence = Item(pouch.container.get(0).id,amount)
|
||||
pouch.container.remove(essence)
|
||||
pouch.container.shift()
|
||||
player.inventory.add(essence)
|
||||
if(pouch.charges-- <= 0){
|
||||
pouch.currentCap -= when(pouchId){
|
||||
5510 -> 1
|
||||
5512 -> 2
|
||||
5514 -> 3
|
||||
else -> 0
|
||||
}
|
||||
if(pouch.currentCap <= 0){
|
||||
player.inventory.remove(Item(pouchId))
|
||||
player.inventory.add(Item(pouchId + 1))
|
||||
player.sendMessage(colorize("%RYour ${Item(pouchId).name} has degraded completely."))
|
||||
}
|
||||
pouch.remakeContainer()
|
||||
pouch.charges = 10
|
||||
if(pouchId != 5509) {
|
||||
player.sendMessage(colorize("%RYour ${Item(pouchId).name.toLowerCase()} has degraded slightly from use."))
|
||||
if (amount > playerFree) {
|
||||
amount = playerFree
|
||||
} else {
|
||||
sendMessage(player, "Your pouch has no essence left in it.") //https://www.youtube.com/watch?v=wbYtRwODKTo
|
||||
if (amount == 0) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
val essence = Item(pouch.container.get(0).id, amount)
|
||||
pouch.container.remove(essence)
|
||||
pouch.container.shift()
|
||||
addItem(player, essence.id, essence.amount)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method to save pouches to a root JSONObject
|
||||
* @param root the JSONObject we are adding the "pouches" JSONArray to
|
||||
* @author Ceikry
|
||||
*/
|
||||
fun save(root: JSONObject){
|
||||
fun save(root: JSONObject) {
|
||||
val pouches = JSONArray()
|
||||
|
||||
for(i in this.pouches){
|
||||
for(i in this.pouches) {
|
||||
val pouch = JSONObject()
|
||||
pouch.put("id",i.key.toString())
|
||||
val items = JSONArray()
|
||||
for(item in i.value.container.toArray()){
|
||||
for(item in i.value.container.toArray()) {
|
||||
item ?: continue
|
||||
val it = JSONObject()
|
||||
it.put("itemId",item.id.toString())
|
||||
|
|
@ -124,14 +147,13 @@ class PouchManager(val player: Player) {
|
|||
root.put("pouches",pouches)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method to parse save data from a JSONArray
|
||||
* @param data the JSONArray that contains the data to parse
|
||||
* @author Ceikry
|
||||
*/
|
||||
fun parse(data: JSONArray){
|
||||
for(e in data){
|
||||
fun parse(data: JSONArray) {
|
||||
for (e in data){
|
||||
val pouch = e as JSONObject
|
||||
val id = pouch["id"].toString().toInt()
|
||||
val p = pouches[id]
|
||||
|
|
@ -141,7 +163,7 @@ class PouchManager(val player: Player) {
|
|||
p.charges = charges
|
||||
p.currentCap = currentCap
|
||||
p.remakeContainer()
|
||||
for(i in pouch["container"] as JSONArray){
|
||||
for (i in pouch["container"] as JSONArray) {
|
||||
val it = i as JSONObject
|
||||
it["itemId"] ?: continue
|
||||
val item = it["itemId"].toString().toInt()
|
||||
|
|
@ -151,33 +173,31 @@ class PouchManager(val player: Player) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method for checking the level requirement for a given pouch.
|
||||
* @param pouchId the item ID of the pouch to check
|
||||
* @author Ceikry
|
||||
*/
|
||||
fun checkRequirement(pouchId: Int): Boolean{
|
||||
fun checkRequirement(pouchId: Int): Boolean {
|
||||
val p = pouches[pouchId]
|
||||
p ?: return false
|
||||
return player.skills.getLevel(Skills.RUNECRAFTING) >= p.levelRequirement
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method for sending the player a message about how much space is left in a pouch
|
||||
* @param pouchId the item ID of the pouch to check
|
||||
* @author Ceikry
|
||||
* @param itemId the item ID of the pouch to check
|
||||
* @author Ceikry, Player Name
|
||||
*/
|
||||
fun checkAmount(pouchId: Int){
|
||||
fun checkAmount(itemId: Int) {
|
||||
val pouchId = if (isDecayedPouch(itemId)) itemId - 1 else itemId
|
||||
val p = pouches[pouchId]
|
||||
p ?: return
|
||||
player.sendMessage("This pouch has space for ${p.container.freeSlots()} more essence.")
|
||||
}
|
||||
|
||||
|
||||
fun isDecayedPouch(pouchId: Int): Boolean{
|
||||
if(pouchId == 5510) return false
|
||||
fun isDecayedPouch(pouchId: Int): Boolean {
|
||||
if (pouchId == Items.MEDIUM_POUCH_5510) return false
|
||||
return pouches[pouchId - 1] != null
|
||||
}
|
||||
|
||||
|
|
@ -185,12 +205,12 @@ class PouchManager(val player: Player) {
|
|||
* A class that represents a runecrafting pouch.
|
||||
* @author Ceikry
|
||||
*/
|
||||
class RCPouch(val capacity: Int, val levelRequirement: Int){
|
||||
class RCPouch(val capacity: Int, val maxCharges: Int, val levelRequirement: Int) {
|
||||
var container = Container(capacity)
|
||||
var currentCap = capacity
|
||||
var charges = 10
|
||||
fun remakeContainer(){
|
||||
var charges = maxCharges
|
||||
fun remakeContainer() {
|
||||
this.container = Container(currentCap)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import core.tools.colorize
|
|||
|
||||
/**
|
||||
* Handles the rune pouches.
|
||||
* @author Ceikry
|
||||
* @author Ceikry, Player Name
|
||||
*/
|
||||
class RunePouchPlugin : OptionHandler() {
|
||||
@Throws(Throwable::class)
|
||||
|
|
@ -37,21 +37,11 @@ class RunePouchPlugin : OptionHandler() {
|
|||
if(preferenceFlag == 0) rEssAmt else pEssAmt
|
||||
)
|
||||
|
||||
|
||||
if(player.pouchManager.isDecayedPouch(node.id)){
|
||||
player.debug("E2")
|
||||
when(option) { //Handling for IF the pouch has already completely decayed
|
||||
"drop" -> player.dialogueInterpreter.open(9878,Item(node.id))
|
||||
else -> player.sendMessage(colorize("%RThis pouch has completely decayed and needs to be repaired."))
|
||||
}
|
||||
} else {
|
||||
player.debug("E")
|
||||
when (option) { //Normal handling
|
||||
"fill" -> player.pouchManager.addToPouch(node.id, essence.amount, essence.id)
|
||||
"empty" -> player.pouchManager.withdrawFromPouch(node.id)
|
||||
"check" -> player.pouchManager.checkAmount(node.id)
|
||||
"drop" -> player.dialogueInterpreter.open(9878,Item(node.id))
|
||||
}
|
||||
when (option) {
|
||||
"fill" -> player.pouchManager.addToPouch(node.id, essence.amount, essence.id)
|
||||
"empty" -> player.pouchManager.withdrawFromPouch(node.id)
|
||||
"check" -> player.pouchManager.checkAmount(node.id)
|
||||
"drop" -> player.dialogueInterpreter.open(9878,Item(node.id))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
@ -59,4 +49,4 @@ class RunePouchPlugin : OptionHandler() {
|
|||
override fun isWalk(): Boolean {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import core.game.dialogue.DialoguePlugin;
|
|||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import org.rs09.consts.Items;
|
||||
|
||||
/**
|
||||
* Handles the dark mages dialogue.
|
||||
|
|
@ -140,18 +141,18 @@ public final class DarkMageDialogue extends DialoguePlugin {
|
|||
private boolean repair() {
|
||||
player.pouchManager.getPouches().forEach((id, pouch) -> {
|
||||
pouch.setCurrentCap(pouch.getCapacity());
|
||||
pouch.setCharges(10);
|
||||
Item essence = null;
|
||||
if(!pouch.getContainer().isEmpty()){
|
||||
int ess = pouch.getContainer().get(0).getId();
|
||||
int amount = pouch.getContainer().getAmount(ess);
|
||||
essence = new Item(ess,amount);
|
||||
pouch.setCharges(pouch.getMaxCharges());
|
||||
Item essItem = null;
|
||||
if (!pouch.getContainer().isEmpty()) {
|
||||
int essence = pouch.getContainer().get(0).getId();
|
||||
int amount = pouch.getContainer().getAmount(essence);
|
||||
essItem = new Item(essence, amount);
|
||||
}
|
||||
pouch.remakeContainer();
|
||||
if(essence != null){
|
||||
pouch.getContainer().add(essence);
|
||||
if (essItem != null) {
|
||||
pouch.getContainer().add(essItem);
|
||||
}
|
||||
if(id != 5509) {
|
||||
if (id != Items.SMALL_POUCH_5509) {
|
||||
if (player.getInventory().contains(id + 1, 1)) {
|
||||
player.getInventory().remove(new Item(id + 1, 1));
|
||||
player.getInventory().add(new Item(id, 1));
|
||||
|
|
|
|||
|
|
@ -26,27 +26,74 @@ class AFURepairClimbHandler : InteractionListener {
|
|||
override fun defineListeners() {
|
||||
|
||||
on(repairIDs, IntType.SCENERY, "repair"){ player, _ ->
|
||||
var rco: RepairClimbObject = RepairClimbObject.GWD
|
||||
for(ent in RepairClimbObject.values()) if(ent.destinationDown?.withinDistance(player.location,2) == true || ent.destinationUp?.withinDistance(player.location,2) == true) rco = ent
|
||||
repair(player,rco)
|
||||
return@on true
|
||||
if (hasRequirement(player, "All Fired Up")){
|
||||
val rco: RepairClimbObject? = getClimbingObject(player)
|
||||
repair(player,rco!!)
|
||||
return@on true
|
||||
}
|
||||
return@on false
|
||||
}
|
||||
|
||||
on(climbIDs, IntType.SCENERY, "climb"){ player, node ->
|
||||
var rco: RepairClimbObject = RepairClimbObject.GWD
|
||||
for(ent in RepairClimbObject.values()) if(ent.destinationDown?.withinDistance(player.location,2) == true || ent.destinationUp?.withinDistance(player.location,2) == true) rco = ent
|
||||
climb(player,rco,node.location)
|
||||
val rco: RepairClimbObject? = getClimbingObject(player)
|
||||
climb(player,rco!!,node.location)
|
||||
return@on true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun getClimbingObject(player: Player): RepairClimbObject?{
|
||||
for(ent in RepairClimbObject.values())
|
||||
if(ent.destinationDown?.withinDistance(player.location,2) == true ||
|
||||
ent.destinationUp?.withinDistance(player.location,2) == true){
|
||||
return ent
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun repair(player: Player,rco: RepairClimbObject){
|
||||
if (rco == RepairClimbObject.TEMPLE){
|
||||
// You can do this 2 different ways
|
||||
val hasSmithingLevel = getDynLevel(player, Skills.SMITHING) >= 70
|
||||
val hasConstructionLevel = getDynLevel(player, Skills.CONSTRUCTION) >= 59
|
||||
|
||||
if (!hasConstructionLevel && !hasSmithingLevel){
|
||||
sendDialogue(player, "You need level 70 smithing or 59 construction for this.")
|
||||
return
|
||||
}
|
||||
|
||||
val hasHammer = inInventory(player, Items.HAMMER_2347)
|
||||
val hasSmithingItems = hasHammer && inInventory(player, Items.IRON_BAR_2351, 2)
|
||||
val hasConstructionItems = hasHammer && inInventory(player, Items.PLANK_960, 2)
|
||||
|
||||
if (hasSmithingLevel && hasSmithingItems){
|
||||
if (removeItem(player,Item(Items.IRON_BAR_2351, 2))) {
|
||||
setVarbit(player, rco.varbit, 1, true)
|
||||
return
|
||||
}
|
||||
}
|
||||
// Only check this if the smithing repair didn't work
|
||||
if (hasConstructionLevel && hasConstructionItems){
|
||||
val nails = NailType.get(player, 4)
|
||||
if (nails != null){
|
||||
if (removeItem(player, Item(Items.PLANK_960, 2)) && removeItem(player, Item(nails.itemId, 4))) {
|
||||
setVarbit(player, rco.varbit, 1, true)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var msg = "You need "
|
||||
msg += if (hasSmithingLevel) "a hammer and 2 iron bars" else ""
|
||||
msg += if (hasSmithingLevel && hasConstructionLevel) " or " else ""
|
||||
msg += if (hasConstructionLevel) "a hammer, 2 planks and 4 nails for this." else " for this."
|
||||
sendDialogue(player, msg)
|
||||
return
|
||||
}
|
||||
val skill = rco.levelRequirement?.first ?: 0
|
||||
val level = rco.levelRequirement?.second ?: 0
|
||||
if(player.skills.getLevel(skill) < level){
|
||||
player.dialogueInterpreter.sendDialogue("You need level $level ${Skills.SKILL_NAME[skill]} for this.")
|
||||
return
|
||||
}
|
||||
|
||||
var requiresNeedle = false
|
||||
|
|
@ -64,10 +111,7 @@ class AFURepairClimbHandler : InteractionListener {
|
|||
requiresNeedle = true
|
||||
arrayOf(Item(Items.JUTE_FIBRE_5931,3))
|
||||
}
|
||||
|
||||
RepairClimbObject.TEMPLE -> {
|
||||
arrayOf(Item(Items.IRON_BAR_2351,2))
|
||||
}
|
||||
else -> return
|
||||
}
|
||||
|
||||
if(requiresNeedle){
|
||||
|
|
@ -75,7 +119,7 @@ class AFURepairClimbHandler : InteractionListener {
|
|||
player.inventory.remove(*requiredItems)
|
||||
if (Random().nextBoolean()) player.inventory.remove(Item(Items.NEEDLE_1733))
|
||||
} else {
|
||||
player.dialogueInterpreter.sendDialogue("You need a needle and ${requiredItems.map { "${it.amount} ${it.name.toLowerCase()}s" }.toString().replace("[","").replace("]","")} for this.")
|
||||
player.dialogueInterpreter.sendDialogue("You need a needle and ${requiredItems.map { "${it.amount} ${it.name.lowercase()}s" }.toString().replace("[","").replace("]","")} for this.")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
|
|
@ -89,11 +133,10 @@ class AFURepairClimbHandler : InteractionListener {
|
|||
}
|
||||
player.inventory.remove(*requiredItems)
|
||||
} else {
|
||||
player.dialogueInterpreter.sendDialogue("You need a hammer and ${requiredItems.map { "${it.amount} ${it.name.toLowerCase()}s" }.toString().replace("[","").replace("]","")} for this.")
|
||||
player.dialogueInterpreter.sendDialogue("You need a hammer and ${requiredItems.map { "${it.amount} ${it.name.lowercase()}s" }.toString().replace("[","").replace("]","")} for this.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
setVarbit(player, rco.varbit, 1, true)
|
||||
}
|
||||
|
||||
|
|
@ -105,7 +148,7 @@ class AFURepairClimbHandler : InteractionListener {
|
|||
DEATH_PLATEAU(5161,Location.create(2949, 3623, 0),Location.create(2954, 3623, 0), Pair(Skills.CONSTRUCTION,42)),
|
||||
BURTHORPE(5160,Location.create(2941, 3563, 0),Location.create(2934, 3563, 0),Pair(Skills.SMITHING,56)),
|
||||
GWD(5163,null,null,Pair(Skills.CRAFTING,60)),
|
||||
TEMPLE(5164,Location.create(2949, 3835, 0),Location.create(2956, 3835, 0),Pair(Skills.SMITHING,64));
|
||||
TEMPLE(5164,Location.create(2949, 3835, 0),Location.create(2956, 3835, 0),Pair(0,0)); // This needs to be handled specially so don't have levels here
|
||||
|
||||
fun getOtherLocation(player: Player): Location?{
|
||||
if(player.location == destinationDown) return destinationUp
|
||||
|
|
|
|||
|
|
@ -305,6 +305,8 @@ class RecruitmentDriveListeners : InteractionListener {
|
|||
// Clear inventory whenever you leave the recruitment drive area
|
||||
entity.inventory.clear()
|
||||
entity.equipment.clear()
|
||||
// Restore player normal tabs on leave
|
||||
entity.interfaceManager.openDefaultTabs()
|
||||
// Teleport you out if you log out. You should do this in one sitting.
|
||||
if (logout) {
|
||||
PacketRepository.send(MinimapState::class.java, MinimapStateContext(entity, 0))
|
||||
|
|
|
|||
|
|
@ -200,7 +200,6 @@ class JarvaldDialogue(player: Player? = null) : DialoguePlugin(player) {
|
|||
}
|
||||
|
||||
override fun getIds(): IntArray {
|
||||
// 2435 is a wrapper for 2436
|
||||
return intArrayOf(2435, NPCs.JARVALD_2436, NPCs.JARVALD_2437, NPCs.JARVALD_2438)
|
||||
return intArrayOf(NPCs.JARVALD_2435, NPCs.JARVALD_2436, NPCs.JARVALD_2437, NPCs.JARVALD_2438)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package content.region.fremennik.rellekka.handlers;
|
||||
|
||||
import content.region.fremennik.rellekka.dialogue.JarvaldDialogue;
|
||||
import content.region.fremennik.rellekka.dialogue.MariaGunnarsDialogue;
|
||||
import core.cache.def.impl.SceneryDefinition;
|
||||
import core.game.system.task.Pulse;
|
||||
|
|
@ -41,7 +40,6 @@ public final class RellekkaZone extends MapZone implements Plugin<Object> {
|
|||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
ZoneBuilder.configure(this);
|
||||
ClassScanner.definePlugin(new JarvaldDialogue());
|
||||
ClassScanner.definePlugins(new RellekaOptionHandler(), new MariaGunnarsDialogue());
|
||||
ClassScanner.definePlugin(new OptionHandler() {
|
||||
|
||||
|
|
|
|||
|
|
@ -87,9 +87,9 @@ class SCThormacDialogue(val questStage: Int) : DialogueFile() {
|
|||
|
||||
|
||||
WAITING_FOR_SCORPIONS -> {
|
||||
if (!hasAnItem(player!!, Items.SCORPION_CAGE_456, Items.SCORPION_CAGE_457, Items.SCORPION_CAGE_458,
|
||||
if (!hasAnItem(player!!, arrayOf(Items.SCORPION_CAGE_456, Items.SCORPION_CAGE_457, Items.SCORPION_CAGE_458,
|
||||
Items.SCORPION_CAGE_459, Items.SCORPION_CAGE_460, Items.SCORPION_CAGE_461,
|
||||
Items.SCORPION_CAGE_462).exists()){
|
||||
Items.SCORPION_CAGE_462), false).exists()){
|
||||
playerl(FacialExpression.SAD, "I've lost my cage.").also { stage = GIVE_ANOTHER_CAGE }
|
||||
}
|
||||
else{
|
||||
|
|
|
|||
|
|
@ -187,10 +187,15 @@ class KingBolrenDialogue : DialogueFile() {
|
|||
}
|
||||
isQuestComplete(player!!, questName) -> {
|
||||
when(stage) {
|
||||
0 -> playerl("Hello Bolren.").also { stage++ }
|
||||
1 -> npcl("Thank you for your help traveler.").also { stage = END_DIALOGUE }
|
||||
0 -> playerl("Hello again Bolren.").also { stage++ }
|
||||
1 -> npcl("Well hello, it's good to see you again.").also { stage = if (hasAnItem(player!!, Items.GNOME_AMULET_589).container != null) END_DIALOGUE else 2 }
|
||||
2 -> playerl("I've lost my amulet.").also { stage++ }
|
||||
3 -> npcl("Oh dear. Here, take another. We are truly indebted to you.").also {
|
||||
addItemOrDrop(player!!, Items.GNOME_AMULET_589)
|
||||
stage = END_DIALOGUE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
package content.region.kandarin.seers.handlers;
|
||||
|
||||
import core.cache.def.impl.SceneryDefinition;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Represents the plugin used to unlock the sheers cage.
|
||||
* @author 'Vexia
|
||||
* @versio 1.0
|
||||
*/
|
||||
@Initializable
|
||||
public final class SeersCageUnlockPlugin extends OptionHandler {
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
player.getPacketDispatch().sendMessage("You can't unlock the pillory, you'll let all the prisoners out!");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
SceneryDefinition.forId(6836).getHandlers().put("option:unlock", this);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ class DimintheisDialogue(player: Player? = null): core.game.dialogue.DialoguePlu
|
|||
return true
|
||||
}
|
||||
|
||||
val hasGauntlets = hasAnItem(player, Items.COOKING_GAUNTLETS_775, Items.GOLDSMITH_GAUNTLETS_776, Items.CHAOS_GAUNTLETS_777, Items.FAMILY_GAUNTLETS_778).container != null
|
||||
val hasGauntlets = hasAnItem(player, arrayOf(Items.COOKING_GAUNTLETS_775, Items.GOLDSMITH_GAUNTLETS_776, Items.CHAOS_GAUNTLETS_777, Items.FAMILY_GAUNTLETS_778), true).container != null
|
||||
|
||||
if (questComplete && hasGauntlets) {
|
||||
npc("Thank you for saving our family honour, ",
|
||||
|
|
|
|||
|
|
@ -2,15 +2,11 @@ package content.region.wilderness.handlers;
|
|||
|
||||
import content.data.BossKillCounter;
|
||||
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.combat.CombatSwingHandler;
|
||||
import core.game.node.entity.combat.*;
|
||||
import core.game.node.entity.combat.ImpactHandler.HitsplatType;
|
||||
import core.game.node.entity.combat.MultiSwingHandler;
|
||||
import core.game.node.entity.combat.equipment.SwitchAttack;
|
||||
import core.game.node.entity.combat.equipment.Weapon;
|
||||
import core.game.node.entity.impl.Projectile;
|
||||
import core.game.node.entity.npc.AbstractNPC;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.npc.NPCBehavior;
|
||||
import core.game.node.entity.player.Player;
|
||||
|
|
@ -22,7 +18,6 @@ import core.game.world.map.RegionManager;
|
|||
import core.game.world.update.flag.context.Animation;
|
||||
import core.game.world.update.flag.context.Graphics;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import core.tools.RandomFunction;
|
||||
import org.rs09.consts.NPCs;
|
||||
|
||||
|
|
@ -32,7 +27,6 @@ import java.util.List;
|
|||
/**
|
||||
* Handles the Corporeal beast NPC.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
@Initializable
|
||||
public final class CorporealBeastNPC extends NPCBehavior {
|
||||
|
|
@ -41,19 +35,24 @@ public final class CorporealBeastNPC extends NPCBehavior {
|
|||
* The combat handler.
|
||||
*/
|
||||
private final MultiSwingHandler combatHandler = new CombatHandler();
|
||||
|
||||
|
||||
/**
|
||||
* The dark energy core NPC.
|
||||
*/
|
||||
public NPC darkEnergyCore;
|
||||
|
||||
|
||||
/**
|
||||
* Whether to force a dark core spawn roll on our next swing (only done if we just got hit >= 32 damage).
|
||||
*/
|
||||
public boolean forceCoreRoll = false;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code CorporealBeastNPC} {@code Object}.
|
||||
*/
|
||||
public CorporealBeastNPC() {
|
||||
super(new int[]{NPCs.CORPOREAL_BEAST_8133});
|
||||
super(new int[] { NPCs.CORPOREAL_BEAST_8133 });
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreation(NPC self) {
|
||||
self.configureBossData();
|
||||
|
|
@ -64,27 +63,31 @@ public final class CorporealBeastNPC extends NPCBehavior {
|
|||
return combatHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeDamageReceived(NPC self, Entity attacker, BattleState state) {
|
||||
if(state.getStyle() == CombatStyle.MELEE || state.getStyle() == CombatStyle.RANGE) {
|
||||
Weapon w = state.getWeapon();
|
||||
String name = w != null ? w.getName() : "";
|
||||
if(w == null || name.toLowerCase().indexOf("spear") == -1) {
|
||||
if(state.getEstimatedHit() > 0) {
|
||||
state.setEstimatedHit(state.getEstimatedHit()/2);
|
||||
}
|
||||
if(state.getSecondaryHit() > 0) {
|
||||
state.setSecondaryHit(state.getSecondaryHit()/2);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(state.getEstimatedHit() > 100) {
|
||||
state.setEstimatedHit(100);
|
||||
}
|
||||
if(state.getSecondaryHit() > 100) {
|
||||
state.setSecondaryHit(100);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void beforeDamageReceived(NPC self, Entity attacker, BattleState state) {
|
||||
if (state.getStyle() == CombatStyle.MELEE || state.getStyle() == CombatStyle.RANGE) {
|
||||
Weapon w = state.getWeapon();
|
||||
String name = w != null ? w.getName() : "";
|
||||
if (w == null || name.toLowerCase().indexOf("spear") == -1) {
|
||||
if (state.getEstimatedHit() > 0) {
|
||||
state.setEstimatedHit(state.getEstimatedHit() / 2);
|
||||
}
|
||||
if (state.getSecondaryHit() > 0) {
|
||||
state.setSecondaryHit(state.getSecondaryHit() / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (state.getEstimatedHit() >= 32) {
|
||||
CorporealBeastNPC corp = (CorporealBeastNPC) self.behavior;
|
||||
corp.forceCoreRoll = true;
|
||||
}
|
||||
if (state.getEstimatedHit() > 100) {
|
||||
state.setEstimatedHit(100);
|
||||
}
|
||||
if (state.getSecondaryHit() > 100) {
|
||||
state.setSecondaryHit(100);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeathFinished(NPC self, Entity killer) {
|
||||
|
|
@ -94,41 +97,46 @@ public final class CorporealBeastNPC extends NPCBehavior {
|
|||
darkEnergyCore = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles the Corporeal beast's combat.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
static class CombatHandler extends MultiSwingHandler {
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new {@code CombatHandler} {@code Object}.
|
||||
*/
|
||||
public CombatHandler() {
|
||||
super(
|
||||
//Melee (crush)
|
||||
new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), Animation.create(10057)).setMaximumHit(52),
|
||||
//Melee (slash)
|
||||
new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), Animation.create(10058)).setMaximumHit(51),
|
||||
//Magic (drain skill)
|
||||
new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), Animation.create(10410), null, null, Projectile.create(null, null, 1823, 60, 36, 41, 46)).setMaximumHit(55),
|
||||
//Magic (location based)
|
||||
new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), Animation.create(10410), null, null, Projectile.create(null, null, 1824, 60, 36, 41, 46)).setMaximumHit(42),
|
||||
//Magic (hit through prayer)
|
||||
new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), Animation.create(10410), null, null, Projectile.create(null, null, 1825, 60, 36, 41, 46)).setMaximumHit(66)
|
||||
);
|
||||
//Melee (crush)
|
||||
new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), Animation.create(10057)).setMaximumHit(51),
|
||||
//Melee (slash)
|
||||
new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), Animation.create(10058)).setMaximumHit(51),
|
||||
//Magic (drain skill, blocked by prayer)
|
||||
new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), Animation.create(10410), null, null, Projectile.create(null, null, 1823, 60, 36, 41, 46)).setMaximumHit(55),
|
||||
//Magic (location-based, hits through prayer)
|
||||
new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), Animation.create(10410), null, null, Projectile.create(null, null, 1824, 60, 36, 41, 46)).setMaximumHit(42),
|
||||
//Magic (hits through prayer)
|
||||
new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), Animation.create(10410), null, null, Projectile.create(null, null, 1825, 60, 36, 41, 46)).setMaximumHit(65)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int swing(Entity entity, Entity victim, BattleState state) {
|
||||
spawnDarkCore(entity, (CorporealBeastNPC)((NPC) entity).behavior, victim);
|
||||
// If we're below the right HP threshold, roll a chance to spawn the dark core
|
||||
CorporealBeastNPC corp = (CorporealBeastNPC) ((NPC) entity).behavior;
|
||||
double thresh = entity.getSkills().getMaximumLifepoints() * (0.3 + (entity.getViewport().getCurrentPlane().getPlayers().size() * 0.05));
|
||||
if (corp.forceCoreRoll || entity.getSkills().getLifepoints() < thresh) {
|
||||
rollDarkCore(entity, corp, victim);
|
||||
corp.forceCoreRoll = false;
|
||||
}
|
||||
// If we can stomp, do that for our turn
|
||||
if (doStompAttack(entity)) {
|
||||
entity.getProperties().getCombatPulse().setNextAttack(entity.getProperties().getAttackSpeed());
|
||||
return -1;
|
||||
}
|
||||
//Location based attack.
|
||||
// Location-based attack.
|
||||
if (super.getNext().getProjectile() != null && super.getNext().getProjectile().getProjectileId() == 1824) {
|
||||
setCurrent(getNext());
|
||||
CombatStyle style = getCurrent().getStyle();
|
||||
|
|
@ -142,18 +150,17 @@ public final class CorporealBeastNPC extends NPCBehavior {
|
|||
}
|
||||
return super.swing(entity, victim, state);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Spawns a dark core.
|
||||
* Rolls a 1/8 chance to spawn a dark core.
|
||||
* @param npc The corporeal beast NPC.
|
||||
* @param victim The victim.
|
||||
*/
|
||||
private void spawnDarkCore(Entity corp, final CorporealBeastNPC npc, Entity victim) {
|
||||
if (npc.darkEnergyCore != null && npc.darkEnergyCore.isActive()) {
|
||||
private void rollDarkCore(Entity corp, final CorporealBeastNPC npc, Entity victim) {
|
||||
if (npc.darkEnergyCore != null && npc.darkEnergyCore.isActive() && !DeathTask.isDead(npc.darkEnergyCore)) {
|
||||
return;
|
||||
}
|
||||
double max = corp.getSkills().getMaximumLifepoints() * (0.3 + (corp.getViewport().getCurrentPlane().getPlayers().size() * 0.05));
|
||||
if (corp.getSkills().getLifepoints() > max) {
|
||||
if (!RandomFunction.roll(8)) {
|
||||
return;
|
||||
}
|
||||
Location l = RegionManager.getTeleportLocation(victim.getLocation(), 3);
|
||||
|
|
@ -163,8 +170,8 @@ public final class CorporealBeastNPC extends NPCBehavior {
|
|||
GameWorld.getPulser().submit(new Pulse(2, corp) {
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
if (npc.darkEnergyCore == null)
|
||||
return true;
|
||||
if (npc.darkEnergyCore == null)
|
||||
return true;
|
||||
npc.darkEnergyCore.init();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -184,6 +191,7 @@ public final class CorporealBeastNPC extends NPCBehavior {
|
|||
boolean secondStage = false;
|
||||
List<Player> players = RegionManager.getLocalPlayers(entity);
|
||||
Location[] locations = null;
|
||||
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
if (!secondStage) {
|
||||
|
|
@ -215,11 +223,14 @@ public final class CorporealBeastNPC extends NPCBehavior {
|
|||
locations = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void hit(Player p) {
|
||||
int max = p.hasProtectionPrayer(CombatStyle.MAGIC) ? 13 : 42;
|
||||
int hit = 0;
|
||||
if (isAccurateImpact(entity, p)) {
|
||||
hit = RandomFunction.random(max);
|
||||
hit = RandomFunction.random(42);
|
||||
if (p.hasProtectionPrayer(CombatStyle.MAGIC)) {
|
||||
hit = (int) (hit * 0.6);
|
||||
}
|
||||
}
|
||||
p.getImpactHandler().handleImpact(entity, hit, CombatStyle.MAGIC);
|
||||
}
|
||||
|
|
@ -252,7 +263,7 @@ public final class CorporealBeastNPC extends NPCBehavior {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void adjustBattleState(Entity entity, Entity victim, BattleState state) {
|
||||
super.adjustBattleState(entity, victim, state);
|
||||
|
|
@ -262,10 +273,9 @@ public final class CorporealBeastNPC extends NPCBehavior {
|
|||
int skill = random == 0 ? Skills.PRAYER : random == 1 ? Skills.MAGIC : Skills.SUMMONING;
|
||||
int drain = 1 + RandomFunction.random(6);
|
||||
if ((skill == Skills.PRAYER ? victim.getSkills().getPrayerPoints() : victim.getSkills().getLevel(skill)) < 1) {
|
||||
victim.getImpactHandler().manualHit(entity, drain, HitsplatType.NORMAL,2);
|
||||
victim.getImpactHandler().manualHit(entity, drain, HitsplatType.NORMAL, 2);
|
||||
((Player) victim).getPacketDispatch().sendMessage("Your Hitpoints have been slightly drained!");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (skill == Skills.PRAYER) {
|
||||
victim.getSkills().decrementPrayerPoints(drain);
|
||||
} else {
|
||||
|
|
@ -278,11 +288,13 @@ public final class CorporealBeastNPC extends NPCBehavior {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int getFormattedHit(Entity entity, Entity victim, BattleState state, int hit) {
|
||||
if (getCurrent().getProjectile() == null || getCurrent().getProjectile().getProjectileId() != 1825) {
|
||||
hit = (int) entity.getFormattedHit(state, hit);
|
||||
} else if (victim.hasProtectionPrayer(CombatStyle.MAGIC)) {
|
||||
hit = (int) (hit * 0.6);
|
||||
}
|
||||
return formatHit(victim, hit);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ 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.path.Path;
|
||||
import core.game.world.map.path.Pathfinder;
|
||||
import core.plugin.Initializable;
|
||||
import core.tools.RandomFunction;
|
||||
|
||||
|
|
@ -16,8 +18,7 @@ import static core.api.ContentAPIKt.*;
|
|||
|
||||
/**
|
||||
* Handles the Dark Energy Core NPC.
|
||||
* @author Emperor
|
||||
*
|
||||
* @author Emperor, Player Name
|
||||
*/
|
||||
@Initializable
|
||||
public final class DarkEnergyCoreNPC extends AbstractNPC {
|
||||
|
|
@ -31,21 +32,22 @@ public final class DarkEnergyCoreNPC extends AbstractNPC {
|
|||
* The amount of ticks.
|
||||
*/
|
||||
private int ticks = 0;
|
||||
|
||||
|
||||
/**
|
||||
* The amount of failed attacks.
|
||||
*/
|
||||
private int fails = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new {@code DarkEnergyCoreNPC} {@code Object}.
|
||||
*/
|
||||
public DarkEnergyCoreNPC() {
|
||||
this(8127, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new {@code DarkEnergyCoreNPC} {@code Object}.
|
||||
*
|
||||
* @param id The NPC id.
|
||||
* @param location The location.
|
||||
*/
|
||||
|
|
@ -59,14 +61,15 @@ public final class DarkEnergyCoreNPC extends AbstractNPC {
|
|||
if (objects.length > 0) {
|
||||
core.master = (NPC) objects[0];
|
||||
}
|
||||
core.setRespawn(false);
|
||||
return core;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canStartCombat(Entity victim) {
|
||||
return false; //No combat needed.
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handleTickActions() {
|
||||
ticks++;
|
||||
|
|
@ -91,8 +94,11 @@ public final class DarkEnergyCoreNPC extends AbstractNPC {
|
|||
if (jump) {
|
||||
Entity victim = master.getProperties().getCombatPulse().getVictim();
|
||||
if (++fails >= 3 && victim != null && victim.getViewport().getCurrentPlane() == getViewport().getCurrentPlane()) {
|
||||
jump(victim.getLocation());
|
||||
fails = 0;
|
||||
Path path = Pathfinder.find(getLocation(), victim.getLocation(), 1);
|
||||
if (path.isSuccessful() || !path.isMoveNear()) {
|
||||
jump(victim.getLocation());
|
||||
fails = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fails = 0;
|
||||
|
|
@ -119,7 +125,6 @@ public final class DarkEnergyCoreNPC extends AbstractNPC {
|
|||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { 8127 };
|
||||
return new int[]{8127};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -247,14 +247,40 @@ class ContainerisedItem(val container: core.game.container.Container?, val itemI
|
|||
}
|
||||
|
||||
/**
|
||||
* Check if player has any of the specified item IDs equipped, in inventory, or in banks
|
||||
* Returns a ContainerisedItem containing the container and the item ID if found, otherwise ContainerisedItem(null, -1) if not found
|
||||
* Check if player has the specified item ID equipped, in inventory, or in their bank
|
||||
* @param id The item ID to check
|
||||
* @return A ContainerisedItem containing the container and the item ID if found, otherwise ContainerisedItem(null, -1) if not found
|
||||
*/
|
||||
fun hasAnItem(player: Player, vararg ids: Int): ContainerisedItem {
|
||||
for (searchSpace in arrayOf(player.inventory, player.equipment, player.bankPrimary, player.bankSecondary)) {
|
||||
fun hasAnItem(player: Player, id: Int): ContainerisedItem {
|
||||
return hasAnItem(player, arrayOf(id), false)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if player has the specified item ID equipped, in inventory, or in their bank
|
||||
* @param id The item ID to check
|
||||
* @param checkSecondBank Whether to check the player's second bank.
|
||||
* @return A ContainerisedItem containing the container and the item ID if found, otherwise ContainerisedItem(null, -1) if not found
|
||||
*/
|
||||
fun hasAnItem(player: Player, id: Int, checkSecondBank: Boolean): ContainerisedItem {
|
||||
return hasAnItem(player, arrayOf(id), checkSecondBank)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if player has any of the specified item IDs equipped, in inventory, or in their bank
|
||||
* @param ids An array of item IDs to check
|
||||
* @param checkSecondBank Whether to check the player's second bank.
|
||||
* @return A ContainerisedItem containing the container and the item ID if found, otherwise ContainerisedItem(null, -1) if not found
|
||||
*/
|
||||
fun hasAnItem(player: Player, ids: Array<Int>, checkSecondBank: Boolean): ContainerisedItem {
|
||||
val searchSpace = if (checkSecondBank) {
|
||||
arrayOf(player.inventory, player.equipment, player.bankPrimary, player.bankSecondary)
|
||||
} else {
|
||||
arrayOf(player.inventory, player.equipment, player.bankPrimary)
|
||||
}
|
||||
for (container in searchSpace) {
|
||||
for (id in ids) {
|
||||
if (searchSpace.containItems(id)) {
|
||||
return ContainerisedItem(searchSpace, id)
|
||||
if (container.containItems(id)) {
|
||||
return ContainerisedItem(container, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -296,6 +296,7 @@ class CombatPulse(
|
|||
}
|
||||
setVictim(victim)
|
||||
entity.onAttack(victim as Entity?)
|
||||
victim.scripts.removeWeakScripts()
|
||||
|
||||
if (!isAttacking)
|
||||
entity.pulseManager.run(this)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import core.tools.RandomFunction
|
|||
/**
|
||||
* Handles combat swings with switching combat styles.
|
||||
* @author Emperor
|
||||
* @author Ceirky, Kotlin conversion
|
||||
* @author Ceikry, Kotlin conversion
|
||||
*/
|
||||
open class MultiSwingHandler(meleeDistance: Boolean, vararg attacks: SwitchAttack) : CombatSwingHandler(CombatStyle.RANGE) {
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -195,5 +195,6 @@ enum class QuestRequirements (val questName: String, vararg val requirements: Re
|
|||
SUMMERS_END ("Summer's End", QuestReq(SPIRIT_OF_SUMMER), SkillReq(Skills.FIREMAKING, 47), SkillReq(Skills.HUNTER, 35), SkillReq(Skills.MINING, 45), SkillReq(Skills.PRAYER, 55), SkillReq(Skills.SUMMONING, 23), SkillReq(Skills.WOODCUTTING, 37)),
|
||||
SEERGAZE ("Legacy of Seergaze", QuestReq(HALLOWVALE), SkillReq(Skills.AGILITY, 29), SkillReq(Skills.CONSTRUCTION, 20), SkillReq(Skills.CRAFTING, 47), SkillReq(Skills.FIREMAKING, 40), SkillReq(Skills.MAGIC, 49), SkillReq(Skills.MINING, 35), SkillReq(Skills.SLAYER, 31)),
|
||||
SMOKING_KILLS ("Smoking Kills", QuestReq(RESTLESS_GHOST), QuestReq(ICTHLARIN), SkillReq(Skills.CRAFTING, 25), SkillReq(Skills.SLAYER, 35)),
|
||||
WHILE_GUTHIX_SLEEPS ("While Guthix Sleeps", SkillReq(Skills.SUMMONING, 23), SkillReq(Skills.HUNTER, 55), SkillReq(Skills.THIEVING, 60), SkillReq(Skills.DEFENCE, 65), SkillReq(Skills.FARMING, 65), SkillReq(Skills.HERBLORE, 65), SkillReq(Skills.MAGIC, 75), QuestReq(DEFENDER_VARROCK), QuestReq(DREAM_MENTOR), QuestReq(SAND), QuestReq(KINGS_RANSOM), QuestReq(LEGEND), QuestReq(MEP_2), QuestReq(PATH_GLOUPHRIE), QuestReq(RFD), QuestReq(SUMMERS_END), QuestReq(SWAN), QuestReq(TEARS_OF_GUTHIX), QuestReq(ZOGRE))
|
||||
WHILE_GUTHIX_SLEEPS ("While Guthix Sleeps", SkillReq(Skills.SUMMONING, 23), SkillReq(Skills.HUNTER, 55), SkillReq(Skills.THIEVING, 60), SkillReq(Skills.DEFENCE, 65), SkillReq(Skills.FARMING, 65), SkillReq(Skills.HERBLORE, 65), SkillReq(Skills.MAGIC, 75), QuestReq(DEFENDER_VARROCK), QuestReq(DREAM_MENTOR), QuestReq(SAND), QuestReq(KINGS_RANSOM), QuestReq(LEGEND), QuestReq(MEP_2), QuestReq(PATH_GLOUPHRIE), QuestReq(RFD), QuestReq(SUMMERS_END), QuestReq(SWAN), QuestReq(TEARS_OF_GUTHIX), QuestReq(ZOGRE)),
|
||||
ALL_FIRED_UP ("All Fired Up", QuestReq(PRIEST), SkillReq(Skills.FIREMAKING, 43))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import java.util.*
|
|||
object SystemLogger {
|
||||
val t = Terminal()
|
||||
val errT = t.forStdErr()
|
||||
val formatter = SimpleDateFormat("HH:mm:ss")
|
||||
val formatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXX")
|
||||
|
||||
private fun getTime(): String{
|
||||
return "[" + formatter.format(Date(System.currentTimeMillis())) +"]"
|
||||
|
|
|
|||
|
|
@ -66,12 +66,18 @@ class MajorUpdateWorker {
|
|||
|
||||
ServerStore.clearDailyEntries()
|
||||
if (ServerConstants.DAILY_RESTART) {
|
||||
for (player in Repository.players.filter { !it.isArtificial }) {
|
||||
player.packetDispatch.sendSystemUpdate(500)
|
||||
}
|
||||
Repository.sendNews(colorize("%RSERVER GOING DOWN FOR DAILY RESTART IN 5 MINUTES!"))
|
||||
ServerConstants.DAILY_RESTART = false
|
||||
submitWorldPulse(object : Pulse(100) {
|
||||
var counter = 0
|
||||
override fun pulse(): Boolean {
|
||||
counter++
|
||||
for (player in Repository.players.filter { !it.isArtificial }) {
|
||||
player.packetDispatch.sendSystemUpdate((5 - counter) * 100)
|
||||
}
|
||||
if (counter == 5) {
|
||||
exitProcess(0)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue