Farmed trees will now correctly regrow based on the same timer as other trees, rather than being tied to growth cycles

Implemented admin ::instachop command
This commit is contained in:
Syndromeramo 2025-10-07 12:46:13 +00:00 committed by Ryan
parent d6f32c56fc
commit 5719d03e4d
5 changed files with 77 additions and 4 deletions

View file

@ -373,8 +373,6 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
setCurrentState(getCurrentState() + 1) setCurrentState(getCurrentState() + 1)
isWatered = false isWatered = false
} }
regrowIfTreeStump()
} }
fun regrowIfTreeStump() { fun regrowIfTreeStump() {

View file

@ -0,0 +1,5 @@
package content.global.skill.farming
class Stump(val varbit: Int, val TTL: Long) {
}

View file

@ -0,0 +1,59 @@
package content.global.skill.farming.timers
import core.game.node.entity.Entity
import core.game.system.timer.*
import core.game.node.entity.player.Player
import content.global.skill.farming.*
import core.tools.ticksToSeconds
import java.util.concurrent.TimeUnit
import org.json.simple.*
class StumpGrowth : PersistTimer (1, "farming:stump", isSoft = true) {
val stumps = ArrayList<Stump>()
lateinit var player: Player
fun addStump(varbit: Int, ttl: Int){
stumps.add(
Stump(
varbit,
System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(ticksToSeconds(ttl).toLong())
)
)
}
override fun onRegister (entity: Entity) {
player = (entity as? Player)!!
}
override fun run (entity: Entity) : Boolean {
val removeList = ArrayList<Stump>()
for (stump in stumps) {
if (System.currentTimeMillis() > stump.TTL) {
FarmingPatch.patches[stump.varbit]?.getPatchFor(player)?.regrowIfTreeStump()
removeList.add(stump)
}
}
stumps.removeAll(removeList)
return stumps.isNotEmpty()
}
override fun save(root: JSONObject, entity: Entity) {
val stumpArray = JSONArray()
for(s in stumps){
val seed = JSONObject()
seed["patch"] = s.varbit
seed["ttl"] = s.TTL
stumpArray.add(seed)
}
root.put("stumps",stumpArray)
}
override fun parse(root: JSONObject, entity: Entity) {
(root["stumps"] as JSONArray).forEach {
val s = it as JSONObject
val id = s["patch"].toString().toInt()
val ttl = s["ttl"].toString().toLong()
stumps.add(Stump(id,ttl))
}
}
}

View file

@ -3,6 +3,7 @@ package content.global.skill.gather.woodcutting
import content.data.skill.SkillingTool import content.data.skill.SkillingTool
import content.data.tables.BirdNest import content.data.tables.BirdNest
import content.global.skill.farming.FarmingPatch.Companion.forObject import content.global.skill.farming.FarmingPatch.Companion.forObject
import content.global.skill.farming.timers.StumpGrowth
import content.global.skill.firemaking.Log import content.global.skill.firemaking.Log
import content.global.skill.skillcapeperks.SkillcapePerks import content.global.skill.skillcapeperks.SkillcapePerks
import content.global.skill.skillcapeperks.SkillcapePerks.Companion.isActive import content.global.skill.skillcapeperks.SkillcapePerks.Companion.isActive
@ -71,7 +72,7 @@ class WoodcuttingListener : InteractionListener {
if (clockReady(player, Clocks.SKILLING)) { if (clockReady(player, Clocks.SKILLING)) {
animateWoodcutting(player) animateWoodcutting(player)
if (!checkReward(player, resource, tool)) if (!checkReward(player, resource, tool) && !getAttribute(player, "instachop", false))
return delayClock(player, Clocks.SKILLING, 3) return delayClock(player, Clocks.SKILLING, 3)
val reward = resource.getReward() val reward = resource.getReward()
@ -156,7 +157,7 @@ class WoodcuttingListener : InteractionListener {
//OSRS: https://oldschool.runescape.wiki/w/Woodcutting scroll down to the mechanics section //OSRS: https://oldschool.runescape.wiki/w/Woodcutting scroll down to the mechanics section
//RS3 : https://runescape.wiki/w/Woodcutting scroll down to the mechanics section, and expand the tree felling chances table //RS3 : https://runescape.wiki/w/Woodcutting scroll down to the mechanics section, and expand the tree felling chances table
if (resource.getRespawnRate() > 0) { if (resource.getRespawnRate() > 0) {
if (RandomFunction.roll(8) || listOf(1, 2, 3, 4, 6).contains(resource.identifier.toInt())){ if (RandomFunction.roll(8) || listOf(1, 2, 3, 4, 6).contains(resource.identifier.toInt()) || getAttribute(player, "instachop", false)){
if (resource.isFarming()) { if (resource.isFarming()) {
val fPatch = forObject(node.asScenery()) val fPatch = forObject(node.asScenery())
if (fPatch != null) { if (fPatch != null) {
@ -168,6 +169,8 @@ class WoodcuttingListener : InteractionListener {
node.isActive = true node.isActive = true
return@queueScript stopExecuting(player) return@queueScript stopExecuting(player)
} }
val stumps = getOrStartTimer <StumpGrowth> (player)
stumps.addStump(fPatch.varbit, resource.respawnDuration)
} }
return true return true
} }

View file

@ -239,6 +239,14 @@ class FunCommandSet : CommandSet(Privilege.ADMIN) {
} }
} }
/**
* Toggle instant woodcutting.
*/
define("instachop", Privilege.ADMIN, "", "Fells trees after a single log is gathered."){ player, _ ->
player.setAttribute("instachop", !player.getAttribute("instachop", false))
notify(player,"Instachop mode " + if (player.getAttribute("instachop", false)) "on." else "off.")
}
} }
fun bury(player: Player){ fun bury(player: Player){