mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-02-01 16:20:59 +00:00
Tuned positioning on player spawned at an AMS; fixed 'AMS' label draw and clear issue by expanding deployment options; modifications to BattlePlanMessage packet
This commit is contained in:
parent
cd91080c9a
commit
e00202e8fb
|
|
@ -7,6 +7,8 @@ import scodec.{Attempt, Codec, Err}
|
|||
import scodec.codecs._
|
||||
import shapeless.{::, HNil}
|
||||
|
||||
import scala.annotation.tailrec
|
||||
|
||||
/**
|
||||
* A `Codec` for the actions that each layer of the diagram performs.
|
||||
* `Style`, `Vertex`, `Action5`, `DrawString`, and `Action7` have additional `DiagramStroke` input data.
|
||||
|
|
@ -152,7 +154,7 @@ final case class BattleDiagramAction(action : DiagramActionCode.Value,
|
|||
*/
|
||||
final case class BattleplanMessage(char_id : Long,
|
||||
player_name : String,
|
||||
zone_id : PlanetSideGUID,
|
||||
zone_id : Int,
|
||||
diagrams : List[BattleDiagramAction])
|
||||
extends PlanetSideGamePacket {
|
||||
type Packet = BattleplanMessage
|
||||
|
|
@ -365,11 +367,11 @@ object BattleplanMessage extends Marshallable[BattleplanMessage] {
|
|||
* @param list a `List` of extracted `BattleDiagrams`;
|
||||
* technically, the output
|
||||
*/
|
||||
private def rollDiagramLayers(element : Option[BattleDiagramChain], list : ListBuffer[BattleDiagramAction]) : Unit = {
|
||||
if(element.isEmpty)
|
||||
return
|
||||
list += element.get.diagram
|
||||
rollDiagramLayers(element.get.next, list) //tail call optimization
|
||||
@tailrec private def rollDiagramLayers(element : Option[BattleDiagramChain], list : ListBuffer[BattleDiagramAction]) : Unit = {
|
||||
if(element.nonEmpty) {
|
||||
list += element.get.diagram
|
||||
rollDiagramLayers(element.get.next, list)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -380,17 +382,20 @@ object BattleplanMessage extends Marshallable[BattleplanMessage] {
|
|||
* technically, the output
|
||||
* @return a linked list of `BattleDiagramChain` objects
|
||||
*/
|
||||
private def unrollDiagramLayers(revIter : Iterator[BattleDiagramAction], layers : Option[BattleDiagramChain] = None) : Option[BattleDiagramChain] = {
|
||||
if(!revIter.hasNext)
|
||||
return layers
|
||||
val elem : BattleDiagramAction = revIter.next
|
||||
unrollDiagramLayers(revIter, Some(BattleDiagramChain(elem, layers))) //tail call optimization
|
||||
@tailrec private def unrollDiagramLayers(revIter : Iterator[BattleDiagramAction], layers : Option[BattleDiagramChain] = None) : Option[BattleDiagramChain] = {
|
||||
if(!revIter.hasNext) {
|
||||
layers
|
||||
}
|
||||
else {
|
||||
val elem : BattleDiagramAction = revIter.next
|
||||
unrollDiagramLayers(revIter, Some(BattleDiagramChain(elem, layers)))
|
||||
}
|
||||
}
|
||||
|
||||
implicit val codec : Codec[BattleplanMessage] = (
|
||||
("char_id" | uint32L) ::
|
||||
("player_name" | PacketHelpers.encodedWideString) ::
|
||||
("zone_id" | PlanetSideGUID.codec) ::
|
||||
("zone_id" | uint16L) ::
|
||||
(uint8L >>:~ { count =>
|
||||
conditional(count > 0, "diagrams" | parse_diagrams_codec(count)).hlist
|
||||
})
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class BattleplanMessageTest extends Specification {
|
|||
case BattleplanMessage(char_id, player_name, zone_id, diagrams) =>
|
||||
char_id mustEqual 41490746
|
||||
player_name mustEqual "YetAnotherFailureAlt"
|
||||
zone_id mustEqual PlanetSideGUID(0)
|
||||
zone_id mustEqual 0
|
||||
diagrams.size mustEqual 1
|
||||
//0
|
||||
diagrams.head.action mustEqual DiagramActionCode.StartDrawing
|
||||
|
|
@ -34,7 +34,7 @@ class BattleplanMessageTest extends Specification {
|
|||
case BattleplanMessage(char_id, player_name, zone_id, diagrams) =>
|
||||
char_id mustEqual 41490746
|
||||
player_name mustEqual "YetAnotherFailureAlt"
|
||||
zone_id mustEqual PlanetSideGUID(0)
|
||||
zone_id mustEqual 0
|
||||
diagrams.size mustEqual 1
|
||||
//0
|
||||
diagrams.head.action mustEqual DiagramActionCode.StopDrawing
|
||||
|
|
@ -49,7 +49,7 @@ class BattleplanMessageTest extends Specification {
|
|||
case BattleplanMessage(char_id, player_name, zone_id, diagrams) =>
|
||||
char_id mustEqual 41378949
|
||||
player_name mustEqual "Outstabulous"
|
||||
zone_id mustEqual PlanetSideGUID(10)
|
||||
zone_id mustEqual 10
|
||||
diagrams.size mustEqual 32
|
||||
//0
|
||||
diagrams.head.action mustEqual DiagramActionCode.Vertex
|
||||
|
|
@ -191,7 +191,7 @@ class BattleplanMessageTest extends Specification {
|
|||
case BattleplanMessage(char_id, player_name, zone_id, diagrams) =>
|
||||
char_id mustEqual 41378949
|
||||
player_name mustEqual "Outstabulous"
|
||||
zone_id mustEqual PlanetSideGUID(10)
|
||||
zone_id mustEqual 10
|
||||
diagrams.size mustEqual 3
|
||||
//0
|
||||
diagrams.head.action mustEqual DiagramActionCode.Style
|
||||
|
|
@ -217,7 +217,7 @@ class BattleplanMessageTest extends Specification {
|
|||
case BattleplanMessage(char_id, player_name, zone_id, diagrams) =>
|
||||
char_id mustEqual 41378949
|
||||
player_name mustEqual "Outstabulous"
|
||||
zone_id mustEqual PlanetSideGUID(10)
|
||||
zone_id mustEqual 10
|
||||
diagrams.size mustEqual 1
|
||||
//0
|
||||
diagrams.head.action mustEqual DiagramActionCode.DrawString
|
||||
|
|
@ -237,7 +237,7 @@ class BattleplanMessageTest extends Specification {
|
|||
val msg = BattleplanMessage(
|
||||
41490746,
|
||||
"YetAnotherFailureAlt",
|
||||
PlanetSideGUID(0),
|
||||
0,
|
||||
BattleDiagramAction(DiagramActionCode.StartDrawing) ::
|
||||
Nil
|
||||
)
|
||||
|
|
@ -250,7 +250,7 @@ class BattleplanMessageTest extends Specification {
|
|||
val msg = BattleplanMessage(
|
||||
41490746,
|
||||
"YetAnotherFailureAlt",
|
||||
PlanetSideGUID(0),
|
||||
0,
|
||||
BattleDiagramAction(DiagramActionCode.StopDrawing) ::
|
||||
Nil
|
||||
)
|
||||
|
|
@ -263,7 +263,7 @@ class BattleplanMessageTest extends Specification {
|
|||
val msg = BattleplanMessage(
|
||||
41378949,
|
||||
"Outstabulous",
|
||||
PlanetSideGUID(10),
|
||||
10,
|
||||
BattleDiagramAction.vertex(7512.0f, 6312.0f) ::
|
||||
BattleDiagramAction.vertex(7512.0f, 6328.0f) ::
|
||||
BattleDiagramAction.vertex(7512.0f, 6344.0f) ::
|
||||
|
|
@ -307,7 +307,7 @@ class BattleplanMessageTest extends Specification {
|
|||
val msg = BattleplanMessage(
|
||||
41378949,
|
||||
"Outstabulous",
|
||||
PlanetSideGUID(10),
|
||||
10,
|
||||
BattleDiagramAction.style(3.0f, 2) ::
|
||||
BattleDiagramAction.vertex(7512.0f, 6328.0f) ::
|
||||
BattleDiagramAction.vertex(7512.0f, 6344.0f) ::
|
||||
|
|
@ -322,7 +322,7 @@ class BattleplanMessageTest extends Specification {
|
|||
val msg = BattleplanMessage(
|
||||
41378949,
|
||||
"Outstabulous",
|
||||
PlanetSideGUID(10),
|
||||
10,
|
||||
BattleDiagramAction.drawString(7512.0f, 6312.0f, 2, 0, "Hello Auraxis!") :: Nil
|
||||
)
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import java.util.concurrent.atomic.AtomicInteger
|
|||
import akka.actor.{Actor, ActorRef, Cancellable, MDCContextAware}
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.control._
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.packet.game.{BattleDiagramAction, _}
|
||||
import scodec.Attempt.{Failure, Successful}
|
||||
import scodec.bits._
|
||||
import org.log4s.MDC
|
||||
|
|
@ -559,10 +559,10 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
.headOption match {
|
||||
case Some(tube) =>
|
||||
sendResponse(
|
||||
DeployableObjectsInfoMessage(
|
||||
DeploymentAction.Build,
|
||||
DeployableInfo(tube.GUID, DeployableIcon.AegisShieldGenerator, tube.Position, player.GUID)
|
||||
)
|
||||
BattleplanMessage(41378949, "ams", continent.Number, List(BattleDiagramAction(DiagramActionCode.StartDrawing)))
|
||||
)
|
||||
sendResponse(
|
||||
BattleplanMessage(41378949, "ams", continent.Number, List(BattleDiagramAction.drawString(tube.Position.x, tube.Position.y, 3, 0, "AMS")))
|
||||
)
|
||||
amsSpawnPoint = Some(tube)
|
||||
case None => ;
|
||||
|
|
@ -574,11 +574,17 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
|
||||
case Deployment.CanDeploy(obj, state) =>
|
||||
val vehicle_guid = obj.GUID
|
||||
if(state == DriveState.Deploying) {
|
||||
//TODO remove this arbitrary allowance angle when no longer helpful
|
||||
if(obj.Orientation.x > 30 && obj.Orientation.x < 330) {
|
||||
obj.DeploymentState = DriveState.Mobile
|
||||
CanNotChangeDeployment(obj, state, "ground too steep")
|
||||
}
|
||||
else if(state == DriveState.Deploying) {
|
||||
log.info(s"DeployRequest: $obj transitioning to deploy state")
|
||||
obj.Velocity = Some(Vector3.Zero) //no velocity
|
||||
sendResponse(DeployRequestMessage(player.GUID, vehicle_guid, state, 0, false, Vector3.Zero))
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.DeployRequest(player.GUID, vehicle_guid, state, 0, false, Vector3.Zero))
|
||||
DeploymentActivities(obj)
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
context.system.scheduler.scheduleOnce(obj.DeployTime milliseconds, obj.Actor, Deployment.TryDeploy(DriveState.Deployed))
|
||||
|
|
@ -600,6 +606,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
log.info(s"DeployRequest: $obj transitioning to undeploy state")
|
||||
sendResponse(DeployRequestMessage(player.GUID, vehicle_guid, state, 0, false, Vector3.Zero))
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.DeployRequest(player.GUID, vehicle_guid, state, 0, false, Vector3.Zero))
|
||||
DeploymentActivities(obj)
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
context.system.scheduler.scheduleOnce(obj.UndeployTime milliseconds, obj.Actor, Deployment.TryUndeploy(DriveState.Mobile))
|
||||
|
|
@ -608,6 +615,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
log.info(s"DeployRequest: $obj is Mobile")
|
||||
sendResponse(DeployRequestMessage(player.GUID, vehicle_guid, state, 0, false, Vector3.Zero))
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.DeployRequest(player.GUID, vehicle_guid, state, 0, false, Vector3.Zero))
|
||||
DeploymentActivities(obj)
|
||||
//...
|
||||
}
|
||||
else {
|
||||
|
|
@ -1271,11 +1279,34 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
log.warn(s"$tplayer is already spawned on zone ${zone.Id}; a clerical error?")
|
||||
|
||||
case Zone.Lattice.SpawnPoint(zone_id, spawn_tube) =>
|
||||
var pos = spawn_tube.Position
|
||||
var ori = spawn_tube.Orientation
|
||||
spawn_tube.Owner match {
|
||||
case building : Building =>
|
||||
log.info(s"Zone.Lattice.SpawnPoint: spawn point on $zone_id in ${building.Id} selected")
|
||||
log.info(s"Zone.Lattice.SpawnPoint: spawn point on $zone_id in building ${building.Id} selected")
|
||||
case vehicle : Vehicle =>
|
||||
log.info(s"Zone.Lattice.SpawnPoint: ams spawn point on $zone_id at ${spawn_tube.Position} selected")
|
||||
//TODO replace this bad math with good math or no math
|
||||
//position the player alongside either of the AMS's terminals, facing away from it
|
||||
val side = if(System.currentTimeMillis() % 2 == 0) 1 else -1 //right | left
|
||||
val z = spawn_tube.Orientation.z
|
||||
val zrot = (z + 90) % 360
|
||||
val x = spawn_tube.Orientation.x
|
||||
val xsin = 3 * side * math.abs(math.sin(math.toRadians(x))).toFloat + 0.5f //sin because 0-degrees is up
|
||||
val zrad = math.toRadians(zrot)
|
||||
pos = pos + (Vector3(math.sin(zrad).toFloat, math.cos(zrad).toFloat, 0) * (3 * side)) //x=sin, y=cos because compass-0 is East, not North
|
||||
ori = if(side == 1) {
|
||||
Vector3(0, 0, zrot)
|
||||
}
|
||||
else {
|
||||
Vector3(0, 0, (z - 90) % 360)
|
||||
}
|
||||
pos = if(x >= 330) {
|
||||
pos + Vector3(0, 0, xsin)
|
||||
}
|
||||
else {
|
||||
pos - Vector3(0, 0, xsin)
|
||||
}
|
||||
log.info(s"Zone.Lattice.SpawnPoint: spawn point on $zone_id at ams ${vehicle.GUID.guid} selected")
|
||||
case owner =>
|
||||
log.warn(s"Zone.Lattice.SpawnPoint: spawn point on $zone_id at ${spawn_tube.Position} has unexpected owner $owner")
|
||||
}
|
||||
|
|
@ -1298,8 +1329,8 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
player //player is deconstructing self
|
||||
}
|
||||
|
||||
tplayer.Position = spawn_tube.Position
|
||||
tplayer.Orientation = spawn_tube.Orientation
|
||||
tplayer.Position = pos
|
||||
tplayer.Orientation = ori
|
||||
val (target, msg) : (ActorRef, Any) = if(sameZone) {
|
||||
if(backpack) {
|
||||
//respawning from unregistered player
|
||||
|
|
@ -1576,7 +1607,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
clientKeepAlive.cancel
|
||||
clientKeepAlive = context.system.scheduler.schedule(0 seconds, 500 milliseconds, self, PokeClient())
|
||||
//log.warn(PacketCoding.DecodePacket(hex"ad00000000000000001d56f0531374426020000010").toString)
|
||||
log.warn(PacketCoding.DecodePacket(hex"d2327e7b8a972b95113881003710").toString)
|
||||
|
||||
case msg @ CharacterCreateRequestMessage(name, head, voice, gender, empire) =>
|
||||
log.info("Handling " + msg)
|
||||
|
|
@ -4047,6 +4078,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
case DriveState.Undeploying =>
|
||||
vehicleService ! VehicleServiceMessage.AMSDeploymentChange(continent)
|
||||
sendResponse(PlanetsideAttributeMessage(obj.GUID, 81, 0))
|
||||
case DriveState.Mobile | DriveState.State7 =>
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
|
@ -4075,12 +4107,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
|
||||
def ClearCurrentAmsSpawnPoint() : Unit = {
|
||||
amsSpawnPoint match {
|
||||
case Some(tube) =>
|
||||
case Some(_) =>
|
||||
sendResponse(
|
||||
DeployableObjectsInfoMessage(
|
||||
DeploymentAction.Dismiss,
|
||||
DeployableInfo(tube.GUID, DeployableIcon.AegisShieldGenerator, tube.Position, player.GUID)
|
||||
)
|
||||
BattleplanMessage(41378949, "ams", continent.Number, List(BattleDiagramAction(DiagramActionCode.StopDrawing)))
|
||||
)
|
||||
amsSpawnPoint = None
|
||||
case None => ;
|
||||
|
|
|
|||
Loading…
Reference in a new issue