mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-01-20 02:24:45 +00:00
commit
16c20eaeac
|
|
@ -10,7 +10,9 @@ class Painbox(tdef : PainboxDefinition) extends Amenity {
|
|||
}
|
||||
|
||||
object Painbox {
|
||||
final case class Start()
|
||||
final case class Tick()
|
||||
final case class Stop()
|
||||
|
||||
def apply(tdef : PainboxDefinition) : Painbox = {
|
||||
new Painbox(tdef)
|
||||
|
|
|
|||
|
|
@ -11,33 +11,50 @@ import scala.concurrent.duration._
|
|||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
|
||||
class PainboxControl(painbox: Painbox) extends Actor {
|
||||
//private[this] val log = org.log4s.getLogger(s"Painbox")
|
||||
private var painboxTick: Cancellable = DefaultCancellable.obj
|
||||
private var nearestDoor : Door = null
|
||||
private[this] val log = org.log4s.getLogger(s"Painbox")
|
||||
var painboxTick: Cancellable = DefaultCancellable.obj
|
||||
var nearestDoor : Option[Door] = None
|
||||
|
||||
def receive : Receive = {
|
||||
case "startup" =>
|
||||
painbox.Owner match {
|
||||
case obj : Building =>
|
||||
nearestDoor = obj.Amenities
|
||||
.collect { case door : Door => door }
|
||||
.minBy(door => Vector3.DistanceSquared(painbox.Position, door.Position))
|
||||
painboxTick = context.system.scheduler.schedule(0 seconds,1 second, self, Painbox.Tick())
|
||||
context.become(Processing)
|
||||
case _ => ;
|
||||
if(painbox.Definition.HasNearestDoorDependency) {
|
||||
(painbox.Owner match {
|
||||
case obj : Building =>
|
||||
obj.Amenities
|
||||
.collect { case door : Door => door }
|
||||
.sortBy(door => Vector3.DistanceSquared(painbox.Position, door.Position))
|
||||
.headOption
|
||||
case _ =>
|
||||
None
|
||||
}) match {
|
||||
case door @ Some(_) =>
|
||||
nearestDoor = door
|
||||
context.become(Stopped)
|
||||
case _ =>
|
||||
log.error(s"object #${painbox.GUID.guid} can not find a door that it needed")
|
||||
}
|
||||
}
|
||||
else {
|
||||
context.become(Stopped)
|
||||
}
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
def Processing : Receive = {
|
||||
def Running : Receive = {
|
||||
case Painbox.Stop() =>
|
||||
context.become(Stopped)
|
||||
painboxTick.cancel
|
||||
painboxTick = DefaultCancellable.obj
|
||||
|
||||
case Painbox.Tick() =>
|
||||
//todo: Account for overlapping pain fields
|
||||
//todo: Pain module
|
||||
//todo: REK boosting
|
||||
val guid = painbox.GUID
|
||||
val owner = painbox.Owner.asInstanceOf[Building]
|
||||
val faction = owner.Faction
|
||||
if(faction != PlanetSideEmpire.NEUTRAL && (!painbox.Definition.HasNearestDoorDependency || (painbox.Definition.HasNearestDoorDependency && nearestDoor.Open.nonEmpty))) {
|
||||
if(faction != PlanetSideEmpire.NEUTRAL && (nearestDoor match { case Some(door) => door.Open.nonEmpty; case _ => true })) {
|
||||
val events = owner.Zone.AvatarEvents
|
||||
val damage = painbox.Definition.Damage
|
||||
val radius = painbox.Definition.Radius * painbox.Definition.Radius
|
||||
|
|
@ -46,8 +63,19 @@ class PainboxControl(painbox: Painbox) extends Actor {
|
|||
.collect { case p if p.Faction != faction
|
||||
&& p.Health > 0
|
||||
&& Vector3.DistanceSquared(p.Position, position) < radius =>
|
||||
events ! AvatarServiceMessage(p.Name, AvatarAction.EnvironmentalDamage(p.GUID, damage))
|
||||
events ! AvatarServiceMessage(p.Name, AvatarAction.EnvironmentalDamage(p.GUID, guid, damage))
|
||||
}
|
||||
}
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
def Stopped : Receive = {
|
||||
case Painbox.Start() =>
|
||||
context.become(Running)
|
||||
painboxTick.cancel
|
||||
painboxTick = context.system.scheduler.schedule(0 seconds, 1 second, self, Painbox.Tick())
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import akka.actor.{ActorContext, ActorRef}
|
|||
import net.psforever.objects.{GlobalDefinitions, Player}
|
||||
import net.psforever.objects.definition.ObjectDefinition
|
||||
import net.psforever.objects.serverobject.hackable.Hackable
|
||||
import net.psforever.objects.serverobject.painbox.Painbox
|
||||
import net.psforever.objects.serverobject.resourcesilo.ResourceSilo
|
||||
import net.psforever.objects.serverobject.terminals.CaptureTerminal
|
||||
import net.psforever.objects.serverobject.tube.SpawnTube
|
||||
|
|
@ -56,6 +57,18 @@ class Building(private val name: String,
|
|||
def PlayersInSOI : List[Player] = playersInSOI
|
||||
|
||||
def PlayersInSOI_=(list : List[Player]) : List[Player] = {
|
||||
if(playersInSOI.isEmpty && list.nonEmpty) {
|
||||
Amenities.collect {
|
||||
case box : Painbox =>
|
||||
box.Actor ! Painbox.Start()
|
||||
}
|
||||
}
|
||||
else if(playersInSOI.nonEmpty && list.isEmpty) {
|
||||
Amenities.collect {
|
||||
case box : Painbox =>
|
||||
box.Actor ! Painbox.Stop()
|
||||
}
|
||||
}
|
||||
playersInSOI = list
|
||||
playersInSOI
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import net.psforever.objects._
|
|||
import net.psforever.objects.serverobject.CommonMessages
|
||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||
import net.psforever.objects.serverobject.hackable.HackableBehavior
|
||||
import services.Service
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -27,17 +26,7 @@ class ProximityTerminalControl(term : Terminal with ProximityUnit) extends Actor
|
|||
|
||||
def TerminalObject : Terminal with ProximityUnit = term
|
||||
|
||||
def receive : Receive = Start
|
||||
|
||||
def Start : Receive = checkBehavior
|
||||
.orElse {
|
||||
case Service.Startup() =>
|
||||
context.become(Run)
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
def Run : Receive = checkBehavior
|
||||
def receive : Receive = checkBehavior
|
||||
.orElse(hackableBehavior)
|
||||
.orElse {
|
||||
case CommonMessages.Use(_, Some(target : PlanetSideGameObject)) =>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ package net.psforever.objects.vital
|
|||
import net.psforever.objects.PlanetSideGameObject
|
||||
import net.psforever.objects.ballistics.{PlayerSource, ResolvedProjectile, SourceEntry, VehicleSource}
|
||||
import net.psforever.objects.definition.KitDefinition
|
||||
import net.psforever.objects.serverobject.painbox.Painbox
|
||||
import net.psforever.objects.serverobject.terminals.TerminalDefinition
|
||||
import net.psforever.objects.vital.resolution.ResolutionCalculations
|
||||
import net.psforever.types.{ExoSuitType, ImplantType}
|
||||
|
|
@ -35,6 +36,8 @@ final case class VehicleShieldCharge(target : VehicleSource, amount : Int) exten
|
|||
|
||||
final case class DamageFromProjectile(data : ResolvedProjectile) extends DamagingActivity(data.target)
|
||||
|
||||
final case class DamageFromPainbox(target : PlayerSource, painbox : Painbox, damage : Int) extends DamagingActivity(target)
|
||||
|
||||
final case class PlayerSuicide(target : PlayerSource) extends DamagingActivity(target)
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,45 +1,86 @@
|
|||
package net.psforever.objects.zones;
|
||||
package net.psforever.objects.zones
|
||||
|
||||
import akka.actor.{Actor, Cancellable}
|
||||
import net.psforever.objects.{DefaultCancellable, Player}
|
||||
import net.psforever.objects.definition.ObjectDefinition
|
||||
import net.psforever.objects.serverobject.structures.{Building, SphereOfInfluence}
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
|
||||
class SphereOfInfluenceActor(zone: Zone) extends Actor {
|
||||
def receive : Receive = Established
|
||||
var sois : Iterable[(Building, Int)] = Nil
|
||||
var populateTick : Cancellable = DefaultCancellable.obj
|
||||
//private[this] val log = org.log4s.getLogger(s"${zone.Id.capitalize}-SphereOfInfluenceActor")
|
||||
|
||||
private var populateTick: Cancellable = context.system.scheduler.scheduleOnce(5 seconds, self, SOI.Populate())
|
||||
private[this] val log = org.log4s.getLogger(s"${zone.Id.capitalize}-SphereOfInfluenceActor")
|
||||
def receive : Receive = Stopped
|
||||
|
||||
def Established : Receive = {
|
||||
def Build : Receive = {
|
||||
case SOI.Build() =>
|
||||
BuildSOI()
|
||||
}
|
||||
|
||||
def Running : Receive = Build.orElse {
|
||||
case SOI.Populate() =>
|
||||
UpdateSOI()
|
||||
|
||||
case SOI.Stop() =>
|
||||
context.become(Stopped)
|
||||
populateTick.cancel
|
||||
sois.foreach { case (facility, _) => facility.PlayersInSOI = Nil }
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
def Stopped : Receive = Build.orElse {
|
||||
case SOI.Start() if sois.nonEmpty =>
|
||||
context.become(Running)
|
||||
UpdateSOI()
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
def BuildSOI() : Unit = {
|
||||
sois = zone.Buildings
|
||||
.values
|
||||
.map { facility => (facility, facility.Definition) }
|
||||
.collect { case (facility, soi : ObjectDefinition with SphereOfInfluence) if soi.SOIRadius > 0 =>
|
||||
(facility, soi.SOIRadius * soi.SOIRadius)
|
||||
}
|
||||
}
|
||||
|
||||
def UpdateSOI(): Unit = {
|
||||
val players = zone.LivePlayers
|
||||
|
||||
zone.Buildings.foreach({
|
||||
case (_, building : Building) =>
|
||||
building.Definition match {
|
||||
case _ : ObjectDefinition with SphereOfInfluence =>
|
||||
// todo: overlapping soi (e.g. tower soi in base soi) order by smallest soi first?
|
||||
val playersInSoi = players.filter(p => Math.pow(p.Position.x - building.Position.x, 2) + Math.pow(p.Position.y - building.Position.y, 2) < Math.pow(300, 2) )
|
||||
if(playersInSoi.length > 0) {
|
||||
// log.info(s"Building ${building.GUID} players in soi: ${playersInSoi.toString()}" )
|
||||
}
|
||||
building.PlayersInSOI = playersInSoi
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
SOI.Populate(sois.iterator, zone.LivePlayers)
|
||||
populateTick.cancel
|
||||
populateTick = context.system.scheduler.scheduleOnce(5 seconds, self, SOI.Populate())
|
||||
}
|
||||
}
|
||||
|
||||
object SOI {
|
||||
/** Rebuild the list of facility SOI data **/
|
||||
final case class Build()
|
||||
/** Populate the list of players within a SOI **/
|
||||
final case class Populate()
|
||||
}
|
||||
/** Stop sorting players into sois */
|
||||
final case class Start()
|
||||
/** Stop sorting players into sois */
|
||||
final case class Stop()
|
||||
|
||||
/**
|
||||
* Recursively populate each facility's sphere of influence with players.
|
||||
* @param buildings an iterator of buildings and the radius of its sphere of influence
|
||||
* @param players a list of players to allocate;
|
||||
* the list gets shorter as each building is allocated
|
||||
*/
|
||||
@tailrec
|
||||
def Populate(buildings : Iterator[(Building, Int)], players : List[Player]) : Unit = {
|
||||
if(players.nonEmpty && buildings.hasNext) {
|
||||
val (facility, radius) = buildings.next
|
||||
val (tenants, remainder) = players.partition(p => Vector3.DistanceSquared(facility.Position.xy, p.Position.xy) < radius)
|
||||
facility.PlayersInSOI = tenants
|
||||
Populate(buildings, remainder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,15 +13,12 @@ import net.psforever.objects.guid.actor.UniqueNumberSystem
|
|||
import net.psforever.objects.guid.selector.RandomSelector
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.inventory.Container
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.painbox.{Painbox, PainboxDefinition}
|
||||
import net.psforever.objects.serverobject.resourcesilo.ResourceSilo
|
||||
import net.psforever.objects.serverobject.structures.{Amenity, Building, WarpGate}
|
||||
import net.psforever.objects.serverobject.terminals.ProximityUnit
|
||||
import net.psforever.objects.serverobject.turret.FacilityTurret
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||
import services.Service
|
||||
import services.avatar.AvatarService
|
||||
import services.local.LocalService
|
||||
import services.vehicle.VehicleService
|
||||
|
|
@ -30,9 +27,9 @@ import scala.collection.concurrent.TrieMap
|
|||
import scala.collection.mutable.ListBuffer
|
||||
import scala.collection.immutable.{Map => PairMap}
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import scalax.collection.Graph
|
||||
import scalax.collection.GraphPredef._, scalax.collection.GraphEdge._
|
||||
import scalax.collection.GraphPredef._
|
||||
import scalax.collection.GraphEdge._
|
||||
|
||||
/**
|
||||
* A server object representing the one-landmass planets as well as the individual subterranean caverns.<br>
|
||||
|
|
@ -413,31 +410,27 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
|
|||
case silo : ResourceSilo =>
|
||||
silo.Actor ! "startup"
|
||||
}
|
||||
//proximity terminals need to startup
|
||||
buildings.values
|
||||
.flatMap(_.Amenities.filter(_.isInstanceOf[ProximityUnit]))
|
||||
.collect {
|
||||
case o : PlanetSideServerObject =>
|
||||
o.Actor ! Service.Startup()
|
||||
}
|
||||
//some painfields need to look for their closest door
|
||||
buildings.values
|
||||
.flatMap(_.Amenities.filter(_.Definition.isInstanceOf[PainboxDefinition]))
|
||||
.collect {
|
||||
case painbox : Painbox =>
|
||||
painbox.Actor ! "startup"
|
||||
}
|
||||
//allocate soi information
|
||||
soi ! SOI.Build()
|
||||
}
|
||||
|
||||
private def MakeLattice(): Unit = {
|
||||
Map.LatticeLink.foreach({ case(source, target) =>
|
||||
val sourceBuilding = Building(source) match {
|
||||
case Some(building) => building
|
||||
case _ => throw new NoSuchElementException(s"Can't create lattice link between ${source} ${target}. Source is missing")
|
||||
case _ => throw new NoSuchElementException(s"Can't create lattice link between $source $target. Source is missing")
|
||||
}
|
||||
|
||||
val targetBuilding = Building(target) match {
|
||||
case Some(building) => building
|
||||
case _ => throw new NoSuchElementException(s"Can't create lattice link between ${source} ${target}. Target is missing")
|
||||
case _ => throw new NoSuchElementException(s"Can't create lattice link between $source $target. Target is missing")
|
||||
}
|
||||
|
||||
lattice += sourceBuilding~targetBuilding
|
||||
|
|
@ -477,6 +470,14 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
|
|||
entry
|
||||
}
|
||||
|
||||
def StartPlayerManagementSystems() : Unit = {
|
||||
soi ! SOI.Start()
|
||||
}
|
||||
|
||||
def StopPlayerManagementSystems() : Unit = {
|
||||
soi ! SOI.Stop()
|
||||
}
|
||||
|
||||
def Activity : ActorRef = projector
|
||||
|
||||
def HotSpots : List[HotSpotInfo] = hotspots toList
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package net.psforever.objects.zones
|
|||
|
||||
import akka.actor.{Actor, ActorRef, Props}
|
||||
import net.psforever.objects.avatar.PlayerControl
|
||||
import net.psforever.objects.vehicles.VehicleControl
|
||||
import net.psforever.objects.{Avatar, Player}
|
||||
|
||||
import scala.annotation.tailrec
|
||||
|
|
@ -24,13 +23,18 @@ class ZonePopulationActor(zone : Zone, playerMap : TrieMap[Avatar, Option[Player
|
|||
|
||||
def receive : Receive = {
|
||||
case Zone.Population.Join(avatar) =>
|
||||
PopulationJoin(avatar, playerMap)
|
||||
if(PopulationJoin(avatar, playerMap) && playerMap.size == 1) {
|
||||
zone.StartPlayerManagementSystems()
|
||||
}
|
||||
|
||||
case Zone.Population.Leave(avatar) =>
|
||||
PopulationLeave(avatar, playerMap) match {
|
||||
case None => ;
|
||||
case player @ Some(_) =>
|
||||
sender ! Zone.Population.PlayerHasLeft(zone, player)
|
||||
if(playerMap.isEmpty) {
|
||||
zone.StopPlayerManagementSystems()
|
||||
}
|
||||
}
|
||||
|
||||
case Zone.Population.Spawn(avatar, player) =>
|
||||
|
|
@ -42,6 +46,7 @@ class ZonePopulationActor(zone : Zone, playerMap : TrieMap[Avatar, Option[Player
|
|||
}
|
||||
else {
|
||||
player.Actor = context.actorOf(Props(classOf[PlayerControl], player), s"${player.Name}_${player.GUID.guid}")
|
||||
player.Zone = zone
|
||||
}
|
||||
case None =>
|
||||
sender ! Zone.Population.PlayerCanNotSpawn(zone, player)
|
||||
|
|
|
|||
|
|
@ -65,9 +65,9 @@ class AvatarService(zone : Zone) extends Actor {
|
|||
AvatarEvents.publish(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.ConcealPlayer())
|
||||
)
|
||||
case AvatarAction.EnvironmentalDamage(player_guid, amount) =>
|
||||
case AvatarAction.EnvironmentalDamage(player_guid, source_guid, amount) =>
|
||||
AvatarEvents.publish(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.EnvironmentalDamage(player_guid, amount))
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.EnvironmentalDamage(player_guid, source_guid, amount))
|
||||
)
|
||||
case AvatarAction.Damage(player_guid, target, resolution_function) =>
|
||||
AvatarEvents.publish(
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ object AvatarAction {
|
|||
final case class ChangeFireState_Start(player_guid : PlanetSideGUID, weapon_guid : PlanetSideGUID) extends Action
|
||||
final case class ChangeFireState_Stop(player_guid : PlanetSideGUID, weapon_guid : PlanetSideGUID) extends Action
|
||||
final case class ConcealPlayer(player_guid : PlanetSideGUID) extends Action
|
||||
final case class EnvironmentalDamage(player_guid : PlanetSideGUID, amount: Int) extends Action
|
||||
final case class EnvironmentalDamage(player_guid : PlanetSideGUID, source_guid : PlanetSideGUID, amount: Int) extends Action
|
||||
final case class Damage(player_guid : PlanetSideGUID, target : Player, resolution_function : ResolutionCalculations.Output) extends Action
|
||||
final case class DeployItem(player_guid : PlanetSideGUID, item : PlanetSideGameObject with Deployable) extends Action
|
||||
final case class Destroy(victim : PlanetSideGUID, killer : PlanetSideGUID, weapon : PlanetSideGUID, pos : Vector3) extends Action
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ object AvatarResponse {
|
|||
final case class ChangeFireState_Start(weapon_guid : PlanetSideGUID) extends Response
|
||||
final case class ChangeFireState_Stop(weapon_guid : PlanetSideGUID) extends Response
|
||||
final case class ConcealPlayer() extends Response
|
||||
final case class EnvironmentalDamage(target : PlanetSideGUID, amount : Int) extends Response
|
||||
final case class EnvironmentalDamage(target : PlanetSideGUID, source_guid : PlanetSideGUID, amount : Int) extends Response
|
||||
final case class DamageResolution(target : Player, resolution_function : ResolutionCalculations.Output) extends Response
|
||||
final case class Destroy(victim : PlanetSideGUID, killer : PlanetSideGUID, weapon : PlanetSideGUID, pos : Vector3) extends Response
|
||||
final case class DestroyDisplay(killer : SourceEntry, victim : SourceEntry, method : Int, unk : Int) extends Response
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import net.psforever.objects.serverobject.implantmech.ImplantTerminalMech
|
|||
import net.psforever.objects.serverobject.locks.IFFLock
|
||||
import net.psforever.objects.serverobject.mblocker.Locker
|
||||
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
|
||||
import net.psforever.objects.serverobject.painbox.Painbox
|
||||
import net.psforever.objects.serverobject.resourcesilo.ResourceSilo
|
||||
import net.psforever.objects.serverobject.structures.{Amenity, Building, StructureType, WarpGate}
|
||||
import net.psforever.objects.serverobject.terminals._
|
||||
|
|
@ -120,7 +121,9 @@ class WorldSessionActor extends Actor
|
|||
var drawDeloyableIcon : PlanetSideGameObject with Deployable => Unit = RedrawDeployableIcons
|
||||
var updateSquad : () => Unit = NoSquadUpdates
|
||||
var recentTeleportAttempt : Long = 0
|
||||
var lastTerminalOrderFulfillment : Boolean = true /**
|
||||
var lastTerminalOrderFulfillment : Boolean = true
|
||||
var shiftPosition : Option[Vector3] = None
|
||||
/**
|
||||
* used during zone transfers to maintain reference to seated vehicle (which does not yet exist in the new zone)
|
||||
* used during intrazone gate transfers, but not in a way distinct from prior zone transfer procedures
|
||||
* should only be set during the transient period when moving between one spawn point and the next
|
||||
|
|
@ -1032,10 +1035,19 @@ class WorldSessionActor extends Actor
|
|||
sendResponse(ReplicationStreamMessage(5, Some(6), Vector.empty)) //clear squad list
|
||||
sendResponse(FriendsResponse(FriendAction.InitializeFriendList, 0, true, true, Nil))
|
||||
sendResponse(FriendsResponse(FriendAction.InitializeIgnoreList, 0, true, true, Nil))
|
||||
//the following subscriptions last until character switch/logout
|
||||
chatService ! Service.Join("local")
|
||||
chatService ! Service.Join("squad")
|
||||
chatService ! Service.Join("voice")
|
||||
chatService ! Service.Join("tell")
|
||||
chatService ! Service.Join("broadcast")
|
||||
chatService ! Service.Join("note")
|
||||
chatService ! Service.Join("gm")
|
||||
galaxyService ! Service.Join("galaxy") //for galaxy-wide messages
|
||||
galaxyService ! Service.Join(s"${avatar.faction}") //for hotspots
|
||||
squadService ! Service.Join(s"${avatar.faction}") //channel will be player.Faction
|
||||
squadService ! Service.Join(s"${avatar.CharId}") //channel will be player.CharId (in order to work with packets)
|
||||
//go home
|
||||
cluster ! InterstellarCluster.GetWorld("home3")
|
||||
|
||||
case InterstellarCluster.GiveWorld(zoneId, zone) =>
|
||||
|
|
@ -1212,11 +1224,18 @@ class WorldSessionActor extends Actor
|
|||
case AvatarResponse.ConcealPlayer() =>
|
||||
sendResponse(GenericObjectActionMessage(guid, 9))
|
||||
|
||||
case AvatarResponse.EnvironmentalDamage(target, amount) =>
|
||||
if(player.isAlive && amount != 0) {
|
||||
case AvatarResponse.EnvironmentalDamage(target, source, amount) =>
|
||||
if(player.isAlive && amount > 0) {
|
||||
val playerGUID = player.GUID
|
||||
val armor = player.Armor
|
||||
val capacitor = player.Capacitor
|
||||
val originalHealth = player.Health
|
||||
//history
|
||||
continent.GUID(source) match {
|
||||
case Some(obj : Painbox) =>
|
||||
player.History(DamageFromPainbox(PlayerSource(player), obj, amount))
|
||||
case _ => ;
|
||||
}
|
||||
player.Health = originalHealth - amount
|
||||
sendResponse(PlanetsideAttributeMessage(target, 0, player.Health))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttribute(target, 0, player.Health))
|
||||
|
|
@ -1224,9 +1243,6 @@ class WorldSessionActor extends Actor
|
|||
if(player.Health == 0 && player.isAlive) {
|
||||
KillPlayer(player)
|
||||
}
|
||||
else {
|
||||
//todo: History?
|
||||
}
|
||||
}
|
||||
|
||||
case AvatarResponse.DamageResolution(target, resolution_function) =>
|
||||
|
|
@ -3056,7 +3072,8 @@ class WorldSessionActor extends Actor
|
|||
sendResponse(PlanetsideAttributeMessage(PlanetSideGUID(0), 75, 0))
|
||||
sendResponse(SetCurrentAvatarMessage(guid, 0, 0))
|
||||
sendResponse(ChatMsg(ChatMessageType.CMT_EXPANSIONS, true, "", "1 on", None)) //CC on //TODO once per respawn?
|
||||
sendResponse(PlayerStateShiftMessage(ShiftState(1, tplayer.Position, tplayer.Orientation.z)))
|
||||
sendResponse(PlayerStateShiftMessage(ShiftState(1, shiftPosition.getOrElse(tplayer.Position), tplayer.Orientation.z)))
|
||||
shiftPosition = None
|
||||
if(spectator) {
|
||||
sendResponse(ChatMsg(ChatMessageType.CMT_TOGGLESPECTATORMODE, false, "", "on", None))
|
||||
}
|
||||
|
|
@ -3664,15 +3681,6 @@ class WorldSessionActor extends Actor
|
|||
}
|
||||
}
|
||||
continent.VehicleEvents ! VehicleServiceMessage(continent.Id, VehicleAction.UpdateAmsSpawnPoint(continent))
|
||||
|
||||
chatService ! Service.Join("local")
|
||||
chatService ! Service.Join("squad")
|
||||
chatService ! Service.Join("voice")
|
||||
chatService ! Service.Join("tell")
|
||||
chatService ! Service.Join("broadcast")
|
||||
chatService ! Service.Join("note")
|
||||
chatService ! Service.Join("gm")
|
||||
|
||||
self ! SetCurrentAvatar(player)
|
||||
|
||||
case msg @ PlayerStateMessageUpstream(avatar_guid, pos, vel, yaw, pitch, yaw_upper, seq_time, unk3, is_crouching, is_jumping, jump_thrust, is_cloaking, unk5, unk6) =>
|
||||
|
|
@ -9093,6 +9101,7 @@ class WorldSessionActor extends Actor
|
|||
val respawnTimeMillis = respawnTime * 1000 //ms
|
||||
deadState = DeadState.RespawnTime
|
||||
sendResponse(AvatarDeadStateMessage(DeadState.RespawnTime, respawnTimeMillis, respawnTimeMillis, Vector3.Zero, player.Faction, true))
|
||||
shiftPosition = Some(pos)
|
||||
val (target, msg) = if(backpack) { //if the player is dead, he is handled as dead infantry, even if he died in a vehicle
|
||||
//new player is spawning
|
||||
val newPlayer = RespawnClone(player)
|
||||
|
|
|
|||
|
|
@ -201,8 +201,8 @@ object Map13 {
|
|||
LocalObject(868, Terminal.Constructor(Vector3(3760.041f, 2809.603f, 94.65012f), order_terminal), owning_building_guid = 2)
|
||||
LocalObject(869, Terminal.Constructor(Vector3(3763.91f, 2806.405f, 94.65012f), order_terminal), owning_building_guid = 2)
|
||||
LocalObject(870, Terminal.Constructor(Vector3(3763.931f, 2809.603f, 94.65012f), order_terminal), owning_building_guid = 2)
|
||||
LocalObject(778, ProximityTerminal.Constructor(Vector3(3617.307f, 2830.855f, 93.34412f), medical_terminal), owning_building_guid = 2)
|
||||
LocalObject(779, ProximityTerminal.Constructor(Vector3(3617.369f, 2785.151f, 93.34412f), medical_terminal), owning_building_guid = 2)
|
||||
LocalObject(778, ProximityTerminal.Constructor(Vector3(3617.369f, 2785.151f, 93.34412f), medical_terminal), owning_building_guid = 2)
|
||||
LocalObject(779, ProximityTerminal.Constructor(Vector3(3617.307f, 2830.855f, 93.34412f), medical_terminal), owning_building_guid = 2)
|
||||
LocalObject(780, ProximityTerminal.Constructor(Vector3(3758.667f, 2785.151f, 93.34412f), medical_terminal), owning_building_guid = 2)
|
||||
LocalObject(781, ProximityTerminal.Constructor(Vector3(3758.689f, 2830.855f, 93.34412f), medical_terminal), owning_building_guid = 2)
|
||||
LocalObject(522, ImplantTerminalMech.Constructor, owning_building_guid = 2)
|
||||
|
|
|
|||
Loading…
Reference in a new issue