Skip to content

Commit

Permalink
Add suspendable helper methods (#591)
Browse files Browse the repository at this point in the history
* Add suspendable walkTo variables

* Add suspending exactMove

* Remove unused imports

* Add suspendable animation method, change how emotes work (interrupt-able)

* Remove playAnimation
  • Loading branch information
GregHib authored Jan 22, 2025
1 parent f1f9729 commit 0731eac
Show file tree
Hide file tree
Showing 36 changed files with 280 additions and 270 deletions.
10 changes: 5 additions & 5 deletions data/definitions/animations.yml
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ emote_shake_snow_globe:
run: false
emote_trample_snow:
id: 7528
ticks: 8
ticks: 4
walk: false
run: false
emote_candy_cane_spin:
Expand Down Expand Up @@ -801,22 +801,22 @@ emote_squirrel_ears:
run: false
emote_toy_horsey_brown:
id: 918
ticks: 4
ticks: 3
walk: false
run: false
emote_toy_horsey_white:
id: 919
ticks: 4
ticks: 3
walk: false
run: false
emote_toy_horsey_black:
id: 920
ticks: 4
ticks: 3
walk: false
run: false
emote_toy_horsey_grey:
id: 921
ticks: 4
ticks: 3
walk: false
run: false
rubber_chicken_whack:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package world.gregs.voidps.engine.client.instruction.handle
import com.github.michaelbull.logging.InlineLogger
import world.gregs.voidps.engine.client.instruction.InstructionHandler
import world.gregs.voidps.engine.client.message
import world.gregs.voidps.engine.client.variable.hasClock
import world.gregs.voidps.engine.entity.character.mode.interact.Interact
import world.gregs.voidps.engine.entity.character.player.Player
import world.gregs.voidps.engine.entity.character.player.chat.ChatType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package world.gregs.voidps.engine.client.instruction.handle
import com.github.michaelbull.logging.InlineLogger
import world.gregs.voidps.cache.definition.Transforms
import world.gregs.voidps.engine.client.instruction.InstructionHandler
import world.gregs.voidps.engine.client.variable.hasClock
import world.gregs.voidps.engine.data.definition.DefinitionsDecoder
import world.gregs.voidps.engine.data.definition.ObjectDefinitions
import world.gregs.voidps.engine.data.definition.VariableDefinitions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package world.gregs.voidps.engine.client.instruction.handle

import com.github.michaelbull.logging.InlineLogger
import world.gregs.voidps.engine.client.instruction.InstructionHandler
import world.gregs.voidps.engine.client.variable.hasClock
import world.gregs.voidps.engine.entity.character.mode.Follow
import world.gregs.voidps.engine.entity.character.mode.interact.Interact
import world.gregs.voidps.engine.entity.character.player.Player
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package world.gregs.voidps.engine.client.instruction.handle

import world.gregs.voidps.engine.client.instruction.InstructionHandler
import world.gregs.voidps.engine.client.ui.closeInterfaces
import world.gregs.voidps.engine.client.variable.hasClock
import world.gregs.voidps.engine.entity.character.clearWatch
import world.gregs.voidps.engine.entity.character.move.walkTo
import world.gregs.voidps.engine.entity.character.player.Player
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import world.gregs.voidps.engine.entity.character.mode.EmptyMode
import world.gregs.voidps.engine.entity.character.mode.Wander
import world.gregs.voidps.engine.entity.character.mode.Wander.Companion.wanders
import world.gregs.voidps.engine.entity.character.npc.NPC
import kotlin.coroutines.resume

class NPCTask(
iterator: TaskIterator<NPC>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import world.gregs.voidps.engine.client.ui.hasMenuOpen
import world.gregs.voidps.engine.client.update.iterator.TaskIterator
import world.gregs.voidps.engine.entity.character.CharacterList
import world.gregs.voidps.engine.entity.character.player.Player
import kotlin.coroutines.resume

class PlayerTask(
iterator: TaskIterator<Player>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import world.gregs.voidps.engine.entity.character.player.skill.Skill
import world.gregs.voidps.engine.entity.obj.GameObject
import world.gregs.voidps.engine.entity.obj.ObjectShape
import world.gregs.voidps.engine.get
import world.gregs.voidps.engine.suspend.SuspendableContext
import world.gregs.voidps.network.login.protocol.visual.VisualMask
import world.gregs.voidps.network.login.protocol.visual.Visuals
import world.gregs.voidps.network.login.protocol.visual.update.Hitsplat
Expand Down Expand Up @@ -69,6 +70,11 @@ fun Character.setAnimation(id: String, delay: Int? = null, override: Boolean = f
return definition["ticks", 0]
}

context(SuspendableContext<*>) suspend fun Character.animate(id: String, override: Boolean = false) {
val ticks = setAnimation(id, override = override)
delay(ticks)
}

fun Character.clearAnimation() {
visuals.animation.reset()
flagAnimation()
Expand Down Expand Up @@ -190,13 +196,21 @@ fun Character.setExactMovement(
flagExactMovement()
}

fun Character.exactMove(delta: Delta, delay: Int = tile.distanceTo(tile.add(delta)) * 30, direction: Direction = Direction.NONE) {
fun Character.setExactMove(delta: Delta, delay: Int = tile.distanceTo(tile.add(delta)) * 30, direction: Direction = Direction.NONE) {
val start = tile
tele(delta)
if (this is Player) {
movementType = MoveType.Walk
}
setExactMovement(Delta.EMPTY, delay, start.delta(tile), direction = direction)
}

fun Character.exactMove(target: Tile, delay: Int = tile.distanceTo(target) * 30, direction: Direction = Direction.NONE, startDelay: Int = 0) {
context(SuspendableContext<*>) suspend fun Character.exactMove(delta: Delta, delay: Int = tile.distanceTo(tile.add(delta)) * 30, direction: Direction = Direction.NONE) {
character.setExactMove(delta, delay, direction)
delay(delay / 30)
}

fun Character.setExactMove(target: Tile, delay: Int = tile.distanceTo(target) * 30, direction: Direction = Direction.NONE, startDelay: Int = 0) {
val start = tile
tele(target)
if (this is Player) {
Expand All @@ -205,6 +219,11 @@ fun Character.exactMove(target: Tile, delay: Int = tile.distanceTo(target) * 30,
setExactMovement(Delta.EMPTY, delay, start.delta(tile), startDelay, direction = direction)
}

context(SuspendableContext<*>) suspend fun Character.exactMove(target: Tile, delay: Int = tile.distanceTo(target) * 30, direction: Direction = Direction.NONE, startDelay: Int = 0) {
character.setExactMove(target, delay, direction, startDelay)
delay((startDelay + delay) / 30)
}

val Character.turn: Delta
get() = Tile(visuals.turn.targetX, visuals.turn.targetY, tile.level).delta(tile)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import world.gregs.voidps.engine.entity.character.Character
import world.gregs.voidps.engine.entity.character.mode.move.Movement
import world.gregs.voidps.engine.entity.character.mode.move.target.TileTargetStrategy
import world.gregs.voidps.engine.entity.obj.GameObject
import world.gregs.voidps.engine.suspend.SuspendableContext
import world.gregs.voidps.type.Tile

/**
Expand All @@ -13,4 +14,56 @@ import world.gregs.voidps.type.Tile
*/
fun Character.walkTo(target: Tile, noCollision: Boolean = false, noRun: Boolean = false) {
mode = Movement(this, TileTargetStrategy(target, noCollision, noRun))
}

/**
* Forces the character to walk to a tile
*/
context(SuspendableContext<*>) suspend fun Character.walkTo(tile: Tile) {
if (this.tile == tile) {
return
}
walkTo(tile, noCollision = false, noRun = false)
while (this.tile != tile) {
delay()
}
}

/**
* Force a character to walk to tile ignoring collisions
*/
context(SuspendableContext<*>) suspend fun Character.walkOver(tile: Tile) {
if (this.tile == tile) {
return
}
walkTo(tile, noCollision = true, noRun = true)
while (this.tile != tile) {
delay()
}
}

/**
* Steps a character to tile (run or walk)
*/
context(SuspendableContext<*>) suspend fun Character.stepTo(tile: Tile) {
if (this.tile == tile) {
return
}
walkTo(tile, noCollision = false, noRun = false)
while (this.tile != tile) {
delay()
}
}

/**
* Steps a character to tile (run or walk) ignoring collisions
*/
context(SuspendableContext<*>) suspend fun Character.stepOver(tile: Tile) {
if (this.tile == tile) {
return
}
walkTo(tile, noCollision = true, noRun = false)
while (this.tile != tile) {
delay()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import kotlinx.coroutines.*
import world.gregs.voidps.engine.client.ui.closeMenu
import world.gregs.voidps.engine.client.ui.dialogue
import world.gregs.voidps.engine.client.ui.hasMenuOpen
import world.gregs.voidps.engine.client.variable.hasClock
import world.gregs.voidps.engine.entity.character.Character
import world.gregs.voidps.engine.entity.character.clearAnimation
import world.gregs.voidps.engine.entity.character.npc.NPC
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
package world.gregs.voidps.engine.suspend

import com.github.michaelbull.logging.InlineLogger
import kotlinx.coroutines.suspendCancellableCoroutine
import world.gregs.voidps.engine.client.ui.dialogue
import world.gregs.voidps.engine.client.ui.menu
import world.gregs.voidps.engine.client.variable.remaining
import world.gregs.voidps.engine.client.variable.start
import world.gregs.voidps.engine.entity.character.Character
import world.gregs.voidps.engine.entity.character.mode.interact.Interact
import world.gregs.voidps.engine.entity.character.mode.interact.Interaction
import world.gregs.voidps.engine.entity.character.player.Player
import world.gregs.voidps.engine.entity.character.setAnimation
import world.gregs.voidps.engine.event.Context
import world.gregs.voidps.engine.queue.Action

fun Character.resumeSuspension(): Boolean {
val suspend = suspension ?: return false
Expand All @@ -26,25 +16,4 @@ fun Character.resumeSuspension(): Boolean {
suspend fun SuspendableContext<Player>.awaitDialogues(): Boolean {
Suspension.start(character) { player.dialogue == null }
return true
}

suspend fun SuspendableContext<Player>.awaitInterfaces(): Boolean {
Suspension.start(character) { player.menu == null }
return true
}

private val logger = InlineLogger()

context(SuspendableContext<*>) suspend fun Character.playAnimation(id: String, override: Boolean = false, canInterrupt: Boolean = true) {
val ticks = setAnimation(id, override = override)
if (ticks == -1) {
logger.warn { "No animation delay $id" }
} else {
character.start("movement_delay", ticks)
if (canInterrupt) {
pause(ticks)
} else {
delay(ticks)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package world.gregs.voidps.engine.suspend

import kotlinx.coroutines.suspendCancellableCoroutine
import world.gregs.voidps.engine.entity.character.Character
import world.gregs.voidps.engine.entity.character.mode.interact.Interaction
import world.gregs.voidps.engine.event.Context

interface SuspendableContext<C : Character> : Context<C> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import world.gregs.voidps.engine.entity.character.mode.move.enterArea
import world.gregs.voidps.engine.entity.character.mode.move.exitArea
import world.gregs.voidps.engine.entity.character.player.Player
import world.gregs.voidps.engine.inject
import world.gregs.voidps.world.interact.dialogue.Happy
import world.gregs.voidps.world.interact.entity.player.display.Tab

val variables: VariableDefinitions by inject()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import world.gregs.voidps.engine.data.Settings
import world.gregs.voidps.engine.data.definition.data.Rock
import world.gregs.voidps.engine.data.settingsReload
import world.gregs.voidps.engine.entity.World
import world.gregs.voidps.engine.entity.character.exactMove
import world.gregs.voidps.engine.entity.character.setExactMove
import world.gregs.voidps.engine.entity.character.mode.interact.Interact
import world.gregs.voidps.engine.entity.character.move.walkTo
import world.gregs.voidps.engine.entity.character.npc.NPC
Expand Down Expand Up @@ -120,7 +120,7 @@ fun startCrashedStarEvent() {
for (player in under) {
player.damage(random.nextInt(10, 50))
val direction = Direction.all.first { !player.blocked(it) }
player.exactMove(direction.delta, 1, direction = direction.inverse())
player.setExactMove(direction.delta, 1, direction = direction.inverse())
player.setAnimation("step_back_startled")
}
World.queue("falling_star_object_removal", 1) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package world.gregs.voidps.world.activity.skill.agility.course

import world.gregs.voidps.engine.entity.character.exactMove
import world.gregs.voidps.engine.entity.character.setExactMove
import world.gregs.voidps.engine.entity.character.face
import world.gregs.voidps.engine.entity.character.move.tele
import world.gregs.voidps.engine.entity.character.move.walkTo
Expand All @@ -13,7 +14,6 @@ import world.gregs.voidps.engine.entity.character.setAnimation
import world.gregs.voidps.engine.entity.obj.objectOperate
import world.gregs.voidps.type.Direction
import world.gregs.voidps.type.Tile
import world.gregs.voidps.type.equals

objectOperate("Run-up", "barbarian_outpost_run_wall") {
if (!player.has(Skill.Agility, 90, message = true)) {
Expand All @@ -24,20 +24,16 @@ objectOperate("Run-up", "barbarian_outpost_run_wall") {
player.face(Direction.NORTH)
player.setAnimation("barbarian_wall_jump_climb")
delay(7)
player.exactMove(Tile(2538, 3545, 2), 30, Direction.NORTH)
player.setAnimation("barbarian_wall_jump")
delay(2)
player.exactMove(Tile(2538, 3545, 2), 30, Direction.NORTH)
delay(1)
player.exp(Skill.Agility, 15.0)
player.agilityStage(3)
}

objectOperate("Climb-up", "barbarian_outpost_climb_wall") {
player.clear("face_entity")
val move = !player.tile.equals(2537, 3546, 2)
if (move) {
player.walkTo(Tile(2537, 3546, 2))
}
delay(if (move) 2 else 1)
player.walkTo(Tile(2537, 3546, 2))
player.face(Direction.WEST)
delay()
player.setAnimation("barbarian_wall_climb")
Expand All @@ -56,11 +52,10 @@ objectOperate("Fire", "barbarian_outpost_spring") {
target.animate("barbarian_spring_fire")
delay(1)
player.tele(2533, 3547, 3)
player.exactMove(Tile(2532, 3553, 3), 60, Direction.NORTH)
player.setAnimation("barbarian_spring_shoot")
delay(1)
player.exactMove(Tile(2532, 3553, 3), 60, Direction.NORTH)
target.animate("barbarian_spring_reset")
delay(3)
delay(2)
player.exp(Skill.Agility, 15.0)
player.agilityStage(5)
}
Expand All @@ -71,7 +66,6 @@ objectOperate("Cross", "barbarian_outpost_balance_beam") {
player.setAnimation("circus_cartwheel")
delay()
player.exactMove(Tile(2536, 3553, 3), 45, Direction.EAST)
delay()
player.renderEmote = "beam_balance"
delay()
player.exp(Skill.Agility, 15.0)
Expand All @@ -90,11 +84,10 @@ objectOperate("Jump-over", "barbarian_outpost_gap") {
}

objectOperate("Slide-down", "barbarian_outpost_roof") {
player.exactMove(player.tile.copy(x = 2540), 30, Direction.EAST)
player.setAnimation("barbarian_slide_start")
delay()
player.exactMove(player.tile.copy(x = 2540), 30, Direction.EAST)
player.setAnimation("barbarian_slide")
player.exactMove(player.tile.copy(x = 2543, level = 1), 90, Direction.EAST)
player.setExactMove(player.tile.copy(x = 2543, level = 1), 90, Direction.EAST)
delay()
player.setAnimation("barbarian_slide")
delay()
Expand Down
Loading

0 comments on commit 0731eac

Please sign in to comment.