Browse Source

many changes

development
Rohan Sircar 3 years ago
parent
commit
12b232fb3c
  1. 1
      .gitignore
  2. 8
      .scalafix.conf
  3. 46
      build.sbt
  4. 2
      project/build.properties
  5. 5
      project/plugins.sbt
  6. 8
      src/main/scala/org/slf4j/impl/StaticLoggerBuilder.scala
  7. 2
      src/main/scala/wow/doge/mygame/AppError.scala
  8. 11
      src/main/scala/wow/doge/mygame/Main.scala
  9. 233
      src/main/scala/wow/doge/mygame/MainApp.scala
  10. 8
      src/main/scala/wow/doge/mygame/actor/GameActorSystem.scala
  11. 1
      src/main/scala/wow/doge/mygame/executors/GUIExecutor.scala
  12. 8
      src/main/scala/wow/doge/mygame/executors/Schedulers.scala
  13. 8
      src/main/scala/wow/doge/mygame/game/GameApp.scala
  14. 7
      src/main/scala/wow/doge/mygame/game/GameAppActor.scala
  15. 30
      src/main/scala/wow/doge/mygame/game/GameModule.scala
  16. 4
      src/main/scala/wow/doge/mygame/game/SimpleAppExt.scala
  17. 2
      src/main/scala/wow/doge/mygame/game/TestActor.scala
  18. 69
      src/main/scala/wow/doge/mygame/game/appstates/MyBaseState.scala
  19. 207
      src/main/scala/wow/doge/mygame/game/appstates/ScriptingEngineState.scala
  20. 71
      src/main/scala/wow/doge/mygame/game/appstates/TestAppState.scala
  21. 6
      src/main/scala/wow/doge/mygame/game/controls/CameraMovementControls.scala
  22. 58
      src/main/scala/wow/doge/mygame/game/entities/CharacterStats.scala
  23. 25
      src/main/scala/wow/doge/mygame/game/entities/NpcActorSupervisor.scala
  24. 87
      src/main/scala/wow/doge/mygame/game/entities/player/PlayerActorSupervisor.scala
  25. 2
      src/main/scala/wow/doge/mygame/game/entities/player/PlayerActorSupervisor2.scala
  26. 2
      src/main/scala/wow/doge/mygame/game/entities/player/PlayerCameraActor.scala
  27. 3
      src/main/scala/wow/doge/mygame/game/entities/player/PlayerController.scala
  28. 4
      src/main/scala/wow/doge/mygame/game/subsystems/ai/GdxAiTest.scala
  29. 13
      src/main/scala/wow/doge/mygame/game/subsystems/input/InputEnums.scala
  30. 41
      src/main/scala/wow/doge/mygame/game/subsystems/level/DefaultGameLevel.scala
  31. 2
      src/main/scala/wow/doge/mygame/game/subsystems/level/GameLevel.scala
  32. 22
      src/main/scala/wow/doge/mygame/implicits/EntityQuery.scala
  33. 304
      src/main/scala/wow/doge/mygame/implicits/JavaFXMonixObservables.scala
  34. 40
      src/main/scala/wow/doge/mygame/implicits/package.scala
  35. 8
      src/main/scala/wow/doge/mygame/launcher/Launcher.scala
  36. 2
      src/main/scala/wow/doge/mygame/math/ImVector3f.scala
  37. 6
      src/main/scala/wow/doge/mygame/subsystems/events/EventBus.scala
  38. 5
      src/main/scala/wow/doge/mygame/subsystems/events/Events.scala
  39. 1
      src/main/scala/wow/doge/mygame/subsystems/events/PlayerCameraEvents.scala
  40. 3
      src/main/scala/wow/doge/mygame/subsystems/events/PlayerEvents.scala
  41. 6
      src/main/scala/wow/doge/mygame/subsystems/moddingsystem/ModdingSystem.scala
  42. 38
      src/main/scala/wow/doge/mygame/subsystems/scriptsystem/MonixScriptCompiler.scala
  43. 9
      src/main/scala/wow/doge/mygame/subsystems/scriptsystem/ScriptActor.scala
  44. 5
      src/main/scala/wow/doge/mygame/subsystems/scriptsystem/ScriptCachingActor.scala
  45. 13
      src/main/scala/wow/doge/mygame/subsystems/scriptsystem/ScriptSystemModule.scala
  46. 4
      src/main/scala/wow/doge/mygame/types/package.scala
  47. 2
      src/main/scala/wow/doge/mygame/utils/GenericConsoleStream.scala
  48. 7
      src/main/scala/wow/doge/mygame/utils/GenericTimerActor.scala
  49. 78
      src/main/scala/wow/doge/mygame/utils/MonixDirectoryWatcher.scala
  50. 2
      src/main/scala/wow/doge/mygame/utils/ReaderDemo.scala
  51. 4
      src/main/scala/wow/doge/mygame/utils/Settings.scala
  52. 7
      src/main/scala/wow/doge/mygame/utils/TreeTest.scala
  53. 67
      src/main/scala/wow/doge/mygame/utils/controls/ActionObservable.scala
  54. 47
      src/main/scala/wow/doge/mygame/utils/controls/FontIcon.scala
  55. 42
      src/main/scala/wow/doge/mygame/utils/controls/JFXButton.scala
  56. 22
      src/main/scala/wow/doge/mygame/utils/controls/JFXDialog.scala
  57. 57
      src/main/scala/wow/doge/mygame/utils/controls/JFXListCell.scala
  58. 40
      src/main/scala/wow/doge/mygame/utils/controls/JFXListView.scala
  59. 11
      src/main/scala/wow/doge/mygame/utils/controls/JFXProgressBar.scala
  60. 37
      src/main/scala/wow/doge/mygame/utils/controls/JFXRippler.scala
  61. 32
      src/main/scala/wow/doge/mygame/utils/controls/JFXSpinner.scala
  62. 43
      src/main/scala/wow/doge/mygame/utils/controls/JFXTextArea.scala
  63. 38
      src/main/scala/wow/doge/mygame/utils/controls/JFXTextField.scala
  64. 63
      src/main/scala/wow/doge/mygame/utils/controls/JFXTreeTableView.scala
  65. 7
      src/main/scala/wow/doge/mygame/utils/controls/MenuItem.scala
  66. 12
      src/main/scala/wow/doge/mygame/utils/wrappers/jme/AssetManager.scala
  67. 2
      src/main/scala/wow/doge/mygame/utils/wrappers/jme/CollisionShapeFactory.scala
  68. 15
      src/test/scala/wow/doge/mygame/ActorTimeoutTest.scala
  69. 20
      src/test/scala/wow/doge/mygame/AnimTest.scala
  70. 17
      src/test/scala/wow/doge/mygame/AssetManagerTest.scala
  71. 16
      src/test/scala/wow/doge/mygame/CollisionShapeFactoryTest.scala
  72. 74
      src/test/scala/wow/doge/mygame/FileWatcherTest.scala
  73. 6
      src/test/scala/wow/doge/mygame/ImVector3fTest.scala
  74. 8
      src/test/scala/wow/doge/mygame/ModdingSystemTest.scala
  75. 12
      src/test/scala/wow/doge/mygame/MonixScriptCompilerTest.scala
  76. 16
      src/test/scala/wow/doge/mygame/ReaderT_Test.scala
  77. 4
      src/test/scala/wow/doge/mygame/ReaderTest.scala

1
.gitignore

@ -15,6 +15,7 @@ metals.sbt
.metals
.bloop
.ammonite
.bsp
# Scala-IDE specific
.scala_dependencies

8
.scalafix.conf

@ -0,0 +1,8 @@
rules = [
# ScalalintClasses,
# ScalalintImports,
# ScalalintPackages,
# ScalalintInference,
OrganizeImports
]
# ScalalintClasses.removeEmptyConstructor = false

46
build.sbt

@ -7,7 +7,7 @@ resolvers += "Jitpack" at "https://jitpack.io"
resolvers += Resolver.mavenLocal
resolvers += Resolver.sonatypeRepo("snapshots")
lazy val jmeVersion = "3.3.2-stable"
val jmeVersion = "3.3.2-stable"
lazy val osName = System.getProperty("os.name") match {
case n if n.startsWith("Linux") => "linux"
@ -67,13 +67,20 @@ lazy val root = (project in file(".")).settings(
"org.scalatest" %% "scalatest" % "3.2.2" % "test",
"org.typelevel" %% "cats-mtl" % "1.1.1",
"io.estatico" %% "newtype" % "0.4.4",
"io.methvin" %% "directory-watcher-better-files" % "0.14.0"
"io.methvin" %% "directory-watcher-better-files" % "0.14.0",
"com.github.rohan-sircar" % "scalafx-utils" % "0.15.0-SNAPSHOT",
"com.jfoenix" % "jfoenix" % "9.0.10",
"org.kordamp.ikonli" % "ikonli-core" % "12.0.0",
"org.kordamp.ikonli" % "ikonli-javafx" % "12.0.0",
"org.kordamp.ikonli" % "ikonli-fontawesome5-pack" % "12.0.0",
"org.kordamp.ikonli" % "ikonli-material-pack" % "12.0.0",
"org.kordamp.bootstrapfx" % "bootstrapfx-core" % "0.4.0"
),
// Determine OS version of JavaFX binaries
// Add JavaFX dependencies
libraryDependencies ++= javaFXModules.map(m =>
"org.openjfx" % s"javafx-$m" % "14.0.1" classifier osName
"org.openjfx" % s"javafx-$m" % "11.0.1" classifier osName
),
scalacOptions ++= Seq(
"-encoding",
@ -126,7 +133,8 @@ lazy val root = (project in file(".")).settings(
// oldStrategy(x)
}
)
initialCommands in (console) := """ammonite.Main.main(Array.empty)"""
// initialCommands in (console) := """ammonite.Main.main(Array.empty)"""
ammoniteVersion := "2.2.0"
addCompilerPlugin("com.olegpy" %% "better-monadic-for" % "0.3.1")
addCompilerPlugin(
"org.typelevel" %% "kind-projector" % "0.11.1" cross CrossVersion.full
@ -139,3 +147,33 @@ inThisBuild(
)
)
ThisBuild / scalafixDependencies += "com.github.liancheng" %% "organize-imports" % "0.4.3"
scalafixDependencies in ThisBuild += "org.scalalint" %% "rules" % "0.1.4"
// wartremoverErrors in (Compile, compile) ++= Warts.allBut(
// Wart.Any,
// Wart.Nothing,
// Wart.Serializable
// )
// wartremoverWarnings in (Compile, compile) ++= Seq(Wart.Any, Wart.Serializable)
wartremoverErrors in (Compile, compile) ++=
Warts.allBut(
Wart.Any,
Wart.NonUnitStatements,
// Wart.StringPlusAny,
Wart.Overloading,
Wart.PublicInference,
Wart.Nothing,
Wart.Var,
Wart.DefaultArguments,
// Wart.MutableDataStructures,
Wart.ImplicitConversion,
Wart.ImplicitParameter,
Wart.ToString,
Wart.Recursion,
Wart.While,
Wart.ExplicitImplicitTypes,
Wart.ListUnapply
)
// Seq(Wart.FinalCaseClass)

2
project/build.properties

@ -1 +1 @@
sbt.version=1.3.13
sbt.version=1.4.7

5
project/plugins.sbt

@ -1,2 +1,7 @@
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.15.0")
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.23")
addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1")
addSbtPlugin(
"com.thoughtworks.deeplearning" % "sbt-ammonite-classpath" % "2.0.0"
)
addSbtPlugin("org.wartremover" % "sbt-wartremover" % "2.4.13")

8
src/main/scala/org/slf4j/impl/StaticLoggerBuilder.scala

@ -60,11 +60,9 @@ class StaticLoggerBinder extends OdinLoggerBinder[IO] {
.allocated
.unsafeRunSync()
{
ArraySeq(release1, release2, release3).foreach(r =>
sys.addShutdownHook(r.unsafeRunSync())
)
}
ArraySeq(release1, release2, release3).foreach(r =>
sys.addShutdownHook(r.unsafeRunSync())
)
val loggers: PartialFunction[String, Logger[IO]] = {
case "some.external.package.SpecificClass" =>

2
src/main/scala/wow/doge/mygame/AppError.scala

@ -9,7 +9,7 @@ import wow.doge.mygame.utils.wrappers.jme.AssetManager
import wow.doge.mygame.utils.wrappers.jme.CollisionShapeFactory
import wow.doge.mygame.utils.wrappers.jme.NodeWrapper2
sealed trait AppError
sealed trait AppError extends Product with Serializable
object AppError {
final case class TimeoutError(reason: String) extends AppError
object TimeoutError {

11
src/main/scala/wow/doge/mygame/Main.scala

@ -2,17 +2,18 @@ package wow.doge.mygame
import scala.concurrent.duration._
import _root_.monix.bio.BIOApp
import _root_.monix.bio.Task
import _root_.monix.bio.UIO
import _root_.monix.execution.Scheduler
import akka.util.Timeout
import cats.effect.ExitCode
import cats.effect.Resource
import cats.implicits._
import io.odin._
import io.odin.consoleLogger
import io.odin.fileLogger
import io.odin.json.Formatter
import io.odin.syntax._
import monix.bio.BIOApp
import monix.bio.Task
import monix.bio.UIO
import monix.execution.Scheduler
import scalafx.scene.control.TextArea
import wow.doge.mygame.ActorSystemResource
import wow.doge.mygame.executors.ExecutorsModule

233
src/main/scala/wow/doge/mygame/MainApp.scala

@ -1,5 +1,7 @@
package wow.doge.mygame
import java.util.concurrent.TimeoutException
import scala.concurrent.duration._
import akka.actor.typed.ActorRef
@ -8,6 +10,8 @@ import akka.util.Timeout
import cats.effect.Resource
import cats.effect.concurrent.Deferred
import cats.syntax.eq._
import cats.syntax.show._
import com.jayfella.jme.jfx.JavaFxUI
import com.jme3.asset.plugins.ZipLocator
import com.jme3.bullet.control.BetterCharacterControl
import com.jme3.input.InputManager
@ -28,9 +32,14 @@ import monix.bio.IO
import monix.bio.Task
import monix.bio.UIO
import monix.eval.Coeval
import monix.execution.cancelables.CompositeCancelable
import monix.execution.exceptions.DummyException
import monix.reactive.Observable
import scalafx.scene.control.Label
import scalafx.scene.control.TextArea
import scalafx.scene.layout.HBox
import scalafx.scene.layout.VBox
import scalafx.scene.paint.Color
import wow.doge.mygame.AppError.TimeoutError
import wow.doge.mygame.executors.Schedulers
import wow.doge.mygame.game.GameApp
@ -59,12 +68,16 @@ import wow.doge.mygame.subsystems.events.PlayerEvent
import wow.doge.mygame.subsystems.events.PlayerMovementEvent
import wow.doge.mygame.subsystems.events.StatsEvent.DamageEvent
import wow.doge.mygame.subsystems.events.TickEvent
import wow.doge.mygame.subsystems.scriptsystem.ScriptCompiler
import wow.doge.mygame.subsystems.scriptsystem.ScriptInitMode
import wow.doge.mygame.subsystems.scriptsystem.ScriptSystemResource
import wow.doge.mygame.types._
import wow.doge.mygame.utils.AkkaUtils
import wow.doge.mygame.utils.GenericConsoleStream
import wow.doge.mygame.utils.IOUtils
import wow.doge.mygame.utils.MonixDirectoryWatcher
import wow.doge.mygame.utils.MonixDirectoryWatcher.ModifyEvent
import wow.doge.mygame.utils.controls.JFXProgressBar
import wow.doge.mygame.utils.wrappers.jme.AssetManager
import wow.doge.mygame.utils.wrappers.jme.PhysicsSpace
class MainApp(
@ -79,8 +92,8 @@ class MainApp(
) {
implicit val as = scheduler.value
val scriptSystemInit =
new ScriptSystemResource(os.pwd, ScriptInitMode.Eager).init
val scriptSystemResource: Resource[UIO, ScriptCompiler] =
new ScriptSystemResource(os.pwd, logger, ScriptInitMode.Eager).init2
val eventsModule = new EventsModule(scheduler, spawnProtocol)
@ -101,7 +114,9 @@ class MainApp(
IOUtils
.toIO(
obs
.doOnNextF(pme => Coeval(pprint.log(s"Received event $pme")).void)
.doOnNextF(pme =>
Coeval(pprint.log(show"Received event $pme")).void
)
.completedL
.startAndForget
)
@ -114,7 +129,7 @@ class MainApp(
viewPort <- gameApp.viewPort
physicsSpace <- UIO.pure(gameApp.physicsSpace)
_ <- logger.infoU("before")
// jfxUI <- gameApp.jfxUI
jfxUI <- gameApp.jfxUI.hideErrors
consoleTextArea <- UIO(new TextArea {
text = "hello \n"
editable = false
@ -122,6 +137,7 @@ class MainApp(
// maxHeight = 150
// maxWidth = 300
})
// _ <- Task(consoleStream := consoleTextArea)
// _ <- Task(jfxUI += consoleTextArea)
_ <- logger.infoU("after")
@ -132,14 +148,48 @@ class MainApp(
.executeOn(gameApp.scheduler.value)
} yield fib
// val k = new FunctionK[Task, UIO] {
// override def apply[A](fa: monix.bio.Task[A]): monix.bio.UIO[A] =
// fa.hideErrors
// }
def gameInit(
tickEventBus: GameEventBus[TickEvent]
): Resource[UIO, Either[AppError, Fiber[Nothing, Unit]]] =
wire[GameAppResource].resource.evalMap {
case Right(gameApp -> gameAppFib) =>
eval(tickEventBus, gameApp, gameAppFib).attempt
case Left(error) => IO.terminate(new Exception(error.toString))
}
for {
r1 <- wire[GameAppResource].resource.evalMap {
case Right(gameApp -> gameAppFib) =>
eval(tickEventBus, gameApp, gameAppFib).attempt
case Left(error) => IO.terminate(new Exception(error.toString))
}
dirWatcher <- Resource.liftF(
MonixDirectoryWatcher(
os.pwd / "assets" / "scripts"
).hideErrors
)
sc <- scriptSystemResource
obs = dirWatcher.doOnNext {
case ModifyEvent(file, count) =>
sc.request(ScriptCompiler.GetScript(os.Path(file.path), _, true))(
15.seconds
).toTask
.void
case _ => monix.eval.Task.unit
}
_ <- Resource.make(obs.completedL.toIO.hideErrors.start)(_.cancel)
// _ <-
// dirWatcher
// .doOnNextF(event =>
// Coeval(pprint.log(show"Received file event $event")).void
// )
// .completedL
// .executeOn(schedulers.io.value)
// .startAndForget
// .toIO
// .hideErrors
} yield r1
val program = for {
// scriptSystem <- scriptSystemInit
@ -185,7 +235,8 @@ class MainAppDelegate(
viewPort: ViewPort,
enqueueR: Function1[() => Unit, Unit],
rootNode: RootNode,
schedulers: Schedulers
schedulers: Schedulers,
jfxUI: JavaFxUI
)(implicit
spawnProtocol: ActorRef[SpawnProtocol.Command],
timeout: Timeout,
@ -203,7 +254,7 @@ class MainAppDelegate(
os.rel / "assets" / "town.zip",
classOf[ZipLocator]
)
_ <- loggerL.infoU("test")
// _ <- Task(consoleStream.println("text"))
level <- DefaultGameLevel(assetManager, viewPort)
_ <- level.addToGame(rootNode, physicsSpace)
@ -231,45 +282,44 @@ class MainAppDelegate(
_ <-
damageObs
.doOnNextF(event =>
(loggerL.debug(s"Received Damage Event $event") >>
(loggerL.debug(show"Received Damage Event $event") >>
(if (event.victimName === "PlayerNode")
// playerActor !! PlayerActorSupervisor.TakeDamage(event.amount)
playerActor.askL(
PlayerActorSupervisor.TakeDamage2(event.amount, _)
)
playerActor
.askL(PlayerActorSupervisor.TakeDamage(event.amount, _))
.onErrorHandle { case ex: TimeoutException => () }
else IO.unit)).toTask
)
.completedL
.toIO
.hideErrors
.startAndForget
_ <-
Observable
.interval(1.second)
.doOnNextF(_ =>
playerActor
.askL(PlayerActorSupervisor.GetStatus)
.flatMap(s => loggerL.debug(s"Player actor status: $s"))
// _ <-
// Observable
// .interval(1.second)
// .doOnNextF(_ =>
// playerActor
// .askL(PlayerActorSupervisor.GetStatus)
// .flatMap(s => loggerL.debug(show"Player actor status: $s"))
// .flatMap(s =>
// if (s == Status.Alive)
// playerActor
// .askL(PlayerActorSupervisor.CurrentStats )
// .flatMap(s => loggerL.debug(s"Got state $s"))
// else IO.unit
// )
.toTask
)
// .doOnNextF(_ =>
// playerActor
// .askL(PlayerActorSupervisor.GetStatus )
// .flatMap(s => loggerL.debug(s"Player actor status: $s"))
// .toTask
// )
.completedL
.toIO
.hideErrors
.startAndForget
// // .flatMap(s =>
// // if (s == Status.Alive)
// // playerActor
// // .askL(PlayerActorSupervisor.CurrentStats )
// // .flatMap(s => loggerL.debug(show"Got state $s"))
// // else IO.unit
// // )
// .toTask
// )
// // .doOnNextF(_ =>
// // playerActor
// // .askL(PlayerActorSupervisor.GetStatus )
// // .flatMap(s => loggerL.debug(show"Player actor status: $s"))
// // .toTask
// // )
// .completedL
// .toIO
// .hideErrors
// .startAndForget
_ <-
physicsSpace.collisionObservable
// .filter(event =>
@ -282,7 +332,7 @@ class MainAppDelegate(
// )
// .doOnNextF(event =>
// loggerL
// .debug(s"$event ${event.appliedImpulse()}")
// .debug(show"$event ${event.appliedImpulse()}")
// .toTask
// )
.filter(_.nodeA.map(_.getName =!= "main-scene_node").getOrElse(false))
@ -295,7 +345,7 @@ class MainAppDelegate(
} yield if (nodeB.getName === "John") nodeA else nodeB)
_ <- Coeval(
victim.foreach { v =>
pprint.log(s"emitted event ${v.getName}")
pprint.log(show"emitted event ${v.getName}")
mainEventBus ! EventBus.Publish(
DamageEvent(
"John",
@ -322,6 +372,63 @@ class MainAppDelegate(
// )
// .executeOn(appScheduler)
// .startAndForget
statsObs <-
playerActor
.askL(PlayerActorSupervisor.GetStatsObservable(_))
.onErrorHandleWith(TimeoutError.from)
playerHud <-
UIO
.deferAction(implicit s =>
UIO(new VBox {
implicit val c = CompositeCancelable()
spacing = 10
style = """-fx-background-color: rgba(0,0,0,0.7);"""
children = List(
new HBox {
spacing = 5
children = List(
new Label("Health") { textFill = Color.White },
new Label("100") {
text == "hello"
text <-- statsObs
.doOnNextF(i => loggerL.debug(show"Received stats: $i"))
.map(_.hp.toInt.toString)
textFill = Color.White
},
new JFXProgressBar {
progress = 100
minHeight = 10
progress <-- statsObs
.map(_.hp.toInt.toDouble / 100)
}
)
},
new HBox {
spacing = 5
children = List(
new Label("Stamina") {
textFill = Color.White
},
new Label("100") {
textFill = Color.White
text <-- statsObs
.doOnNextF(i => loggerL.debug(show"Received stats: $i"))
.map(_.stamina.toInt.toString)
},
new JFXProgressBar {
progress = 100
minHeight = 10
progress <-- statsObs
.map(_.stamina.toInt.toDouble / 100)
}
)
}
)
})
)
.executeOn(schedulers.fx.value)
_ <- UIO(jfxUI += playerHud)
} yield ()
def createPlayerController(
@ -369,70 +476,34 @@ class MainAppDelegate(
.scan(new Quaternion) {
case (rotationBuf, action) =>
action.binding match {
// case PlayerCameraEvent.CameraLeft =>
case PlayerCameraInput.CameraRotateLeft =>
// me.Task {
val rot = rotationBuf
.fromAngleAxis(1 * FastMath.DEG_TO_RAD, Vector3f.UNIT_Y)
cameraPivotNode.rotate(rot)
rotationBuf
// }
// case PlayerCameraEvent.CameraRight =>
case PlayerCameraInput.CameraRotateRight =>
// me.Task {
val rot = rotationBuf
.fromAngleAxis(-1 * FastMath.DEG_TO_RAD, Vector3f.UNIT_Y)
cameraPivotNode.rotate(rot)
rotationBuf
// }
// case PlayerCameraEvent.CameraMovedUp =>
case PlayerCameraInput.CameraRotateUp =>
// me.Task {
val rot = rotationBuf
.fromAngleAxis(-1 * FastMath.DEG_TO_RAD, Vector3f.UNIT_X)
cameraPivotNode.rotate(rot)
rotationBuf
// }
// case PlayerCameraEvent.CameraMovedDown =>
case PlayerCameraInput.CameraRotateDown =>
// me.Task {
val rot = rotationBuf
.fromAngleAxis(1 * FastMath.DEG_TO_RAD, Vector3f.UNIT_X)
cameraPivotNode.rotate(rot)
rotationBuf
// }
}
}
.completedL
.toIO
.hideErrors
.startAndForget
// _ <-
// Observable
// .interval(10.millis)
// .doOnNextF(_ =>
// Coeval {
// val location = playerNode.getWorldTranslation()
// cameraPivotNode.setLocalTranslation(location)
// }
// )
// .completedL
// .toIO
// .hideErrors
// .startAndForget
sched <- UIO.pure(schedulers.async)
playerActor <- wire[PlayerController.Props].create
obs <-
playerActor
.askL(PlayerActorSupervisor.GetStatsObservable2)
.onErrorHandleWith(TimeoutError.from)
_ <-
obs
.doOnNext(s => loggerL.debug(s"Got state $s").toTask)
.completedL
.toIO
.hideErrors
.startAndForget
} yield playerActor
}
@ -456,7 +527,7 @@ class MainAppDelegate(
npcName,
initialPos
).behavior,
actorName = Some(s"${npcName}-npcActorSupervisor")
actorName = Some(show"${npcName}-npcActorSupervisor")
)
(for {

8
src/main/scala/wow/doge/mygame/actor/GameActorSystem.scala

@ -16,11 +16,11 @@ import wow.doge.mygame.implicits._
object GameActorSystem {
sealed trait Command
case class GetSpawnProtocol(
final case class GetSpawnProtocol(
replyTo: ActorRef[ActorRef[SpawnProtocol.Command]]
) extends Command
class Props() {
class Props {
def create =
Behaviors.setup[Command] { ctx =>
val systemSpawnProtocol = ctx.spawnN(SpawnProtocol())
@ -44,9 +44,9 @@ class GameActorSystem(
// object EventBusSupervisor {
// sealed trait Command
// case class GetMainEventBus(replyTo: ActorRef[GameEventBus[Event]])
// final case class GetMainEventBus(replyTo: ActorRef[GameEventBus[Event]])
// extends Command
// case class GetEventBus[T](replyTo: ActorRef[GameEventBus[T]])(implicit
// final case class GetEventBus[T](replyTo: ActorRef[GameEventBus[T]])(implicit
// classTag: ClassTag[T]
// ) extends Command {
// def ct = classTag

1
src/main/scala/wow/doge/mygame/executors/GUIExecutor.scala

@ -47,6 +47,7 @@ object JMEExecutorService extends GUIExecutorService {
}
object JMERunner {
@SuppressWarnings(Array("org.wartremover.warts.Null"))
var runner: Application = null
}

8
src/main/scala/wow/doge/mygame/executors/Schedulers.scala

@ -5,7 +5,7 @@ import monix.execution.Scheduler
import monix.execution.UncaughtExceptionReporter
final case class Schedulers(
blockingIO: Schedulers.IoScheduler,
io: Schedulers.IoScheduler,
async: Schedulers.AsyncScheduler,
fx: Schedulers.FxScheduler
)
@ -32,8 +32,8 @@ object Schedulers {
)
)
case class AsyncScheduler(value: Scheduler)
case class IoScheduler(value: Scheduler)
case class FxScheduler(value: Scheduler)
final case class AsyncScheduler(value: Scheduler)
final case class IoScheduler(value: Scheduler)
final case class FxScheduler(value: Scheduler)
}

8
src/main/scala/wow/doge/mygame/game/GameApp.scala

@ -8,8 +8,10 @@ import akka.actor.typed.Props
import akka.actor.typed.SpawnProtocol
import akka.actor.typed.scaladsl.AskPattern._
import akka.util.Timeout
import cats.Show
import cats.effect.Resource
import cats.effect.concurrent.Deferred
import cats.syntax.show._
import com.jme3.bullet.BulletAppState
import com.jme3.input.InputManager
import com.jme3.scene.Node
@ -177,6 +179,10 @@ object SpawnSystem {
result: Deferred[Task, Result]
)
object SpawnRequestWrapper {
implicit val show = Show.fromToString[SpawnRequestWrapper]
}
def apply(logger: Logger[Task]) =
for {
spawnChannel <- ConcurrentChannel[Task].of[Complete, SpawnRequestWrapper]
@ -213,7 +219,7 @@ class SpawnSystem(
for {
_ <-
logger
.debug(s"Received spawn request $message")
.debug(show"Received spawn request $message")
_ <- handleSpawn(message)
} yield receive(consumer)
case Left(r) =>

7
src/main/scala/wow/doge/mygame/game/GameAppActor.scala

@ -22,12 +22,13 @@ object GameAppActor {
case object Start extends Command
case object Pause extends Command
case object Ping extends Command
case class Stop(stopSignal: ActorRef[CancelableFuture[Unit]]) extends Command
case class GetSpawnProtocol(
final case class Stop(stopSignal: ActorRef[CancelableFuture[Unit]])
extends Command
final case class GetSpawnProtocol(
replyTo: ActorRef[ActorRef[SpawnProtocol.Command]]
) extends Command
case class Props(tickEventBus: GameEventBus[TickEvent]) {
final case class Props(tickEventBus: GameEventBus[TickEvent]) {
def behavior =
Behaviors.setup[Command] { ctx =>
ctx.log.infoP("Hello from GameAppActor")

30
src/main/scala/wow/doge/mygame/game/GameModule.scala

@ -1,30 +0,0 @@
package wow.doge.mygame.game
// class GameAppResource(
// logger: Logger[Task],
// jmeScheduler: Scheduler,
// schedulers: Schedulers
// ) {
// def get: Resource[Task, GameApp] =
// Resource.make(
// for {
// _ <- logger.info("Creating game app")
// appExt <- Task(new SimpleAppExt(schedulers, new StatsAppState()))
// app <- Task {
// val settings = new AppSettings(true)
// settings.setVSync(true)
// /**
// * disables the launcher
// * We'll be making our own launcher anyway
// */
// appExt.setShowSettings(false)
// appExt.setSettings(settings)
// // JMERunner.runner = app
// new GameApp(logger, appExt)
// }
// } yield (app)
// )(_ => logger.info("Closing game app"))
// }

4
src/main/scala/wow/doge/mygame/game/SimpleAppExt.scala

@ -1,7 +1,6 @@
package wow.doge.mygame.game
import scala.collection.immutable.Queue
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import com.jme3.app.SimpleApplication
@ -28,6 +27,7 @@ class SimpleAppExt(
private val startSignal: CancelablePromise[Unit] = CancelablePromise()
private val terminationSignal: CancelablePromise[Unit] = CancelablePromise()
private implicit val ec = schedulers.async.value
var cancelToken: Option[() => Future[Unit]] = None
@ -87,7 +87,7 @@ class SimpleAppExt(
val scheduler = Scheduler(JMEExecutorService)
}
object SimpleAppExt {
private[game] case class MyTask[T](p: CancelablePromise[T], cb: () => T)
private[game] final case class MyTask[T](p: CancelablePromise[T], cb: () => T)
}
// val ship = ed.createEntity()

2
src/main/scala/wow/doge/mygame/game/TestActor.scala

@ -40,7 +40,7 @@ object TestActor {
// ctx.log.debugP(value.toString())
// Done
// case Failure(exception) =>
// ctx.log.debugP(s"Received Error ${exception.getMessage()}")
// ctx.log.debugP(show"Received Error ${exception.getMessage()}")
// Done
// }
}

69
src/main/scala/wow/doge/mygame/game/appstates/MyBaseState.scala

@ -1,69 +0,0 @@
package wow.doge.mygame.state
import com.jme3.app.Application
import com.jme3.app.SimpleApplication
import com.jme3.app.state.AppState
import com.jme3.app.state.BaseAppState
import com.jme3.scene.Node
import com.jme3.scene.Spatial
import com.simsilica.es.EntityData
import com.simsilica.es.base.DefaultEntityData
trait MyBaseState extends BaseAppState {
var simpleApp: SimpleApplication = null
implicit val entityData: EntityData = new DefaultEntityData()
def stateManager = simpleApp.getStateManager
def guiNode = simpleApp.getGuiNode
def rootNode = simpleApp.getRootNode
def assetManager = simpleApp.getAssetManager
def inputManager = simpleApp.getInputManager
def cam = simpleApp.getCamera
override protected final def initialize(app: Application): Unit = {
simpleApp = app.asInstanceOf[SimpleApplication]
init()
// stateManager.getState(classOf[FlyCamAppState]).getCamera().setMoveSpeed(100)
}
protected def init(): Unit
protected def stop(): Unit
override protected def cleanup(app: Application): Unit = {
entityData.close()
// stop()
}
protected def getChildOption(parent: Node, id: String) =
Option(parent.getChild(id))
protected def getOrCreateSpatial(parent: Node, id: String): Spatial =
Option(parent.getChild(id)).getOrElse {
val node: Spatial = new Node(id)
parent.attachChild(node)
node
}
protected def enableStates(classes: Class[_ <: AppState]*) =
setEnabledToStates(true, classes: _*)
protected def disableStates(classes: Class[_ <: AppState]*) =
setEnabledToStates(false, classes: _*)
protected def setEnabledToStates(
enabled: Boolean,
classes: Class[_ <: AppState]*
) = {
for (clazz <- classes) {
val st = stateManager.getState(clazz)
if (st != null) st.setEnabled(enabled)
}
}
protected def removeStates(classes: Class[_ <: AppState]*) = {
for (clazz <- classes) {
val st = stateManager.getState(clazz)
if (st != null) stateManager.detach(st)
}
}
}

207
src/main/scala/wow/doge/mygame/game/appstates/ScriptingEngineState.scala

@ -1,207 +0,0 @@
package wow.doge.mygame.state
import javax.script.ScriptEngine
import akka.actor.typed.ActorRef
import akka.actor.typed.Behavior
import akka.actor.typed.SpawnProtocol
import akka.actor.typed.scaladsl.AbstractBehavior
import akka.actor.typed.scaladsl.ActorContext
import akka.actor.typed.scaladsl.Behaviors
import ammonite.Main
import ammonite.main.Defaults
import ammonite.runtime.Storage.Folder
import ammonite.util.Res.Success
import com.jme3.app.state.AppState
class ScriptingEngineState(
sse: ScalaScriptingEngine,
kse: KotlinScriptingEngine
) extends MyBaseState {
// implicit val actorSystem =
// ActorSystem.create(MyActorSystem(), "rootActor")
// implicit val timeout: Timeout = Timeout(3.seconds)
// val scalaScriptActor: Future[ActorRef[ScalaScriptBehavior.Command]] =
// actorSystem.ask(
// SpawnProtocol.Spawn(
// ScalaScriptBehavior(sse.runner),
// name = "ScalaScriptCompilerActor",
// Props.empty,
// _
// )
// )
override def stop(): Unit = {}
// override protected def cleanup(app: Application): Unit = {
// // actorSystem.terminate()
// }
// override protected def initialize(app: Application): Unit = {
// super.initialize(app)
// }
override def init() = {
// Future {
// while (true) {
// // super.update(tpf)
// val (res, k) = sse.runner.runScript(
// // os.Path(getClass().getResource("/hello.sc").getPath),
// os.pwd / "src" / "main" / "resources" / "hello.sc",
// Seq.empty
// // Seq(("start", None))
// // Scripts.groupArgs(List(""))
// )
// val ms = res.map(_.asInstanceOf[GameScript])
// ms.map(_.start())
// val res2 = kse.engine.eval(
// os.read(os.pwd / "src" / "main" / "resources" / "hello.main.kts")
// )
// // val res2 = engine.eval(getClass().getResource("/hello.main.kts").getPath)
// // val invoker = engine.asInstanceOf[Invocable]
// // val scr = invoker.getInterface(res2, classOf[GameScript])
// val scr = res2.asInstanceOf[GameScript]
// scr.start()
// Thread.sleep(2000)
// }
// }
// Future {
// sse.runner
// .runScript(
// os.pwd / "src" / "main" / "resources" / "hello2.sc",
// Seq.empty
// )
// ._1
// .map(_.asInstanceOf[MyBaseState])
// .map(s => stateManager.attach(s))
// ()
// }
// val res = scalaScriptActor
// .map(
// _.ask(ref =>
// ScalaScriptBehavior.Compile(
// ref,
// os.pwd / "src" / "main" / "resources" / "hello2.sc"
// // os.Path(getClass().getResource("/hello2.sc").getPath)
// )
// )(Timeout(10.seconds), actorSystem.scheduler)
// )
// .flatten
// res.foreach(_ match {
// case AppStateResult(state) => {
// stateManager.attach(state)
// }
// case wow.doge.mygame.state.ScalaScriptBehavior.Error(reason) =>
// println("error")
// })
}
override def update(tpf: Float): Unit = {}
override protected def onEnable(): Unit = {}
override protected def onDisable(): Unit = {}
}
object MyActorSystem {
def apply(): Behavior[SpawnProtocol.Command] =
Behaviors.setup { context =>
// Start initial tasks
// context.spawn(...)
SpawnProtocol()
}
}
class ScalaScriptingEngine(
val runner: Main = ammonite
.Main(
// predefCode = """
// import coursierapi.MavenRepository
// interp.repositories.update(
// interp.repositories() ::: List(
// MavenRepository.of("file://home/rohan/.m2/repository")
// )
// )
// @
// """,
defaultPredef = false,
storageBackend = new Folder(Defaults.ammoniteHome, isRepl = false)
)
) {}
class KotlinScriptingEngine(val engine: ScriptEngine) {
// val manager = new ScriptEngineManager()
// val engine = manager.getEngineByExtension("main.kts")
}
object ScalaScriptBehavior {
sealed trait Result
final case class AppStateResult(state: AppState) extends Result
final case class Error(reason: String) extends Result
sealed trait Command
final case class Compile(sender: ActorRef[Result], path: os.Path)
extends Command
// final case class CompileScripts(sender: ActorRef[Result], paths: os.Path*)
// extends Command
def apply(
runner: Main = ammonite
.Main(
storageBackend = new Folder(
// os.pwd / "target"
Defaults.ammoniteHome,
isRepl = false
)
)
) =
Behaviors.setup(ctx => new ScalaScriptActor(runner, ctx))
private class ScalaScriptActor(
val runner: Main,
context: ActorContext[Command]
) extends AbstractBehavior[Command](context) {
override def onMessage(msg: Command): Behavior[Command] = {
msg match {
case Compile(sender, path) =>
context.log.debug(s"Received $path")
val res = getScript(path)
println(res)
sender ! res
Behaviors.same
// case CompileScripts(sender, paths) =>
}
}
def getScript(path: os.Path): Result = {
runner
.runScript(
path,
Seq.empty
)
._1 match {
case ammonite.util.Res.Exception(t, msg) => Error(msg)
case Success(obj) =>
obj match {
case s: MyBaseState => AppStateResult(s)
case _ => Error("Unknown script type")
// AppStateResult(s.asInstanceOf[AppState])
}
case _ => Error("Failed to run script")
}
}
}
}

71
src/main/scala/wow/doge/mygame/game/appstates/TestAppState.scala

@ -1,71 +0,0 @@
package wow.doge.mygame.state
import com.jme3.asset.AssetManager
import com.jme3.material.Material
import com.jme3.math.ColorRGBA
import com.jme3.math.Vector3f
import com.jme3.scene.Geometry
import com.jme3.scene.shape.Box
import wow.doge.mygame.components.TestComponent
import wow.doge.mygame.implicits._
class TestAppState(
// private var _entity: Option[EntityData] = Some(new DefaultEntityData())
) extends MyBaseState {
var geom: Option[Geometry] = None
// def entity = _entity
// override def initialize(app: Application): Unit = {
// super.initialize(app)
// }
override def init() = {
entityData
.createEntity()
.withComponents(TestComponent())
// entityData.setComponents(x, TestComponent())
val es = entityData.getEntities(classOf[TestComponent])
println(es)
val b = new Box(1, 1, 1)
geom = Some(new Geometry("Box", b))
val mat = MyMaterial(
assetManager = assetManager,
path = os.rel / "Common" / "MatDefs" / "Misc" / "Unshaded.j3md"
)
geom.foreach(e => {
e.setMaterial(mat)
rootNode.attachChild(e)
})
}
override def update(tpf: Float) = {
geom.foreach(_.rotate(0, 0.5f * tpf, 0))
geom.foreach(_.move(new Vector3f(0, 1 * tpf, 0)))
}
// override def cleanup(app: Application): Unit = {
// // _entity.map(_.close())
// // _entity = None
// }
override def onEnable(): Unit = {}
override def onDisable(): Unit = {}
override def stop(): Unit = {}
}
object MyMaterial {
def apply(
color: String = "Color",
colorType: com.jme3.math.ColorRGBA = ColorRGBA.Blue,
assetManager: AssetManager,
path: os.RelPath
): Material = {
val mat =
new Material(assetManager, path.toString())
mat.setColor(color, colorType)
mat
}
}

6
src/main/scala/wow/doge/mygame/game/controls/CameraMovementControls.scala

@ -2,6 +2,7 @@ package wow.doge.mygame.game.controls
import scala.concurrent.Future
import cats.syntax.eq._
import com.jme3.math.FastMath
import com.jme3.math.Quaternion
import com.jme3.math.Vector3f
@ -26,6 +27,7 @@ import wow.doge.mygame.game.subsystems.input.PlayerCameraInput
* @param rotateFn
* @param s
*/
@SuppressWarnings(Array("org.wartremover.warts.Null"))
class CameraMovementControl(
rotationBuf: Quaternion,
obs: Observable[PlayerCameraInput],
@ -49,7 +51,7 @@ class CameraMovementControl(
}
override def controlUpdate(tpf: Float): Unit =
if (_event != null) {
if (_event =!= null) {
_event match {
case PlayerCameraInput.CameraRotateLeft =>
val rot = rotationBuf
@ -75,6 +77,8 @@ class CameraMovementControl(
x$1: RenderManager,
x$2: ViewPort
): Unit = {}
@SuppressWarnings(Array("org.wartremover.warts.Equals"))
override def setSpatial(spatial: Spatial): Unit = {
super.setSpatial(spatial)
if (this.spatial != null)

58
src/main/scala/wow/doge/mygame/game/entities/CharacterStats.scala

@ -4,14 +4,18 @@ import akka.actor.typed.ActorRef
import akka.actor.typed.Behavior
import akka.actor.typed.scaladsl.ActorContext
import akka.actor.typed.scaladsl.Behaviors
import cats.Show
import io.estatico.newtype.macros.newtype
import wow.doge.mygame.game.entities.CharacterStats.HealHealth
case class CharacterStats(hp: CharacterStats.Health, stamina: Int)
final case class CharacterStats(
hp: CharacterStats.Health,
stamina: CharacterStats.Stamina
)
object CharacterStats {
@newtype case class HealHealth(toInt: Int)
@newtype case class DamageHealth(toInt: Int)
@newtype case class Health(toInt: Int)
@newtype final case class HealHealth(toInt: Int)
@newtype final case class DamageHealth(toInt: Int)
@newtype final case class Health(toInt: Int)
object Health {
implicit class HealthOps(private val h: Health) extends AnyVal {
// def +(v: Int): Health = Health(h.toInt + v)
@ -22,9 +26,9 @@ object CharacterStats {
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)
@newtype final case class HealStamina(toInt: Int)
@newtype final case class DamageStamina(toInt: Int)
@newtype final case class Stamina(toInt: Int)
object Stamina {
implicit class StaminaOps(private val h: Stamina) extends AnyVal {
// def +(v: Int): Stamina = Stamina(h.toInt + v)
@ -53,18 +57,25 @@ object CharacterStats {
// }
// }
implicit val show = Show.fromToString[CharacterStats]
}
object StatsActor {
sealed trait Command
// case class TakeDamage(value: Int) extends Command
case class TakeDamageResult(
// final case class TakeDamage(value: Int) extends Command
final 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
final case class ConsumeStaminaResult(
value: CharacterStats.DamageStamina,
replyTo: ActorRef[(Boolean, CharacterStats)]
) extends Command
final case class HealResult(value: HealHealth) extends Command
final case class CurrentStats(replyTo: ActorRef[CharacterStats])
extends Command
class Props(
startingHealth: CharacterStats.Health,
@ -74,12 +85,12 @@ object StatsActor {
Behaviors.setup[Command] { ctx =>
new StatsActor(ctx, this)
.receive(
State(CharacterStats(startingHealth, startingStamina.toInt))
State(CharacterStats(startingHealth, startingStamina))
)
}
}
case class State(stats: CharacterStats)
final case class State(stats: CharacterStats)
}
class StatsActor(
ctx: ActorContext[StatsActor.Command],
@ -100,11 +111,24 @@ class StatsActor(
// 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))
val s = state.modify(_.stats.hp).setTo(Health(0))
replyTo ! true -> s.stats
s
} else {
val s = state.modify(_.stats.hp).using(_ - value)
replyTo ! false -> s.stats
s
}
receive(nextState)
case ConsumeStaminaResult(value, replyTo) =>
val nextState = if ((state.stats.stamina - value).toInt <= 0) {
val s = state.modify(_.stats.stamina).setTo(Stamina(0))
replyTo ! false -> s.stats
s
} else {
replyTo ! false -> state.stats
state.modify(_.stats.hp).using(_ - value)
val s = state.modify(_.stats.stamina).using(_ - value)
replyTo ! false -> s.stats
s
}
receive(nextState)
case HealResult(value) =>

25
src/main/scala/wow/doge/mygame/game/entities/NpcActorSupervisor.scala

@ -10,6 +10,7 @@ import akka.actor.typed.SupervisorStrategy
import akka.actor.typed.scaladsl.ActorContext
import akka.actor.typed.scaladsl.Behaviors
import akka.util.Timeout
import cats.syntax.eq._
import cats.syntax.show._
import monix.execution.CancelableFuture
import monix.execution.CancelablePromise
@ -39,8 +40,8 @@ object NpcActorSupervisor {
signal: CancelableFuture[NpcMovementActor.DoneMoving.type]
) extends Command
private case object DoneMoving extends Command
private case class LogError(err: Throwable) extends Command
private case class MovementFailed(err: Throwable) extends Command
private final case class LogError(err: Throwable) extends Command
private final case class MovementFailed(err: Throwable) extends Command
class Props(
val npcMovementActorBehavior: Behavior[NpcMovementActor.Command],
@ -86,7 +87,7 @@ class NpcActorSupervisor(
def idle(state: State): Behavior[NpcActorSupervisor.Command] =
Behaviors.setup { _ =>
ctx.log.debugP(s"npcActor-${props.npcName}: Entered Idle State")
ctx.log.debugP(show"npcActor-${props.npcName}: Entered Idle State")
Behaviors.receiveMessage[Command] {
case m @ Move(pos) =>
ctx.ask(
@ -113,7 +114,7 @@ class NpcActorSupervisor(
signal: CancelableFuture[NpcMovementActor.DoneMoving.type]
): Behavior[NpcActorSupervisor.Command] =
Behaviors.setup { _ =>
ctx.log.debugP(s"npcActor-${props.npcName}: Entered Moving State")
ctx.log.debugP(show"npcActor-${props.npcName}: Entered Moving State")
movementTimer ! GenericTimerActor.Start
ctx.pipeToSelf(signal) {
case Success(value) => DoneMoving
@ -150,7 +151,7 @@ class NpcActorSupervisor(
}
def logError(err: Throwable) =
ctx.log.errorP(s"npcActor-${props.npcName}: " + err.getMessage)
ctx.log.errorP(show"npcActor-${props.npcName}: " + err.getMessage)
}
object NpcMovementActor {
@ -158,10 +159,10 @@ object NpcMovementActor {
case object DoneMoving
sealed trait Command
case class AskPosition(replyTo: ActorRef[ImVector3f]) extends Command
final case class AskPosition(replyTo: ActorRef[ImVector3f]) extends Command
case object MovementTick extends Command
case object StopMoving extends Command
case class MoveTo(
final case class MoveTo(
target: ImVector3f,
doneSignal: ActorRef[CancelableFuture[DoneMoving.type]]
) extends Command
@ -212,7 +213,7 @@ class NpcMovementActor[T](
Behaviors.receiveMessagePartial {
case StopMoving =>
ctx.log.debugP(
show"npcActor-${props.npcName}: Position at Stop = " + location
show"npcActor-${props.npcName}: Position at Stop = $location"
)
props.enqueueR(() => cm.stop(props.movable))
receive(state)
@ -262,19 +263,19 @@ object NpcMovementActorNotUsed {
case event: EntityMovementEvent =>
event match {
case MovedLeft(name, pressed) =>
if (name == npcName)
if (name === npcName)
movementActor ! ImMovementActor.MoveLeft(pressed)
Behaviors.same
case MovedUp(name, pressed) =>
if (name == npcName)
if (name === npcName)
movementActor ! ImMovementActor.MoveUp(pressed)
Behaviors.same
case MovedRight(name, pressed) =>
if (name == npcName)
if (name === npcName)
movementActor ! ImMovementActor.MoveRight(pressed)
Behaviors.same
case MovedDown(name, pressed) =>
if (name == npcName)
if (name === npcName)
movementActor ! ImMovementActor.MoveDown(pressed)
Behaviors.same
}

87
src/main/scala/wow/doge/mygame/game/entities/player/PlayerActorSupervisor.scala

@ -12,7 +12,10 @@ import akka.actor.typed.SupervisorStrategy
import akka.actor.typed.scaladsl.ActorContext
import akka.actor.typed.scaladsl.Behaviors
import akka.util.Timeout
import cats.syntax.show._
import com.typesafe.scalalogging.Logger
import monix.eval.Coeval
import monix.execution.AsyncQueue
import monix.reactive.Observable
import monix.reactive.OverflowStrategy
import monix.reactive.subjects.ConcurrentSubject
@ -27,8 +30,6 @@ import wow.doge.mygame.subsystems.events.PlayerEvent
import wow.doge.mygame.subsystems.events.TickEvent
import wow.doge.mygame.subsystems.events.TickEvent.RenderTick
import wow.doge.mygame.subsystems.movement.ImMovementActor
import monix.eval.Coeval
import monix.execution.AsyncQueue
object PlayerActorSupervisor {
type Ref = ActorRef[PlayerActorSupervisor.Command]
@ -40,28 +41,29 @@ object PlayerActorSupervisor {
}
sealed trait Command
case class TakeDamage(value: CharacterStats.DamageHealth) extends Command
case class TakeDamage2(
final case class TakeDamage(
value: CharacterStats.DamageHealth,
replyTo: ActorRef[Unit]
) extends Command
case class Heal(value: CharacterStats.HealHealth) extends Command
case class CurrentStats(replyTo: ActorRef[CharacterStats]) extends Command
case class GetStatus(replyTo: ActorRef[Status]) extends Command
case class GetStatsObservable(replyTo: ActorRef[Observable[CharacterStats]])
extends Command
case class GetStatsObservable2(replyTo: ActorRef[Observable[CharacterStats]])
final case class ConsumeStamina(
value: CharacterStats.DamageStamina,