package wow.doge.mygame.game.subsystems.level import cats.effect.Resource import com.jme3.bullet.control.RigidBodyControl import com.jme3.light.AmbientLight import com.jme3.light.DirectionalLight import com.jme3.scene.Node import com.jme3.scene.Spatial import com.softwaremill.tagging._ import monix.bio.IO import monix.bio.UIO import wow.doge.mygame.AppError import wow.doge.mygame.game.GameAppTags import wow.doge.mygame.utils.wrappers.jme.AppNode2 import wow.doge.mygame.utils.wrappers.jme.CollisionShapeFactory import wow.doge.mygame.utils.wrappers.jme.PhysicsSpace class GameLevel( val model: Spatial, val physicsControl: RigidBodyControl, val ambientLight: AmbientLight, val directionalLight: DirectionalLight ) { def addToGame( rootNode: AppNode2 @@ GameAppTags.RootNode, physicsSpace: PhysicsSpace ) = (for { _ <- rootNode += model _ <- rootNode += ambientLight _ <- rootNode += directionalLight _ <- physicsSpace += model _ <- physicsSpace += physicsControl } yield ()).mapError(AppError.AppNodeError) def removeFromGame( rootNode: AppNode2 @@ GameAppTags.RootNode, physicsSpace: PhysicsSpace ) = for { _ <- rootNode -= model _ <- rootNode -= ambientLight _ <- rootNode -= directionalLight _ <- physicsSpace -= model _ <- physicsSpace -= physicsControl } yield () def resource( rootNode: AppNode2 @@ GameAppTags.RootNode, physicsSpace: PhysicsSpace ) = Resource.make(this.addToGame(rootNode, physicsSpace))(_ => this.removeFromGame(rootNode, physicsSpace) ) } object GameLevel { def apply( modelPath: os.RelPath, al: AmbientLight, dl: DirectionalLight )(implicit assetManager: wow.doge.mygame.utils.wrappers.jme.AssetManager ): IO[AppError, GameLevel] = for { sceneModel <- assetManager .loadModelAs[Node](modelPath) .mapError(AppError.AssetManagerError) sceneShape <- CollisionShapeFactory .createMeshShape(sceneModel) .mapError(AppError.CollisionShapeCreationFailed) landscape <- UIO(new RigidBodyControl(sceneShape, 0)) } yield new GameLevel( model = sceneModel, physicsControl = landscape, ambientLight = al, directionalLight = dl ) }