|
|
package wow.doge.mygame.game.entities
import akka.actor.typed.ActorRef import akka.actor.typed.Scheduler import akka.actor.typed.SpawnProtocol import akka.util.Timeout import com.jme3.bullet.BulletAppState 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.Spatial import com.jme3.scene.shape.Box import com.softwaremill.tagging._ import io.odin.Logger import monix.bio.IO import monix.bio.Task import wow.doge.mygame.AppError 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.subsystems.events.EventsModule.GameEventBus import wow.doge.mygame.subsystems.events.PlayerEvent import wow.doge.mygame.subsystems.events.TickEvent import wow.doge.mygame.subsystems.movement.ImMovementActor import wow.doge.mygame.utils.AkkaUtils import wow.doge.mygame.utils.wrappers.jme._ object PlayerControllerTags { sealed trait PlayerTag sealed trait PlayerCameraNode sealed trait PlayerCameraPivotNode }
object PlayerController { sealed trait Error case class CouldNotCreatePlayerModel(reason: AssetManager.Error) extends Error
class Props( enqueueR: Function1[() => Unit, Unit], rootNode: AppNode2 @@ GameAppTags.RootNode, loggerL: Logger[Task], // physicsSpace: com.jme3.bullet.PhysicsSpace,
physicsSpace: PhysicsSpace, initialPlayerPos: ImVector3f = ImVector3f.Zero, playerEventBus: GameEventBus[PlayerEvent], playerPhysicsControl: BetterCharacterControl, // appScheduler: monix.execution.Scheduler,
playerNode: Node @@ PlayerControllerTags.PlayerTag, cameraNode: CameraNode @@ PlayerControllerTags.PlayerCameraNode, cameraPivotNode: Node @@ PlayerControllerTags.PlayerCameraPivotNode, tickEventBus: GameEventBus[TickEvent], camera: Camera )(implicit spawnProtocol: ActorRef[SpawnProtocol.Command], timeout: Timeout, scheduler: Scheduler ) { val playerActorBehavior = { val movementActorBeh = new ImMovementActor.Props( enqueueR, camera ).behavior(playerPhysicsControl) val cameraActorBeh = new PlayerCameraActor.Props( cameraPivotNode, enqueueR, playerNode.getWorldTranslation _ ).behavior new PlayerActorSupervisor.Props( playerEventBus, tickEventBus, movementActorBeh, cameraActorBeh ).behavior } val create: IO[AppError, ActorRef[PlayerActorSupervisor.Command]] = (for { playerActor <- AkkaUtils.spawnActorL(playerActorBehavior, "playerActorSupervisor") _ <- (for { _ <- rootNode += playerNode _ <- physicsSpace += playerNode _ <- physicsSpace += playerPhysicsControl _ = cameraPivotNode += cameraNode _ <- rootNode += cameraPivotNode } yield ()).mapError(AppError.AppNodeError) } yield playerActor)
}
def apply( app: SimpleAppExt, modelPath: os.RelPath, cam: Camera )(assetManager: AssetManager, bulletAppState: BulletAppState) = { val playerPos = ImVector3f.Zero val playerPhysicsControl = new BetterCharacterControl(1.5f, 6f, 1f) .withJumpForce(ImVector3f(0, 5f, 0)) 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"
// )
// new CameraControl(cam) {
// override def controlUpdate(tpf: Float) = {
// this.getCamera().setRotation(spatial.getWorldRotation())
// cameraPivotNode.setLocalTranslation(
// playerNode.getWorldTranslation()
// )
// this.getCamera().setLocation(spatial.getWorldTranslation())
// }
// }
def defaultCamerNode( cam: Camera, // playerNode: Node,
// cameraPivotNode: Node,
playerPos: ImVector3f ) = new CameraNode("CameraNode", cam) // .withControlDir(ControlDirection.SpatialToCamera)
.withLocalTranslation(ImVector3f(0, 1.5f, 10)) .withLookAt(playerPos, ImVector3f.UnitY)
def defaultPlayerNode( playerPos: ImVector3f, playerModel: Node, // camNode: CameraNode,
playerPhysicsControl: BetterCharacterControl ) = Node("PlayerNode") .withChildren(playerModel) .withLocalTranslation(playerPos) .withControl(playerPhysicsControl) .taggedWith[PlayerControllerTags.PlayerTag]
def defaultNpcNode( // assetManager: AssetManager,
npcModel: Spatial, initialPos: ImVector3f, npcPhysicsControl: BetterCharacterControl, npcName: String ) = // Either
// .catchNonFatal(
Node(npcName) .withChildren( // defaultMesh.withMaterial(defaultTexture(assetManager))
npcModel ) .withLocalTranslation(initialPos) .withControl(npcPhysicsControl) // )
def defaultPlayerPhysicsControl = new BetterCharacterControl(1.5f, 6f, 1f) .withJumpForce(ImVector3f(0, 5f, 0)) } }
|