mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2025-12-09 16:45:44 -07:00
Refactored canoe handling
Canoe station should now have the full animation suite Canoe making now scales with axe and level of woodcutting Interfaces are now fully updated with proper hide/show/animation Canoes now sink at the end of the journey Added a black screen backdrop overlay seen only in HD
This commit is contained in:
parent
b87a3821dd
commit
e9fd74b379
7 changed files with 379 additions and 453 deletions
|
|
@ -1,86 +0,0 @@
|
|||
package content.global.travel.canoe;
|
||||
|
||||
/**
|
||||
* Represents a canoe to craft.
|
||||
* @author 'Vexia
|
||||
* @date 09/11/2013
|
||||
*/
|
||||
public enum Canoe {
|
||||
LOG(12, 30, 30,0,0),
|
||||
DUGOUT(27, 60, 31,9,3),
|
||||
STABLE_DUGOUT(42, 90, 32,10,2),
|
||||
WAKA(57, 150, 33,8,5);
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Canoe.java} {@code Object}.
|
||||
* @param level the woodcutting level requirement.
|
||||
* @param experience the experience.
|
||||
* @param child the child.
|
||||
*/
|
||||
Canoe(final int level, final double experience, final int child, final int silhouetteChild, final int textChild) {
|
||||
this.level = level;
|
||||
this.experience = experience;
|
||||
this.child = child;
|
||||
this.silhouetteChild = silhouetteChild;
|
||||
this.textChild = textChild;
|
||||
this.maxDist = ordinal() + 1;
|
||||
}
|
||||
|
||||
public final int silhouetteChild;
|
||||
public final int textChild;
|
||||
public final int maxDist;
|
||||
|
||||
/**
|
||||
* Represents the woodcutting level requirement to craft the canoe.
|
||||
*/
|
||||
private final int level;
|
||||
|
||||
/**
|
||||
* Represents the experience received for crafting the canoe.
|
||||
*/
|
||||
private final double experience;
|
||||
|
||||
/**
|
||||
* Represents the child's id on the interface.
|
||||
*/
|
||||
private final int child;
|
||||
|
||||
/**
|
||||
* Gets the woodcutting level requirement.
|
||||
* @return The required level.
|
||||
*/
|
||||
public int getRequiredLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the experience received.
|
||||
* @return The experience amount.
|
||||
*/
|
||||
public double getExperience() {
|
||||
return experience;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the child.
|
||||
* @return The child.
|
||||
*/
|
||||
public int getChild() {
|
||||
return child;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to get the canoe from the child.
|
||||
* @param child the child.
|
||||
* @return <code>True</code> if so
|
||||
*/
|
||||
public static Canoe getCanoeFromChild(final int child) {
|
||||
for (Canoe canoe : values()) {
|
||||
if(canoe.getChild() == child)
|
||||
{
|
||||
return canoe;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
package content.global.travel.canoe
|
||||
|
||||
import core.api.*
|
||||
import core.cache.def.impl.VarbitDefinition
|
||||
import core.game.component.Component
|
||||
import core.game.node.entity.skill.Skills
|
||||
import content.data.skill.SkillingTool
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.net.packet.PacketRepository
|
||||
import core.net.packet.context.MinimapStateContext
|
||||
import core.net.packet.out.MinimapState
|
||||
import core.tools.RandomFunction
|
||||
import org.rs09.consts.Components
|
||||
import core.game.interaction.InterfaceListener
|
||||
import kotlin.math.abs
|
||||
|
||||
class CanoeInterfaceListeners : InterfaceListener {
|
||||
|
||||
val SHAPE_INTERFACE = Components.CANOE_52
|
||||
val DESTINATION_INTERFACE = Components.CANOE_STATIONS_MAP_53
|
||||
|
||||
private val boatChilds = intArrayOf(47, 48, 3, 6, 49)
|
||||
private val locationChilds = intArrayOf(50, 47, 44, 36)
|
||||
|
||||
|
||||
override fun defineInterfaceListeners() {
|
||||
|
||||
onOpen(SHAPE_INTERFACE){player, _ ->
|
||||
CanoeUtils.checkCanoe(player, Canoe.DUGOUT)
|
||||
CanoeUtils.checkCanoe(player, Canoe.STABLE_DUGOUT)
|
||||
CanoeUtils.checkCanoe(player, Canoe.WAKA)
|
||||
return@onOpen true
|
||||
}
|
||||
|
||||
on(SHAPE_INTERFACE) { player, _, _, buttonID, _, _ ->
|
||||
player.interfaceManager.close()
|
||||
val canoe = Canoe.getCanoeFromChild(buttonID)
|
||||
val varbit = player.getAttribute("canoe-varbit", VarbitDefinition.forObjectID(0))
|
||||
|
||||
val axe: SkillingTool? = SkillingTool.getHatchet(player)
|
||||
if (axe == null) {
|
||||
player.packetDispatch.sendMessage("You do not have an axe which you have the woodcutting level to use.")
|
||||
return@on true
|
||||
}
|
||||
|
||||
lock(player, 4)
|
||||
animate(player, CanoeUtils.getShapeAnimation(axe))
|
||||
player.pulseManager.run(object : Pulse(3) {
|
||||
override fun pulse(): Boolean {
|
||||
if (RandomFunction.random(if (canoe == Canoe.WAKA) 8 else 6) == 1) {
|
||||
setVarbit(player,varbit, CanoeUtils.getCraftValue(canoe, false))
|
||||
player.skills.addExperience(Skills.WOODCUTTING, canoe.experience)
|
||||
player.unlock()
|
||||
return true
|
||||
}
|
||||
animate(player, CanoeUtils.getShapeAnimation(axe))
|
||||
return false
|
||||
}
|
||||
})
|
||||
return@on true
|
||||
}
|
||||
|
||||
onOpen(DESTINATION_INTERFACE){player, component ->
|
||||
val varbit = player.getAttribute("canoe-varbit",VarbitDefinition.forObjectID(0))
|
||||
val canoe = CanoeUtils.getCanoeFromVarbit(player, varbit)
|
||||
val stationIndex = CanoeUtils.getStationIndex(player.location)
|
||||
val maxDistance = canoe.maxDist
|
||||
player.packetDispatch.sendInterfaceConfig(DESTINATION_INTERFACE,boatChilds[stationIndex],true)
|
||||
player.packetDispatch.sendInterfaceConfig(DESTINATION_INTERFACE,locationChilds[stationIndex],false)
|
||||
if(canoe != Canoe.WAKA){
|
||||
player.packetDispatch.sendInterfaceConfig(DESTINATION_INTERFACE,49,true)
|
||||
for(i in 0..3){
|
||||
if(i == stationIndex) continue
|
||||
if(abs(i - stationIndex) > maxDistance){
|
||||
player.packetDispatch.sendInterfaceConfig(DESTINATION_INTERFACE,boatChilds[i],true)
|
||||
player.packetDispatch.sendInterfaceConfig(DESTINATION_INTERFACE,locationChilds[i],true)
|
||||
}
|
||||
}
|
||||
}
|
||||
return@onOpen true
|
||||
}
|
||||
|
||||
on(DESTINATION_INTERFACE){player, _, _, buttonID, _, _ ->
|
||||
val dest = CanoeUtils.getDestinationFromButtonID(buttonID)
|
||||
val destIndex = CanoeUtils.getStationIndex(dest)
|
||||
val arrivalMessage = CanoeUtils.getNameByIndex(destIndex)
|
||||
val stationIndex = CanoeUtils.getStationIndex(player.location)
|
||||
val interfaceAnimationId = CanoeUtils.getTravelAnimation(stationIndex, destIndex)
|
||||
var travelAnimDur = 15
|
||||
val varbit = player.getAttribute("canoe-varbit",VarbitDefinition.forObjectID(0))
|
||||
|
||||
if (player.familiarManager.hasFamiliar()) {
|
||||
player.sendMessage("You can't take a follower on a canoe.")
|
||||
return@on true
|
||||
}
|
||||
if (interfaceAnimationId != 0) {
|
||||
travelAnimDur = Animation(interfaceAnimationId).duration
|
||||
}
|
||||
|
||||
lock(player, travelAnimDur + 4)
|
||||
player.interfaceManager.close()
|
||||
player.pulseManager.run(object : Pulse(){
|
||||
var counter = 0
|
||||
override fun pulse(): Boolean {
|
||||
when(counter++){
|
||||
0 -> {
|
||||
player.interfaceManager.openOverlay(Component(Components.FADE_TO_BLACK_120))
|
||||
player.interfaceManager.open(Component(Components.CANOE_TRAVEL_758))
|
||||
animateInterface(player, Components.CANOE_TRAVEL_758, 3, interfaceAnimationId)
|
||||
}
|
||||
2 -> {
|
||||
PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2))
|
||||
player.interfaceManager.removeTabs(0, 1, 2, 3, 4, 5, 6, 11, 12)
|
||||
}
|
||||
travelAnimDur+1 -> {
|
||||
player.properties.teleportLocation = dest
|
||||
player.interfaceManager.close(Component(Components.CANOE_TRAVEL_758))
|
||||
player.interfaceManager.closeOverlay()
|
||||
player.interfaceManager.openOverlay(Component(Components.FADE_FROM_BLACK_170))
|
||||
}
|
||||
travelAnimDur+3 -> {
|
||||
player.unlock()
|
||||
player.interfaceManager.restoreTabs()
|
||||
PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0))
|
||||
player.sendMessage("You arrive at $arrivalMessage.")
|
||||
player.sendMessage("Your canoe sinks from the long journey.")
|
||||
if(destIndex == 4){
|
||||
player.sendMessage("There are no trees nearby to make a new canoe. Guess you're walking.")
|
||||
}
|
||||
setVarbit(player,varbit,0)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
}
|
||||
372
Server/src/main/content/global/travel/canoe/CanoeListener.kt
Normal file
372
Server/src/main/content/global/travel/canoe/CanoeListener.kt
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
package content.global.travel.canoe
|
||||
|
||||
import content.data.skill.SkillingTool
|
||||
import core.api.*
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.InterfaceListener
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.node.scenery.SceneryBuilder
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.net.packet.PacketRepository
|
||||
import core.net.packet.context.MinimapStateContext
|
||||
import core.net.packet.out.MinimapState
|
||||
import core.tools.RandomFunction
|
||||
import org.rs09.consts.Components
|
||||
import org.rs09.consts.Scenery
|
||||
import org.rs09.consts.Sounds
|
||||
import kotlin.math.abs
|
||||
|
||||
/**
|
||||
* Interaction and interface listener for canoe along river Lum.
|
||||
* This handles Components.CANOE_52, Components.CANOE_STATIONS_MAP_53 and Components.CANOE_TRAVEL_758 globally.
|
||||
*/
|
||||
class CanoeListener : InteractionListener, InterfaceListener {
|
||||
companion object {
|
||||
const val CANOE_STATION_VARBIT_ATTRIBUTE = "canoeStationVarbit" // Index of Canoe Stations (0-4)
|
||||
const val CANOE_SELECTED_ATTRIBUTE = "canoeSelected" // Index of Canoes (0-3)
|
||||
|
||||
const val CANOE_SHAPING_INTERFACE = Components.CANOE_52
|
||||
const val CANOE_DESTINATION_INTERFACE = Components.CANOE_STATIONS_MAP_53
|
||||
const val CANOE_TRAVEL_INTERFACE = Components.CANOE_TRAVEL_758
|
||||
|
||||
val CANOE_SHAPING_SILHOUETTE = arrayOf(0, 9, 10, 8)
|
||||
val CANOE_SHAPING_TEXT = arrayOf(0, 3, 2, 5)
|
||||
val CANOE_SHAPING_BUTTONS = arrayOf(30, 31, 32, 33)
|
||||
|
||||
val CANOE_DESTINATION_BUTTONS = arrayOf(47, 48, 3, 6, 49)
|
||||
val CANOE_DESTINATION_HIDE_ROW = arrayOf(10, 11, 12, 20, 18)
|
||||
val CANOE_DESTINATION_YOU_ARE_HERE = arrayOf(25, 24, 23, 19, 0)
|
||||
|
||||
val CANOE_TREE_FALLING_ANIMATION = Animation(3304)
|
||||
val CANOE_PLAYER_PUSHING_ANIMATION = Animation(3301)
|
||||
val CANOE_PUSHING_ANIMATION = Animation(3304)
|
||||
val CANOE_SINKING_ANIMATION = Animation(3305)
|
||||
/** Canoe travel interface animations. A 2D array mapping [ origin ][ destination ]. Index 0-4 for Lumbridge to Wilderness. */
|
||||
val CANOE_TRAVEL_ANIMATIONS = arrayOf(
|
||||
arrayOf(0, 9890, 9889, 9888, 9887),
|
||||
arrayOf(9906, 0, 9893, 9892, 9891),
|
||||
arrayOf(9904, 9905, 0, 9895, 9894),
|
||||
arrayOf(9901, 9902, 9903, 0, 9896),
|
||||
arrayOf(9897, 9898, 9899, 9900, 0),
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
fun getAxeAnimation(axe: SkillingTool): Animation {
|
||||
return when (axe) {
|
||||
SkillingTool.BRONZE_AXE -> Animation(6744)
|
||||
SkillingTool.IRON_AXE -> Animation(6743)
|
||||
SkillingTool.STEEL_AXE -> Animation(6742)
|
||||
SkillingTool.BLACK_AXE -> Animation(6741)
|
||||
SkillingTool.MITHRIL_AXE -> Animation(6740)
|
||||
SkillingTool.ADAMANT_AXE -> Animation(6739)
|
||||
SkillingTool.RUNE_AXE -> Animation(6738)
|
||||
SkillingTool.DRAGON_AXE -> Animation(6745)
|
||||
else -> axe.animation
|
||||
}
|
||||
}
|
||||
|
||||
/** To scale woodcutting success. Follows WoodcuttingNode values at 15,30,45,60 (3 levels 'harder'). */
|
||||
private fun checkSuccess(player: Player, resource: Canoes, tool: SkillingTool): Boolean {
|
||||
val skill = Skills.WOODCUTTING
|
||||
val level: Int = getDynLevel(player, skill) + getFamiliarBoost(player, skill)
|
||||
val hostRatio = RandomFunction.randomDouble(100.0)
|
||||
val lowMod: Double = if (tool == SkillingTool.BLACK_AXE) resource.tierModLow / 2 else resource.tierModLow
|
||||
val low: Double = resource.baseLow + tool.ordinal * lowMod
|
||||
val highMod: Double = if (tool == SkillingTool.BLACK_AXE) resource.tierModHigh / 2 else resource.tierModHigh
|
||||
val high: Double = resource.baseHigh + tool.ordinal * highMod
|
||||
val clientRatio = RandomFunction.getSkillSuccessChance(low, high, level)
|
||||
return hostRatio < clientRatio
|
||||
}
|
||||
|
||||
/** Maps canoe stations stages to related properties. */
|
||||
enum class CanoeStationSceneries(val sceneryId: Int, val varbitValue: Int) {
|
||||
// Stage 1 - Tree is standing, option to chop-down.
|
||||
TREE_STANDING(Scenery.CANOE_STATION_12144, 0),
|
||||
|
||||
// Stage 2 - The tree is falling via an animation, denies player of options.
|
||||
TREE_FALLING(Scenery.CANOE_STATION_12145, 9),
|
||||
|
||||
// Stage 3 - Tree is on the cradle after the chop, option to shape the boat via an interface.
|
||||
TREE_FALLEN(Scenery.CANOE_STATION_12146, 10),
|
||||
|
||||
// Stage 4 - Tree gets shaped into 1 of 4 canoes, option to push it into the water.
|
||||
TREE_SHAPED_LOG(Scenery.CANOE_STATION_12147, 1),
|
||||
TREE_SHAPED_DUGOUT(Scenery.CANOE_STATION_12148, 2),
|
||||
TREE_SHAPED_STABLE_DUGOUT(Scenery.CANOE_STATION_12149, 3),
|
||||
TREE_SHAPED_WAKA(Scenery.CANOE_STATION_12150, 4),
|
||||
|
||||
// Stage 5 - Canoe is being pushed into the water via an animation, option to travel is available.
|
||||
CANOE_PUSHING_LOG(Scenery.CANOE_STATION_12151, 5),
|
||||
CANOE_PUSHING_DUGOUT(Scenery.CANOE_STATION_12152, 6),
|
||||
CANOE_PUSHING_STABLE_DUGOUT(Scenery.CANOE_STATION_12153, 7),
|
||||
CANOE_PUSHING_WAKA(Scenery.CANOE_STATION_12154, 8),
|
||||
|
||||
// Stage 6 - Canoe is in the water, option to travel via an interface.
|
||||
CANOE_FLOATING_LOG(Scenery.CANOE_STATION_12155, 11),
|
||||
CANOE_FLOATING_DUGOUT(Scenery.CANOE_STATION_12156, 12),
|
||||
CANOE_FLOATING_STABLE_DUGOUT(Scenery.CANOE_STATION_12157, 13),
|
||||
CANOE_FLOATING_WAKA(Scenery.CANOE_STATION_12158, 14),
|
||||
|
||||
// Stage 7 - Canoe is animated to be sunk at the end of the ride. NO VARBITS, NOT PART OF THE CANOE_STATION SCENERY.
|
||||
CANOE_SINKING_LOG(Scenery.A_SINKING_CANOE_12159, 0),
|
||||
CANOE_SINKING_DUGOUT(Scenery.A_SINKING_CANOE_12160, 0),
|
||||
CANOE_SINKING_STABLE_DUGOUT(Scenery.A_SINKING_CANOE_12161, 0),
|
||||
CANOE_SINKING_WAKA(Scenery.A_SINKING_CANOE_12162, 0);
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val stationIdMap = values().associateBy { it.sceneryId }
|
||||
val stationIdArray = stationIdMap.values.map { it.sceneryId }.toIntArray()
|
||||
}
|
||||
}
|
||||
|
||||
/** Enums to map canoes to related properties. */
|
||||
enum class Canoes(val level: Int, val experience: Double, val maxDistance: Int, val baseLow: Double, val baseHigh: Double, val tierModLow: Double, val tierModHigh: Double, val treeShaped: CanoeStationSceneries, val canoePushing: CanoeStationSceneries, val canoeFloating: CanoeStationSceneries, val canoeSinking: CanoeStationSceneries) {
|
||||
LOG (12, 30.0, 1, 32.0, 100.0, 16.0, 50.0, CanoeStationSceneries.TREE_SHAPED_LOG, CanoeStationSceneries.CANOE_PUSHING_LOG, CanoeStationSceneries.CANOE_FLOATING_LOG, CanoeStationSceneries.CANOE_SINKING_LOG),
|
||||
DUGOUT (27, 60.0, 2, 16.0, 50.0, 8.0, 25.0, CanoeStationSceneries.TREE_SHAPED_DUGOUT, CanoeStationSceneries.CANOE_PUSHING_DUGOUT, CanoeStationSceneries.CANOE_FLOATING_DUGOUT, CanoeStationSceneries.CANOE_SINKING_DUGOUT),
|
||||
STABLE_DUGOUT (42, 90.0, 3, 8.0, 25.0, 4.0, 12.5, CanoeStationSceneries.TREE_SHAPED_STABLE_DUGOUT, CanoeStationSceneries.CANOE_PUSHING_STABLE_DUGOUT, CanoeStationSceneries.CANOE_FLOATING_STABLE_DUGOUT, CanoeStationSceneries.CANOE_SINKING_STABLE_DUGOUT),
|
||||
WAKA (57, 150.0, 4, 4.0, 12.5, 2.0, 6.25, CanoeStationSceneries.TREE_SHAPED_WAKA, CanoeStationSceneries.CANOE_PUSHING_WAKA, CanoeStationSceneries.CANOE_FLOATING_WAKA, CanoeStationSceneries.CANOE_SINKING_WAKA);
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val indexMap = Canoes.values().associateBy { it.ordinal }
|
||||
}
|
||||
}
|
||||
|
||||
/** Enums to map canoe stations locations to related properties. */
|
||||
enum class CanoeStationLocations(val stationRegion: Int, val stationVarbit: Int, val playerChopLocation: Location, val playerFloatLocation: Location, val playerFacingLocation: Location, val canoeSinkLocation: Location, val playerDestination: Location, val locationName: String) {
|
||||
LUMBRIDGE(12850, 1839, Location(3243, 3235), Location(3243, 3237), Location(-1, 0), Location(3239, 3242), Location(3240, 3242), "Lumbridge"),
|
||||
CHAMPIONS(12852, 1840, Location(3204, 3343), Location(3202, 3343), Location(0, -1), Location(3199, 3344), Location(3199, 3344), "the Champion's Guild"),
|
||||
BARBARIAN(12341, 1841, Location(3112, 3409), Location(3112, 3411), Location(-1, 0), Location(3109, 3411), Location(3109, 3415), "Barbarian Village"),
|
||||
EDGEVILLE(12342, 1842, Location(3132, 3508), Location(3132, 3510), Location(-1, 0), Location(3132, 3510), Location(3132, 3510), "Edgeville"),
|
||||
WILDERNESS(12603, 0, Location(0, 0), Location(0, 0), Location(0, 0), Location(3142, 3795), Location(3139, 3796), "the Wilderness Pond");
|
||||
|
||||
companion object {
|
||||
private val stationRegionMap = CanoeStationLocations.values().associateBy { it.stationRegion }
|
||||
|
||||
@JvmStatic
|
||||
fun getCanoeStationbyLocation(location: Location): CanoeStationLocations {
|
||||
return stationRegionMap[location.regionId]!!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineDestinationOverrides() {
|
||||
// Set player's standing location when chopping down the tree.
|
||||
setDest(IntType.SCENERY, CanoeStationSceneries.stationIdArray, "chop-down") { _, node ->
|
||||
return@setDest CanoeStationLocations.getCanoeStationbyLocation(node.location).playerChopLocation
|
||||
}
|
||||
// Set player's standing location when shaping and floating the canoe.
|
||||
setDest(IntType.SCENERY, CanoeStationSceneries.stationIdArray, "shape-canoe", "float canoe", "float log", "float waka") { _, node ->
|
||||
return@setDest CanoeStationLocations.getCanoeStationbyLocation(node.location).playerFloatLocation
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
// Stage 1 - 2: Tree is standing, option to chop-down.
|
||||
on(CanoeStationSceneries.stationIdArray, IntType.SCENERY, "chop-down") { player, node ->
|
||||
val canoeStation = CanoeStationLocations.getCanoeStationbyLocation(node.location)
|
||||
val axe: SkillingTool? = SkillingTool.getHatchet(player)
|
||||
val stationVarbit = node.asScenery().definition.configFile
|
||||
if (axe == null) {
|
||||
sendMessage(player, "You do not have an axe which you have the woodcutting level to use.")
|
||||
return@on true
|
||||
}
|
||||
if (getStatLevel(player, Skills.WOODCUTTING) < 12) {
|
||||
sendMessage(player, "You need a woodcutting level of at least 12 to chop down this tree.")
|
||||
return@on true
|
||||
}
|
||||
lock(player, axe.animation.duration + CANOE_TREE_FALLING_ANIMATION.duration)
|
||||
face(player, canoeStation.playerChopLocation.transform(canoeStation.playerFacingLocation))
|
||||
animate(player, axe.animation)
|
||||
queueScript(player, axe.animation.duration, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
player.animator.stop()
|
||||
setVarbit(player, stationVarbit, CanoeStationSceneries.TREE_FALLING.varbitValue)
|
||||
animateScenery(player, node.asScenery(), CANOE_TREE_FALLING_ANIMATION.id)
|
||||
return@queueScript delayScript(player, CANOE_TREE_FALLING_ANIMATION.duration)
|
||||
}
|
||||
1 -> {
|
||||
setVarbit(player, stationVarbit, CanoeStationSceneries.TREE_FALLEN.varbitValue)
|
||||
unlock(player)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
|
||||
// Stage 3: Tree is on the cradle after the chop, option to shape-canoe via interface CANOE_52.
|
||||
on(CanoeStationSceneries.stationIdArray, IntType.SCENERY, "shape-canoe") { player, node ->
|
||||
val canoeStation = CanoeStationLocations.getCanoeStationbyLocation(node.location)
|
||||
setAttribute(player, CANOE_STATION_VARBIT_ATTRIBUTE, canoeStation.stationVarbit)
|
||||
face(player, canoeStation.playerFloatLocation.transform(canoeStation.playerFacingLocation))
|
||||
openInterface(player, CANOE_SHAPING_INTERFACE)
|
||||
openOverlay(player, 333) // Black overlay
|
||||
return@on true
|
||||
}
|
||||
|
||||
// Stage 4 - 5: Tree gets shaped into 1 of 4 canoes, option to float-canoe.
|
||||
on(CanoeStationSceneries.stationIdArray, IntType.SCENERY, "float canoe", "float log", "float waka") { player, node ->
|
||||
val canoeStation = CanoeStationLocations.getCanoeStationbyLocation(node.location)
|
||||
val canoe = Canoes.indexMap[getAttribute(player, CANOE_SELECTED_ATTRIBUTE, 0)]!!
|
||||
setVarbit(player, canoeStation.stationVarbit, canoe.canoePushing.varbitValue)
|
||||
lock(player, CANOE_PLAYER_PUSHING_ANIMATION.duration)
|
||||
playAudio(player, Sounds.CANOE_ROLL_2731)
|
||||
face(player, canoeStation.playerFloatLocation.transform(canoeStation.playerFacingLocation))
|
||||
queueScript(player, 0, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
animate(player, CANOE_PLAYER_PUSHING_ANIMATION)
|
||||
animateScenery(player, node.asScenery(), CANOE_PUSHING_ANIMATION.id)
|
||||
return@queueScript delayScript(player, CANOE_PLAYER_PUSHING_ANIMATION.duration)
|
||||
}
|
||||
1 -> {
|
||||
setVarbit(player, canoeStation.stationVarbit, canoe.canoeFloating.varbitValue)
|
||||
unlock(player)
|
||||
player.animator.stop()
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
|
||||
// Stage 6: Canoe is in the water, option to paddle via interface CANOE_STATIONS_MAP_53.
|
||||
on(CanoeStationSceneries.stationIdArray, IntType.SCENERY, "paddle log", "paddle canoe") { player, _ ->
|
||||
closeInterface(player)
|
||||
openInterface(player, Components.CANOE_STATIONS_MAP_53)
|
||||
openOverlay(player, 333) // Black overlay
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
||||
var temp = 14
|
||||
override fun defineInterfaceListeners() {
|
||||
|
||||
// Stage 3: Opening interface 52
|
||||
onOpen(CANOE_SHAPING_INTERFACE) { player, _ ->
|
||||
Canoes.values().forEach {
|
||||
if (getStatLevel(player, Skills.WOODCUTTING) >= it.level && it != Canoes.LOG) {
|
||||
setComponentVisibility(player, CANOE_SHAPING_INTERFACE, CANOE_SHAPING_SILHOUETTE[it.ordinal], true)
|
||||
setComponentVisibility(player, CANOE_SHAPING_INTERFACE, CANOE_SHAPING_TEXT[it.ordinal], false)
|
||||
}
|
||||
}
|
||||
return@onOpen true
|
||||
}
|
||||
|
||||
// Stage 3: On button click interface 52
|
||||
on(CANOE_SHAPING_INTERFACE) { player, _, _, buttonID, _, _ ->
|
||||
closeInterface(player)
|
||||
val canoe = Canoes.indexMap[CANOE_SHAPING_BUTTONS.indexOf(buttonID)]!!
|
||||
val stationVarbit = getAttribute(player, CANOE_STATION_VARBIT_ATTRIBUTE, 1839)
|
||||
val axe: SkillingTool? = SkillingTool.getHatchet(player)
|
||||
if (axe == null) {
|
||||
sendMessage(player, "You do not have an axe which you have the woodcutting level to use.")
|
||||
return@on true
|
||||
}
|
||||
|
||||
lock(player, 4)
|
||||
animate(player, getAxeAnimation(axe))
|
||||
submitIndividualPulse(player, object : Pulse(3) {
|
||||
override fun pulse(): Boolean {
|
||||
if (checkSuccess(player, canoe, axe)) {
|
||||
setAttribute(player, CANOE_SELECTED_ATTRIBUTE, CANOE_SHAPING_BUTTONS.indexOf(buttonID))
|
||||
setVarbit(player, stationVarbit, canoe.treeShaped.varbitValue)
|
||||
rewardXP(player, Skills.WOODCUTTING, canoe.experience)
|
||||
unlock(player)
|
||||
return true
|
||||
}
|
||||
animate(player, getAxeAnimation(axe))
|
||||
return false
|
||||
}
|
||||
})
|
||||
return@on true
|
||||
}
|
||||
|
||||
onOpen(CANOE_DESTINATION_INTERFACE) { player, component ->
|
||||
val canoe = Canoes.indexMap[getAttribute(player, CANOE_SELECTED_ATTRIBUTE, 0)]!!
|
||||
val origin = CanoeStationLocations.getCanoeStationbyLocation(player.location)
|
||||
for (i in CanoeStationLocations.values()) {
|
||||
setComponentVisibility(player, component.id, CANOE_DESTINATION_HIDE_ROW[i.ordinal], true)
|
||||
if (i == CanoeStationLocations.WILDERNESS) {
|
||||
if (canoe == Canoes.WAKA) {
|
||||
// setComponentVisibility(player, component.id, 22, false) // Some red text on Wildy text.
|
||||
setComponentVisibility(player, component.id, CANOE_DESTINATION_HIDE_ROW[i.ordinal], false)
|
||||
}
|
||||
} else if (i.ordinal == origin.ordinal) {
|
||||
setComponentVisibility(player, component.id, CANOE_DESTINATION_YOU_ARE_HERE[i.ordinal], false)
|
||||
}else if (abs(i.ordinal - origin.ordinal) <= canoe.maxDistance) {
|
||||
setComponentVisibility(player, component.id, CANOE_DESTINATION_HIDE_ROW[i.ordinal], false)
|
||||
}
|
||||
}
|
||||
return@onOpen true
|
||||
}
|
||||
|
||||
on(CANOE_DESTINATION_INTERFACE) { player, _, _, buttonID, _, _ ->
|
||||
val origin = CanoeStationLocations.getCanoeStationbyLocation(player.location)
|
||||
var destination: CanoeStationLocations = CanoeStationLocations.LUMBRIDGE
|
||||
when (buttonID) {
|
||||
CANOE_DESTINATION_BUTTONS[0] -> destination = CanoeStationLocations.LUMBRIDGE
|
||||
CANOE_DESTINATION_BUTTONS[1] -> destination = CanoeStationLocations.CHAMPIONS
|
||||
CANOE_DESTINATION_BUTTONS[2] -> destination = CanoeStationLocations.BARBARIAN
|
||||
CANOE_DESTINATION_BUTTONS[3] -> destination = CanoeStationLocations.EDGEVILLE
|
||||
CANOE_DESTINATION_BUTTONS[4] -> destination = CanoeStationLocations.WILDERNESS
|
||||
}
|
||||
val arrivalMessage = destination.locationName
|
||||
val interfaceAnimationId = CANOE_TRAVEL_ANIMATIONS[origin.ordinal][destination.ordinal]
|
||||
|
||||
if (player.familiarManager.hasFamiliar()) {
|
||||
sendMessage(player, "You can't take a follower on a canoe.")
|
||||
return@on true
|
||||
}
|
||||
lock(player, Animation(interfaceAnimationId).duration + 1 + Animation(Components.FADE_FROM_BLACK_170).duration)
|
||||
// Tried using queueScript here, but it doesn't work as interfaces and overlays can't open. Maybe its because this is within an interface listener.
|
||||
submitIndividualPulse(player, object : Pulse() {
|
||||
var counter = 0
|
||||
override fun pulse(): Boolean {
|
||||
when (counter++) {
|
||||
0 -> {
|
||||
openInterface(player, CANOE_TRAVEL_INTERFACE)
|
||||
openOverlay(player, 333) // Only call openOverlay(player, 333) after openInterface
|
||||
animateInterface(player, CANOE_TRAVEL_INTERFACE, 3, interfaceAnimationId)
|
||||
PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2))
|
||||
player.interfaceManager.removeTabs(0, 1, 2, 3, 4, 5, 6, 11, 12)
|
||||
}
|
||||
Animation(interfaceAnimationId).duration + 1 -> {
|
||||
teleport(player, destination.playerDestination)
|
||||
closeInterface(player)
|
||||
closeOverlay(player)
|
||||
openOverlay(player, Components.FADE_FROM_BLACK_170)
|
||||
}
|
||||
Animation(interfaceAnimationId).duration + 1 + Animation(Components.FADE_FROM_BLACK_170).duration -> {
|
||||
unlock(player)
|
||||
player.interfaceManager.restoreTabs()
|
||||
PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0))
|
||||
val sinkingScenery = SceneryBuilder.add(core.game.node.scenery.Scenery(Scenery.A_SINKING_CANOE_12159, destination.canoeSinkLocation, 1), 3) as core.game.node.scenery.Scenery
|
||||
animateScenery(sinkingScenery, CANOE_SINKING_ANIMATION.id)
|
||||
sendMessage(player, "You arrive at $arrivalMessage.")
|
||||
sendMessage(player, "Your canoe sinks from the long journey.")
|
||||
if (destination == CanoeStationLocations.WILDERNESS) {
|
||||
sendMessage(player, "There are no trees nearby to make a new canoe. Guess you're walking.")
|
||||
}
|
||||
setVarbit(player, origin.stationVarbit, 0)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
package content.global.travel.canoe
|
||||
|
||||
import core.game.component.Component
|
||||
import core.game.node.entity.skill.Skills
|
||||
import content.data.skill.SkillingTool
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import org.rs09.consts.Components
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.IntType
|
||||
|
||||
import core.api.*
|
||||
import core.game.interaction.QueueStrength
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
class CanoeStationListener : InteractionListener {
|
||||
|
||||
private val STATION_IDs = intArrayOf(12140, 12141, 12142, 12143, 12144, 12145, 12146, 12147, 12148, 12151, 12152, 12153, 12154, 12155, 12156, 12157, 12158, 12149, 12150)
|
||||
private val STAGE_TREE_NONINTERACTABLE = 9
|
||||
private val STAGE_LOG_CHOPPED = 10
|
||||
private val SHAPING_INTERFACE = Components.CANOE_52
|
||||
private val PUSH = Animation(3301)
|
||||
private val FALL = Animation(3303)
|
||||
private val FLOAT = Animation(3304)
|
||||
|
||||
override fun defineDestinationOverrides() {
|
||||
setDest(IntType.SCENERY,STATION_IDs,"chop-down"){ _, node ->
|
||||
return@setDest CanoeUtils.getChopLocation(node.location)
|
||||
}
|
||||
setDest(IntType.SCENERY,STATION_IDs,"shape-canoe","float canoe","float log","float waka"){ _, node ->
|
||||
return@setDest CanoeUtils.getCraftFloatLocation(node.location)
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
on(STATION_IDs, IntType.SCENERY, "chop-down"){ player, node ->
|
||||
val axe: SkillingTool? = SkillingTool.getHatchet(player)
|
||||
val varbit = node.asScenery().definition.configFile
|
||||
if(varbit.getValue(player) != 0){
|
||||
setVarbit(player,varbit,0)
|
||||
}
|
||||
|
||||
if (axe == null) {
|
||||
player.packetDispatch.sendMessage("You do not have an axe which you have the woodcutting level to use.")
|
||||
return@on true
|
||||
}
|
||||
if (player.skills.getLevel(Skills.WOODCUTTING) < 12) {
|
||||
player.packetDispatch.sendMessage("You need a woodcutting level of at least 12 to chop down this tree.")
|
||||
return@on true
|
||||
}
|
||||
lock(player, 5)
|
||||
setVarp(player, varbit.varpId, 0)
|
||||
player.faceLocation(CanoeUtils.getFaceLocation(player.location))
|
||||
player.animate(axe.animation)
|
||||
setVarbit(player,varbit,STAGE_TREE_NONINTERACTABLE)
|
||||
queueScript(player, 4, QueueStrength.SOFT) {
|
||||
player.animator.stop()
|
||||
setVarbit(player,varbit,STAGE_LOG_CHOPPED)
|
||||
player.packetDispatch.sendSceneryAnimation(node.asScenery().getChild(player), FALL, false)
|
||||
player.unlock()
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(STATION_IDs, IntType.SCENERY, "shape-canoe"){ player, node ->
|
||||
val varbit = node.asScenery().definition.configFile
|
||||
if(varbit.getValue(player) != STAGE_LOG_CHOPPED){
|
||||
setVarbit(player,varbit,0)
|
||||
return@on true
|
||||
}
|
||||
player.faceLocation(CanoeUtils.getFaceLocation(player.location))
|
||||
player.interfaceManager.open(Component(SHAPING_INTERFACE))
|
||||
player.setAttribute("canoe-varbit",varbit)
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(STATION_IDs, IntType.SCENERY, "float canoe","float log","float waka"){ player, node ->
|
||||
val varbit = node.asScenery().definition.configFile
|
||||
val canoe = CanoeUtils.getCanoeFromVarbit(player, varbit)
|
||||
player.animator.animate(PUSH)
|
||||
lock(player, 2)
|
||||
playAudio(player, Sounds.CANOE_ROLL_2731)
|
||||
player.faceLocation(CanoeUtils.getFaceLocation(player.location))
|
||||
player.pulseManager.run(object : Pulse(){
|
||||
override fun pulse(): Boolean {
|
||||
setVarbit(player,varbit, CanoeUtils.getCraftValue(canoe, true))
|
||||
player.packetDispatch.sendSceneryAnimation(node.asScenery(), FLOAT, false)
|
||||
player.unlock()
|
||||
return true
|
||||
}
|
||||
})
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(STATION_IDs, IntType.SCENERY, "paddle log","paddle canoe"){ player, node ->
|
||||
player.interfaceManager.open(Component(Components.CANOE_STATIONS_MAP_53))
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
package content.global.travel.canoe
|
||||
|
||||
import core.cache.def.impl.VarbitDefinition
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import content.data.skill.SkillingTool
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import org.rs09.consts.Components
|
||||
|
||||
object CanoeUtils {
|
||||
private const val SHAPE_INTERFACE = Components.CANOE_52
|
||||
|
||||
private val FROM_LUMBRIDGE = mapOf(4 to 9887, 3 to 9888, 2 to 9889, 1 to 9890)
|
||||
private val FROM_CHAMPIONS = mapOf(4 to 9891, 3 to 9892, 2 to 9893, 0 to 9906)
|
||||
private val FROM_BARBARIAN = mapOf(4 to 9894, 3 to 9895, 1 to 9905, 0 to 9906)
|
||||
private val FROM_EDGE = mapOf(4 to 9896, 2 to 9903, 1 to 9902, 0 to 9901)
|
||||
private val FROM_WILDERNESS = mapOf(3 to 9900, 2 to 9899, 1 to 9898, 0 to 9897)
|
||||
|
||||
fun checkCanoe(player: Player, canoe: Canoe){
|
||||
if(player.skills.getLevel(Skills.WOODCUTTING) < canoe.requiredLevel) return
|
||||
player.packetDispatch.sendInterfaceConfig(SHAPE_INTERFACE,canoe.silhouetteChild,true)
|
||||
player.packetDispatch.sendInterfaceConfig(SHAPE_INTERFACE,canoe.textChild,false)
|
||||
}
|
||||
|
||||
fun getCanoeFromVarbit(player: Player, varbit: VarbitDefinition): Canoe {
|
||||
var bit = varbit.getValue(player)
|
||||
if(bit > 10) bit -= 10
|
||||
return Canoe.values()[bit - 1]
|
||||
}
|
||||
|
||||
fun getCraftValue(canoe: Canoe, floating: Boolean): Int{
|
||||
return 1 + (canoe.ordinal + if (floating) 10 else 0)
|
||||
}
|
||||
|
||||
fun getStationIndex(location: Location): Int{
|
||||
return when(location.regionId){
|
||||
12850 -> 0
|
||||
12852,12596 -> 1
|
||||
12341 -> 2
|
||||
12342 -> 3
|
||||
12603 -> 4
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
|
||||
fun getTravelAnimation(stationId: Int, destId: Int): Int {
|
||||
return when(stationId){
|
||||
0 -> FROM_LUMBRIDGE.getOrDefault(destId,0)
|
||||
1 -> FROM_CHAMPIONS.getOrDefault(destId,0)
|
||||
2 -> FROM_BARBARIAN.getOrDefault(destId,0)
|
||||
3 -> FROM_EDGE.getOrDefault(destId,0)
|
||||
4 -> FROM_WILDERNESS.getOrDefault(destId,0)
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
|
||||
fun getShapeAnimation(axe: SkillingTool): Animation{
|
||||
return when(axe){
|
||||
SkillingTool.BRONZE_AXE -> Animation(6744)
|
||||
SkillingTool.IRON_AXE -> Animation(6743)
|
||||
SkillingTool.STEEL_AXE -> Animation(6742)
|
||||
SkillingTool.BLACK_AXE -> Animation(6741)
|
||||
SkillingTool.MITHRIL_AXE -> Animation(6740)
|
||||
SkillingTool.ADAMANT_AXE -> Animation(6739)
|
||||
SkillingTool.RUNE_AXE -> Animation(6738)
|
||||
SkillingTool.DRAGON_AXE -> Animation(6745)
|
||||
else -> axe.animation
|
||||
}
|
||||
}
|
||||
|
||||
fun getDestinationFromButtonID(buttonID: Int): Location {
|
||||
return when(buttonID){
|
||||
47 -> Location.create(3240, 3242, 0)
|
||||
48 -> Location.create(3199, 3344, 0)
|
||||
3 -> Location.create(3109, 3415, 0)
|
||||
6 -> Location.create(3132, 3510, 0)
|
||||
49 -> Location.create(3139, 3796, 0)
|
||||
else -> Location.create(3240, 3242, 0)
|
||||
}
|
||||
}
|
||||
|
||||
fun getNameByIndex(index: Int): String{
|
||||
return when(index){
|
||||
0 -> "Lumbridge"
|
||||
1 -> "the Champion's Guild."
|
||||
2 -> "Barbarian Village"
|
||||
3 -> "Edgeville"
|
||||
4 -> "the Wilderness Pond"
|
||||
else -> "Uhhh report this."
|
||||
}
|
||||
}
|
||||
|
||||
fun getFaceLocation(location: Location): Location{
|
||||
return when(getStationIndex(location)){
|
||||
1 -> location.transform(0,-1,0)
|
||||
0,2,3 -> location.transform(-1,0,0)
|
||||
else -> location
|
||||
}
|
||||
}
|
||||
|
||||
fun getChopLocation(location: Location): Location{
|
||||
return when(getStationIndex(location)){
|
||||
0 -> Location.create(3243, 3235, 0)
|
||||
1 -> Location.create(3204, 3343, 0)
|
||||
2 -> Location.create(3112, 3409, 0)
|
||||
3 -> Location.create(3132, 3508, 0)
|
||||
else -> Location.create(0,0)
|
||||
}
|
||||
}
|
||||
|
||||
fun getCraftFloatLocation(location: Location): Location{
|
||||
return when(getStationIndex(location)){
|
||||
0 -> Location.create(3243, 3237, 0)
|
||||
1 -> Location.create(3202, 3343, 0)
|
||||
2 -> Location.create(3112, 3411, 0)
|
||||
3 -> Location.create(3132, 3510, 0)
|
||||
else -> Location.create(0,0)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package content.region.misthalin.varrock.diary
|
||||
|
||||
import content.global.skill.prayer.Bones
|
||||
import content.global.travel.canoe.Canoe
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.diary.DiaryType
|
||||
|
|
@ -13,6 +12,7 @@ import org.rs09.consts.Scenery
|
|||
import content.region.misthalin.varrock.dialogue.ElsieDialogue
|
||||
import content.global.handlers.iface.FairyRing
|
||||
import content.global.skill.magic.TeleportMethod
|
||||
import content.global.travel.canoe.CanoeListener
|
||||
import core.api.getStatLevel
|
||||
import core.api.inBorders
|
||||
import core.game.diary.AreaDiaryTask
|
||||
|
|
@ -219,8 +219,8 @@ class VarrockAchivementDiary : DiaryEventHookBase(DiaryType.VARROCK) {
|
|||
player.viewport.region?.let {
|
||||
when (it.id) {
|
||||
12342 -> {
|
||||
if (event.iface == Components.CANOE_52
|
||||
&& Canoe.getCanoeFromChild(event.buttonId) == Canoe.WAKA) {
|
||||
if (event.iface == CanoeListener.CANOE_SHAPING_INTERFACE
|
||||
&& event.buttonId == CanoeListener.CANOE_SHAPING_BUTTONS[CanoeListener.Companion.Canoes.WAKA.ordinal]) {
|
||||
finishTask(
|
||||
player,
|
||||
DiaryLevel.HARD,
|
||||
|
|
|
|||
|
|
@ -206,6 +206,10 @@ public final class InterfaceManager {
|
|||
player.removeAttribute("runscript");
|
||||
player.getPacketDispatch().sendRunScript(101, "");
|
||||
}
|
||||
// Component 333 is an immediate(no-fading) full-screen HD-mode black screen which auto-clears when interrupted.
|
||||
if (overlay != null && overlay.getId() == 333) {
|
||||
closeOverlay();
|
||||
}
|
||||
if (opened != null && opened.close(player)) {
|
||||
if (opened != null && (!opened.getDefinition().isWalkable() || opened.getId() == 14)) {
|
||||
PacketRepository.send(CloseInterface.class, new InterfaceContext(player, opened.getDefinition().getWindowPaneId(isResizable()), opened.getDefinition().getChildId(isResizable()), opened.getId(), opened.getDefinition().isWalkable()));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue