Add witchaven lever puzzle (was supposed to be included in family crest).

This commit is contained in:
Avi Weinstock 2021-12-26 00:25:09 +00:00 committed by Ceikry
parent b057a4bea6
commit 024a34d11e

View file

@ -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
}
}
}