mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2025-12-10 10:20:41 -07:00
Add witchaven lever puzzle (was supposed to be included in family crest).
This commit is contained in:
parent
b057a4bea6
commit
024a34d11e
1 changed files with 103 additions and 0 deletions
|
|
@ -0,0 +1,103 @@
|
||||||
|
package core.game.content.quest.members.familycrest
|
||||||
|
|
||||||
|
import core.game.node.entity.impl.ForceMovement
|
||||||
|
import core.game.node.entity.player.Player
|
||||||
|
import core.game.node.scenery.Scenery
|
||||||
|
import core.game.world.map.Direction
|
||||||
|
import core.game.world.map.Location
|
||||||
|
import core.game.world.map.RegionManager
|
||||||
|
import core.game.world.update.flag.context.Animation
|
||||||
|
import core.net.packet.PacketRepository
|
||||||
|
import core.net.packet.context.BuildSceneryContext
|
||||||
|
import core.net.packet.out.ClearScenery
|
||||||
|
import core.net.packet.out.ConstructScenery
|
||||||
|
import core.net.packet.out.UpdateAreaPosition;
|
||||||
|
import rs09.game.interaction.InteractionListener
|
||||||
|
|
||||||
|
fun doDoor(player: Player, scenery: Scenery) {
|
||||||
|
val d = if(scenery.rotation == 0 || scenery.rotation == 3) { -1 } else { 0 }
|
||||||
|
var direction = Direction.NORTH
|
||||||
|
if(scenery.rotation % 2 == 0) {
|
||||||
|
direction = if(player.location.x <= scenery.location.x + d) { Direction.EAST } else { Direction.WEST }
|
||||||
|
} else {
|
||||||
|
direction = if(player.location.y <= scenery.location.y + d) { Direction.NORTH } else { Direction.SOUTH }
|
||||||
|
}
|
||||||
|
ForceMovement.run(player,
|
||||||
|
player.location,
|
||||||
|
player.location.transform(direction.stepX, direction.stepY, 0),
|
||||||
|
ForceMovement.WALK_ANIMATION,
|
||||||
|
ForceMovement.WALK_ANIMATION,
|
||||||
|
direction,
|
||||||
|
8);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class WitchavenLeverInteraction : InteractionListener() {
|
||||||
|
val DOWN_ANIMATION = Animation(2140)
|
||||||
|
val UP_ANIMATION = Animation(2139)
|
||||||
|
|
||||||
|
// TODO: It seems like the even numbers are used for the "up" positions, but there's no parent object with varps for them.
|
||||||
|
// Currently, we just send a `ConstructScenery` packet to the specific player. Is there a cleaner way to do this?
|
||||||
|
val NORTH_LEVER_A = 2421
|
||||||
|
val NORTH_LEVER_B = 2425
|
||||||
|
val SOUTH_LEVER = 2423
|
||||||
|
val LEVERS = intArrayOf(NORTH_LEVER_A, NORTH_LEVER_A+1, NORTH_LEVER_B, NORTH_LEVER_B+1, SOUTH_LEVER, SOUTH_LEVER+1)
|
||||||
|
|
||||||
|
val NORTH_DOOR = 2431 // 92 in RSC
|
||||||
|
val HELLHOUND_DOOR = 2430 // 91 in RSC
|
||||||
|
val SOUTHWEST_DOOR = 2427 // 90 in RSC
|
||||||
|
val SOUTHEAST_DOOR = 2429 // 88 in RSC
|
||||||
|
val DOORS = intArrayOf(NORTH_DOOR, HELLHOUND_DOOR, SOUTHWEST_DOOR, SOUTHEAST_DOOR)
|
||||||
|
|
||||||
|
override fun defineListeners() {
|
||||||
|
on(LEVERS, SCENERY, "pull") { player, node ->
|
||||||
|
val baseId = if(node.id % 2 == 0) { node.id - 1 } else { node.id }
|
||||||
|
if(player.questRepository.getQuest("Family Crest").getStage(player) == 0) {
|
||||||
|
player.sendMessage("Nothing interesting happens.")
|
||||||
|
}
|
||||||
|
val old = player.getAttribute("family-crest:witchaven-lever:${baseId}", false)
|
||||||
|
player.setAttribute("family-crest:witchaven-lever:${baseId}", !old)
|
||||||
|
val direction = if(old) { "down" } else { "up" }
|
||||||
|
player.sendMessage("You pull the lever ${direction}.")
|
||||||
|
player.sendMessage("You hear a clunk.")
|
||||||
|
player.animate(if(old) { DOWN_ANIMATION } else { UP_ANIMATION })
|
||||||
|
val downLever = (node as Scenery).transform(baseId)
|
||||||
|
val upLever = (node as Scenery).transform(baseId + 1)
|
||||||
|
player.debug("lever: ${downLever.id} ${upLever.id}")
|
||||||
|
val buffer = UpdateAreaPosition.getChunkUpdateBuffer(player, RegionManager.getRegionChunk(player.location).currentBase)
|
||||||
|
if(old) {
|
||||||
|
// TODO: This doesn't seem to properly make the lever return to the "down" position visually.
|
||||||
|
ClearScenery.write(buffer, upLever)
|
||||||
|
ConstructScenery.write(buffer, downLever)
|
||||||
|
//PacketRepository.send(ClearScenery::class.java, BuildSceneryContext(player, downLever))
|
||||||
|
} else {
|
||||||
|
ClearScenery.write(buffer, downLever)
|
||||||
|
ConstructScenery.write(buffer, upLever)
|
||||||
|
//PacketRepository.send(ConstructScenery::class.java, BuildSceneryContext(player, upLever))
|
||||||
|
}
|
||||||
|
player.session.write(buffer)
|
||||||
|
return@on true
|
||||||
|
}
|
||||||
|
on(DOORS, SCENERY, "open") { player, node ->
|
||||||
|
val northA = player.getAttribute("family-crest:witchaven-lever:${NORTH_LEVER_A}", false)
|
||||||
|
val northB = player.getAttribute("family-crest:witchaven-lever:${NORTH_LEVER_B}", false)
|
||||||
|
val south = player.getAttribute("family-crest:witchaven-lever:${SOUTH_LEVER}", false)
|
||||||
|
val questComplete = player.questRepository.getQuest("Family Crest").getStage(player) >= 100
|
||||||
|
// Authentic door formulae from https://gitlab.com/open-runescape-classic/core/-/blob/develop/server/plugins/com/openrsc/server/plugins/authentic/quests/members/FamilyCrest.java#L575-657
|
||||||
|
val canPass = when(node.id) {
|
||||||
|
NORTH_DOOR -> !northA && (south || northB)
|
||||||
|
HELLHOUND_DOOR -> questComplete || (northA && northB && !south)
|
||||||
|
SOUTHWEST_DOOR -> (northA && !south) || (northA && northB && !south)
|
||||||
|
SOUTHEAST_DOOR -> (northA && south) || (northA && northB && south)
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
if(canPass) {
|
||||||
|
player.sendMessage("The door swings open. You go through the door.")
|
||||||
|
doDoor(player, node as Scenery)
|
||||||
|
} else {
|
||||||
|
player.sendMessage("The door is locked.")
|
||||||
|
}
|
||||||
|
return@on true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue