started doors

This commit is contained in:
FateJH 2017-09-25 21:54:59 -04:00
parent c85d7a65a2
commit fa633aa79d
10 changed files with 233 additions and 16 deletions

View file

@ -0,0 +1,77 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.doors
import akka.actor.{ActorContext, ActorRef, Props}
import net.psforever.objects.{PlanetSideGameObject, Player}
import net.psforever.packet.game.UseItemMessage
import net.psforever.types.PlanetSideEmpire
/**
* na
* @param ddef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
*/
class Door(ddef : DoorDefinition) extends PlanetSideGameObject {
/** Internal reference to the `Actor` for this `Door`, sets up by this `Door`. */
private var actor = ActorRef.noSender
def Actor(implicit context : ActorContext) : ActorRef = {
if(actor == ActorRef.noSender) {
actor = context.actorOf(Props(classOf[DoorControl], this), s"${ddef.Name}_${GUID.guid}")
}
actor
}
private var openState : Boolean = false
private var faction : PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL
private var hackedBy : Option[PlanetSideEmpire.Value] = None
def Open : Boolean = openState
def Faction : PlanetSideEmpire.Value = faction
def Convert(toFaction : PlanetSideEmpire.Value) : Unit = {
hackedBy = None
faction = toFaction
}
def Request(player : Player, msg : UseItemMessage) : Door.Exchange = {
if(!openState) {
if(faction == PlanetSideEmpire.NEUTRAL || player.Faction == faction) {
Door.OpenEvent()
}
else {
Door.NoEvent()
}
}
else {
Door.NoEvent()
}
}
def Definition : DoorDefinition = ddef
}
object Door {
final case class Request(player : Player, msg : UseItemMessage)
sealed trait Exchange
final case class DoorMessage(player : Player, msg : UseItemMessage, response : Exchange)
final case class OpenEvent() extends Exchange
final case class CloseEvent() extends Exchange
final case class NoEvent() extends Exchange
def apply(tdef : DoorDefinition) : Door = {
new Door(tdef)
}
import net.psforever.packet.game.PlanetSideGUID
def apply(guid : PlanetSideGUID, ddef : DoorDefinition) : Door = {
val obj = new Door(ddef)
obj.GUID = guid
obj
}
}

View file

@ -0,0 +1,40 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.doors
import akka.actor.{Actor, ActorRef, Cancellable}
import net.psforever.packet.game.PlanetSideGUID
import scala.collection.mutable.ListBuffer
class DoorCloseControl(implicit val environment : ActorRef) extends Actor {
import DoorCloseControl._
private var doorCloser : Cancellable = DefaultCloser
private var openDoors : List[DoorEntry] = Nil
def receive : Receive = {
case DoorIsOpen(guid, time) =>
if(openDoors.isEmpty) {
//doorCloser = context.system.scheduler.scheduleOnce(timeout, environment, Door.DoorMessage())
}
else {
openDoors = openDoors :+ DoorEntry(guid, time)
}
case _ => ;
}
}
object DoorCloseControl {
private final val timeout : Long = 5000L
private final val DefaultCloser : Cancellable = new Cancellable() {
override def cancel : Boolean = true
override def isCancelled : Boolean = true
}
private final case class DoorEntry(door_guid : PlanetSideGUID, opened_at_time : Long)
final case class DoorIsOpen(door_guid : PlanetSideGUID, opened_at_time : Long = System.nanoTime())
final case class CloseTheDoor(door_guid : PlanetSideGUID)
}

View file

@ -0,0 +1,27 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.doors
import akka.actor.{Actor, Cancellable}
/**
* An `Actor` that handles messages being dispatched to a specific `Door`.
* @param door the `Door` object being governed
*/
class DoorControl(door : Door) extends Actor {
private var doorCloser : Cancellable = DoorControl.DefaultCloser
def receive : Receive = {
case Door.Request(player, msg) =>
sender ! Door.DoorMessage(player, msg, door.Request(player, msg))
//doorCloser = context.system.scheduler.scheduleOnce(5000L, sender, Door.DoorMessage())
case _ =>
sender ! Door.NoEvent()
}
}
object DoorControl {
final val DefaultCloser : Cancellable = new Cancellable() {
override def cancel : Boolean = true
override def isCancelled : Boolean = true
}
}

View file

@ -0,0 +1,13 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.doors
import net.psforever.objects.definition.ObjectDefinition
/**
* The definition for any `door`.
* @param objectId the object's identifier number
*/
abstract class DoorDefinition(objectId : Int) extends ObjectDefinition(objectId) {
Name = "door"
}

View file

@ -0,0 +1,33 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.zones
import net.psforever.objects.doors.{Door, DoorDefinition}
/**
* Wrapper `Class` designed to instantiate a `Door` server object.
* @param ddef a `DoorDefinition` object, indicating the specific functionality of the resulting `Door`
* @param id the globally unique identifier to which this `Door` will be registered
*/
class DoorObjectBuilder(private val ddef : DoorDefinition, private val id : Int) extends ServerObjectBuilder[Door] {
import akka.actor.ActorContext
import net.psforever.objects.guid.NumberPoolHub
def Build(implicit context : ActorContext, guid : NumberPoolHub) : Door = {
val obj = Door(ddef)
guid.register(obj, id) //non-Actor GUID registration
obj.Actor //it's necessary to register beforehand because the Actor name utilizes the GUID
obj
}
}
object DoorObjectBuilder {
/**
* Overloaded constructor for a `DoorObjectBuilder`.
* @param ddef a `DoorDefinition` object
* @param id a globally unique identifier
* @return a `DoorObjectBuilder` object
*/
def apply(ddef : DoorDefinition, id : Int) : DoorObjectBuilder = {
new DoorObjectBuilder(ddef, id)
}
}

View file

@ -9,7 +9,7 @@ import net.psforever.objects.guid.NumberPoolHub
* Wrapper `Trait` designed to be extended to implement custom object instantiation logic at the `ZoneMap` level.
* @see `Zone.Init`
*/
trait ServerObjectBuilder {
trait ServerObjectBuilder[A <: PlanetSideGameObject] {
/**
* Instantiate and configure the given server object
* (at a later time compared to the construction of the builder class).<br>
@ -23,5 +23,5 @@ trait ServerObjectBuilder {
* defaults to `null`
* @return the object that was created and integrated into the `Zone`
*/
def Build(implicit context : ActorContext = null, guid : NumberPoolHub = null) : PlanetSideGameObject
def Build(implicit context : ActorContext = null, guid : NumberPoolHub = null) : A
}

View file

@ -8,7 +8,7 @@ import net.psforever.objects.terminals.{Terminal, TerminalDefinition}
* @param tdef a `TerminalDefinition` object, indicating the specific functionality of the resulting `Terminal`
* @param id the globally unique identifier to which this `Terminal` will be registered
*/
class TerminalObjectBuilder(private val tdef : TerminalDefinition, private val id : Int) extends ServerObjectBuilder {
class TerminalObjectBuilder(private val tdef : TerminalDefinition, private val id : Int) extends ServerObjectBuilder[Terminal] {
import akka.actor.ActorContext
import net.psforever.objects.guid.NumberPoolHub

View file

@ -21,7 +21,7 @@ package net.psforever.objects.zones
* `LoadMapMessage`
*/
class ZoneMap(private val name : String) {
private var localObjects : List[ServerObjectBuilder] = List()
private var localObjects : List[ServerObjectBuilder[_]] = List()
def Name : String = name
@ -29,7 +29,7 @@ class ZoneMap(private val name : String) {
* Append the builder for a server object to the list of builders known to this `ZoneMap`.
* @param obj the builder for a server object
*/
def LocalObject(obj : ServerObjectBuilder) : Unit = {
def LocalObject(obj : ServerObjectBuilder[_]) : Unit = {
localObjects = localObjects :+ obj
}
@ -37,7 +37,7 @@ class ZoneMap(private val name : String) {
* The list of all server object builder wrappers that have been assigned to this `ZoneMap`.
* @return the `List` of all `ServerObjectBuilders` known to this `ZoneMap`
*/
def LocalObjects : List[ServerObjectBuilder] = {
def LocalObjects : List[ServerObjectBuilder[_]] = {
localObjects
}
}