Turret Fix (#267)

* created a transitional period within facility turret upgrades structured around a completion boolean; the turret upgrader responds properly to this boolean and also possesses a new task flow for GUID registration; facility turrets now have variable weapon rendering, a custom mounting function, and a back door in case they get stuck upgrading

* moving the code to reset the turret upgrade process from the case for RequestDestory to ChatMsg, alongside the vehicle terminal reset
This commit is contained in:
Fate-JH 2019-10-06 14:05:17 -04:00 committed by GitHub
parent d7a950a16f
commit 242cc4f7c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 94 additions and 45 deletions

View file

@ -11,6 +11,7 @@ class FacilityTurret(tDef : TurretDefinition) extends Amenity
with StandardResistanceProfile { with StandardResistanceProfile {
/** some turrets can be updated; they all start without updates */ /** some turrets can be updated; they all start without updates */
private var upgradePath : TurretUpgrade.Value = TurretUpgrade.None private var upgradePath : TurretUpgrade.Value = TurretUpgrade.None
private var middleOfUpgrade : Boolean = false
WeaponTurret.LoadDefinition(this) WeaponTurret.LoadDefinition(this)
@ -23,16 +24,33 @@ class FacilityTurret(tDef : TurretDefinition) extends Amenity
def Upgrade : TurretUpgrade.Value = upgradePath def Upgrade : TurretUpgrade.Value = upgradePath
def Upgrade_=(upgrade : TurretUpgrade.Value) : TurretUpgrade.Value = { def Upgrade_=(upgrade : TurretUpgrade.Value) : TurretUpgrade.Value = {
upgradePath = upgrade middleOfUpgrade = true //blocking flag; block early
var updated = false
//upgrade each weapon as long as that weapon has a valid option for that upgrade //upgrade each weapon as long as that weapon has a valid option for that upgrade
Definition.Weapons.foreach({ case(index, upgradePaths) => Definition.Weapons.foreach({ case(index, upgradePaths) =>
if(upgradePaths.contains(upgrade)) { if(upgradePaths.contains(upgrade)) {
updated = true
weapons(index).Equipment.get.asInstanceOf[TurretWeapon].Upgrade = upgrade weapons(index).Equipment.get.asInstanceOf[TurretWeapon].Upgrade = upgrade
} }
}) })
if(updated) {
upgradePath = upgrade
}
else {
middleOfUpgrade = false //reset
}
Upgrade Upgrade
} }
def ConfirmUpgrade(upgrade : TurretUpgrade.Value) : TurretUpgrade.Value = {
if(middleOfUpgrade && upgradePath == upgrade) {
middleOfUpgrade = false
}
upgradePath
}
def isUpgrading : Boolean = middleOfUpgrade
def DamageModel = Definition.asInstanceOf[DamageResistanceModel] def DamageModel = Definition.asInstanceOf[DamageResistanceModel]
def Definition : TurretDefinition = tDef def Definition : TurretDefinition = tDef

View file

@ -176,11 +176,13 @@ class TurretUpgrader extends SupportActor[TurretUpgrader.Entry] {
}) })
info(s"Converting manned wall turret weapon to $upgrade") info(s"Converting manned wall turret weapon to $upgrade")
val oldBoxesTask = AllMountedWeaponMagazines(target) val oldBoxes = AllMountedWeaponMagazines(target)
.map(box => GUIDTask.UnregisterEquipment(box)(guid))
.toList
target.Upgrade = upgrade //perform upgrade target.Upgrade = upgrade //perform upgrade
val newBoxes = AllMountedWeaponMagazines(target)
val oldBoxesTask = oldBoxes
.filterNot { box => newBoxes.exists(_ eq box) }
.map(box => GUIDTask.UnregisterEquipment(box)(guid)).toList
val newBoxesTask = TaskResolver.GiveTask( val newBoxesTask = TaskResolver.GiveTask(
new Task() { new Task() {
private val localFunc : ()=>Unit = FinishUpgradingTurret(entry) private val localFunc : ()=>Unit = FinishUpgradingTurret(entry)
@ -188,17 +190,27 @@ class TurretUpgrader extends SupportActor[TurretUpgrader.Entry] {
override def isComplete = Task.Resolution.Success override def isComplete = Task.Resolution.Success
def Execute(resolver : ActorRef) : Unit = { def Execute(resolver : ActorRef) : Unit = {
localFunc()
resolver ! scala.util.Success(this) resolver ! scala.util.Success(this)
} }
}, AllMountedWeaponMagazines(target).map(box => GUIDTask.RegisterEquipment(box)(guid)).toList
override def onSuccess() : Unit = {
super.onSuccess()
localFunc()
}
},
newBoxes
.filterNot { box => oldBoxes.exists(_ eq box) }
.map(box => GUIDTask.RegisterEquipment(box)(guid)).toList
) )
taskResolver ! TaskResolver.GiveTask( taskResolver ! TaskResolver.GiveTask(
new Task() { new Task() {
private val tasks = oldBoxesTask
def Execute(resolver : ActorRef) : Unit = { def Execute(resolver : ActorRef) : Unit = {
tasks.foreach { resolver ! _ }
resolver ! scala.util.Success(this) resolver ! scala.util.Success(this)
} }
}, oldBoxesTask :+ newBoxesTask }, List(newBoxesTask)
) )
} }
@ -225,15 +237,18 @@ class TurretUpgrader extends SupportActor[TurretUpgrader.Entry] {
val target = entry.obj.asInstanceOf[FacilityTurret] val target = entry.obj.asInstanceOf[FacilityTurret]
val zone = entry.zone val zone = entry.zone
info(s"Wall turret finished ${target.Upgrade} upgrade") info(s"Wall turret finished ${target.Upgrade} upgrade")
target.ConfirmUpgrade(entry.upgrade)
val targetGUID = target.GUID val targetGUID = target.GUID
target.Weapons if(target.Health > 0) {
.map({ case (index, slot) => (index, slot.Equipment) }) target.Weapons
.collect { case (index, Some(tool : Tool)) => .map({ case (index, slot) => (index, slot.Equipment) })
context.parent ! VehicleServiceMessage( .collect { case (index, Some(tool : Tool)) =>
zone.Id, context.parent ! VehicleServiceMessage(
VehicleAction.EquipmentInSlot(PlanetSideGUID(0), targetGUID, index, tool) zone.Id,
) VehicleAction.EquipmentInSlot(PlanetSideGUID(0), targetGUID, index, tool)
} )
}
}
} }
} }

View file

@ -1409,6 +1409,16 @@ class WorldSessionActor extends Actor with MDCContextAware {
UpdateWeaponAtSeatPosition(obj, seat_num) UpdateWeaponAtSeatPosition(obj, seat_num)
MountingAction(tplayer, obj, seat_num) MountingAction(tplayer, obj, seat_num)
case Mountable.CanMount(obj : FacilityTurret, seat_num) =>
if(!obj.isUpgrading) {
sendResponse(PlanetsideAttributeMessage(obj.GUID, 0, obj.Health))
UpdateWeaponAtSeatPosition(obj, seat_num)
MountingAction(tplayer, obj, seat_num)
}
else {
log.warn(s"MountVehicleMsg: ${tplayer.Name} wants to mount turret ${obj.GUID.guid}, but needs to wait until it finishes updating")
}
case Mountable.CanMount(obj : PlanetSideGameObject with WeaponTurret, seat_num) => case Mountable.CanMount(obj : PlanetSideGameObject with WeaponTurret, seat_num) =>
sendResponse(PlanetsideAttributeMessage(obj.GUID, 0, obj.Health)) sendResponse(PlanetsideAttributeMessage(obj.GUID, 0, obj.Health))
UpdateWeaponAtSeatPosition(obj, seat_num) UpdateWeaponAtSeatPosition(obj, seat_num)
@ -3225,43 +3235,43 @@ class WorldSessionActor extends Actor with MDCContextAware {
}) })
//base turrets //base turrets
continent.Map.TurretToWeapon.foreach({ case((turret_guid, weapon_guid)) => continent.Map.TurretToWeapon
val parent_guid = PlanetSideGUID(turret_guid) .map { case((turret_guid, _)) => continent.GUID(turret_guid) }
continent.GUID(turret_guid) match { .collect { case Some(turret : FacilityTurret) =>
case Some(turret : FacilityTurret) => val pguid = turret.GUID
//attached weapon //attached weapon
turret.ControlledWeapon(1) match { if(!turret.isUpgrading) {
turret.ControlledWeapon(wepNumber = 1) match {
case Some(obj : Tool) => case Some(obj : Tool) =>
val objDef = obj.Definition val objDef = obj.Definition
sendResponse( sendResponse(
ObjectCreateMessage( ObjectCreateMessage(
objDef.ObjectId, objDef.ObjectId,
obj.GUID, obj.GUID,
ObjectCreateMessageParent(parent_guid, 1), ObjectCreateMessageParent(pguid, 1),
objDef.Packet.ConstructorData(obj).get objDef.Packet.ConstructorData(obj).get
) )
) )
case _ => ; case _ => ;
} }
//reserved ammunition? }
//TODO need to register if it exists //reserved ammunition?
//seat turret occupant //TODO need to register if it exists
turret.Seats(0).Occupant match { //seat turret occupant
case Some(tplayer) => turret.Seats(0).Occupant match {
val tdefintion = tplayer.Definition case Some(tplayer) =>
sendResponse( val tdefintion = tplayer.Definition
ObjectCreateMessage( sendResponse(
tdefintion.ObjectId, ObjectCreateMessage(
tplayer.GUID, tdefintion.ObjectId,
ObjectCreateMessageParent(parent_guid, 0), tplayer.GUID,
tdefintion.Packet.ConstructorData(tplayer).get ObjectCreateMessageParent(pguid, 0),
) tdefintion.Packet.ConstructorData(tplayer).get
) )
case None => ; )
} case None => ;
case _ => ; }
} }
})
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.UpdateAmsSpawnPoint(continent)) vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.UpdateAmsSpawnPoint(continent))
self ! SetCurrentAvatar(player) self ! SetCurrentAvatar(player)
@ -3506,10 +3516,12 @@ class WorldSessionActor extends Actor with MDCContextAware {
} }
if(messagetype == ChatMessageType.CMT_DESTROY) { if(messagetype == ChatMessageType.CMT_DESTROY) {
val guid = contents.toInt val guid = contents.toInt
continent.Map.TerminalToSpawnPad.get(guid) match { continent.GUID(continent.Map.TerminalToSpawnPad.getOrElse(guid, guid)) match {
case Some(padGUID) => case Some(pad : VehicleSpawnPad) =>
continent.GUID(padGUID).get.asInstanceOf[VehicleSpawnPad].Actor ! VehicleSpawnControl.ProcessControl.Flush pad.Actor ! VehicleSpawnControl.ProcessControl.Flush
case None => case Some(turret : FacilityTurret) if turret.isUpgrading =>
FinishUpgradingMannedTurret(turret, TurretUpgrade.None)
case _ =>
self ! PacketCoding.CreateGamePacket(0, RequestDestroyMessage(PlanetSideGUID(guid))) self ! PacketCoding.CreateGamePacket(0, RequestDestroyMessage(PlanetSideGUID(guid)))
} }
} }
@ -5500,9 +5512,13 @@ class WorldSessionActor extends Actor with MDCContextAware {
* @param upgrade the new upgrade state * @param upgrade the new upgrade state
*/ */
private def FinishUpgradingMannedTurret(target : FacilityTurret, tool : Tool, upgrade : TurretUpgrade.Value)() : Unit = { private def FinishUpgradingMannedTurret(target : FacilityTurret, tool : Tool, upgrade : TurretUpgrade.Value)() : Unit = {
log.info(s"Converting manned wall turret weapon to $upgrade")
tool.Magazine = 0 tool.Magazine = 0
sendResponse(InventoryStateMessage(tool.AmmoSlot.Box.GUID, tool.GUID, 0)) sendResponse(InventoryStateMessage(tool.AmmoSlot.Box.GUID, tool.GUID, 0))
FinishUpgradingMannedTurret(target, upgrade)
}
private def FinishUpgradingMannedTurret(target : FacilityTurret, upgrade : TurretUpgrade.Value) : Unit = {
log.info(s"Converting manned wall turret weapon to $upgrade")
vehicleService ! VehicleServiceMessage.TurretUpgrade(TurretUpgrader.ClearSpecific(List(target), continent)) vehicleService ! VehicleServiceMessage.TurretUpgrade(TurretUpgrader.ClearSpecific(List(target), continent))
vehicleService ! VehicleServiceMessage.TurretUpgrade(TurretUpgrader.AddTask(target, continent, upgrade)) vehicleService ! VehicleServiceMessage.TurretUpgrade(TurretUpgrader.AddTask(target, continent, upgrade))
} }
@ -6210,7 +6226,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
sendResponse(ObjectDetachMessage(tool.GUID, previousBox.GUID, Vector3.Zero, 0f)) sendResponse(ObjectDetachMessage(tool.GUID, previousBox.GUID, Vector3.Zero, 0f))
sendResponse(ObjectDetachMessage(player.GUID, box.GUID, Vector3.Zero, 0f)) sendResponse(ObjectDetachMessage(player.GUID, box.GUID, Vector3.Zero, 0f))
obj.Inventory -= x.start //remove replacement ammo from inventory obj.Inventory -= x.start //remove replacement ammo from inventory
val ammoSlotIndex = tool.FireMode.AmmoSlotIndex val ammoSlotIndex = tool.FireMode.AmmoSlotIndex
tool.AmmoSlots(ammoSlotIndex).Box = box //put replacement ammo in tool tool.AmmoSlots(ammoSlotIndex).Box = box //put replacement ammo in tool
sendResponse(ObjectAttachMessage(tool.GUID, box.GUID, ammoSlotIndex)) sendResponse(ObjectAttachMessage(tool.GUID, box.GUID, ammoSlotIndex))