Skip to content

Commit

Permalink
Entity Interference (#1191)
Browse files Browse the repository at this point in the history
* basic interference fields; setting up operations for ce deployables

* applying corrected properties to object definitions and applying them to interference tests for deployable ce and for deploying vehicles; made two otherwise useles object definitions to store property data (if we ever need ziplines or teleport pads ...)

* sent deployment requests to a centralized pipeline for interference testing; swapped out math.pow(a,2) for a * a

* temporary interference for vehicles that are going to transition to deployed eventually and block other deploying vehicles

* reversed the origin of the interference tests

* exception for non-interference resolves to wrong conclusion

* ramshackle merge conflict resolution; fixing interference for non-interference deploying vehicles
  • Loading branch information
Fate-JH authored May 11, 2024
1 parent 426ab84 commit a3eb3a8
Show file tree
Hide file tree
Showing 19 changed files with 383 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
case _ =>
GUIDTask.registerObject(continent.GUID, dObj)
}
TaskWorkflow.execute(CallBackForTask(tasking, continent.Deployables, Zone.Deployable.BuildByOwner(dObj, player, obj)))
TaskWorkflow.execute(CallBackForTask(tasking, continent.Deployables, Zone.Deployable.BuildByOwner(dObj, player, obj), context.self))
case Some(obj) =>
log.warn(s"DeployObject: what is $obj, ${player.Name}? It's not a construction tool!")
case None =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package net.psforever.actors.session.normal
import akka.actor.Actor.Receive
import akka.actor.ActorRef
import net.psforever.actors.session.support.{ChatFunctions, GeneralFunctions, LocalHandlerFunctions, MountHandlerFunctions, SquadHandlerFunctions, TerminalHandlerFunctions, VehicleFunctions, VehicleHandlerFunctions, WeaponAndProjectileFunctions}
import net.psforever.objects.Players
import net.psforever.packet.game.UplinkRequest
import net.psforever.services.chat.ChatService
//
Expand Down Expand Up @@ -248,9 +249,11 @@ class NormalModeLogic(data: SessionData) extends ModeLogic {
case _: Zone.Vehicle.HasDespawned => ;

case Zone.Deployable.IsDismissed(obj: TurretDeployable) => //only if target deployable was never fully introduced
Players.buildCooldownReset(data.continent, data.player.Name, obj)
TaskWorkflow.execute(GUIDTask.unregisterDeployableTurret(data.continent.GUID, obj))

case Zone.Deployable.IsDismissed(obj) => //only if target deployable was never fully introduced
Players.buildCooldownReset(data.continent, data.player.Name, obj)
TaskWorkflow.execute(GUIDTask.unregisterObject(data.continent.GUID, obj))

case msg: Containable.ItemPutInSlot =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,24 +272,29 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex

def handleDeployRequest(pkt: DeployRequestMessage): Unit = {
val DeployRequestMessage(_, vehicle_guid, deploy_state, _, _, _) = pkt
val vehicle = player.avatar.vehicle
if (vehicle.contains(vehicle_guid)) {
if (vehicle == player.VehicleSeated) {
continent.GUID(vehicle_guid) match {
case Some(obj: Vehicle) =>
continent.GUID(vehicle_guid)
.collect {
case obj: Vehicle =>
val vehicle = player.avatar.vehicle
if (!vehicle.contains(vehicle_guid)) {
log.warn(s"DeployRequest: ${player.Name} does not own the would-be-deploying ${obj.Definition.Name}")
} else if (vehicle != player.VehicleSeated) {
log.warn(s"${player.Name} must be mounted as the driver to request a deployment change")
} else {
log.info(s"${player.Name} is requesting a deployment change for ${obj.Definition.Name} - $deploy_state")
obj.Actor ! Deployment.TryDeploymentChange(deploy_state)

case _ =>
log.error(s"DeployRequest: ${player.Name} can not find vehicle $vehicle_guid")
avatarActor ! AvatarActor.SetVehicle(None)
}
} else {
log.warn(s"${player.Name} must be mounted to request a deployment change")
continent.Transport ! Zone.Vehicle.TryDeploymentChange(obj, deploy_state)
}
obj
case obj =>
log.error(s"DeployRequest: ${player.Name} expected a vehicle, but found a ${obj.Definition.Name} instead")
obj
}
.orElse {
log.error(s"DeployRequest: ${player.Name} can not find entity $vehicle_guid")
avatarActor ! AvatarActor.SetVehicle(None) //todo is this safe
None
}
} else {
log.warn(s"DeployRequest: ${player.Name} does not own the deploying $vehicle_guid object")
}
}

/* messages */
Expand Down
18 changes: 18 additions & 0 deletions src/main/scala/net/psforever/login/WorldSession.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1080,4 +1080,22 @@ object WorldSession {
task
)
}

def CallBackForTask(task: TaskBundle, sendTo: ActorRef, pass: Any, replyTo: ActorRef): TaskBundle = {
TaskBundle(
new StraightforwardTask() {
private val localDesc = task.description()
private val destination = sendTo
private val passMsg = pass

override def description(): String = s"callback for tasking $localDesc"

def action() : Future[Any] = {
destination.tell(passMsg, replyTo)
Future(this)
}
},
task
)
}
}
50 changes: 27 additions & 23 deletions src/main/scala/net/psforever/objects/GlobalDefinitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import net.psforever.objects.vital._
import net.psforever.types.{ExoSuitType, ImplantType, PlanetSideEmpire, Vector3}
import net.psforever.types._
import net.psforever.objects.serverobject.llu.{CaptureFlagDefinition, CaptureFlagSocketDefinition}
import net.psforever.objects.serverobject.zipline.GenericTeleportationDefinition

import scala.annotation.switch

Expand Down Expand Up @@ -1277,6 +1278,10 @@ object GlobalDefinitions {

val targeting_laser_dispenser = new OrderTerminalDefinition(851)

val stationaryteleportpad = new GenericTeleportationDefinition(836)

val zipline = new GenericTeleportationDefinition(1047)

/*
Buildings
*/
Expand All @@ -1294,29 +1299,28 @@ object GlobalDefinitions {

val vanu_core = new BuildingDefinition(932)

//the following group borrows the object id from entity mainbase1
val ground_bldg_a = new BuildingDefinition(474)
val ground_bldg_b = new BuildingDefinition(474)
val ground_bldg_c = new BuildingDefinition(474)
val ground_bldg_d = new BuildingDefinition(474)
val ground_bldg_e = new BuildingDefinition(474)
val ground_bldg_f = new BuildingDefinition(474)
val ground_bldg_g = new BuildingDefinition(474)
val ground_bldg_h = new BuildingDefinition(474)
val ground_bldg_i = new BuildingDefinition(474)
val ground_bldg_j = new BuildingDefinition(474)
val ground_bldg_z = new BuildingDefinition(474)
val ceiling_bldg_a = new BuildingDefinition(474)
val ceiling_bldg_b = new BuildingDefinition(474)
val ceiling_bldg_c = new BuildingDefinition(474)
val ceiling_bldg_d = new BuildingDefinition(474)
val ceiling_bldg_e = new BuildingDefinition(474)
val ceiling_bldg_f = new BuildingDefinition(474)
val ceiling_bldg_g = new BuildingDefinition(474)
val ceiling_bldg_h = new BuildingDefinition(474)
val ceiling_bldg_i = new BuildingDefinition(474)
val ceiling_bldg_j = new BuildingDefinition(474)
val ceiling_bldg_z = new BuildingDefinition(474)
val ground_bldg_a = new BuildingDefinition(373)
val ground_bldg_b = new BuildingDefinition(374)
val ground_bldg_c = new BuildingDefinition(375)
val ground_bldg_d = new BuildingDefinition(376)
val ground_bldg_e = new BuildingDefinition(377)
val ground_bldg_f = new BuildingDefinition(378)
val ground_bldg_g = new BuildingDefinition(379)
val ground_bldg_h = new BuildingDefinition(380)
val ground_bldg_i = new BuildingDefinition(381)
val ground_bldg_j = new BuildingDefinition(382)
val ground_bldg_z = new BuildingDefinition(383)
val ceiling_bldg_a = new BuildingDefinition(159)
val ceiling_bldg_b = new BuildingDefinition(160)
val ceiling_bldg_c = new BuildingDefinition(161)
val ceiling_bldg_d = new BuildingDefinition(162)
val ceiling_bldg_e = new BuildingDefinition(163)
val ceiling_bldg_f = new BuildingDefinition(164)
val ceiling_bldg_g = new BuildingDefinition(165)
val ceiling_bldg_h = new BuildingDefinition(166)
val ceiling_bldg_i = new BuildingDefinition(167)
val ceiling_bldg_j = new BuildingDefinition(168)
val ceiling_bldg_z = new BuildingDefinition(169)

val mainbase1 = new BuildingDefinition(474)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class DeployableToolbox {
* keys: categories, values: quantity storage object
*/
private val categoryCounts =
DeployableCategory.values.toSeq.map(value => { value -> new DeployableToolbox.Bin }).toMap
DeployableCategory.values.map(value => { value -> new DeployableToolbox.Bin }).toMap

/**
* a map of bins for keeping track of the quantities of individual deployables
Expand All @@ -46,7 +46,7 @@ class DeployableToolbox {
* keys: categories, values: deployable objects
*/
private val deployableLists =
DeployableCategory.values.toSeq
DeployableCategory.values
.map(value => { value -> mutable.ListBuffer[DeployableToolbox.AcceptableDeployable]() })
.toMap

Expand All @@ -73,7 +73,7 @@ class DeployableToolbox {
}
}

def UpdateMaxCounts(certifications: Set[Certification]) = {
def UpdateMaxCounts(certifications: Set[Certification]): Unit = {
DeployableToolbox.UpdateMaxCounts(deployableCounts, categoryCounts, certifications)
}

Expand Down Expand Up @@ -247,7 +247,7 @@ class DeployableToolbox {
* @param category the target category
* @return any deployable that is found
*/
def DisplaceFirst(category: DeployableCategory.Value): Option[DeployableToolbox.AcceptableDeployable] = {
def DisplaceFirst(category: DeployableCategory): Option[DeployableToolbox.AcceptableDeployable] = {
val categoryList = deployableLists(category)
if (categoryList.nonEmpty) {
val found = categoryList.remove(0)
Expand Down Expand Up @@ -294,7 +294,7 @@ class DeployableToolbox {
* @param filter the type of deployable
* @return a list of globally unique identifiers that should be valid for the current zone
*/
def Category(filter: DeployableCategory.Value): List[PlanetSideGUID] = {
def Category(filter: DeployableCategory): List[PlanetSideGUID] = {
deployableLists(filter).map(_.GUID).toList
}

Expand Down Expand Up @@ -478,7 +478,7 @@ object DeployableToolbox {
*/
private def UpdateMaxCounts(
counts: Map[DeployedItem.Value, DeployableToolbox.Bin],
categories: Map[DeployableCategory.Value, DeployableToolbox.Bin],
categories: Map[DeployableCategory, DeployableToolbox.Bin],
certifications: Set[Certification]
): Unit = {
import Certification._
Expand Down
10 changes: 5 additions & 5 deletions src/main/scala/net/psforever/objects/ce/Deployable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,18 @@ object Deployable {
}

object Category {
def Of(item: DeployedItem.Value): DeployableCategory.Value = deployablesToCategories(item)
def Of(item: DeployedItem.Value): DeployableCategory = deployablesToCategories(item)

def Includes(category: DeployableCategory.Value): List[DeployedItem.Value] = {
def Includes(category: DeployableCategory): List[DeployedItem.Value] = {
(for {
(ce: DeployedItem.Value, cat: DeployableCategory.Value) <- deployablesToCategories
(ce: DeployedItem.Value, cat: DeployableCategory) <- deployablesToCategories
if cat == category
} yield ce) toList
}

def OfAll(): Map[DeployedItem.Value, DeployableCategory.Value] = deployablesToCategories
def OfAll(): Map[DeployedItem.Value, DeployableCategory] = deployablesToCategories

private val deployablesToCategories: Map[DeployedItem.Value, DeployableCategory.Value] = Map(
private val deployablesToCategories: Map[DeployedItem.Value, DeployableCategory] = Map(
DeployedItem.boomer -> DeployableCategory.Boomers,
DeployedItem.he_mine -> DeployableCategory.Mines,
DeployedItem.jammer_mine -> DeployableCategory.Mines,
Expand Down
24 changes: 21 additions & 3 deletions src/main/scala/net/psforever/objects/ce/DeployableCategory.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.ce

object DeployableCategory extends Enumeration {
type Type = Value
abstract class DeployableCategory(val name: String)

val Boomers, Mines, SmallTurrets, Sensors, TankTraps, FieldTurrets, ShieldGenerators, Telepads = Value
object DeployableCategory {
case object None extends DeployableCategory(name = "None")

case object Boomers extends DeployableCategory(name = "Boomers")

case object Mines extends DeployableCategory(name = "Mines")

case object SmallTurrets extends DeployableCategory(name = "SmallTurrets")

case object Sensors extends DeployableCategory(name = "Sensors")

case object TankTraps extends DeployableCategory(name = "TankTraps")

case object FieldTurrets extends DeployableCategory(name = "FieldTurrets")

case object ShieldGenerators extends DeployableCategory(name = "ShieldGenerators")

case object Telepads extends DeployableCategory(name = "Telepads")

val values: Seq[DeployableCategory] = Seq(None, Boomers, Mines, SmallTurrets, Sensors, TankTraps, FieldTurrets, ShieldGenerators, Telepads)
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ object DeployAnimation extends Enumeration {
}

trait BaseDeployableDefinition {
private var category: DeployableCategory.Value = DeployableCategory.Boomers
private var category: DeployableCategory = DeployableCategory.None
private var deployTime: Long = (1 second).toMillis //ms
var deployAnimation: DeployAnimation.Value = DeployAnimation.None

def Item: DeployedItem.Value

def DeployCategory: DeployableCategory.Value = category
def DeployCategory: DeployableCategory = category

def DeployCategory_=(cat: DeployableCategory.Value): DeployableCategory.Value = {
def DeployCategory_=(cat: DeployableCategory): DeployableCategory = {
category = cat
DeployCategory
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import net.psforever.objects.PlanetSideGameObject
import net.psforever.objects.definition.converter.{ObjectCreateConverter, PacketConverter}
import net.psforever.objects.geometry.GeometryForm
import net.psforever.objects.geometry.d3.VolumetricGeometry
import net.psforever.objects.serverobject.deploy.{Interference, InterferenceRange}
import net.psforever.types.OxygenState

/**
Expand Down Expand Up @@ -121,5 +122,10 @@ abstract class ObjectDefinition(private val objectId: Int)
*/
var maxForwardSpeed: Float = 0f

/**
* na
*/
var interference: InterferenceRange = Interference.AllowAll

def ObjectId: Int = objectId
}
Loading

0 comments on commit a3eb3a8

Please sign in to comment.