Milestone fixes (#376)

* Fix resource silos not showing the correct charge levels after server startup

* Make all continents have broadcast warpgates, disable geowarps, common initialization functions for zones

* Make instant action respect spawn point overrides e.g. z offset

* /warp and /zone restrictions from PTSv3

* Allow players hit by EMPs to disable implants correctly to prevent infinite stamina drain

* Quick fix to stop VehicleRemover from crashing if the target vehicle has no Actor assigned
This commit is contained in:
Mazo 2020-04-20 23:19:50 +01:00 committed by GitHub
parent 484fcbf56d
commit 140c2ccbc3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 152 additions and 97 deletions

View file

@ -45,7 +45,8 @@ class PlayerControl(player : Player) extends Actor
// todo: disable implants with stamina cost when changing armour type
val implantSlot = player.ImplantSlot(slot)
if(status == 0 && implantSlot.Active) {
// Allow uninitialized implants to be deactivated in case they're stuck in a state where they are no longer active or initialized but still draining stamina (e.g. by EMP)
if(status == 0 && (implantSlot.Active || !implantSlot.Initialized)) {
// Cancel stamina drain timer
implantSlotStaminaDrainTimers(slot).cancel()
implantSlotStaminaDrainTimers(slot) = DefaultCancellable.obj
@ -261,7 +262,7 @@ class PlayerControl(player : Player) extends Actor
for(slot <- 0 to player.Implants.length - 1) { // Deactivate & uninitialize all implants
player.Zone.AvatarEvents ! AvatarServiceMessage(player.Zone.Id, AvatarAction.PlanetsideAttribute(player.GUID, 28, player.Implant(slot).id * 2)) // Deactivation sound / effect
events ! AvatarServiceMessage(player.Name, AvatarAction.DeactivateImplantSlot(guid, slot))
self ! Player.ImplantActivation(slot, 0)
PlayerControl.UninitializeImplant(player, slot)
}

View file

@ -39,11 +39,7 @@ class ResourceSilo extends Amenity {
LowNtuWarningOn
}
def CapacitorDisplay : Long = capacitorDisplay
def CapacitorDisplay_=(value: Long) : Long = {
capacitorDisplay = value
CapacitorDisplay
}
def CapacitorDisplay : Long = scala.math.ceil((ChargeLevel.toFloat / MaximumCharge.toFloat) * 10).toInt
def Definition : ResourceSiloDefinition = GlobalDefinitions.resource_silo

View file

@ -50,6 +50,7 @@ class ResourceSiloControl(resourceSilo : ResourceSilo) extends Actor with Factio
case ResourceSilo.UpdateChargeLevel(amount: Int) =>
val siloChargeBeforeChange = resourceSilo.ChargeLevel
val siloDisplayBeforeChange = resourceSilo.CapacitorDisplay
val building = resourceSilo.Owner.asInstanceOf[Building]
val zone = building.Zone
@ -59,11 +60,9 @@ class ResourceSiloControl(resourceSilo : ResourceSilo) extends Actor with Factio
log.trace(s"UpdateChargeLevel: Silo ${resourceSilo.GUID} set to ${resourceSilo.ChargeLevel}")
}
val ntuBarLevel = scala.math.ceil((resourceSilo.ChargeLevel.toFloat / resourceSilo.MaximumCharge.toFloat) * 10).toInt
// Only send updated capacitor display value to all clients if it has actually changed
if(resourceSilo.CapacitorDisplay != ntuBarLevel) {
log.trace(s"Silo ${resourceSilo.GUID} NTU bar level has changed from ${resourceSilo.CapacitorDisplay} to $ntuBarLevel")
resourceSilo.CapacitorDisplay = ntuBarLevel
if(resourceSilo.CapacitorDisplay != siloDisplayBeforeChange) {
log.trace(s"Silo ${resourceSilo.GUID} NTU bar level has changed from $siloDisplayBeforeChange to ${resourceSilo.CapacitorDisplay}")
resourceSilo.Owner.Actor ! Building.SendMapUpdate(all_clients = true)
zone.AvatarEvents ! AvatarServiceMessage(
zone.Id,

View file

@ -8,7 +8,13 @@ import scodec.codecs._
/**
* Dispatched to the client in regards to cavern connections via geowarp gates.
* @param zone the zone
* @param unk na
* @param unk determines the number and composition of cavern links
* assuming two geowarps per continent the logic seems to be roughly:
* 0 - gate A disabled, B active
* 1 - gate A active, B disabled
* 2 - gate A and B active
* 3 - same as 2 (no change in destination)
* Destinations also change (north/south/east/west), but seemingly only to two of the currently active caverns can be linked to?
*/
final case class ZoneForcedCavernConnectionsMessage(zone : Int,
unk : Int)

View file

@ -1,6 +1,7 @@
// Copyright (c) 2017 PSForever
package services.vehicle.support
import akka.actor.ActorRef
import net.psforever.objects.Vehicle
import net.psforever.objects.guid.{GUIDTask, TaskResolver}
import net.psforever.objects.zones.Zone
@ -26,7 +27,9 @@ class VehicleRemover extends RemoverActor {
entry.zone.GUID(vehicleGUID) match {
case Some(vehicle : Vehicle) if vehicle.HasGUID =>
val zoneId = entry.zone.Id
vehicle.Actor ! Vehicle.PrepareForDeletion()
if(vehicle.Actor != ActorRef.noSender) {
vehicle.Actor ! Vehicle.PrepareForDeletion()
}
//escape being someone else's cargo
(vehicle.MountedIn match {
case Some(carrierGUID) =>

View file

@ -36,10 +36,9 @@ class ResourceSiloTest extends Specification {
//
obj.ChargeLevel = 50
obj.LowNtuWarningOn = false
obj.CapacitorDisplay = 75
obj.ChargeLevel mustEqual 50
obj.LowNtuWarningOn mustEqual false
obj.CapacitorDisplay mustEqual 75
obj.CapacitorDisplay mustEqual 1
}
"charge level can not exceed limits(0 to maximum)" in {
@ -237,7 +236,6 @@ class ResourceSiloControlUpdate2Test extends ActorTest {
bldg.Actor = buildingEvents.ref
obj.ChargeLevel = 100
obj.CapacitorDisplay = 1
obj.LowNtuWarningOn = true
assert(obj.ChargeLevel == 100)
assert(obj.CapacitorDisplay == 1)
@ -295,7 +293,6 @@ class ResourceSiloControlNoUpdateTest extends ActorTest {
bldg.Actor = buildingEvents.ref
obj.ChargeLevel = 250
obj.CapacitorDisplay = 3
obj.LowNtuWarningOn = false
assert(obj.ChargeLevel == 250)
assert(obj.CapacitorDisplay == 3)