mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-03-17 19:10:37 +00:00
Implant definitions, stamina audit and initialization
This commit is contained in:
parent
28960ad24f
commit
404e2579ef
11 changed files with 273 additions and 201 deletions
|
|
@ -162,11 +162,13 @@ class WorldSessionActor extends Actor
|
|||
var squadUpdateCounter : Int = 0
|
||||
val queuedSquadActions : Seq[() => Unit] = Seq(SquadUpdates, NoSquadUpdates, NoSquadUpdates, NoSquadUpdates)
|
||||
|
||||
var timeDL : Long = 0
|
||||
var timeSurge : Long = 0
|
||||
lazy val unsignedIntMaxValue : Long = Int.MaxValue.toLong * 2L + 1L
|
||||
var serverTime : Long = 0
|
||||
|
||||
/** Keeps track of the number of PlayerStateMessageUpstream messages received by the client
|
||||
* As they should arrive roughly every 250 milliseconds this allows for a very crude method of scheduling tasks up to four times per second */
|
||||
private var playerStateMessageUpstreamCount = 0
|
||||
|
||||
var amsSpawnPoints : List[SpawnPoint] = Nil
|
||||
var clientKeepAlive : Cancellable = DefaultCancellable.obj
|
||||
var progressBarUpdate : Cancellable = DefaultCancellable.obj
|
||||
|
|
@ -1301,8 +1303,26 @@ class WorldSessionActor extends Actor
|
|||
InitializeDeployableQuantities(avatar) //set deployables ui elements
|
||||
AwardBattleExperiencePoints(avatar, 20000000L)
|
||||
avatar.CEP = 600000
|
||||
avatar.Implants(0).Unlocked = true
|
||||
avatar.Implants(0).Implant = GlobalDefinitions.darklight_vision
|
||||
avatar.Implants(1).Unlocked = true
|
||||
avatar.Implants(1).Implant = GlobalDefinitions.surge
|
||||
avatar.Implants(2).Unlocked = true
|
||||
avatar.Implants(2).Implant = GlobalDefinitions.targeting
|
||||
|
||||
player = new Player(avatar)
|
||||
|
||||
(0 until DetailedCharacterData.numberOfImplantSlots(player.BEP)).foreach(slot => {
|
||||
val implantSlot = player.ImplantSlot(slot)
|
||||
if(implantSlot.Initialized) {
|
||||
sendResponse(AvatarImplantMessage(player.GUID, ImplantAction.Initialization, slot, 1))
|
||||
}
|
||||
else {
|
||||
player.Actor ! Player.ImplantInitializationStart(slot)
|
||||
}
|
||||
//TODO if this implant is Installed but does not have shortcut, add to a free slot or write over slot 61/62/63
|
||||
})
|
||||
|
||||
//xy-coordinates indicate sanctuary spawn bias:
|
||||
player.Position = math.abs(scala.util.Random.nextInt() % avatar.name.hashCode % 4) match {
|
||||
case 0 => Vector3(8192, 8192, 0) //NE
|
||||
|
|
@ -1534,12 +1554,10 @@ class WorldSessionActor extends Actor
|
|||
}
|
||||
|
||||
case AvatarResponse.DeactivateImplantSlot(slot) =>
|
||||
//temporary solution until implants are finalized
|
||||
slot match {
|
||||
case 1 => DeactivateImplantDarkLight()
|
||||
case 2 => DeactivateImplantSurge()
|
||||
case _ => ;
|
||||
}
|
||||
sendResponse(AvatarImplantMessage(PlanetSideGUID(player.GUID.guid), ImplantAction.Activation, slot, 0))
|
||||
|
||||
case AvatarResponse.ActivateImplantSlot(slot) =>
|
||||
sendResponse(AvatarImplantMessage(PlanetSideGUID(player.GUID.guid), ImplantAction.Activation, slot, 1))
|
||||
|
||||
case AvatarResponse.Destroy(victim, killer, weapon, pos) =>
|
||||
// guid = victim // killer = killer ;)
|
||||
|
|
@ -1572,8 +1590,6 @@ class WorldSessionActor extends Actor
|
|||
val respawnTimer = 300000 //milliseconds
|
||||
ToggleMaxSpecialState(enable = false)
|
||||
deadState = DeadState.Dead
|
||||
timeDL = 0
|
||||
timeSurge = 0
|
||||
continent.GUID(player.VehicleSeated) match {
|
||||
case Some(obj : Vehicle) =>
|
||||
TotalDriverVehicleControl(obj)
|
||||
|
|
@ -2587,6 +2603,7 @@ class WorldSessionActor extends Actor
|
|||
log.info(s"$message - put in slot $slot")
|
||||
sendResponse(AvatarImplantMessage(tplayer.GUID, ImplantAction.Add, slot, implant_type.id))
|
||||
sendResponse(ItemTransactionResultMessage(terminal_guid, TransactionType.Learn, true))
|
||||
player.Actor ! Player.ImplantInitializationStart(slot)
|
||||
}
|
||||
else {
|
||||
if(interface.isEmpty) {
|
||||
|
|
@ -2620,6 +2637,7 @@ class WorldSessionActor extends Actor
|
|||
if(interface.contains(terminal_guid.guid) && slotNumber.isDefined) {
|
||||
val slot = slotNumber.get
|
||||
log.info(s"$tplayer is selling $implant_type - take from slot $slot")
|
||||
player.Actor ! Player.UninitializeImplant(slot)
|
||||
sendResponse(AvatarImplantMessage(tplayer.GUID, ImplantAction.Remove, slot, 0))
|
||||
sendResponse(ItemTransactionResultMessage(terminal_guid, TransactionType.Sell, true))
|
||||
}
|
||||
|
|
@ -3358,8 +3376,13 @@ class WorldSessionActor extends Actor
|
|||
sendResponse(ChatMsg(ChatMessageType.CMT_TOGGLESPECTATORMODE, false, "", "on", None))
|
||||
}
|
||||
(0 until DetailedCharacterData.numberOfImplantSlots(tplayer.BEP)).foreach(slot => {
|
||||
sendResponse(AvatarImplantMessage(guid, ImplantAction.Initialization, slot, 1)) //init implant slot
|
||||
sendResponse(AvatarImplantMessage(guid, ImplantAction.Activation, slot, 0)) //deactivate implant
|
||||
val implantSlot = player.ImplantSlot(slot)
|
||||
if(implantSlot.Initialized) {
|
||||
sendResponse(AvatarImplantMessage(guid, ImplantAction.Initialization, slot, 1))
|
||||
}
|
||||
else {
|
||||
player.Actor ! Player.ImplantInitializationStart(slot)
|
||||
}
|
||||
//TODO if this implant is Installed but does not have shortcut, add to a free slot or write over slot 61/62/63
|
||||
})
|
||||
sendResponse(PlanetsideAttributeMessage(PlanetSideGUID(0), 82, 0))
|
||||
|
|
@ -4011,70 +4034,20 @@ class WorldSessionActor extends Actor
|
|||
beginZoningSetCurrentAvatarFunc(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) =>
|
||||
playerStateMessageUpstreamCount += 1
|
||||
val isMoving = WorldEntity.isMoving(vel)
|
||||
val isMovingPlus = isMoving || is_jumping || jump_thrust
|
||||
//implants and stamina management start
|
||||
val implantsAreActive = avatar.Implants(0).Active || avatar.Implants(1).Active
|
||||
val staminaBefore = player.Stamina
|
||||
val hadStaminaBefore = staminaBefore > 0
|
||||
val hasStaminaAfter = if(deadState == DeadState.Alive) {
|
||||
if(implantsAreActive && hadStaminaBefore) {
|
||||
val time = System.currentTimeMillis()
|
||||
if(timeDL != 0) {
|
||||
val duration = time - timeDL
|
||||
if(duration > 500) {
|
||||
val units = (duration / 500).toInt
|
||||
player.Stamina = player.Stamina - units
|
||||
timeDL += units * 500
|
||||
}
|
||||
}
|
||||
if(timeSurge != 0) {
|
||||
val duration = time - timeSurge
|
||||
val period = player.ExoSuit match {
|
||||
case ExoSuitType.Agile => 500
|
||||
case ExoSuitType.Reinforced => 333
|
||||
case ExoSuitType.Infiltration => 1000
|
||||
case ExoSuitType.Standard => 1000
|
||||
case _ => 1
|
||||
}
|
||||
if(duration > period) {
|
||||
val units = (duration / period).toInt
|
||||
player.Stamina = player.Stamina - units
|
||||
timeSurge += period * units
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(deadState == DeadState.Alive && playerStateMessageUpstreamCount % 2 == 0) { // Regen stamina roughly every 500ms
|
||||
if(player.skipStaminaRegenForTurns > 0) {
|
||||
//do not renew stamina for a while
|
||||
player.skipStaminaRegenForTurns -= 1
|
||||
player.Stamina > 0
|
||||
}
|
||||
else if(player.Stamina == 0 && hadStaminaBefore) {
|
||||
//if the player lost all stamina this turn (had stamina at the start), do not renew stamina for a while
|
||||
player.skipStaminaRegenForTurns = 4
|
||||
player.Stamina > 0
|
||||
}
|
||||
else if(isMovingPlus || player.Stamina == player.MaxStamina) {
|
||||
//ineligible for stamina regen
|
||||
player.Stamina > 0
|
||||
}
|
||||
else {
|
||||
player.Stamina = player.Stamina + 1
|
||||
true
|
||||
else if(!isMovingPlus && player.Stamina != player.MaxStamina) {
|
||||
player.Stamina += 1
|
||||
}
|
||||
}
|
||||
else {
|
||||
timeDL = 0
|
||||
timeSurge = 0
|
||||
false
|
||||
}
|
||||
if(staminaBefore != player.Stamina) { //stamina changed
|
||||
sendResponse(PlanetsideAttributeMessage(player.GUID, 2, player.Stamina))
|
||||
}
|
||||
if(implantsAreActive && !hasStaminaAfter) { //implants deactivated at 0 stamina
|
||||
DeactivateImplants()
|
||||
}
|
||||
//implants and stamina management finish
|
||||
|
||||
player.Position = pos
|
||||
player.Velocity = vel
|
||||
player.Orientation = Vector3(player.Orientation.x, pitch, yaw)
|
||||
|
|
@ -4667,7 +4640,6 @@ class WorldSessionActor extends Actor
|
|||
//log.info("AvatarJump: " + msg)
|
||||
player.Stamina = player.Stamina - 10
|
||||
player.skipStaminaRegenForTurns = math.max(player.skipStaminaRegenForTurns, 5)
|
||||
sendResponse(PlanetsideAttributeMessage(player.GUID, 2, player.Stamina))
|
||||
|
||||
case msg @ ZipLineMessage(player_guid,forwards,action,path_id,pos) =>
|
||||
log.info("ZipLineMessage: " + msg)
|
||||
|
|
@ -4882,25 +4854,10 @@ class WorldSessionActor extends Actor
|
|||
log.warn(s"LootItem: can not find where to put $item_guid")
|
||||
}
|
||||
|
||||
case msg @ AvatarImplantMessage(_, action, slot, status) => //(player_guid, unk1, unk2, implant) =>
|
||||
case msg @ AvatarImplantMessage(player_guid, action, slot, status) =>
|
||||
log.info("AvatarImplantMessage: " + msg)
|
||||
if (avatar.Implants(slot).Initialized) {
|
||||
if(action == ImplantAction.Activation && status == 1) { // active
|
||||
avatar.Implants(slot).Active = true
|
||||
continent.AvatarEvents ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttribute(player.GUID, 28, avatar.Implant(slot).id * 2 + 1))
|
||||
if (avatar.Implant(slot).id == 3) {
|
||||
timeDL = System.currentTimeMillis()
|
||||
player.Stamina = player.Stamina - 3
|
||||
sendResponse(PlanetsideAttributeMessage(player.GUID, 2, player.Stamina))
|
||||
}
|
||||
if (avatar.Implant(slot).id == 9) timeSurge = System.currentTimeMillis()
|
||||
} else if(action == ImplantAction.Activation && status == 0) { //desactive
|
||||
avatar.Implants(slot).Active = false
|
||||
continent.AvatarEvents ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttribute(player.GUID, 28, avatar.Implant(slot).id * 2))
|
||||
if (avatar.Implant(slot).id == 3) timeDL = 0
|
||||
if (avatar.Implant(slot).id == 9) timeSurge = 0
|
||||
}
|
||||
sendResponse(AvatarImplantMessage(PlanetSideGUID(player.GUID.guid),action,slot,status))
|
||||
if(action == ImplantAction.Activation) {
|
||||
player.Actor ! Player.ImplantActivation(slot, status)
|
||||
}
|
||||
|
||||
case msg @ UseItemMessage(avatar_guid, item_used_guid, object_guid, unk2, unk3, unk4, unk5, unk6, unk7, unk8, itemType) =>
|
||||
|
|
@ -5073,7 +5030,6 @@ class WorldSessionActor extends Actor
|
|||
sendResponse(ObjectDeleteMessage(kit.GUID, 0))
|
||||
taskResolver ! GUIDTask.UnregisterEquipment(kit)(continent.GUID)
|
||||
player.Stamina = player.Stamina + 100
|
||||
sendResponse(PlanetsideAttributeMessage(avatar_guid, 2, player.Stamina))
|
||||
case None =>
|
||||
log.error(s"UseItem: anticipated a $kit, but can't find it")
|
||||
}
|
||||
|
|
@ -5652,7 +5608,6 @@ class WorldSessionActor extends Actor
|
|||
else { //shooting
|
||||
if (tool.FireModeIndex == 1 && (tool.Definition.Name == "anniversary_guna" || tool.Definition.Name == "anniversary_gun" || tool.Definition.Name == "anniversary_gunb")) {
|
||||
player.Stamina = 0
|
||||
sendResponse(PlanetsideAttributeMessage(player.GUID, 2, 0))
|
||||
}
|
||||
|
||||
prefire = shooting.orElse(Some(weapon_guid))
|
||||
|
|
@ -8292,6 +8247,7 @@ class WorldSessionActor extends Actor
|
|||
def RespawnClone(tplayer : Player) : Player = {
|
||||
val faction = tplayer.Faction
|
||||
val obj = Player.Respawn(tplayer)
|
||||
obj.ResetAllImplants()
|
||||
LoadClassicDefault(obj)
|
||||
obj
|
||||
}
|
||||
|
|
@ -11066,39 +11022,9 @@ class WorldSessionActor extends Actor
|
|||
projectilesToCleanUp(local_index) = false
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate all active implants.
|
||||
* This method is intended to support only the current Live server implants that are functional,
|
||||
* the darklight vision implant and the surge implant.
|
||||
*/
|
||||
def DeactivateImplants() : Unit = {
|
||||
DeactivateImplantDarkLight()
|
||||
DeactivateImplantSurge()
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate the darklight vision implant.
|
||||
* This method is intended to support only the current Live server implants.
|
||||
*/
|
||||
def DeactivateImplantDarkLight() : Unit = {
|
||||
if(avatar.Implants(0).Active && avatar.Implants(0).Implant == ImplantType.DarklightVision) {
|
||||
avatar.Implants(0).Active = false
|
||||
continent.AvatarEvents ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttribute(player.GUID, 28, avatar.Implant(0).id * 2))
|
||||
sendResponse(AvatarImplantMessage(PlanetSideGUID(player.GUID.guid), ImplantAction.Activation, 0, 0))
|
||||
timeDL = 0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate the surge implant.
|
||||
* This method is intended to support only the current Live server implants.
|
||||
*/
|
||||
def DeactivateImplantSurge() : Unit = {
|
||||
if(avatar.Implants(1).Active && avatar.Implants(0).Implant == ImplantType.Surge) {
|
||||
avatar.Implants(1).Active = false
|
||||
continent.AvatarEvents ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttribute(player.GUID, 28, avatar.Implant(1).id * 2))
|
||||
sendResponse(AvatarImplantMessage(PlanetSideGUID(player.GUID.guid), ImplantAction.Activation, 1, 0))
|
||||
timeSurge = 0
|
||||
for(slot <- 0 to player.Implants.length - 1) {
|
||||
player.Actor ! Player.ImplantActivation(slot, 0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue