package wow.doge.mygame.game import scala.concurrent.duration._ import akka.actor.typed.ActorRef import akka.actor.typed.Props import akka.actor.typed.Scheduler import akka.actor.typed.SpawnProtocol import akka.util.Timeout import com.jme3.asset.plugins.ZipLocator import com.jme3.bullet.BulletAppState import com.jme3.bullet.control.BetterCharacterControl import com.softwaremill.macwire._ import com.softwaremill.tagging._ import io.odin.Logger import monix.bio.Task import monix.reactive.Consumer import wow.doge.mygame.events.EventBus import wow.doge.mygame.events.EventsModule import wow.doge.mygame.game.nodes.Player import wow.doge.mygame.game.nodes.PlayerController import wow.doge.mygame.game.subsystems.input.GameInputHandler import wow.doge.mygame.game.subsystems.level.DefaultGameLevel import wow.doge.mygame.implicits._ import wow.doge.mygame.subsystems.events.MovementEvent.PlayerMovementEvent import wow.doge.mygame.subsystems.movement.ImMovementActor import wow.doge.mygame.utils.IOUtils class GameSystemsInitializer()( override val spawnProtocol: ActorRef[SpawnProtocol.Command], override implicit val akkaScheduler: Scheduler, app: GameApp, loggerL: Logger[Task] ) extends EventsModule { override implicit val timeout: Timeout = Timeout(1.second) import GameSystemsInitializer._ def init = for { playerMovementEventBus <- playerMovementEventBusTask inputManager = app.inputManager bulletAppState = new BulletAppState() _ <- Task(app.stateManager.attach(bulletAppState)) _ <- Task( app.assetManager.registerLocator( // "src/main/resources/assets/town.zip", (os.rel / "src" / "main" / "resources" / "assets" / "town.zip"), classOf[ZipLocator] ) ) _ <- app.enqueueL(() => DefaultGameLevel(app, bulletAppState)) playerController <- app.enqueueL(() => PlayerController( app, modelPath = os.rel / "Models" / "Jaime" / "Jaime.j3o", cam = app.camera )(app.assetManager, bulletAppState) .taggedWith[Player] ) // _ <- loggerL.debug(playerNode.getName()) // _ <- Task(app.rootNode.attachChild(playerNode)) // playerMovementActor <- wireWith(spawnMovementActor _) // _ <- // IOUtils // .toIO( // app.tickObservable // .doOnNext { tpf => // IOUtils.toTask(playerMovementActor !! ImMovementActor.Tick(tpf)) // } // .completedL // .startAndForget // .onErrorRestart(3) // ) _ <- wire[GameInputHandler.Props].begin } yield () } object GameSystemsInitializer { def spawnMovementActor( app: GameApp, spawnProtocol: ActorRef[SpawnProtocol.Command], playerNode: BetterCharacterControl @@ Player, playerMovementEventBus: ActorRef[ EventBus.Command[PlayerMovementEvent] ], loggerL: Logger[Task] )(implicit timeout: Timeout, scheduler: Scheduler) = spawnProtocol.askL[ActorRef[ImMovementActor.Command]]( SpawnProtocol.Spawn( ImMovementActor.Props(app, playerNode, playerMovementEventBus).create, "imMovementActor", Props.empty, _ ) ) def playerMovementActorTickConsumer( playerMovementActor: ActorRef[ImMovementActor.Command] ) = Consumer .foreachTask[Float](tpf => IOUtils.toTask(playerMovementActor !! ImMovementActor.Tick(tpf)) ) // .mapTask() }