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.
116 lines
4.1 KiB
116 lines
4.1 KiB
package wow.doge.mygame.game.entities
|
|
|
|
import akka.actor.typed.ActorRef
|
|
import akka.actor.typed.Behavior
|
|
import akka.actor.typed.scaladsl.ActorContext
|
|
import akka.actor.typed.scaladsl.Behaviors
|
|
import io.estatico.newtype.macros.newtype
|
|
import wow.doge.mygame.game.entities.CharacterStats.HealHealth
|
|
|
|
case class CharacterStats(hp: CharacterStats.Health, stamina: Int)
|
|
object CharacterStats {
|
|
@newtype case class HealHealth(toInt: Int)
|
|
@newtype case class DamageHealth(toInt: Int)
|
|
@newtype case class Health(toInt: Int)
|
|
object Health {
|
|
implicit class HealthOps(private val h: Health) extends AnyVal {
|
|
// def +(v: Int): Health = Health(h.toInt + v)
|
|
// def -(v: Int): Health = Health(h.toInt - v)
|
|
// def *(v: Int): Health = Health(h.toInt * v)
|
|
// def /(v: Int): Health = Health(h.toInt / v)
|
|
def :+(v: HealHealth): Health = Health(h.toInt + v.toInt)
|
|
def -(v: DamageHealth): Health = Health(h.toInt - v.toInt)
|
|
}
|
|
}
|
|
@newtype case class HealStamina(toInt: Int)
|
|
@newtype case class DamageStamina(toInt: Int)
|
|
@newtype case class Stamina(toInt: Int)
|
|
object Stamina {
|
|
implicit class StaminaOps(private val h: Stamina) extends AnyVal {
|
|
// def +(v: Int): Stamina = Stamina(h.toInt + v)
|
|
// def -(v: Int): Stamina = Stamina(h.toInt - v)
|
|
// def *(v: Int): Stamina = Stamina(h.toInt * v)
|
|
// def /(v: Int): Stamina = Stamina(h.toInt / v)
|
|
def :+(v: HealStamina): Stamina = Stamina(h.toInt + v.toInt)
|
|
def -(v: DamageStamina): Stamina = Stamina(h.toInt - v.toInt)
|
|
}
|
|
}
|
|
// object Stamina {
|
|
// implicit class StaminaOps(private val h: Stamina) extends AnyVal {
|
|
// def +(v: Health): Stamina = Stamina(h.toInt + v.toInt)
|
|
// def -(v: Health): Stamina = Stamina(h.toInt - v.toInt)
|
|
// def *(v: Health): Stamina = Stamina(h.toInt * v.toInt)
|
|
// def /(v: Health): Stamina = Stamina(h.toInt / v.toInt)
|
|
// }
|
|
// }
|
|
|
|
// object Damage {
|
|
// implicit class DamageOps(private val h: Damage) extends AnyVal {
|
|
// def +(v: Health): Damage = Damage(h.toInt + v.toInt)
|
|
// def -(v: Health): Damage = Damage(h.toInt - v.toInt)
|
|
// def *(v: Health): Damage = Damage(h.toInt * v.toInt)
|
|
// def /(v: Health): Damage = Damage(h.toInt / v.toInt)
|
|
// }
|
|
// }
|
|
|
|
}
|
|
|
|
object StatsActor {
|
|
|
|
sealed trait Command
|
|
// case class TakeDamage(value: Int) extends Command
|
|
case class TakeDamageResult(
|
|
value: CharacterStats.DamageHealth,
|
|
replyTo: ActorRef[(Boolean, CharacterStats)]
|
|
) extends Command
|
|
case class HealResult(value: HealHealth) extends Command
|
|
case class CurrentStats(replyTo: ActorRef[CharacterStats]) extends Command
|
|
|
|
class Props(
|
|
startingHealth: CharacterStats.Health,
|
|
startingStamina: CharacterStats.Stamina
|
|
) {
|
|
def behavior =
|
|
Behaviors.setup[Command] { ctx =>
|
|
new StatsActor(ctx, this)
|
|
.receive(
|
|
State(CharacterStats(startingHealth, startingStamina.toInt))
|
|
)
|
|
}
|
|
}
|
|
|
|
case class State(stats: CharacterStats)
|
|
}
|
|
class StatsActor(
|
|
ctx: ActorContext[StatsActor.Command],
|
|
props: StatsActor.Props
|
|
) {
|
|
import StatsActor._
|
|
import CharacterStats._
|
|
import com.softwaremill.quicklens._
|
|
def receive(state: State): Behavior[Command] =
|
|
Behaviors.receiveMessage[Command] {
|
|
// Todo add min max values
|
|
// case TakeDamage(value) =>
|
|
// val nextState =
|
|
// if (state.stats.hp - value <= 0)
|
|
// state.modify(_.stats.hp).setTo(0)
|
|
// else
|
|
// state.modify(_.stats.hp).using(_ - value)
|
|
// receive(nextState)
|
|
case TakeDamageResult(value, replyTo) =>
|
|
val nextState = if ((state.stats.hp - value).toInt <= 0) {
|
|
replyTo ! true -> state.stats
|
|
state.modify(_.stats.hp).setTo(Health(0))
|
|
} else {
|
|
replyTo ! false -> state.stats
|
|
state.modify(_.stats.hp).using(_ - value)
|
|
}
|
|
receive(nextState)
|
|
case HealResult(value) =>
|
|
receive(state.modify(_.stats.hp).using(_ :+ value))
|
|
case CurrentStats(replyTo) =>
|
|
replyTo ! state.stats
|
|
Behaviors.same
|
|
}
|
|
}
|