Fixed farming bug, redid canoe stations entirely into new listener system

This commit is contained in:
Ceikry
2021-03-15 15:49:57 -05:00
parent 8992e81581
commit df40fbb32d
11 changed files with 298 additions and 772 deletions
@@ -0,0 +1,127 @@
package rs09.game.interaction.`object`.canoestation
import core.cache.def.impl.VarbitDefinition
import core.game.component.Component
import core.game.content.global.travel.canoe.Canoe
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.entity.skill.Skills
import core.game.node.entity.skill.gather.SkillingTool
import core.game.system.task.Pulse
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 rs09.game.interaction.InterfaceListener
class CanoeInterfaceListeners : InterfaceListener() {
val SHAPE_INTERFACE = Components.CANOE_52
val DESTINATION_INTERFACE = Components.CANOE_STATIONS_MAP_53
val EDGEVILLE_REGION = 12342
private val boatChilds = intArrayOf(47, 48, 3, 6, 49)
private val locationChilds = intArrayOf(50, 47, 44, 36)
override fun defineListeners() {
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
}
player.lock()
player.animate(axe.animation)
player.pulseManager.run(object : Pulse(3) {
override fun pulse(): Boolean {
if (RandomFunction.random(if (canoe == Canoe.WAKA) 8 else 6) == 1) {
if (player.location.regionId == EDGEVILLE_REGION && canoe == Canoe.WAKA) {
player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 2, 10)
}
player.varpManager.setVarbit(varbit,CanoeUtils.getCraftValue(canoe,false))
player.skills.addExperience(Skills.WOODCUTTING, canoe.experience)
player.unlock()
return true
}
player.animate(axe.animation)
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(Math.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 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
}
player.lock()
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))
2 -> {
PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2))
player.interfaceManager.hideTabs(0, 1, 2, 3, 4, 5, 6, 11, 12)
}
15 -> player.properties.teleportLocation = dest
16 -> {player.interfaceManager.closeOverlay(); player.interfaceManager.openOverlay(Component(Components.FADE_FROM_BLACK_170))}
18 -> {
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.")
}
player.varpManager.setVarbit(varbit,0)
return true
}
}
return false
}
})
return@on true
}
}
}
@@ -0,0 +1,88 @@
package rs09.game.interaction.`object`.canoestation
import core.game.component.Component
import core.game.node.entity.skill.Skills
import core.game.node.entity.skill.gather.SkillingTool
import core.game.system.task.Pulse
import core.game.world.update.flag.context.Animation
import org.rs09.consts.Components
import rs09.game.interaction.InteractionListener
class CanoeStationListener : InteractionListener() {
val STATION_IDs = intArrayOf(12140, 12141, 12142, 12143, 12145, 12146, 12147, 12148, 12151, 12152, 12153, 12154, 12155, 12156, 12157, 12158, 12144, 12146, 12149, 12150, 12157)
val CHOP_STATION = intArrayOf(12144)
val STAGE_TREE_NONINTERACTABLE = 9
val STAGE_LOG_CHOPPED = 10
private val SHAPING_INTERFACE = Components.CANOE_52
private val PUSH = Animation(3301)
private val ROW = Animation(3302)
private val FALL = Animation(3303)
private val FLOAT = Animation(3304)
private val SINK = Animation(3305)
override fun defineListeners() {
on(CHOP_STATION,OBJECT,"chop-down"){player, node ->
val axe: SkillingTool? = SkillingTool.getHatchet(player)
val varbit = node.asObject().definition.configFile
if(varbit.getValue(player) != 0){
player.varpManager.setVarbit(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
}
player.lock()
player.animate(axe.animation)
player.varpManager.setVarbit(varbit,STAGE_TREE_NONINTERACTABLE)
player.pulseManager.run(object : Pulse(4){
override fun pulse(): Boolean {
player.animator.stop()
player.varpManager.setVarbit(varbit,STAGE_LOG_CHOPPED)
player.packetDispatch.sendObjectAnimation(node.asObject().getChild(player), FALL, false)
player.unlock()
return true
}
})
return@on true
}
on(STATION_IDs,OBJECT,"shape-canoe"){player, node ->
val varbit = node.asObject().definition.configFile
if(varbit.getValue(player) != STAGE_LOG_CHOPPED){
player.varpManager.setVarbit(varbit,0)
return@on true
}
player.interfaceManager.open(Component(SHAPING_INTERFACE))
player.setAttribute("canoe-varbit",varbit)
return@on true
}
on(STATION_IDs,OBJECT,"float canoe","float log","float waka"){player, node ->
val varbit = node.asObject().definition.configFile
val canoe = CanoeUtils.getCanoeFromVarbit(player,varbit)
player.animator.animate(PUSH)
player.lock()
player.pulseManager.run(object : Pulse(){
override fun pulse(): Boolean {
player.varpManager.setVarbit(varbit,CanoeUtils.getCraftValue(canoe,true))
player.packetDispatch.sendObjectAnimation(node.asObject(), FLOAT, false)
player.unlock()
return true
}
})
return@on true
}
on(STATION_IDs,OBJECT,"paddle log","paddle canoe"){player, node ->
player.interfaceManager.open(Component(Components.CANOE_STATIONS_MAP_53))
return@on true
}
}
}
@@ -0,0 +1,62 @@
package rs09.game.interaction.`object`.canoestation
import core.cache.def.impl.VarbitDefinition
import core.game.content.global.travel.canoe.Canoe
import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills
import core.game.world.map.Location
import org.rs09.consts.Components
object CanoeUtils {
val SHAPE_INTERFACE = Components.CANOE_52
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 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."
}
}
}
@@ -1,8 +1,8 @@
package rs09.game.node.entity.skill.farming
import core.game.node.entity.player.Player
import rs09.game.system.SystemLogger
import core.tools.RandomFunction
import rs09.game.system.SystemLogger
import java.util.concurrent.TimeUnit
class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantable?, var currentGrowthStage: Int, var isDiseased: Boolean, var isDead: Boolean, var isWatered: Boolean, var nextGrowth: Long, var harvestAmt: Int, var isCheckHealth: Boolean) {
@@ -180,6 +180,7 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
currentGrowthStage = 3
setCurrentState(3)
compost = CompostType.NONE
protectionPaid = false
}
fun getFruitOrBerryCount() : Int {
@@ -97,7 +97,8 @@ class FarmingState(player: Player? = null) : State(player) {
patch.compost = CompostType.values()[compostOrdinal]
patch.protectionPaid = protectionPaid
if(patch.currentGrowthStage < patch.plantable?.stages ?: 0 && !patch.isWeedy()){
patch.setCurrentState(savedState)
if((patch.currentGrowthStage < patch.plantable?.stages ?: 0) && !patch.isWeedy()){
val startTime = (patch.nextGrowth - TimeUnit.MINUTES.toMillis(patch.patch.type.stageGrowthTime * (patch.currentGrowthStage + 1).toLong()))
var expectedStage = Math.floor((System.currentTimeMillis() - startTime.toDouble()) / TimeUnit.MINUTES.toMillis(patch.patch.type.stageGrowthTime.toLong())).toInt()
SystemLogger.logErr("$expectedStage $startTime ${System.currentTimeMillis()}")
@@ -112,7 +113,7 @@ class FarmingState(player: Player? = null) : State(player) {
}
}
if(savedState > patch.plantable?.value ?: 0 + patch.currentGrowthStage){
if((savedState - (patch?.plantable?.value ?: 0)) > patch.plantable?.value ?: 0 + patch.currentGrowthStage){
patch.setCurrentState(savedState)
} else {
patch.setCurrentState((patch.plantable?.value ?: 0) + patch.currentGrowthStage)