|
|
package wow.doge.mygame.game.entities
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 cats.implicits._ import com.jme3.asset.AssetManager import com.jme3.bullet.BulletAppState import com.jme3.bullet.PhysicsSpace import com.jme3.bullet.control.BetterCharacterControl import com.jme3.math.FastMath import com.jme3.renderer.Camera import com.jme3.scene.CameraNode import com.jme3.scene.Geometry import com.jme3.scene.Node import com.jme3.scene.control.CameraControl.ControlDirection import com.jme3.scene.shape.Box import com.softwaremill.macwire._ import com.softwaremill.tagging._ import io.odin.Logger import monix.bio.IO import monix.bio.Task import wow.doge.mygame.game.GameAppTags import wow.doge.mygame.game.SimpleAppExt import wow.doge.mygame.implicits._ import wow.doge.mygame.math.ImVector3f import wow.doge.mygame.state.MyMaterial import wow.doge.mygame.subsystems.events.EventBus import wow.doge.mygame.subsystems.events.EventsModule.GameEventBus import wow.doge.mygame.subsystems.events.PlayerCameraEvent import wow.doge.mygame.subsystems.events.PlayerMovementEvent import wow.doge.mygame.subsystems.events.TickEvent import wow.doge.mygame.subsystems.movement.ImMovementActor import wow.doge.mygame.utils.AkkaUtils
object PlayerControllerTags { sealed trait PlayerTag sealed trait PlayerCameraNode }
object PlayerController { sealed trait Error case class CouldNotCreatePlayerNode(reason: String) extends Error case class GenericError(reason: String) extends Error
class Props( enqueueR: Function1[() => Unit, Unit], rootNode: Node @@ GameAppTags.RootNode, loggerL: Logger[Task], physicsSpace: PhysicsSpace, initialPlayerPos: ImVector3f = ImVector3f.ZERO, spawnProtocol: ActorRef[SpawnProtocol.Command], playerMovementEventBus: ActorRef[ EventBus.Command[PlayerMovementEvent] ], playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]], playerPhysicsControl: BetterCharacterControl, appScheduler: monix.execution.Scheduler, playerNode: Node @@ PlayerControllerTags.PlayerTag, cameraNode: CameraNode @@ PlayerControllerTags.PlayerCameraNode, tickEventBus: GameEventBus[TickEvent] )(implicit timeout: Timeout, scheduler: Scheduler) { val create: IO[Error, Unit] = (for { playerActor <- AkkaUtils.spawnActorL( spawnProtocol, "playerActorSupervisor", new PlayerActorSupervisor.Props( playerMovementEventBus, playerCameraEventBus, tickEventBus, ImMovementActor .Props(enqueueR, playerPhysicsControl) .create, wireWith(PlayerCameraEventListener.apply _) ).create(playerPhysicsControl) ) _ <- IO { physicsSpace += playerNode physicsSpace += playerPhysicsControl } _ <- Task(rootNode += playerNode) } yield ()) .onErrorHandleWith(e => IO.raiseError(GenericError(e.getMessage()))) .executeOn(appScheduler) }
def apply( app: SimpleAppExt, modelPath: os.RelPath, cam: Camera )(assetManager: AssetManager, bulletAppState: BulletAppState) = { lazy val playerPos = ImVector3f.ZERO lazy val playerPhysicsControl = new BetterCharacterControl(1.5f, 6f, 1f) .withJumpForce(ImVector3f(0, 5f, 0)) lazy val playerNode = new Node("PlayerNode") .withChildren( assetManager .loadModel(modelPath) .asInstanceOf[Node] .withRotate(0, FastMath.PI, 0) ) .withLocalTranslation(playerPos) .withControl(playerPhysicsControl)
{ bulletAppState.physicsSpace += playerNode bulletAppState.physicsSpace += playerPhysicsControl }
{ app.rootNode += playerNode }
playerPhysicsControl }
object Defaults { def defaultMesh = { val b = Box(1, 1, 1) val geom = Geometry("playerGeom", b) geom } def defaultTexture(assetManager: AssetManager) = MyMaterial( assetManager = assetManager, path = os.rel / "Common" / "MatDefs" / "Misc" / "Unshaded.j3md" )
def defaultCamerNode(cam: Camera, playerPos: ImVector3f) = new CameraNode("CameraNode", cam) .withControlDir(ControlDirection.SpatialToCamera) .withLocalTranslation(ImVector3f(0, 1.5f, 10)) .withLookAt(playerPos, ImVector3f.UNIT_Y)
def defaultPlayerNode( assetManager: AssetManager, modelPath: os.RelPath, playerPos: ImVector3f, camNode: CameraNode, playerPhysicsControl: BetterCharacterControl ) = Either .catchNonFatal( Node("PlayerNode") .withChildren( camNode, assetManager .loadModel(modelPath) .asInstanceOf[Node] .withRotate(0, FastMath.PI, 0) ) .withLocalTranslation(playerPos) .withControl(playerPhysicsControl) ) .map(_.taggedWith[PlayerControllerTags.PlayerTag]) .leftMap(e => PlayerController.CouldNotCreatePlayerNode(e.getMessage()))
def defaultNpcNode( assetManager: AssetManager, // modelPath: os.RelPath,
initialPos: ImVector3f, npcPhysicsControl: BetterCharacterControl, npcName: String ) = Either .catchNonFatal( Node(npcName) .withChildren( // assetManager
// .loadModel(modelPath)
// .asInstanceOf[Node]
// .withRotate(0, FastMath.PI, 0)
defaultMesh.withMaterial(defaultTexture(assetManager)) ) .withLocalTranslation(initialPos) .withControl(npcPhysicsControl) ) // .map(_.taggedWith[PlayerControllerTags.PlayerTag])
// .leftMap(e => PlayerController.CouldNotCreatePlayerNode(e.getMessage()))
def defaultPlayerPhysicsControl = new BetterCharacterControl(1.5f, 6f, 1f) .withJumpForce(ImVector3f(0, 5f, 0)) } }
object Methods { def spawnMovementActor( enqueueR: Function1[() => Unit, Unit], spawnProtocol: ActorRef[SpawnProtocol.Command], movable: BetterCharacterControl @@ PlayerControllerTags.PlayerTag, playerMovementEventBus: ActorRef[ EventBus.Command[PlayerMovementEvent] ], loggerL: Logger[Task] )(implicit timeout: Timeout, scheduler: Scheduler) = spawnProtocol.askL[ActorRef[ImMovementActor.Command]]( SpawnProtocol.Spawn( ImMovementActor.Props(enqueueR, movable).create, "imMovementActor", Props.empty, _ ) ) // def spawnPlayerActor(
// app: GameApp,
// spawnProtocol: ActorRef[SpawnProtocol.Command],
// movable: BetterCharacterControl @@ Player,
// playerMovementEventBus: ActorRef[
// EventBus.Command[PlayerMovementEvent]
// ]
// )(implicit timeout: Timeout, scheduler: Scheduler) =
// spawnProtocol.askL[ActorRef[PlayerActorSupervisor.Command]](
// SpawnProtocol.Spawn(
// new PlayerActorSupervisor.Props(
// app,
// movable,
// playerMovementEventBus
// ).create,
// "playerActor",
// Props.empty,
// _
// )
// )
}
// camNode <- IO(
// _cameraNode.getOrElse(defaultCamerNode(camera, initialPlayerPos))
// )
// playerPhysicsControl <- IO(
// _playerPhysicsControl
// .getOrElse(defaultPlayerPhysicsControl)
// .taggedWith[PlayerTag]
// )
// playerNode <- IO.fromEither(
// _playerNode.fold(
// defaultPlayerNode(
// assetManager,
// modelPath,
// initialPlayerPos,
// camNode,
// playerPhysicsControl
// )
// )(_.asRight)
// )
|