You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
5.0 KiB
153 lines
5.0 KiB
package wow.doge.mygame.game.entities.player
|
|
|
|
import scala.concurrent.duration._
|
|
|
|
import akka.actor.typed.Behavior
|
|
import akka.actor.typed.LogOptions
|
|
import akka.actor.typed.scaladsl.ActorContext
|
|
import akka.actor.typed.scaladsl.AskPattern._
|
|
import akka.actor.typed.scaladsl.Behaviors
|
|
import akka.util.Timeout
|
|
import cats.syntax.eq._
|
|
import com.typesafe.scalalogging.Logger
|
|
import monix.eval.Task
|
|
import monix.execution.CancelableFuture
|
|
import monix.reactive.Observable
|
|
import org.slf4j.event.Level
|
|
import wow.doge.mygame.executors.Schedulers
|
|
import wow.doge.mygame.game.entities.CharacterStats
|
|
import wow.doge.mygame.implicits._
|
|
import wow.doge.mygame.subsystems.events.PlayerMovementEvent
|
|
|
|
object PlayerMovementEventListener {
|
|
final case class State(
|
|
keysPressed: Int,
|
|
staminaTimer: CancelableFuture[Unit],
|
|
staminaRegenTimer: CancelableFuture[Unit]
|
|
)
|
|
|
|
class Props(
|
|
val playerActor: PlayerActor.Ref,
|
|
val asyncScheduler: Schedulers.AsyncScheduler
|
|
) {
|
|
def behavior =
|
|
Behaviors.setup[PlayerMovementEvent] { ctx =>
|
|
new PlayerMovementEventListener(ctx, this)
|
|
.receive(State(0, CancelableFuture.unit, CancelableFuture.unit))
|
|
}
|
|
}
|
|
}
|
|
class PlayerMovementEventListener(
|
|
ctx: ActorContext[PlayerMovementEvent],
|
|
props: PlayerMovementEventListener.Props
|
|
) {
|
|
import PlayerMovementEventListener._
|
|
import PlayerMovementEvent._
|
|
import com.softwaremill.quicklens._
|
|
def receive(state: State): Behavior[PlayerMovementEvent] =
|
|
Behaviors.logMessages(
|
|
LogOptions()
|
|
.withLevel(Level.TRACE)
|
|
.withLogger(
|
|
Logger[PlayerMovementEventListener.type].underlying
|
|
),
|
|
Behaviors.setup[PlayerMovementEvent] { ctx =>
|
|
implicit val timeout = Timeout(1.second)
|
|
implicit val sched = ctx.system.scheduler
|
|
|
|
val staminaTimer =
|
|
Task.deferAction(implicit s =>
|
|
Observable
|
|
.interval(250.millis)
|
|
.doOnNext(_ => Task(pprint.log("Sending Stamina Consume Item")))
|
|
.doOnNextF(_ =>
|
|
props.playerActor
|
|
.askL(
|
|
PlayerActor
|
|
.ConsumeStamina(CharacterStats.DamageStamina(25), _)
|
|
)
|
|
.void
|
|
)
|
|
.completedL
|
|
)
|
|
|
|
val staminaRegenTimer =
|
|
Task.deferAction(implicit s =>
|
|
Observable
|
|
.interval(500.millis)
|
|
.doOnNext(_ => Task(pprint.log("Sending Stamina Regen Item")))
|
|
.mapEvalF(_ =>
|
|
props.playerActor.askL(
|
|
PlayerActor
|
|
.HealStamina(CharacterStats.HealStamina(1), _)
|
|
)
|
|
)
|
|
.takeWhile(_.stamina.toInt =!= 100)
|
|
.delayExecution(1.second)
|
|
.completedL
|
|
)
|
|
|
|
def handleStamina(pressed: Boolean) = {
|
|
state.staminaRegenTimer.cancel()
|
|
if (pressed) {
|
|
val nextState1 =
|
|
if (state.keysPressed === 0)
|
|
state
|
|
.modify(_.staminaTimer)
|
|
.setTo(
|
|
staminaTimer.runToFuture(props.asyncScheduler.value)
|
|
)
|
|
else state
|
|
val nextState2 = nextState1
|
|
.modify(_.keysPressed)
|
|
.using(_ + 1)
|
|
nextState2
|
|
} else {
|
|
val nextState1 = state
|
|
.modify(_.keysPressed)
|
|
.using(_ - 1)
|
|
if (nextState1.keysPressed === 0) {
|
|
nextState1.staminaTimer.cancel()
|
|
nextState1
|
|
.modify(_.staminaRegenTimer)
|
|
.setTo(
|
|
staminaRegenTimer.runToFuture(props.asyncScheduler.value)
|
|
)
|
|
} else
|
|
nextState1
|
|
}
|
|
}
|
|
|
|
Behaviors.receiveMessage {
|
|
case PlayerMovedLeft(pressed) =>
|
|
// props.movementActor ! ImMovementActor.MoveLeft(pressed)
|
|
props.playerActor ! PlayerActor.MoveLeft(pressed)
|
|
receive(handleStamina(pressed))
|
|
case PlayerMovedRight(pressed) =>
|
|
props.playerActor ! PlayerActor.MoveRight(pressed)
|
|
receive(handleStamina(pressed))
|
|
case PlayerMovedForward(pressed) =>
|
|
props.playerActor ! PlayerActor.MoveUp(pressed)
|
|
receive(handleStamina(pressed))
|
|
case PlayerMovedBackward(pressed) =>
|
|
props.playerActor ! PlayerActor.MoveDown(pressed)
|
|
receive(handleStamina(pressed))
|
|
case PlayerJumped =>
|
|
props.playerActor ! PlayerActor.Jump
|
|
// props.playerActor
|
|
// ctx.ask(
|
|
// props.playerActor,
|
|
// PlayerActor
|
|
// .ConsumeStamina(CharacterStats.DamageStamina(1), _)
|
|
// )(_ => ())
|
|
Behaviors.same
|
|
// case PlayerTurnedRight =>
|
|
// movementActor ! ImMovementActor.RotateRight
|
|
// Behaviors.same
|
|
// case PlayerTurnedLeft =>
|
|
// movementActor ! ImMovementActor.RotateLeft
|
|
// Behaviors.same
|
|
}
|
|
}
|
|
)
|
|
}
|