package wow.doge.mygame import com.jme3.app.SimpleApplication import com.jme3.app.state.AppStateManager import scala.reflect.ClassTag import com.jme3.app.state.AppState import com.jme3.scene.Node import com.jme3.scene.Spatial import com.simsilica.es.EntityData import com.simsilica.es.EntityComponent import com.simsilica.es.EntityId import akka.actor.typed.ActorRef import akka.util.Timeout import akka.actor.typed.Scheduler import monix.eval.Task import com.jme3.input.InputManager import com.jme3.input.controls.Trigger import com.jme3.input.controls.InputListener import com.jme3.math.Vector3f import wow.doge.mygame.math.ImVector3f import com.jme3.scene.Geometry import wow.doge.mygame.state.CardinalDirection import wow.doge.mygame.state.CanMove import com.jme3.renderer.Camera package object implicits { implicit class StateManagerExt(val sm: AppStateManager) extends AnyVal { def state[S <: AppState]()(implicit c: ClassTag[S]): S = sm.getState(c.runtimeClass.asInstanceOf[Class[S]]) } implicit class SimpleApplicationExt(val sa: SimpleApplication) extends AnyVal { def stateManager() = sa.getStateManager() } implicit class NodeExt(val n: Node) extends AnyVal { def child(s: Spatial): Node = { n.attachChild(s) n } } implicit class EntityDataExt(val ed: EntityData) extends AnyVal { def query = new EntityQuery(ed) // def entities[T <: EntityComponent](entities: Seq[T]) } implicit class EntityExt(val e: EntityId) extends AnyVal { def withComponents(classes: EntityComponent*)(implicit ed: EntityData ): EntityId = { ed.setComponents(e, classes: _*) e } } implicit class ActorRefExt[Req](val a: ActorRef[Req]) extends AnyVal { import akka.actor.typed.scaladsl.AskPattern._ def askT[Res]( replyTo: ActorRef[Res] => Req )(implicit timeout: Timeout, scheduler: Scheduler): Task[Res] = { Task.deferFuture(a.ask(replyTo)(timeout, scheduler)) } } // def ?[Res](replyTo: ActorRef[Res] => Req)(implicit timeout: Timeout, scheduler: Scheduler): Future[Res] = { // ask(replyTo)(timeout, scheduler) // } implicit class InputManagerExt(val inputManager: InputManager) extends AnyVal { def withMapping(mapping: String, triggers: Trigger*): InputManager = { inputManager.addMapping(mapping, triggers: _*) inputManager } def withListener(listener: InputListener, mappings: String*) = { inputManager.addListener(listener, mappings: _*) inputManager } } implicit class Vector3fExt(val v: Vector3f) extends AnyVal { def +=(that: Vector3f) = v.addLocal(that) def *=(that: Vector3f) = v.multLocal(that) def -=(that: Vector3f) = v.subtractLocal(that) def /=(that: Vector3f) = v.divideLocal(that) def unary_- = v.negateLocal() def immutable = ImVector3f(v.x, v.y, v.z) } implicit class ImVector3fExt(val v: ImVector3f) extends AnyVal { def +(that: ImVector3f) = v.copy(v.x + that.x, v.y + that.y, v.z + that.z) def *(that: ImVector3f) = v.copy(v.x * that.x, v.y * that.y, v.z * that.z) def *(f: Float): ImVector3f = // v.copy(v.x * f, v.y * f, v.x * f) v * ImVector3f(f, f, f) def -(that: ImVector3f) = v.copy(v.x - that.x, v.y - that.y, v.z - that.z) def /(that: ImVector3f) = v.copy(v.x / that.x, v.y / that.y, v.z / that.z) def unary_- = v.copy(-v.x, -v.y, -v.z) // def unary_-(that: ImVector3f) = this.copy(this.x, this.y, this.z) def mutable = new Vector3f(v.x, v.y, v.z) } // implicit val implVector3fForVector3 = new Vector3[Vector3f] { // override def +(implicit v: Vector3f, that: com.jme3.math.Vector3f): Unit = // v += that // override def *(implicit v: Vector3f, that: Vector3f): Unit = v *= that // override def -(implicit v: Vector3f, that: Vector3f): Unit = v -= that // override def /(implicit v: Vector3f, that: Vector3f): Unit = v /= that // } // implicit val implImVector3fForVector3 = new Vector3[ImVector3f] { // override def +(implicit v: ImVector3f, that: ImVector3f): Unit = // v + that // override def *(implicit v: ImVector3f, that: ImVector3f): Unit = v * that // override def -(implicit v: ImVector3f, that: ImVector3f): Unit = v - that // override def /(implicit v: ImVector3f, that: ImVector3f): Unit = v / that // } // def test[T](v: T)(implicit ev: Vector3[T]) = { // import ev._ // ev.+ // } implicit val implCanMoveForGeom = new CanMove[Geometry] { override def getDirection( cam: Camera, cardinalDir: CardinalDirection ): ImVector3f = { val camDir = cam.getDirection().immutable * 0.6f val camLeft = cam.getLeft().immutable * 0.4f val zero = ImVector3f.ZERO val dir = cardinalDir val walkDir = { val mutWalkDir = new Vector3f() if (dir.left) { // ctx.log.trace("left") mutWalkDir += (zero + camLeft).mutable } if (dir.right) { // ctx.log.trace("right") mutWalkDir += (zero + -camLeft).mutable } if (dir.up) { // ctx.log.trace("up") mutWalkDir += (zero + camDir).mutable } if (dir.down) { // ctx.log.trace("down") mutWalkDir += (zero + -camDir).mutable } mutWalkDir.immutable } walkDir } override def move(geom: Geometry, direction: ImVector3f): Unit = { val v = geom.getLocalTranslation() geom.setLocalTranslation(v += direction.mutable) } } }