mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-07-13 15:34:42 +00:00
logic for door opening has been exorcised from SessionActor into DoorControl
This commit is contained in:
parent
ef0d18d214
commit
4a0805b698
5 changed files with 82 additions and 76 deletions
|
|
@ -542,9 +542,6 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
||||||
case ProgressEvent(delta, finishedAction, stepAction, tick) =>
|
case ProgressEvent(delta, finishedAction, stepAction, tick) =>
|
||||||
HandleProgressChange(delta, finishedAction, stepAction, tick)
|
HandleProgressChange(delta, finishedAction, stepAction, tick)
|
||||||
|
|
||||||
case Door.DoorMessage(tplayer, msg, order) =>
|
|
||||||
HandleDoorMessage(tplayer, msg, order)
|
|
||||||
|
|
||||||
case GalaxyServiceResponse(_, reply) =>
|
case GalaxyServiceResponse(_, reply) =>
|
||||||
reply match {
|
reply match {
|
||||||
case GalaxyResponse.HotSpotUpdate(zone_index, priority, hot_spot_info) =>
|
case GalaxyResponse.HotSpotUpdate(zone_index, priority, hot_spot_info) =>
|
||||||
|
|
@ -2189,36 +2186,6 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* na
|
|
||||||
* @param tplayer na
|
|
||||||
* @param msg na
|
|
||||||
* @param order na
|
|
||||||
*/
|
|
||||||
def HandleDoorMessage(tplayer: Player, msg: UseItemMessage, order: Door.Exchange): Unit = {
|
|
||||||
val door_guid = msg.object_guid
|
|
||||||
order match {
|
|
||||||
case Door.OpenEvent() =>
|
|
||||||
continent.GUID(door_guid) match {
|
|
||||||
case Some(door: Door) =>
|
|
||||||
sendResponse(GenericObjectStateMsg(door_guid, 16))
|
|
||||||
continent.LocalEvents ! LocalServiceMessage(
|
|
||||||
continent.id,
|
|
||||||
LocalAction.DoorOpens(tplayer.GUID, continent, door)
|
|
||||||
)
|
|
||||||
|
|
||||||
case _ =>
|
|
||||||
log.warn(s"door $door_guid wanted to be opened but could not be found")
|
|
||||||
}
|
|
||||||
|
|
||||||
case Door.CloseEvent() =>
|
|
||||||
sendResponse(GenericObjectStateMsg(door_guid, 17))
|
|
||||||
continent.LocalEvents ! LocalServiceMessage(continent.id, LocalAction.DoorCloses(tplayer.GUID, door_guid))
|
|
||||||
|
|
||||||
case Door.NoEvent() => ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* na
|
* na
|
||||||
* @param toChannel na
|
* @param toChannel na
|
||||||
|
|
@ -4477,29 +4444,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
||||||
}
|
}
|
||||||
ValidObject(object_guid) match {
|
ValidObject(object_guid) match {
|
||||||
case Some(door: Door) =>
|
case Some(door: Door) =>
|
||||||
if (
|
door.Actor ! CommonMessages.Use(player)
|
||||||
player.Faction == door.Faction || (continent.map.doorToLock.get(object_guid.guid) match {
|
|
||||||
case Some(lock_guid) =>
|
|
||||||
val lock = continent.GUID(lock_guid).get.asInstanceOf[IFFLock]
|
|
||||||
val owner = lock.Owner.asInstanceOf[Building]
|
|
||||||
val playerIsOnInside = Vector3.ScalarProjection(lock.Outwards, player.Position - door.Position) < 0f
|
|
||||||
|
|
||||||
// If an IFF lock exists and the IFF lock faction doesn't match the current player and one of the following conditions are met open the door:
|
|
||||||
// The player is on the inside of the door, determined by the lock orientation
|
|
||||||
// The lock is hacked
|
|
||||||
// A base is hacked
|
|
||||||
// A base is neutral
|
|
||||||
// todo: A base is out of power (generator down)
|
|
||||||
|
|
||||||
playerIsOnInside || lock.HackedBy.isDefined || owner.CaptureTerminalIsHacked || lock.Faction == PlanetSideEmpire.NEUTRAL
|
|
||||||
case None => !door.isOpen // If there's no linked IFF lock just open the door if it's closed.
|
|
||||||
})
|
|
||||||
) {
|
|
||||||
door.Actor ! Door.Use(player, msg)
|
|
||||||
} else if (door.isOpen) {
|
|
||||||
//the door is open globally ... except on our screen
|
|
||||||
sendResponse(GenericObjectStateMsg(object_guid, 16))
|
|
||||||
}
|
|
||||||
|
|
||||||
case Some(resourceSilo: ResourceSilo) =>
|
case Some(resourceSilo: ResourceSilo) =>
|
||||||
resourceSilo.Actor ! CommonMessages.Use(player)
|
resourceSilo.Actor ! CommonMessages.Use(player)
|
||||||
|
|
|
||||||
|
|
@ -25,16 +25,6 @@ class Door(private val ddef: DoorDefinition) extends Amenity {
|
||||||
Open
|
Open
|
||||||
}
|
}
|
||||||
|
|
||||||
def Use(player: Player, msg: UseItemMessage): Door.Exchange = {
|
|
||||||
if (openState.isEmpty) {
|
|
||||||
openState = Some(player)
|
|
||||||
Door.OpenEvent()
|
|
||||||
} else {
|
|
||||||
openState = None
|
|
||||||
Door.CloseEvent()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def Definition: DoorDefinition = ddef
|
def Definition: DoorDefinition = ddef
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,90 @@
|
||||||
// Copyright (c) 2017 PSForever
|
// Copyright (c) 2017 PSForever
|
||||||
package net.psforever.objects.serverobject.doors
|
package net.psforever.objects.serverobject.doors
|
||||||
|
|
||||||
import akka.actor.Actor
|
import net.psforever.objects.Player
|
||||||
|
import net.psforever.objects.serverobject.CommonMessages
|
||||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||||
|
import net.psforever.objects.serverobject.locks.IFFLock
|
||||||
|
import net.psforever.objects.serverobject.structures.{Building, PoweredAmenityControl}
|
||||||
|
import net.psforever.services.Service
|
||||||
|
import net.psforever.services.local.{LocalAction, LocalResponse, LocalServiceMessage, LocalServiceResponse}
|
||||||
|
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An `Actor` that handles messages being dispatched to a specific `Door`.
|
* An `Actor` that handles messages being dispatched to a specific `Door`.
|
||||||
* @param door the `Door` object being governed
|
* @param door the `Door` object being governed
|
||||||
*/
|
*/
|
||||||
class DoorControl(door: Door) extends Actor with FactionAffinityBehavior.Check {
|
class DoorControl(door: Door)
|
||||||
|
extends PoweredAmenityControl
|
||||||
|
with FactionAffinityBehavior.Check {
|
||||||
def FactionObject: FactionAffinity = door
|
def FactionObject: FactionAffinity = door
|
||||||
|
|
||||||
def receive: Receive =
|
val commonBehavior: Receive = checkBehavior
|
||||||
checkBehavior.orElse {
|
|
||||||
case Door.Use(player, msg) =>
|
|
||||||
sender() ! Door.DoorMessage(player, msg, door.Use(player, msg))
|
|
||||||
|
|
||||||
case _ => ;
|
def poweredStateLogic: Receive =
|
||||||
|
commonBehavior
|
||||||
|
.orElse {
|
||||||
|
case CommonMessages.Use(player, _) =>
|
||||||
|
val zone = door.Zone
|
||||||
|
val doorGUID = door.GUID
|
||||||
|
if (
|
||||||
|
player.Faction == door.Faction || (zone.GUID(zone.map.doorToLock.getOrElse(doorGUID.guid, 0)) match {
|
||||||
|
case Some(lock: IFFLock) =>
|
||||||
|
val owner = lock.Owner.asInstanceOf[Building]
|
||||||
|
val playerIsOnInside = Vector3.ScalarProjection(lock.Outwards, player.Position - door.Position) < 0f
|
||||||
|
/*
|
||||||
|
If an IFF lock exists and
|
||||||
|
the IFF lock faction doesn't match the current player and
|
||||||
|
one of the following conditions are met:
|
||||||
|
1. player is on the inside of the door (determined by the lock orientation)
|
||||||
|
2. lock is hacked
|
||||||
|
3. facility capture terminal has been hacked
|
||||||
|
4. base is neutral
|
||||||
|
... open the door.
|
||||||
|
*/
|
||||||
|
playerIsOnInside || lock.HackedBy.isDefined || owner.CaptureTerminalIsHacked || lock.Faction == PlanetSideEmpire.NEUTRAL
|
||||||
|
case _ => true // no linked IFF lock, just try open the door
|
||||||
|
})
|
||||||
|
) {
|
||||||
|
openDoor(player)
|
||||||
|
}
|
||||||
|
|
||||||
|
case _ => ;
|
||||||
|
}
|
||||||
|
|
||||||
|
def unpoweredStateLogic: Receive = {
|
||||||
|
commonBehavior
|
||||||
|
.orElse {
|
||||||
|
case CommonMessages.Use(player, _) =>
|
||||||
|
//without power, the door opens freely
|
||||||
|
openDoor(player)
|
||||||
|
|
||||||
|
case _ => ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def openDoor(player: Player): Unit = {
|
||||||
|
val zone = door.Zone
|
||||||
|
val doorGUID = door.GUID
|
||||||
|
if (!door.isOpen) {
|
||||||
|
//global open
|
||||||
|
door.Open = player
|
||||||
|
zone.LocalEvents ! LocalServiceMessage(
|
||||||
|
zone.id,
|
||||||
|
LocalAction.DoorOpens(Service.defaultPlayerGUID, zone, door)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
//the door should already open, but the requesting player does not see it as open
|
||||||
|
sender() ! LocalServiceResponse(
|
||||||
|
player.Name,
|
||||||
|
Service.defaultPlayerGUID,
|
||||||
|
LocalResponse.DoorOpens(doorGUID)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override def powerTurnOffCallback() : Unit = { }
|
||||||
|
|
||||||
|
override def powerTurnOnCallback() : Unit = { }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ class PainboxControl(painbox: Painbox) extends PoweredAmenityControl {
|
||||||
|
|
||||||
var disabled = false // Temporary to disable cavern non-radius fields
|
var disabled = false // Temporary to disable cavern non-radius fields
|
||||||
|
|
||||||
val initialStartup: Unit = {
|
def initialStartup(): Unit = {
|
||||||
if (painbox.Definition.HasNearestDoorDependency) {
|
if (painbox.Definition.HasNearestDoorDependency) {
|
||||||
(painbox.Owner match {
|
(painbox.Owner match {
|
||||||
case obj : Building =>
|
case obj : Building =>
|
||||||
|
|
|
||||||
|
|
@ -59,10 +59,12 @@ class DoorTest extends Specification {
|
||||||
)
|
)
|
||||||
val door = Door(GlobalDefinitions.door)
|
val door = Door(GlobalDefinitions.door)
|
||||||
door.Open.isEmpty mustEqual true
|
door.Open.isEmpty mustEqual true
|
||||||
door.Use(player, msg)
|
door.Open = player
|
||||||
|
door.isOpen mustEqual true
|
||||||
door.Open.contains(player) mustEqual true
|
door.Open.contains(player) mustEqual true
|
||||||
door.Use(player, msg)
|
door.Open = None
|
||||||
door.Open.isEmpty mustEqual true
|
door.Open.isEmpty mustEqual true
|
||||||
|
door.isOpen mustEqual false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue