From 5428bbbfbf9e00f47a1c9ecfc9f6a22f2aaf7d69 Mon Sep 17 00:00:00 2001 From: FateJH Date: Wed, 8 Nov 2017 21:00:46 -0500 Subject: [PATCH 1/5] Operational vehicle terminals: Vehicles can now be pulled from assigned and initialized terminals. The vehicle's chosen spawn pad controls (or paces) all aspects of the spawning process. Support Actors ensure that a fully-realized Vehicle will be unloaded and unregistered if left alone, either right after spawning on the pad or after an extended period of time. The latter half of the procedure used for spawning vehicles is a temporary workaround until future analysis and functionality of the server vehicle override packet is incorporated. Weapons: Weapons will now construct their own default magazines thanks to a switch from Ammo.Value to AmmoBoxDefinition in the ToolDefinition. GenericObjectActionMessage : The only thing this packet does, at the moment, is obscure the player when he is being promoted into the owner of a vehicle. --- .../objects/DefaultCancellable.scala | 18 + .../psforever/objects/ExoSuitDefinition.scala | 10 +- .../psforever/objects/GlobalDefinitions.scala | 1231 +++++++++++++++-- .../{InfantryLoadout.scala => Loadout.scala} | 58 +- .../scala/net/psforever/objects/Player.scala | 8 +- .../scala/net/psforever/objects/Tool.scala | 97 +- .../scala/net/psforever/objects/Vehicle.scala | 10 +- .../objects/definition/ToolDefinition.scala | 6 +- .../psforever/objects/equipment/Ammo.scala | 2 +- .../objects/equipment/FireModeSwitch.scala | 2 +- .../objects/inventory/GridInventory.scala | 28 +- .../objects/inventory/InventoryTile.scala | 16 +- .../serverobject/PlanetSideServerObject.scala | 2 +- .../VehicleSpawnPadObjectBuilder.scala | 35 + .../pad/VehicleSpawnControl.scala | 203 +++ .../serverobject/pad/VehicleSpawnPad.scala | 89 ++ .../AirVehicleTerminalDefinition.scala | 18 + .../terminals/BFRTerminalDefinition.scala | 19 + .../terminals/CertTerminalDefinition.scala | 10 +- .../DropshipVehicleTerminalDefinition.scala | 19 + .../GroundVehicleTerminalDefinition.scala | 18 + .../terminals/OrderTerminalDefinition.scala | 14 +- .../serverobject/terminals/Terminal.scala | 14 + .../terminals/TerminalDefinition.scala | 233 +++- .../VehicleTerminalCombinedDefinition.scala | 19 + .../psforever/objects/zones/ZoneActor.scala | 32 +- .../net/psforever/objects/zones/ZoneMap.scala | 9 +- .../psforever/packet/GamePacketOpcode.scala | 2 +- .../game/GenericObjectActionMessage.scala | 39 + .../game/PlanetsideAttributeMessage.scala | 2 +- .../game/objectcreate/ObjectClass.scala | 8 +- .../packet/game/objectcreate/Prefab.scala | 180 +-- .../scala/net/psforever/types/Vector3.scala | 78 +- common/src/test/scala/Vector3Test.scala | 68 + .../game/GenericObjectActionMessageTest.scala | 28 + .../test/scala/objects/ConverterTest.scala | 25 +- .../test/scala/objects/EquipmentTest.scala | 74 +- .../test/scala/objects/InventoryTest.scala | 20 +- .../scala/objects/VehicleSpawnPadTest.scala | 110 ++ .../src/test/scala/objects/VehicleTest.scala | 4 +- .../terminal/AirVehicleTerminalTest.scala | 37 + .../DropshipVehicleTerminalTest.scala | 37 + .../terminal/GroundVehicleTerminalTest.scala | 37 + .../terminal/TerminalControlTest.scala | 37 + .../VehicleTerminalCombinedTest.scala | 47 + pslogin/src/main/scala/PsLogin.scala | 26 +- .../src/main/scala/WorldSessionActor.scala | 254 ++-- .../scala/services/avatar/AvatarAction.scala | 1 + .../services/avatar/AvatarResponse.scala | 1 + .../scala/services/avatar/AvatarService.scala | 4 + .../local/support/DoorCloseActor.scala | 8 +- .../local/support/HackClearActor.scala | 8 +- .../services/vehicle/VehicleService.scala | 11 +- .../vehicle/VehicleServiceMessage.scala | 3 + .../vehicle/support/DeconstructionActor.scala | 13 +- .../support/DelayedDeconstructionActor.scala | 104 ++ .../vehicle/support/VehicleContextActor.scala | 9 +- 57 files changed, 2957 insertions(+), 538 deletions(-) create mode 100644 common/src/main/scala/net/psforever/objects/DefaultCancellable.scala rename common/src/main/scala/net/psforever/objects/{InfantryLoadout.scala => Loadout.scala} (81%) create mode 100644 common/src/main/scala/net/psforever/objects/serverobject/builders/VehicleSpawnPadObjectBuilder.scala create mode 100644 common/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnControl.scala create mode 100644 common/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala create mode 100644 common/src/main/scala/net/psforever/objects/serverobject/terminals/AirVehicleTerminalDefinition.scala create mode 100644 common/src/main/scala/net/psforever/objects/serverobject/terminals/BFRTerminalDefinition.scala create mode 100644 common/src/main/scala/net/psforever/objects/serverobject/terminals/DropshipVehicleTerminalDefinition.scala create mode 100644 common/src/main/scala/net/psforever/objects/serverobject/terminals/GroundVehicleTerminalDefinition.scala create mode 100644 common/src/main/scala/net/psforever/objects/serverobject/terminals/VehicleTerminalCombinedDefinition.scala create mode 100644 common/src/main/scala/net/psforever/packet/game/GenericObjectActionMessage.scala create mode 100644 common/src/test/scala/Vector3Test.scala create mode 100644 common/src/test/scala/game/GenericObjectActionMessageTest.scala create mode 100644 common/src/test/scala/objects/VehicleSpawnPadTest.scala create mode 100644 common/src/test/scala/objects/terminal/AirVehicleTerminalTest.scala create mode 100644 common/src/test/scala/objects/terminal/DropshipVehicleTerminalTest.scala create mode 100644 common/src/test/scala/objects/terminal/GroundVehicleTerminalTest.scala create mode 100644 common/src/test/scala/objects/terminal/VehicleTerminalCombinedTest.scala create mode 100644 pslogin/src/main/scala/services/vehicle/support/DelayedDeconstructionActor.scala diff --git a/common/src/main/scala/net/psforever/objects/DefaultCancellable.scala b/common/src/main/scala/net/psforever/objects/DefaultCancellable.scala new file mode 100644 index 000000000..394ba9c9f --- /dev/null +++ b/common/src/main/scala/net/psforever/objects/DefaultCancellable.scala @@ -0,0 +1,18 @@ +// Copyright (c) 2017 PSForever +package net.psforever.objects + +/** + * Used to initialize the value of a re-usable `Cancellable` object. + * By convention, it always acts like it has been cancelled before and can be cancelled. + * Should be replaced with pertinent `Cancellable` logic through the initialization of an executor. + */ +object DefaultCancellable { + import akka.actor.Cancellable + + protected class InternalCancellable extends Cancellable { + override def cancel : Boolean = true + override def isCancelled : Boolean = true + } + + final val obj : Cancellable = new InternalCancellable +} diff --git a/common/src/main/scala/net/psforever/objects/ExoSuitDefinition.scala b/common/src/main/scala/net/psforever/objects/ExoSuitDefinition.scala index 0ef2ba55f..4eea81599 100644 --- a/common/src/main/scala/net/psforever/objects/ExoSuitDefinition.scala +++ b/common/src/main/scala/net/psforever/objects/ExoSuitDefinition.scala @@ -65,7 +65,7 @@ class ExoSuitDefinition(private val suitType : ExoSuitType.Value) { object ExoSuitDefinition { final val Standard = ExoSuitDefinition(ExoSuitType.Standard) Standard.MaxArmor = 50 - Standard.InventoryScale = new InventoryTile(9,6) + Standard.InventoryScale = InventoryTile.Tile96 Standard.InventoryOffset = 6 Standard.Holster(0, EquipmentSize.Pistol) Standard.Holster(2, EquipmentSize.Rifle) @@ -73,7 +73,7 @@ object ExoSuitDefinition { final val Agile = ExoSuitDefinition(ExoSuitType.Agile) Agile.MaxArmor = 100 - Agile.InventoryScale = new InventoryTile(9,9) + Agile.InventoryScale = InventoryTile.Tile99 Agile.InventoryOffset = 6 Agile.Holster(0, EquipmentSize.Pistol) Agile.Holster(1, EquipmentSize.Pistol) @@ -83,7 +83,7 @@ object ExoSuitDefinition { final val Reinforced = ExoSuitDefinition(ExoSuitType.Reinforced) Reinforced.permission = 1 Reinforced.MaxArmor = 200 - Reinforced.InventoryScale = new InventoryTile(12,9) + Reinforced.InventoryScale = InventoryTile.Tile1209 Reinforced.InventoryOffset = 6 Reinforced.Holster(0, EquipmentSize.Pistol) Reinforced.Holster(1, EquipmentSize.Pistol) @@ -94,7 +94,7 @@ object ExoSuitDefinition { final val Infiltration = ExoSuitDefinition(ExoSuitType.Standard) Infiltration.permission = 1 Infiltration.MaxArmor = 0 - Infiltration.InventoryScale = new InventoryTile(6,6) + Infiltration.InventoryScale = InventoryTile.Tile66 Infiltration.InventoryOffset = 6 Infiltration.Holster(0, EquipmentSize.Pistol) Infiltration.Holster(4, EquipmentSize.Melee) @@ -102,7 +102,7 @@ object ExoSuitDefinition { final val MAX = ExoSuitDefinition(ExoSuitType.MAX) MAX.permission = 1 MAX.MaxArmor = 650 - MAX.InventoryScale = new InventoryTile(16,12) + MAX.InventoryScale = InventoryTile.Tile1612 MAX.InventoryOffset = 6 MAX.Holster(0, EquipmentSize.Max) MAX.Holster(4, EquipmentSize.Melee) diff --git a/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala b/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala index dba9b469e..c8ac95d62 100644 --- a/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala +++ b/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala @@ -2,13 +2,14 @@ package net.psforever.objects import net.psforever.objects.definition._ -import net.psforever.objects.definition.converter.{CommandDetonaterConverter, LockerContainerConverter, REKConverter} +import net.psforever.objects.definition.converter._ import net.psforever.objects.serverobject.doors.DoorDefinition import net.psforever.objects.equipment.CItem.DeployedItem import net.psforever.objects.equipment._ import net.psforever.objects.inventory.InventoryTile import net.psforever.objects.serverobject.locks.IFFLockDefinition -import net.psforever.objects.serverobject.terminals.{CertTerminalDefinition, OrderTerminalDefinition} +import net.psforever.objects.serverobject.terminals._ +import net.psforever.objects.vehicles.SeatArmorRestriction import net.psforever.types.PlanetSideEmpire object GlobalDefinitions { @@ -163,6 +164,33 @@ object GlobalDefinitions { } } + def AIMAX(faction : PlanetSideEmpire.Value) : ToolDefinition = { + faction match { + case PlanetSideEmpire.TR => trhev_dualcycler + case PlanetSideEmpire.NC => nchev_scattercannon + case PlanetSideEmpire.VS => vshev_quasar + case PlanetSideEmpire.NEUTRAL => suppressor //there is no common pool MAX arms + } + } + + def AVMAX(faction : PlanetSideEmpire.Value) : ToolDefinition = { + faction match { + case PlanetSideEmpire.TR => trhev_pounder + case PlanetSideEmpire.NC => nchev_falcon + case PlanetSideEmpire.VS => vshev_comet + case PlanetSideEmpire.NEUTRAL => suppressor //there is no common pool MAX arms + } + } + + def AAMAX(faction : PlanetSideEmpire.Value) : ToolDefinition = { + faction match { + case PlanetSideEmpire.TR => trhev_burster + case PlanetSideEmpire.NC => nchev_sparrow + case PlanetSideEmpire.VS => vshev_starfire + case PlanetSideEmpire.NEUTRAL => suppressor //there is no common pool MAX arms + } + } + /** * Using the definition for a piece of `Equipment` determine if it is a grenade-type weapon. * Only the normal grenades count; the grenade packs are excluded. @@ -196,17 +224,17 @@ object GlobalDefinitions { /** * Using the definition for a piece of `Equipment` determine with which faction it aligns if it is a weapon. * Only checks `Tool` objects. - * Useful for determining if some item has to be dropped during an activity like `InfantryLoadout` switching. + * Useful for determining if some item has to be dropped during an activity like `Loadout` switching. * @param edef the `EquipmentDefinition` of the item * @return the faction alignment, or `Neutral` */ def isFactionWeapon(edef : EquipmentDefinition) : PlanetSideEmpire.Value = { edef match { - case `chainblade` | `repeater` | `anniversary_guna` | `cycler` | `mini_chaingun` | `striker` => + case `chainblade` | `repeater` | `anniversary_guna` | `cycler` | `mini_chaingun` | `striker` | `trhev_dualcycler` | `trhev_pounder` | `trhev_burster` => PlanetSideEmpire.TR - case `magcutter` | `isp` | `anniversary_gun` | `gauss` | `r_shotgun` | `hunterseeker` => + case `magcutter` | `isp` | `anniversary_gun` | `gauss` | `r_shotgun` | `hunterseeker` | `nchev_scattercannon` | `nchev_falcon` | `nchev_sparrow` => PlanetSideEmpire.NC - case `forceblade` | `beamer` | `anniversary_gunb` | `pulsar` | `lasher` | `lancer` => + case `forceblade` | `beamer` | `anniversary_gunb` | `pulsar` | `lasher` | `lancer` | `vshev_quasar` | `vshev_comet` | `vshev_starfire` => PlanetSideEmpire.VS case _ => PlanetSideEmpire.NEUTRAL @@ -221,11 +249,11 @@ object GlobalDefinitions { */ def isFactionEquipment(edef : EquipmentDefinition) : PlanetSideEmpire.Value = { edef match { - case `chainblade` | `repeater` | `anniversary_guna` | `cycler` | `mini_chaingun` | `striker` | `striker_missile_ammo` => + case `chainblade` | `repeater` | `anniversary_guna` | `cycler` | `mini_chaingun` | `striker` | `striker_missile_ammo` | `trhev_dualcycler` | `trhev_pounder` | `trhev_burster` => PlanetSideEmpire.TR - case `magcutter` | `isp` | `anniversary_gun` | `gauss` | `r_shotgun` | `hunterseeker` | `hunter_seeker_missile` => + case `magcutter` | `isp` | `anniversary_gun` | `gauss` | `r_shotgun` | `hunterseeker` | `hunter_seeker_missile` | `nchev_scattercannon` | `nchev_falcon` | `nchev_sparrow` => PlanetSideEmpire.NC - case `forceblade` | `beamer` | `anniversary_gunb` | `pulsar` | `lasher` | `lancer` | `energy_cell` | `lancer_cartridge` => + case `forceblade` | `beamer` | `anniversary_gunb` | `pulsar` | `lasher` | `lancer` | `energy_cell` | `lancer_cartridge` | `vshev_quasar` | `vshev_comet` | `vshev_starfire` => PlanetSideEmpire.VS case _ => PlanetSideEmpire.NEUTRAL @@ -234,7 +262,7 @@ object GlobalDefinitions { /** * Using the definition for a piece of `Equipment` determine whether it is a "cavern weapon." - * Useful for determining if some item has to be dropped during an activity like `InfantryLoadout` switching. + * Useful for determining if some item has to be dropped during an activity like `Loadout` switching. * @param edef the `EquipmentDefinition` of the item * @return `true`, if it is; otherwise, `false` */ @@ -457,6 +485,9 @@ object GlobalDefinitions { bullet_35mm.Capacity = 100 bullet_35mm.Tile = InventoryTile.Tile44 + val ancient_ammo_vehicle = AmmoBoxDefinition(Ammo.ancient_ammo_vehicle) +// + val aphelion_laser_ammo = AmmoBoxDefinition(Ammo.aphelion_laser_ammo) aphelion_laser_ammo.Capacity = 165 @@ -487,6 +518,11 @@ object GlobalDefinitions { skyguard_flak_cannon_ammo.Capacity = 200 skyguard_flak_cannon_ammo.Tile = InventoryTile.Tile44 + val + firebird_missile = AmmoBoxDefinition(ObjectClass.firebird_missile) + firebird_missile.Capacity = 50 + firebird_missile.Tile = InventoryTile.Tile44 + val flux_cannon_thresher_battery = AmmoBoxDefinition(Ammo.flux_cannon_thresher_battery) flux_cannon_thresher_battery.Capacity = 150 @@ -630,7 +666,7 @@ object GlobalDefinitions { val chainblade = ToolDefinition(ObjectClass.chainblade) chainblade.Size = EquipmentSize.Melee - chainblade.AmmoTypes += Ammo.melee_ammo + chainblade.AmmoTypes += melee_ammo chainblade.FireModes += new FireModeDefinition chainblade.FireModes.head.AmmoTypeIndices += 0 chainblade.FireModes.head.AmmoSlotIndex = 0 @@ -643,7 +679,7 @@ object GlobalDefinitions { val magcutter = ToolDefinition(ObjectClass.magcutter) magcutter.Size = EquipmentSize.Melee - magcutter.AmmoTypes += Ammo.melee_ammo + magcutter.AmmoTypes += melee_ammo magcutter.FireModes += new FireModeDefinition magcutter.FireModes.head.AmmoTypeIndices += 0 magcutter.FireModes.head.AmmoSlotIndex = 0 @@ -656,7 +692,7 @@ object GlobalDefinitions { val forceblade = ToolDefinition(ObjectClass.forceblade) forceblade.Size = EquipmentSize.Melee - forceblade.AmmoTypes += Ammo.melee_ammo + forceblade.AmmoTypes += melee_ammo forceblade.FireModes += new FireModeDefinition forceblade.FireModes.head.AmmoTypeIndices += 0 forceblade.FireModes.head.AmmoSlotIndex = 0 @@ -671,7 +707,7 @@ object GlobalDefinitions { val katana = ToolDefinition(ObjectClass.katana) katana.Size = EquipmentSize.Melee - katana.AmmoTypes += Ammo.melee_ammo + katana.AmmoTypes += melee_ammo katana.FireModes += new FireModeDefinition katana.FireModes.head.AmmoTypeIndices += 0 katana.FireModes.head.AmmoSlotIndex = 0 @@ -686,7 +722,7 @@ object GlobalDefinitions { val frag_grenade = ToolDefinition(ObjectClass.frag_grenade) frag_grenade.Size = EquipmentSize.Pistol - frag_grenade.AmmoTypes += Ammo.frag_grenade_ammo + frag_grenade.AmmoTypes += frag_grenade_ammo frag_grenade.FireModes += new FireModeDefinition frag_grenade.FireModes.head.AmmoTypeIndices += 0 frag_grenade.FireModes.head.AmmoSlotIndex = 0 @@ -700,7 +736,7 @@ object GlobalDefinitions { val plasma_grenade = ToolDefinition(ObjectClass.plasma_grenade) plasma_grenade.Size = EquipmentSize.Pistol - plasma_grenade.AmmoTypes += Ammo.plasma_grenade_ammo + plasma_grenade.AmmoTypes += plasma_grenade_ammo plasma_grenade.FireModes += new FireModeDefinition plasma_grenade.FireModes.head.AmmoTypeIndices += 0 plasma_grenade.FireModes.head.AmmoSlotIndex = 0 @@ -714,7 +750,7 @@ object GlobalDefinitions { val jammer_grenade = ToolDefinition(ObjectClass.jammer_grenade) jammer_grenade.Size = EquipmentSize.Pistol - jammer_grenade.AmmoTypes += Ammo.jammer_grenade_ammo + jammer_grenade.AmmoTypes += jammer_grenade_ammo jammer_grenade.FireModes += new FireModeDefinition jammer_grenade.FireModes.head.AmmoTypeIndices += 0 jammer_grenade.FireModes.head.AmmoSlotIndex = 0 @@ -728,8 +764,8 @@ object GlobalDefinitions { val repeater = ToolDefinition(ObjectClass.repeater) repeater.Size = EquipmentSize.Pistol - repeater.AmmoTypes += Ammo.bullet_9mm - repeater.AmmoTypes += Ammo.bullet_9mm_AP + repeater.AmmoTypes += bullet_9mm + repeater.AmmoTypes += bullet_9mm_AP repeater.FireModes += new FireModeDefinition repeater.FireModes.head.AmmoTypeIndices += 0 repeater.FireModes.head.AmmoTypeIndices += 1 @@ -740,8 +776,8 @@ object GlobalDefinitions { val isp = ToolDefinition(ObjectClass.isp) //mag-scatter isp.Size = EquipmentSize.Pistol - isp.AmmoTypes += Ammo.shotgun_shell - isp.AmmoTypes += Ammo.shotgun_shell_AP + isp.AmmoTypes += shotgun_shell + isp.AmmoTypes += shotgun_shell_AP isp.FireModes += new FireModeDefinition isp.FireModes.head.AmmoTypeIndices += 0 isp.FireModes.head.AmmoTypeIndices += 1 @@ -752,7 +788,7 @@ object GlobalDefinitions { val beamer = ToolDefinition(ObjectClass.beamer) beamer.Size = EquipmentSize.Pistol - beamer.AmmoTypes += Ammo.energy_cell + beamer.AmmoTypes += energy_cell beamer.FireModes += new FireModeDefinition beamer.FireModes.head.AmmoTypeIndices += 0 beamer.FireModes.head.AmmoSlotIndex = 0 @@ -766,8 +802,8 @@ object GlobalDefinitions { val ilc9 = ToolDefinition(ObjectClass.ilc9) //amp ilc9.Size = EquipmentSize.Pistol - ilc9.AmmoTypes += Ammo.bullet_9mm - ilc9.AmmoTypes += Ammo.bullet_9mm_AP + ilc9.AmmoTypes += bullet_9mm + ilc9.AmmoTypes += bullet_9mm_AP ilc9.FireModes += new FireModeDefinition ilc9.FireModes.head.AmmoTypeIndices += 0 ilc9.FireModes.head.AmmoTypeIndices += 1 @@ -778,8 +814,8 @@ object GlobalDefinitions { val suppressor = ToolDefinition(ObjectClass.suppressor) suppressor.Size = EquipmentSize.Rifle - suppressor.AmmoTypes += Ammo.bullet_9mm - suppressor.AmmoTypes += Ammo.bullet_9mm_AP + suppressor.AmmoTypes += bullet_9mm + suppressor.AmmoTypes += bullet_9mm_AP suppressor.FireModes += new FireModeDefinition suppressor.FireModes.head.AmmoTypeIndices += 0 suppressor.FireModes.head.AmmoTypeIndices += 1 @@ -790,12 +826,12 @@ object GlobalDefinitions { val punisher = ToolDefinition(ObjectClass.punisher) punisher.Size = EquipmentSize.Rifle - punisher.AmmoTypes += Ammo.bullet_9mm - punisher.AmmoTypes += Ammo.bullet_9mm_AP - punisher.AmmoTypes += Ammo.rocket - punisher.AmmoTypes += Ammo.frag_cartridge - punisher.AmmoTypes += Ammo.jammer_cartridge - punisher.AmmoTypes += Ammo.plasma_cartridge + punisher.AmmoTypes += bullet_9mm + punisher.AmmoTypes += bullet_9mm_AP + punisher.AmmoTypes += rocket + punisher.AmmoTypes += frag_cartridge + punisher.AmmoTypes += jammer_cartridge + punisher.AmmoTypes += plasma_cartridge punisher.FireModes += new FireModeDefinition punisher.FireModes.head.AmmoTypeIndices += 0 punisher.FireModes.head.AmmoTypeIndices += 1 @@ -813,8 +849,8 @@ object GlobalDefinitions { val flechette = ToolDefinition(ObjectClass.flechette) //sweeper flechette.Size = EquipmentSize.Rifle - flechette.AmmoTypes += Ammo.shotgun_shell - flechette.AmmoTypes += Ammo.shotgun_shell_AP + flechette.AmmoTypes += shotgun_shell + flechette.AmmoTypes += shotgun_shell_AP flechette.FireModes += new FireModeDefinition flechette.FireModes.head.AmmoTypeIndices += 0 flechette.FireModes.head.AmmoTypeIndices += 1 @@ -825,8 +861,8 @@ object GlobalDefinitions { val cycler = ToolDefinition(ObjectClass.cycler) cycler.Size = EquipmentSize.Rifle - cycler.AmmoTypes += Ammo.bullet_9mm - cycler.AmmoTypes += Ammo.bullet_9mm_AP + cycler.AmmoTypes += bullet_9mm + cycler.AmmoTypes += bullet_9mm_AP cycler.FireModes += new FireModeDefinition cycler.FireModes.head.AmmoTypeIndices += 0 cycler.FireModes.head.AmmoTypeIndices += 1 @@ -837,8 +873,8 @@ object GlobalDefinitions { val gauss = ToolDefinition(ObjectClass.gauss) gauss.Size = EquipmentSize.Rifle - gauss.AmmoTypes += Ammo.bullet_9mm - gauss.AmmoTypes += Ammo.bullet_9mm_AP + gauss.AmmoTypes += bullet_9mm + gauss.AmmoTypes += bullet_9mm_AP gauss.FireModes += new FireModeDefinition gauss.FireModes.head.AmmoTypeIndices += 0 gauss.FireModes.head.AmmoTypeIndices += 1 @@ -849,7 +885,7 @@ object GlobalDefinitions { val pulsar = ToolDefinition(ObjectClass.pulsar) pulsar.Size = EquipmentSize.Rifle - pulsar.AmmoTypes += Ammo.energy_cell + pulsar.AmmoTypes += energy_cell pulsar.FireModes += new FireModeDefinition pulsar.FireModes.head.AmmoTypeIndices += 0 pulsar.FireModes.head.AmmoSlotIndex = 0 @@ -863,7 +899,7 @@ object GlobalDefinitions { val anniversary_guna = ToolDefinition(ObjectClass.anniversary_guna) //tr stinger anniversary_guna.Size = EquipmentSize.Pistol - anniversary_guna.AmmoTypes += Ammo.anniversary_ammo + anniversary_guna.AmmoTypes += anniversary_ammo anniversary_guna.FireModes += new FireModeDefinition anniversary_guna.FireModes.head.AmmoTypeIndices += 0 anniversary_guna.FireModes.head.AmmoSlotIndex = 0 @@ -878,7 +914,7 @@ object GlobalDefinitions { val anniversary_gun = ToolDefinition(ObjectClass.anniversary_gun) //nc spear anniversary_gun.Size = EquipmentSize.Pistol - anniversary_gun.AmmoTypes += Ammo.anniversary_ammo + anniversary_gun.AmmoTypes += anniversary_ammo anniversary_gun.FireModes += new FireModeDefinition anniversary_gun.FireModes.head.AmmoTypeIndices += 0 anniversary_gun.FireModes.head.AmmoSlotIndex = 0 @@ -893,7 +929,7 @@ object GlobalDefinitions { val anniversary_gunb = ToolDefinition(ObjectClass.anniversary_gunb) //vs eraser anniversary_gunb.Size = EquipmentSize.Pistol - anniversary_gunb.AmmoTypes += Ammo.anniversary_ammo + anniversary_gunb.AmmoTypes += anniversary_ammo anniversary_gunb.FireModes += new FireModeDefinition anniversary_gunb.FireModes.head.AmmoTypeIndices += 0 anniversary_gunb.FireModes.head.AmmoSlotIndex = 0 @@ -908,7 +944,7 @@ object GlobalDefinitions { val spiker = ToolDefinition(ObjectClass.spiker) spiker.Size = EquipmentSize.Pistol - spiker.AmmoTypes += Ammo.ancient_ammo_combo + spiker.AmmoTypes += ancient_ammo_combo spiker.FireModes += new FireModeDefinition spiker.FireModes.head.AmmoTypeIndices += 0 spiker.FireModes.head.AmmoSlotIndex = 0 @@ -918,8 +954,8 @@ object GlobalDefinitions { val mini_chaingun = ToolDefinition(ObjectClass.mini_chaingun) mini_chaingun.Size = EquipmentSize.Rifle - mini_chaingun.AmmoTypes += Ammo.bullet_9mm - mini_chaingun.AmmoTypes += Ammo.bullet_9mm_AP + mini_chaingun.AmmoTypes += bullet_9mm + mini_chaingun.AmmoTypes += bullet_9mm_AP mini_chaingun.FireModes += new FireModeDefinition mini_chaingun.FireModes.head.AmmoTypeIndices += 0 mini_chaingun.FireModes.head.AmmoTypeIndices += 1 @@ -930,8 +966,8 @@ object GlobalDefinitions { val r_shotgun = ToolDefinition(ObjectClass.r_shotgun) //jackhammer r_shotgun.Size = EquipmentSize.Rifle - r_shotgun.AmmoTypes += Ammo.shotgun_shell - r_shotgun.AmmoTypes += Ammo.shotgun_shell_AP + r_shotgun.AmmoTypes += shotgun_shell + r_shotgun.AmmoTypes += shotgun_shell_AP r_shotgun.FireModes += new FireModeDefinition r_shotgun.FireModes.head.AmmoTypeIndices += 0 r_shotgun.FireModes.head.AmmoTypeIndices += 1 @@ -948,7 +984,7 @@ object GlobalDefinitions { val lasher = ToolDefinition(ObjectClass.lasher) lasher.Size = EquipmentSize.Rifle - lasher.AmmoTypes += Ammo.energy_cell + lasher.AmmoTypes += energy_cell lasher.FireModes += new FireModeDefinition lasher.FireModes.head.AmmoTypeIndices += 0 lasher.FireModes.head.AmmoSlotIndex = 0 @@ -962,7 +998,7 @@ object GlobalDefinitions { val maelstrom = ToolDefinition(ObjectClass.maelstrom) maelstrom.Size = EquipmentSize.Rifle - maelstrom.AmmoTypes += Ammo.maelstrom_ammo + maelstrom.AmmoTypes += maelstrom_ammo maelstrom.FireModes += new FireModeDefinition maelstrom.FireModes.head.AmmoTypeIndices += 0 maelstrom.FireModes.head.AmmoSlotIndex = 0 @@ -980,7 +1016,7 @@ object GlobalDefinitions { val phoenix = ToolDefinition(ObjectClass.phoenix) //decimator phoenix.Size = EquipmentSize.Rifle - phoenix.AmmoTypes += Ammo.phoenix_missile + phoenix.AmmoTypes += phoenix_missile phoenix.FireModes += new FireModeDefinition phoenix.FireModes.head.AmmoTypeIndices += 0 phoenix.FireModes.head.AmmoSlotIndex = 0 @@ -994,7 +1030,7 @@ object GlobalDefinitions { val striker = ToolDefinition(ObjectClass.striker) striker.Size = EquipmentSize.Rifle - striker.AmmoTypes += Ammo.striker_missile_ammo + striker.AmmoTypes += striker_missile_ammo striker.FireModes += new FireModeDefinition striker.FireModes.head.AmmoTypeIndices += 0 striker.FireModes.head.AmmoSlotIndex = 0 @@ -1008,7 +1044,7 @@ object GlobalDefinitions { val hunterseeker = ToolDefinition(ObjectClass.hunterseeker) //phoenix hunterseeker.Size = EquipmentSize.Rifle - hunterseeker.AmmoTypes += Ammo.hunter_seeker_missile + hunterseeker.AmmoTypes += hunter_seeker_missile hunterseeker.FireModes += new FireModeDefinition hunterseeker.FireModes.head.AmmoTypeIndices += 0 hunterseeker.FireModes.head.AmmoSlotIndex = 0 @@ -1022,7 +1058,7 @@ object GlobalDefinitions { val lancer = ToolDefinition(ObjectClass.lancer) lancer.Size = EquipmentSize.Rifle - lancer.AmmoTypes += Ammo.lancer_cartridge + lancer.AmmoTypes += lancer_cartridge lancer.FireModes += new FireModeDefinition lancer.FireModes.head.AmmoTypeIndices += 0 lancer.FireModes.head.AmmoSlotIndex = 0 @@ -1032,8 +1068,8 @@ object GlobalDefinitions { val rocklet = ToolDefinition(ObjectClass.rocklet) rocklet.Size = EquipmentSize.Rifle - rocklet.AmmoTypes += Ammo.rocket - rocklet.AmmoTypes += Ammo.frag_cartridge + rocklet.AmmoTypes += rocket + rocklet.AmmoTypes += frag_cartridge rocklet.FireModes += new FireModeDefinition rocklet.FireModes.head.AmmoTypeIndices += 0 rocklet.FireModes.head.AmmoTypeIndices += 1 @@ -1050,9 +1086,9 @@ object GlobalDefinitions { val thumper = ToolDefinition(ObjectClass.thumper) thumper.Size = EquipmentSize.Rifle - thumper.AmmoTypes += Ammo.frag_cartridge - thumper.AmmoTypes += Ammo.plasma_cartridge - thumper.AmmoTypes += Ammo.jammer_cartridge + thumper.AmmoTypes += frag_cartridge + thumper.AmmoTypes += plasma_cartridge + thumper.AmmoTypes += jammer_cartridge thumper.FireModes += new FireModeDefinition thumper.FireModes.head.AmmoTypeIndices += 0 thumper.FireModes.head.AmmoTypeIndices += 1 @@ -1070,7 +1106,7 @@ object GlobalDefinitions { val radiator = ToolDefinition(ObjectClass.radiator) radiator.Size = EquipmentSize.Rifle - radiator.AmmoTypes += Ammo.ancient_ammo_combo + radiator.AmmoTypes += ancient_ammo_combo radiator.FireModes += new FireModeDefinition radiator.FireModes.head.AmmoTypeIndices += 0 radiator.FireModes.head.AmmoSlotIndex = 0 @@ -1084,7 +1120,7 @@ object GlobalDefinitions { val heavy_sniper = ToolDefinition(ObjectClass.heavy_sniper) //hsr heavy_sniper.Size = EquipmentSize.Rifle - heavy_sniper.AmmoTypes += Ammo.bolt + heavy_sniper.AmmoTypes += bolt heavy_sniper.FireModes += new FireModeDefinition heavy_sniper.FireModes.head.AmmoTypeIndices += 0 heavy_sniper.FireModes.head.AmmoSlotIndex = 0 @@ -1094,7 +1130,7 @@ object GlobalDefinitions { val bolt_driver = ToolDefinition(ObjectClass.bolt_driver) bolt_driver.Size = EquipmentSize.Rifle - bolt_driver.AmmoTypes += Ammo.bolt + bolt_driver.AmmoTypes += bolt bolt_driver.FireModes += new FireModeDefinition bolt_driver.FireModes.head.AmmoTypeIndices += 0 bolt_driver.FireModes.head.AmmoSlotIndex = 0 @@ -1104,7 +1140,7 @@ object GlobalDefinitions { val oicw = ToolDefinition(ObjectClass.oicw) //scorpion oicw.Size = EquipmentSize.Rifle - oicw.AmmoTypes += Ammo.oicw_ammo + oicw.AmmoTypes += oicw_ammo oicw.FireModes += new FireModeDefinition oicw.FireModes.head.AmmoTypeIndices += 0 oicw.FireModes.head.AmmoSlotIndex = 0 @@ -1118,7 +1154,7 @@ object GlobalDefinitions { val flamethrower = ToolDefinition(ObjectClass.flamethrower) flamethrower.Size = EquipmentSize.Rifle - flamethrower.AmmoTypes += Ammo.flamethrower_ammo + flamethrower.AmmoTypes += flamethrower_ammo flamethrower.FireModes += new FireModeDefinition flamethrower.FireModes.head.AmmoTypeIndices += 0 flamethrower.FireModes.head.AmmoSlotIndex = 0 @@ -1131,10 +1167,37 @@ object GlobalDefinitions { flamethrower.FireModes(1).Chamber = 50 flamethrower.Tile = InventoryTile.Tile63 + val + trhev_dualcycler = ToolDefinition(ObjectClass.trhev_dualcycler) + + val + trhev_pounder = ToolDefinition(ObjectClass.trhev_pounder) + + val + trhev_burster = ToolDefinition(ObjectClass.trhev_burster) + + val + nchev_scattercannon = ToolDefinition(ObjectClass.nchev_scattercannon) + + val + nchev_falcon = ToolDefinition(ObjectClass.nchev_falcon) + + val + nchev_sparrow = ToolDefinition(ObjectClass.nchev_sparrow) + + val + vshev_quasar = ToolDefinition(ObjectClass.vshev_quasar) + + val + vshev_comet = ToolDefinition(ObjectClass.vshev_comet) + + val + vshev_starfire = ToolDefinition(ObjectClass.vshev_starfire) + val medicalapplicator = ToolDefinition(ObjectClass.medicalapplicator) medicalapplicator.Size = EquipmentSize.Pistol - medicalapplicator.AmmoTypes += Ammo.health_canister + medicalapplicator.AmmoTypes += health_canister medicalapplicator.FireModes += new FireModeDefinition medicalapplicator.FireModes.head.AmmoTypeIndices += 0 medicalapplicator.FireModes.head.AmmoSlotIndex = 0 @@ -1148,8 +1211,8 @@ object GlobalDefinitions { val nano_dispenser = ToolDefinition(ObjectClass.nano_dispenser) nano_dispenser.Size = EquipmentSize.Rifle - nano_dispenser.AmmoTypes += Ammo.armor_canister - nano_dispenser.AmmoTypes += Ammo.upgrade_canister + nano_dispenser.AmmoTypes += armor_canister + nano_dispenser.AmmoTypes += upgrade_canister nano_dispenser.FireModes += new FireModeDefinition nano_dispenser.FireModes.head.AmmoTypeIndices += 0 nano_dispenser.FireModes.head.AmmoTypeIndices += 1 @@ -1160,7 +1223,7 @@ object GlobalDefinitions { val bank = ToolDefinition(ObjectClass.bank) bank.Size = EquipmentSize.Pistol - bank.AmmoTypes += Ammo.armor_canister + bank.AmmoTypes += armor_canister bank.FireModes += new FireModeDefinition bank.FireModes.head.AmmoTypeIndices += 0 bank.FireModes.head.AmmoSlotIndex = 0 @@ -1179,7 +1242,7 @@ object GlobalDefinitions { val trek = ToolDefinition(ObjectClass.trek) trek.Size = EquipmentSize.Pistol - trek.AmmoTypes += Ammo.trek_ammo + trek.AmmoTypes += trek_ammo trek.FireModes += new FireModeDefinition trek.FireModes.head.AmmoTypeIndices += 0 trek.FireModes.head.AmmoSlotIndex = 0 @@ -1222,7 +1285,7 @@ object GlobalDefinitions { val fury_weapon_systema = ToolDefinition(ObjectClass.fury_weapon_systema) fury_weapon_systema.Size = EquipmentSize.VehicleWeapon - fury_weapon_systema.AmmoTypes += Ammo.hellfire_ammo + fury_weapon_systema.AmmoTypes += hellfire_ammo fury_weapon_systema.FireModes += new FireModeDefinition fury_weapon_systema.FireModes.head.AmmoTypeIndices += 0 fury_weapon_systema.FireModes.head.AmmoSlotIndex = 0 @@ -1231,30 +1294,486 @@ object GlobalDefinitions { val quadassault_weapon_system = ToolDefinition(ObjectClass.quadassault_weapon_system) quadassault_weapon_system.Size = EquipmentSize.VehicleWeapon - quadassault_weapon_system.AmmoTypes += Ammo.bullet_12mm + quadassault_weapon_system.AmmoTypes += bullet_12mm quadassault_weapon_system.FireModes += new FireModeDefinition quadassault_weapon_system.FireModes.head.AmmoTypeIndices += 0 quadassault_weapon_system.FireModes.head.AmmoSlotIndex = 0 - quadassault_weapon_system.FireModes.head.Magazine = 100 + quadassault_weapon_system.FireModes.head.Magazine = 150 + + val + scythe = ToolDefinition(ObjectClass.scythe) //TODO resolve ammo slot/pool discrepancy + scythe.Size = EquipmentSize.VehicleWeapon + scythe.AmmoTypes += ancient_ammo_vehicle + scythe.AmmoTypes += ancient_ammo_vehicle + scythe.FireModes += new FireModeDefinition + scythe.FireModes.head.AmmoTypeIndices += 0 + scythe.FireModes.head.AmmoSlotIndex = 0 + scythe.FireModes.head.Magazine = 250 + scythe.FireModes += new FireModeDefinition + scythe.FireModes(1).AmmoTypeIndices += 0 + scythe.FireModes(1).AmmoSlotIndex = 1 //note: the scythe has two magazines using a single pool; however, it can not ammo-switch or mode-switch + scythe.FireModes(1).Magazine = 250 val chaingun_p = ToolDefinition(ObjectClass.chaingun_p) chaingun_p.Size = EquipmentSize.VehicleWeapon - chaingun_p.AmmoTypes += Ammo.bullet_12mm + chaingun_p.AmmoTypes += bullet_12mm chaingun_p.FireModes += new FireModeDefinition chaingun_p.FireModes.head.AmmoTypeIndices += 0 chaingun_p.FireModes.head.AmmoSlotIndex = 0 chaingun_p.FireModes.head.Magazine = 150 + val + skyguard_weapon_system = ToolDefinition(ObjectClass.skyguard_weapon_system) + skyguard_weapon_system.Size = EquipmentSize.VehicleWeapon + skyguard_weapon_system.AmmoTypes += skyguard_flak_cannon_ammo + skyguard_weapon_system.AmmoTypes += bullet_12mm + skyguard_weapon_system.FireModes += new FireModeDefinition + skyguard_weapon_system.FireModes.head.AmmoTypeIndices += 0 + skyguard_weapon_system.FireModes.head.AmmoSlotIndex = 0 + skyguard_weapon_system.FireModes.head.Magazine = 40 + skyguard_weapon_system.FireModes += new FireModeDefinition + skyguard_weapon_system.FireModes(1).AmmoTypeIndices += 1 + skyguard_weapon_system.FireModes(1).AmmoSlotIndex = 1 + skyguard_weapon_system.FireModes(1).Magazine = 1 //TODO check + + val + grenade_launcher_marauder = ToolDefinition(ObjectClass.grenade_launcher_marauder) + grenade_launcher_marauder.Size = EquipmentSize.VehicleWeapon + grenade_launcher_marauder.AmmoTypes += heavy_grenade_mortar + grenade_launcher_marauder.FireModes += new FireModeDefinition + grenade_launcher_marauder.FireModes.head.AmmoTypeIndices += 0 + grenade_launcher_marauder.FireModes.head.AmmoSlotIndex = 0 + grenade_launcher_marauder.FireModes.head.Magazine = 50 + + val + advanced_missile_launcher_t = ToolDefinition(ObjectClass.advanced_missile_launcher_t) + advanced_missile_launcher_t.Size = EquipmentSize.VehicleWeapon + advanced_missile_launcher_t.AmmoTypes += firebird_missile + advanced_missile_launcher_t.FireModes += new FireModeDefinition + advanced_missile_launcher_t.FireModes.head.AmmoTypeIndices += 0 + advanced_missile_launcher_t.FireModes.head.AmmoSlotIndex = 0 + advanced_missile_launcher_t.FireModes.head.Magazine = 40 + + val + flux_cannon_thresher = ToolDefinition(ObjectClass.flux_cannon_thresher) + flux_cannon_thresher.Size = EquipmentSize.VehicleWeapon + flux_cannon_thresher.AmmoTypes += flux_cannon_thresher_battery + flux_cannon_thresher.FireModes += new FireModeDefinition + flux_cannon_thresher.FireModes.head.AmmoTypeIndices += 0 + flux_cannon_thresher.FireModes.head.AmmoSlotIndex = 0 + flux_cannon_thresher.FireModes.head.Magazine = 100 + + val + mediumtransport_weapon_systemA = ToolDefinition(ObjectClass.mediumtransport_weapon_systemA) + mediumtransport_weapon_systemA.Size = EquipmentSize.VehicleWeapon + mediumtransport_weapon_systemA.AmmoTypes += bullet_20mm + mediumtransport_weapon_systemA.FireModes += new FireModeDefinition + mediumtransport_weapon_systemA.FireModes.head.AmmoTypeIndices += 0 + mediumtransport_weapon_systemA.FireModes.head.AmmoSlotIndex = 0 + mediumtransport_weapon_systemA.FireModes.head.Magazine = 150 + + val + mediumtransport_weapon_systemB = ToolDefinition(ObjectClass.mediumtransport_weapon_systemB) + mediumtransport_weapon_systemB.Size = EquipmentSize.VehicleWeapon + mediumtransport_weapon_systemB.AmmoTypes += bullet_20mm + mediumtransport_weapon_systemB.FireModes += new FireModeDefinition + mediumtransport_weapon_systemB.FireModes.head.AmmoTypeIndices += 0 + mediumtransport_weapon_systemB.FireModes.head.AmmoSlotIndex = 0 + mediumtransport_weapon_systemB.FireModes.head.Magazine = 150 + + val + battlewagon_weapon_systema = ToolDefinition(ObjectClass.battlewagon_weapon_systema) + battlewagon_weapon_systema.Size = EquipmentSize.VehicleWeapon + battlewagon_weapon_systema.AmmoTypes += bullet_15mm + battlewagon_weapon_systema.FireModes += new FireModeDefinition + battlewagon_weapon_systema.FireModes.head.AmmoTypeIndices += 0 + battlewagon_weapon_systema.FireModes.head.AmmoSlotIndex = 0 + battlewagon_weapon_systema.FireModes.head.Magazine = 235 + + val + battlewagon_weapon_systemb = ToolDefinition(ObjectClass.battlewagon_weapon_systemb) + battlewagon_weapon_systemb.Size = EquipmentSize.VehicleWeapon + battlewagon_weapon_systemb.AmmoTypes += bullet_15mm + battlewagon_weapon_systemb.FireModes += new FireModeDefinition + battlewagon_weapon_systemb.FireModes.head.AmmoTypeIndices += 0 + battlewagon_weapon_systemb.FireModes.head.AmmoSlotIndex = 0 + battlewagon_weapon_systemb.FireModes.head.Magazine = 235 + + val + battlewagon_weapon_systemc = ToolDefinition(ObjectClass.battlewagon_weapon_systemc) + battlewagon_weapon_systemc.Size = EquipmentSize.VehicleWeapon + battlewagon_weapon_systemc.AmmoTypes += bullet_15mm + battlewagon_weapon_systemc.FireModes += new FireModeDefinition + battlewagon_weapon_systemc.FireModes.head.AmmoTypeIndices += 0 + battlewagon_weapon_systemc.FireModes.head.AmmoSlotIndex = 0 + battlewagon_weapon_systemc.FireModes.head.Magazine = 235 + + val + battlewagon_weapon_systemd = ToolDefinition(ObjectClass.battlewagon_weapon_systemd) + battlewagon_weapon_systemd.Size = EquipmentSize.VehicleWeapon + battlewagon_weapon_systemd.AmmoTypes += bullet_15mm + battlewagon_weapon_systemd.FireModes += new FireModeDefinition + battlewagon_weapon_systemd.FireModes.head.AmmoTypeIndices += 0 + battlewagon_weapon_systemd.FireModes.head.AmmoSlotIndex = 0 + battlewagon_weapon_systemd.FireModes.head.Magazine = 235 + + val + thunderer_weapon_systema = ToolDefinition(ObjectClass.thunderer_weapon_systema) + thunderer_weapon_systema.Size = EquipmentSize.VehicleWeapon + thunderer_weapon_systema.AmmoTypes += gauss_cannon_ammo + thunderer_weapon_systema.FireModes += new FireModeDefinition + thunderer_weapon_systema.FireModes.head.AmmoTypeIndices += 0 + thunderer_weapon_systema.FireModes.head.AmmoSlotIndex = 0 + thunderer_weapon_systema.FireModes.head.Magazine = 15 + + val + thunderer_weapon_systemb = ToolDefinition(ObjectClass.thunderer_weapon_systemb) + thunderer_weapon_systemb.Size = EquipmentSize.VehicleWeapon + thunderer_weapon_systemb.AmmoTypes += gauss_cannon_ammo + thunderer_weapon_systemb.FireModes += new FireModeDefinition + thunderer_weapon_systemb.FireModes.head.AmmoTypeIndices += 0 + thunderer_weapon_systemb.FireModes.head.AmmoSlotIndex = 0 + thunderer_weapon_systemb.FireModes.head.Magazine = 15 + + val + aurora_weapon_systema = ToolDefinition(ObjectClass.aurora_weapon_systema) + aurora_weapon_systema.Size = EquipmentSize.VehicleWeapon + aurora_weapon_systema.AmmoTypes += fluxpod_ammo + aurora_weapon_systema.FireModes += new FireModeDefinition + aurora_weapon_systema.FireModes.head.AmmoTypeIndices += 0 + aurora_weapon_systema.FireModes.head.AmmoSlotIndex = 0 + aurora_weapon_systema.FireModes.head.Magazine = 12 + aurora_weapon_systema.FireModes += new FireModeDefinition + aurora_weapon_systema.FireModes(1).AmmoTypeIndices += 0 + aurora_weapon_systema.FireModes(1).AmmoSlotIndex = 1 + aurora_weapon_systema.FireModes(1).Magazine = 12 + + val + aurora_weapon_systemb = ToolDefinition(ObjectClass.aurora_weapon_systemb) + aurora_weapon_systemb.Size = EquipmentSize.VehicleWeapon + aurora_weapon_systemb.AmmoTypes += fluxpod_ammo + aurora_weapon_systemb.FireModes += new FireModeDefinition + aurora_weapon_systemb.FireModes.head.AmmoTypeIndices += 0 + aurora_weapon_systemb.FireModes.head.AmmoSlotIndex = 0 + aurora_weapon_systemb.FireModes.head.Magazine = 12 + aurora_weapon_systemb.FireModes += new FireModeDefinition + aurora_weapon_systemb.FireModes(1).AmmoTypeIndices += 0 + aurora_weapon_systemb.FireModes(1).AmmoSlotIndex = 1 + aurora_weapon_systemb.FireModes(1).Magazine = 12 + + val + apc_weapon_systema = ToolDefinition(ObjectClass.apc_weapon_systema) + apc_weapon_systema.Size = EquipmentSize.VehicleWeapon + apc_weapon_systema.AmmoTypes += bullet_75mm + apc_weapon_systema.FireModes += new FireModeDefinition + apc_weapon_systema.FireModes.head.AmmoTypeIndices += 0 + apc_weapon_systema.FireModes.head.AmmoSlotIndex = 0 + apc_weapon_systema.FireModes.head.Magazine = 50 + + val + apc_weapon_systemb = ToolDefinition(ObjectClass.apc_weapon_systemb) + apc_weapon_systemb.Size = EquipmentSize.VehicleWeapon + apc_weapon_systemb.AmmoTypes += bullet_75mm + apc_weapon_systemb.FireModes += new FireModeDefinition + apc_weapon_systemb.FireModes.head.AmmoTypeIndices += 0 + apc_weapon_systemb.FireModes.head.AmmoSlotIndex = 0 + apc_weapon_systemb.FireModes.head.Magazine = 50 + + val + apc_ballgun_r = ToolDefinition(ObjectClass.apc_ballgun_r) + apc_ballgun_r.Size = EquipmentSize.VehicleWeapon + apc_ballgun_r.AmmoTypes += bullet_12mm + apc_ballgun_r.FireModes += new FireModeDefinition + apc_ballgun_r.FireModes.head.AmmoTypeIndices += 0 + apc_ballgun_r.FireModes.head.AmmoSlotIndex = 0 + apc_ballgun_r.FireModes.head.Magazine = 150 + + val + apc_ballgun_l = ToolDefinition(ObjectClass.apc_ballgun_l) + apc_ballgun_l.Size = EquipmentSize.VehicleWeapon + apc_ballgun_l.AmmoTypes += bullet_12mm + apc_ballgun_l.FireModes += new FireModeDefinition + apc_ballgun_l.FireModes.head.AmmoTypeIndices += 0 + apc_ballgun_l.FireModes.head.AmmoSlotIndex = 0 + apc_ballgun_l.FireModes.head.Magazine = 150 + + val + apc_weapon_systemc_tr = ToolDefinition(ObjectClass.apc_weapon_systemc_tr) + apc_weapon_systemc_tr.Size = EquipmentSize.VehicleWeapon + apc_weapon_systemc_tr.AmmoTypes += bullet_15mm + apc_weapon_systemc_tr.FireModes += new FireModeDefinition + apc_weapon_systemc_tr.FireModes.head.AmmoTypeIndices += 0 + apc_weapon_systemc_tr.FireModes.head.AmmoSlotIndex = 0 + apc_weapon_systemc_tr.FireModes.head.Magazine = 150 + + val + apc_weapon_systemd_tr = ToolDefinition(ObjectClass.apc_weapon_systemd_tr) + apc_weapon_systemd_tr.Size = EquipmentSize.VehicleWeapon + apc_weapon_systemd_tr.AmmoTypes += bullet_15mm + apc_weapon_systemd_tr.FireModes += new FireModeDefinition + apc_weapon_systemd_tr.FireModes.head.AmmoTypeIndices += 0 + apc_weapon_systemd_tr.FireModes.head.AmmoSlotIndex = 0 + apc_weapon_systemd_tr.FireModes.head.Magazine = 150 + + val + apc_weapon_systemc_nc = ToolDefinition(ObjectClass.apc_weapon_systemc_nc) + apc_weapon_systemc_nc.Size = EquipmentSize.VehicleWeapon + apc_weapon_systemc_nc.AmmoTypes += bullet_20mm + apc_weapon_systemc_nc.FireModes += new FireModeDefinition + apc_weapon_systemc_nc.FireModes.head.AmmoTypeIndices += 0 + apc_weapon_systemc_nc.FireModes.head.AmmoSlotIndex = 0 + apc_weapon_systemc_nc.FireModes.head.Magazine = 150 + + val + apc_weapon_systemd_nc = ToolDefinition(ObjectClass.apc_weapon_systemd_nc) + apc_weapon_systemd_nc.Size = EquipmentSize.VehicleWeapon + apc_weapon_systemd_nc.AmmoTypes += bullet_20mm + apc_weapon_systemd_nc.FireModes += new FireModeDefinition + apc_weapon_systemd_nc.FireModes.head.AmmoTypeIndices += 0 + apc_weapon_systemd_nc.FireModes.head.AmmoSlotIndex = 0 + apc_weapon_systemd_nc.FireModes.head.Magazine = 150 + + val + apc_weapon_systemc_vs = ToolDefinition(ObjectClass.apc_weapon_systemc_vs) + apc_weapon_systemc_vs.Size = EquipmentSize.VehicleWeapon + apc_weapon_systemc_vs.AmmoTypes += flux_cannon_thresher_battery + apc_weapon_systemc_vs.FireModes += new FireModeDefinition + apc_weapon_systemc_vs.FireModes.head.AmmoTypeIndices += 0 + apc_weapon_systemc_vs.FireModes.head.AmmoSlotIndex = 0 + apc_weapon_systemc_vs.FireModes.head.Magazine = 100 + + val + apc_weapon_systemd_vs = ToolDefinition(ObjectClass.apc_weapon_systemd_vs) + apc_weapon_systemd_vs.Size = EquipmentSize.VehicleWeapon + apc_weapon_systemd_vs.AmmoTypes += flux_cannon_thresher_battery + apc_weapon_systemd_vs.FireModes += new FireModeDefinition + apc_weapon_systemd_vs.FireModes.head.AmmoTypeIndices += 0 + apc_weapon_systemd_vs.FireModes.head.AmmoSlotIndex = 0 + apc_weapon_systemd_vs.FireModes.head.Magazine = 100 + + val + lightning_weapon_system = ToolDefinition(ObjectClass.lightning_weapon_system) + lightning_weapon_system.Size = EquipmentSize.VehicleWeapon + lightning_weapon_system.AmmoTypes += bullet_75mm + lightning_weapon_system.AmmoTypes += bullet_25mm + lightning_weapon_system.FireModes += new FireModeDefinition + lightning_weapon_system.FireModes.head.AmmoTypeIndices += 0 + lightning_weapon_system.FireModes.head.AmmoSlotIndex = 0 + lightning_weapon_system.FireModes.head.Magazine = 20 + lightning_weapon_system.FireModes += new FireModeDefinition + lightning_weapon_system.FireModes(1).AmmoTypeIndices += 1 + lightning_weapon_system.FireModes(1).AmmoSlotIndex = 1 + lightning_weapon_system.FireModes(1).Magazine = 1 //TODO check + + val + prowler_weapon_systemA = ToolDefinition(ObjectClass.prowler_weapon_systemA) + prowler_weapon_systemA.Size = EquipmentSize.VehicleWeapon + prowler_weapon_systemA.AmmoTypes += bullet_105mm + prowler_weapon_systemA.FireModes += new FireModeDefinition + prowler_weapon_systemA.FireModes.head.AmmoTypeIndices += 0 + prowler_weapon_systemA.FireModes.head.AmmoSlotIndex = 0 + prowler_weapon_systemA.FireModes.head.Magazine = 20 + + val + prowler_weapon_systemB = ToolDefinition(ObjectClass.prowler_weapon_systemB) + prowler_weapon_systemB.Size = EquipmentSize.VehicleWeapon + prowler_weapon_systemB.AmmoTypes += bullet_15mm + prowler_weapon_systemB.FireModes += new FireModeDefinition + prowler_weapon_systemB.FireModes.head.AmmoTypeIndices += 0 + prowler_weapon_systemB.FireModes.head.AmmoSlotIndex = 0 + prowler_weapon_systemB.FireModes.head.Magazine = 235 + + val + vanguard_weapon_system = ToolDefinition(ObjectClass.vanguard_weapon_system) + vanguard_weapon_system.Size = EquipmentSize.VehicleWeapon + vanguard_weapon_system.AmmoTypes += bullet_150mm + vanguard_weapon_system.AmmoTypes += bullet_20mm + vanguard_weapon_system.FireModes += new FireModeDefinition + vanguard_weapon_system.FireModes.head.AmmoTypeIndices += 0 + vanguard_weapon_system.FireModes.head.AmmoSlotIndex = 0 + vanguard_weapon_system.FireModes.head.Magazine = 10 + vanguard_weapon_system.FireModes += new FireModeDefinition + vanguard_weapon_system.FireModes(1).AmmoTypeIndices += 1 + vanguard_weapon_system.FireModes(1).AmmoSlotIndex = 1 + vanguard_weapon_system.FireModes(1).Magazine = 1 //TODO check + + val + particle_beam_magrider = ToolDefinition(ObjectClass.particle_beam_magrider) + particle_beam_magrider.Size = EquipmentSize.VehicleWeapon + particle_beam_magrider.AmmoTypes += pulse_battery + particle_beam_magrider.FireModes += new FireModeDefinition + particle_beam_magrider.FireModes.head.AmmoTypeIndices += 0 + particle_beam_magrider.FireModes.head.AmmoSlotIndex = 0 + particle_beam_magrider.FireModes.head.Magazine = 150 + + val + heavy_rail_beam_magrider = ToolDefinition(ObjectClass.heavy_rail_beam_magrider) + heavy_rail_beam_magrider.Size = EquipmentSize.VehicleWeapon + heavy_rail_beam_magrider.AmmoTypes += heavy_rail_beam_battery + heavy_rail_beam_magrider.FireModes += new FireModeDefinition + heavy_rail_beam_magrider.FireModes.head.AmmoTypeIndices += 0 + heavy_rail_beam_magrider.FireModes.head.AmmoSlotIndex = 0 + heavy_rail_beam_magrider.FireModes.head.Magazine = 25 + + val + flail_weapon = ToolDefinition(ObjectClass.flail_weapon) + flail_weapon.Size = EquipmentSize.VehicleWeapon + flail_weapon.AmmoTypes += ancient_ammo_vehicle + flail_weapon.FireModes += new FireModeDefinition + flail_weapon.FireModes.head.AmmoTypeIndices += 0 + flail_weapon.FireModes.head.AmmoSlotIndex = 0 + flail_weapon.FireModes.head.Magazine = 100 + + val + rotarychaingun_mosquito = ToolDefinition(ObjectClass.rotarychaingun_mosquito) + rotarychaingun_mosquito.Size = EquipmentSize.VehicleWeapon + rotarychaingun_mosquito.AmmoTypes += bullet_12mm + rotarychaingun_mosquito.FireModes += new FireModeDefinition + rotarychaingun_mosquito.FireModes.head.AmmoTypeIndices += 0 + rotarychaingun_mosquito.FireModes.head.AmmoSlotIndex = 0 + rotarychaingun_mosquito.FireModes.head.Magazine = 150 + + val + lightgunship_weapon_system = ToolDefinition(ObjectClass.lightgunship_weapon_system) + lightgunship_weapon_system.Size = EquipmentSize.VehicleWeapon + lightgunship_weapon_system.AmmoTypes += bullet_20mm + lightgunship_weapon_system.AmmoTypes += reaver_rocket + lightgunship_weapon_system.FireModes += new FireModeDefinition + lightgunship_weapon_system.FireModes.head.AmmoTypeIndices += 0 + lightgunship_weapon_system.FireModes.head.AmmoSlotIndex = 0 + lightgunship_weapon_system.FireModes.head.Magazine = 150 + lightgunship_weapon_system.FireModes += new FireModeDefinition + lightgunship_weapon_system.FireModes(1).AmmoTypeIndices += 1 + lightgunship_weapon_system.FireModes(1).AmmoSlotIndex = 1 + lightgunship_weapon_system.FireModes(1).Magazine = 1 //TODO check + + val + wasp_weapon_system = ToolDefinition(ObjectClass.wasp_weapon_system) + wasp_weapon_system.Size = EquipmentSize.VehicleWeapon + wasp_weapon_system.AmmoTypes += wasp_gun_ammo + wasp_weapon_system.AmmoTypes += wasp_rocket_ammo + wasp_weapon_system.FireModes += new FireModeDefinition + wasp_weapon_system.FireModes.head.AmmoTypeIndices += 0 + wasp_weapon_system.FireModes.head.AmmoSlotIndex = 0 + wasp_weapon_system.FireModes.head.Magazine = 30 + wasp_weapon_system.FireModes += new FireModeDefinition + wasp_weapon_system.FireModes(1).AmmoTypeIndices += 1 + wasp_weapon_system.FireModes(1).AmmoSlotIndex = 1 + wasp_weapon_system.FireModes(1).Magazine = 1 //TODO check + + val + liberator_weapon_system = ToolDefinition(ObjectClass.liberator_weapon_system) + liberator_weapon_system.Size = EquipmentSize.VehicleWeapon + liberator_weapon_system.AmmoTypes += bullet_35mm + liberator_weapon_system.FireModes += new FireModeDefinition + liberator_weapon_system.FireModes.head.AmmoTypeIndices += 0 + liberator_weapon_system.FireModes.head.AmmoSlotIndex = 0 + liberator_weapon_system.FireModes.head.Magazine = 100 + + val + liberator_bomb_bay = ToolDefinition(ObjectClass.liberator_bomb_bay) + liberator_bomb_bay.Size = EquipmentSize.VehicleWeapon + liberator_bomb_bay.AmmoTypes += liberator_bomb + liberator_bomb_bay.FireModes += new FireModeDefinition + liberator_bomb_bay.FireModes.head.AmmoTypeIndices += 0 + liberator_bomb_bay.FireModes.head.AmmoSlotIndex = 0 + liberator_bomb_bay.FireModes.head.Magazine = 10 + liberator_bomb_bay.FireModes += new FireModeDefinition + liberator_bomb_bay.FireModes(1).AmmoTypeIndices += 0 + liberator_bomb_bay.FireModes(1).AmmoSlotIndex = 0 + liberator_bomb_bay.FireModes(1).Magazine = 10 + + val + liberator_25mm_cannon = ToolDefinition(ObjectClass.liberator_25mm_cannon) + liberator_25mm_cannon.Size = EquipmentSize.VehicleWeapon + liberator_25mm_cannon.AmmoTypes += bullet_25mm + liberator_25mm_cannon.FireModes += new FireModeDefinition + liberator_25mm_cannon.FireModes.head.AmmoTypeIndices += 0 + liberator_25mm_cannon.FireModes.head.AmmoSlotIndex = 0 + liberator_25mm_cannon.FireModes.head.Magazine = 150 + + val + vulture_nose_weapon_system = ToolDefinition(ObjectClass.vulture_nose_weapon_system) + vulture_nose_weapon_system.Size = EquipmentSize.VehicleWeapon + vulture_nose_weapon_system.AmmoTypes += bullet_35mm + vulture_nose_weapon_system.FireModes += new FireModeDefinition + vulture_nose_weapon_system.FireModes.head.AmmoTypeIndices += 0 + vulture_nose_weapon_system.FireModes.head.AmmoSlotIndex = 0 + vulture_nose_weapon_system.FireModes.head.Magazine = 75 //80? + + val + vulture_bomb_bay = ToolDefinition(ObjectClass.vulture_bomb_bay) + vulture_bomb_bay.Size = EquipmentSize.VehicleWeapon + vulture_bomb_bay.AmmoTypes += liberator_bomb + vulture_bomb_bay.FireModes += new FireModeDefinition + vulture_bomb_bay.FireModes.head.AmmoTypeIndices += 0 + vulture_bomb_bay.FireModes.head.AmmoSlotIndex = 0 + vulture_bomb_bay.FireModes.head.Magazine = 10 + + val + vulture_tail_cannon = ToolDefinition(ObjectClass.vulture_tail_cannon) + vulture_tail_cannon.Size = EquipmentSize.VehicleWeapon + vulture_tail_cannon.AmmoTypes += bullet_25mm + vulture_tail_cannon.FireModes += new FireModeDefinition + vulture_tail_cannon.FireModes.head.AmmoTypeIndices += 0 + vulture_tail_cannon.FireModes.head.AmmoSlotIndex = 0 + vulture_tail_cannon.FireModes.head.Magazine = 100 + + val + cannon_dropship_20mm = ToolDefinition(ObjectClass.cannon_dropship_20mm) + cannon_dropship_20mm.Size = EquipmentSize.VehicleWeapon + cannon_dropship_20mm.AmmoTypes += bullet_20mm + cannon_dropship_20mm.FireModes += new FireModeDefinition + cannon_dropship_20mm.FireModes.head.AmmoTypeIndices += 0 + cannon_dropship_20mm.FireModes.head.AmmoSlotIndex = 0 + cannon_dropship_20mm.FireModes.head.Magazine = 250 + + val + dropship_rear_turret = ToolDefinition(ObjectClass.dropship_rear_turret) + dropship_rear_turret.Size = EquipmentSize.VehicleWeapon + dropship_rear_turret.AmmoTypes += bullet_20mm + dropship_rear_turret.FireModes += new FireModeDefinition + dropship_rear_turret.FireModes.head.AmmoTypeIndices += 0 + dropship_rear_turret.FireModes.head.AmmoSlotIndex = 0 + dropship_rear_turret.FireModes.head.Magazine = 250 + + val + galaxy_gunship_cannon = ToolDefinition(ObjectClass.galaxy_gunship_cannon) + galaxy_gunship_cannon.Size = EquipmentSize.VehicleWeapon + galaxy_gunship_cannon.AmmoTypes += heavy_grenade_mortar + galaxy_gunship_cannon.FireModes += new FireModeDefinition + galaxy_gunship_cannon.FireModes.head.AmmoTypeIndices += 0 + galaxy_gunship_cannon.FireModes.head.AmmoSlotIndex = 0 + galaxy_gunship_cannon.FireModes.head.Magazine = 50 + + val + galaxy_gunship_tailgun = ToolDefinition(ObjectClass.galaxy_gunship_tailgun) + galaxy_gunship_tailgun.Size = EquipmentSize.VehicleWeapon + galaxy_gunship_tailgun.AmmoTypes += bullet_35mm + galaxy_gunship_tailgun.FireModes += new FireModeDefinition + galaxy_gunship_tailgun.FireModes.head.AmmoTypeIndices += 0 + galaxy_gunship_tailgun.FireModes.head.AmmoSlotIndex = 0 + galaxy_gunship_tailgun.FireModes.head.Magazine = 200 + + val + galaxy_gunship_gun = ToolDefinition(ObjectClass.galaxy_gunship_gun) + galaxy_gunship_gun.Size = EquipmentSize.VehicleWeapon + galaxy_gunship_gun.AmmoTypes += bullet_35mm + galaxy_gunship_gun.FireModes += new FireModeDefinition + galaxy_gunship_gun.FireModes.head.AmmoTypeIndices += 0 + galaxy_gunship_gun.FireModes.head.AmmoSlotIndex = 0 + galaxy_gunship_gun.FireModes.head.Magazine = 200 + val fury = VehicleDefinition(ObjectClass.fury) fury.Seats += 0 -> new SeatDefinition() fury.Seats(0).Bailable = true fury.Seats(0).ControlledWeapon = 1 + fury.Weapons += 1 -> fury_weapon_systema fury.MountPoints += 1 -> 0 fury.MountPoints += 2 -> 0 - fury.Weapons += 1 -> fury_weapon_systema - fury.TrunkSize = InventoryTile(11, 11) + fury.TrunkSize = InventoryTile.Tile1111 fury.TrunkOffset = 30 val @@ -1262,10 +1781,10 @@ object GlobalDefinitions { quadassault.Seats += 0 -> new SeatDefinition() quadassault.Seats(0).Bailable = true quadassault.Seats(0).ControlledWeapon = 1 + quadassault.Weapons += 1 -> quadassault_weapon_system quadassault.MountPoints += 1 -> 0 quadassault.MountPoints += 2 -> 0 - quadassault.Weapons += 1 -> quadassault_weapon_system - quadassault.TrunkSize = InventoryTile(11, 11) + quadassault.TrunkSize = InventoryTile.Tile1111 quadassault.TrunkOffset = 30 val @@ -1273,10 +1792,10 @@ object GlobalDefinitions { quadstealth.CanCloak = true quadstealth.Seats += 0 -> new SeatDefinition() quadstealth.Seats(0).Bailable = true + quadstealth.CanCloak = true quadstealth.MountPoints += 1 -> 0 quadstealth.MountPoints += 2 -> 0 - quadstealth.CanCloak = true - quadstealth.TrunkSize = InventoryTile(11, 11) + quadstealth.TrunkSize = InventoryTile.Tile1111 quadstealth.TrunkOffset = 30 val @@ -1286,12 +1805,542 @@ object GlobalDefinitions { two_man_assault_buggy.Seats += 1 -> new SeatDefinition() two_man_assault_buggy.Seats(1).Bailable = true two_man_assault_buggy.Seats(1).ControlledWeapon = 2 + two_man_assault_buggy.Weapons += 2 -> chaingun_p two_man_assault_buggy.MountPoints += 1 -> 0 two_man_assault_buggy.MountPoints += 2 -> 1 - two_man_assault_buggy.Weapons += 2 -> chaingun_p - two_man_assault_buggy.TrunkSize = InventoryTile(11, 11) + two_man_assault_buggy.TrunkSize = InventoryTile.Tile1111 two_man_assault_buggy.TrunkOffset = 30 + val + skyguard = VehicleDefinition(ObjectClass.skyguard) + skyguard.Seats += 0 -> new SeatDefinition() + skyguard.Seats(0).Bailable = true + skyguard.Seats += 1 -> new SeatDefinition() + skyguard.Seats(1).Bailable = true + skyguard.Seats(1).ControlledWeapon = 2 + skyguard.Weapons += 2 -> skyguard_weapon_system + skyguard.MountPoints += 1 -> 0 + skyguard.MountPoints += 2 -> 0 + skyguard.MountPoints += 3 -> 1 + skyguard.TrunkSize = InventoryTile.Tile1511 + skyguard.TrunkOffset = 30 + + val + threemanheavybuggy = VehicleDefinition(ObjectClass.threemanheavybuggy) + threemanheavybuggy.Seats += 0 -> new SeatDefinition() + threemanheavybuggy.Seats(0).Bailable = true + threemanheavybuggy.Seats += 1 -> new SeatDefinition() + threemanheavybuggy.Seats(1).Bailable = true + threemanheavybuggy.Seats(1).ControlledWeapon = 3 + threemanheavybuggy.Seats += 2 -> new SeatDefinition() + threemanheavybuggy.Seats(2).Bailable = true + threemanheavybuggy.Seats(2).ControlledWeapon = 4 + threemanheavybuggy.Weapons += 3 -> chaingun_p + threemanheavybuggy.Weapons += 4 -> grenade_launcher_marauder + threemanheavybuggy.MountPoints += 1 -> 0 + threemanheavybuggy.MountPoints += 2 -> 1 + threemanheavybuggy.MountPoints += 3 -> 2 + threemanheavybuggy.TrunkSize = InventoryTile.Tile1511 + threemanheavybuggy.TrunkOffset = 30 + + val + twomanheavybuggy = VehicleDefinition(ObjectClass.twomanheavybuggy) + twomanheavybuggy.Seats += 0 -> new SeatDefinition() + twomanheavybuggy.Seats(0).Bailable = true + twomanheavybuggy.Seats += 1 -> new SeatDefinition() + twomanheavybuggy.Seats(1).Bailable = true + twomanheavybuggy.Seats(1).ControlledWeapon = 2 + twomanheavybuggy.Weapons += 2 -> advanced_missile_launcher_t + twomanheavybuggy.MountPoints += 1 -> 0 + twomanheavybuggy.MountPoints += 2 -> 1 + twomanheavybuggy.TrunkSize = InventoryTile.Tile1511 + twomanheavybuggy.TrunkOffset = 30 + + val + twomanhoverbuggy = VehicleDefinition(ObjectClass.twomanhoverbuggy) + twomanhoverbuggy.Seats += 0 -> new SeatDefinition() + twomanhoverbuggy.Seats(0).Bailable = true + twomanhoverbuggy.Seats += 1 -> new SeatDefinition() + twomanhoverbuggy.Seats(1).Bailable = true + twomanhoverbuggy.Seats(1).ControlledWeapon = 2 + twomanhoverbuggy.Weapons += 2 -> flux_cannon_thresher + twomanhoverbuggy.MountPoints += 1 -> 0 + twomanhoverbuggy.MountPoints += 2 -> 1 + twomanhoverbuggy.TrunkSize = InventoryTile.Tile1511 + twomanhoverbuggy.TrunkOffset = 30 + + val + mediumtransport = VehicleDefinition(ObjectClass.mediumtransport) + mediumtransport.Seats += 0 -> new SeatDefinition() + mediumtransport.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + mediumtransport.Seats += 1 -> new SeatDefinition() + mediumtransport.Seats(1).ControlledWeapon = 5 + mediumtransport.Seats += 2 -> new SeatDefinition() + mediumtransport.Seats(2).ControlledWeapon = 6 + mediumtransport.Seats += 3 -> new SeatDefinition() + mediumtransport.Seats += 4 -> new SeatDefinition() + mediumtransport.Weapons += 5 -> mediumtransport_weapon_systemA + mediumtransport.Weapons += 6 -> mediumtransport_weapon_systemB + mediumtransport.MountPoints += 1 -> 0 + mediumtransport.MountPoints += 2 -> 1 + mediumtransport.MountPoints += 3 -> 2 + mediumtransport.MountPoints += 4 -> 3 + mediumtransport.MountPoints += 5 -> 4 + mediumtransport.TrunkSize = InventoryTile.Tile1515 + mediumtransport.TrunkOffset = 30 + + val + battlewagon = VehicleDefinition(ObjectClass.battlewagon) + battlewagon.Seats += 0 -> new SeatDefinition() + battlewagon.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + battlewagon.Seats += 1 -> new SeatDefinition() + battlewagon.Seats(1).ControlledWeapon = 5 + battlewagon.Seats += 2 -> new SeatDefinition() + battlewagon.Seats(2).ControlledWeapon = 6 + battlewagon.Seats += 3 -> new SeatDefinition() + battlewagon.Seats(3).ControlledWeapon = 7 + battlewagon.Seats += 4 -> new SeatDefinition() + battlewagon.Seats(4).ControlledWeapon = 8 + battlewagon.Weapons += 5 -> battlewagon_weapon_systema + battlewagon.Weapons += 6 -> battlewagon_weapon_systemb + battlewagon.Weapons += 7 -> battlewagon_weapon_systemc + battlewagon.Weapons += 8 -> battlewagon_weapon_systemd + battlewagon.MountPoints += 1 -> 0 + battlewagon.MountPoints += 2 -> 1 + battlewagon.MountPoints += 3 -> 2 + battlewagon.MountPoints += 4 -> 3 + battlewagon.MountPoints += 5 -> 4 + battlewagon.TrunkSize = InventoryTile.Tile1515 + battlewagon.TrunkOffset = 30 + + val + thunderer = VehicleDefinition(ObjectClass.thunderer) + thunderer.Seats += 0 -> new SeatDefinition() + thunderer.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + thunderer.Seats += 1 -> new SeatDefinition() + thunderer.Seats(1).ControlledWeapon = 5 + thunderer.Seats += 2 -> new SeatDefinition() + thunderer.Seats(2).ControlledWeapon = 6 + thunderer.Seats += 3 -> new SeatDefinition() + thunderer.Seats += 4 -> new SeatDefinition() + thunderer.Weapons += 5 -> thunderer_weapon_systema + thunderer.Weapons += 6 -> thunderer_weapon_systemb + thunderer.MountPoints += 1 -> 0 + thunderer.MountPoints += 2 -> 1 + thunderer.MountPoints += 3 -> 2 + thunderer.MountPoints += 4 -> 3 + thunderer.MountPoints += 5 -> 4 + thunderer.TrunkSize = InventoryTile.Tile1515 + thunderer.TrunkOffset = 30 + + val + aurora = VehicleDefinition(ObjectClass.aurora) + aurora.Seats += 0 -> new SeatDefinition() + aurora.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + aurora.Seats += 1 -> new SeatDefinition() + aurora.Seats(1).ControlledWeapon = 5 + aurora.Seats += 2 -> new SeatDefinition() + aurora.Seats(2).ControlledWeapon = 6 + aurora.Seats += 3 -> new SeatDefinition() + aurora.Seats += 4 -> new SeatDefinition() + aurora.Weapons += 5 -> aurora_weapon_systema + aurora.Weapons += 6 -> aurora_weapon_systemb + aurora.MountPoints += 1 -> 0 + aurora.MountPoints += 2 -> 1 + aurora.MountPoints += 3 -> 2 + aurora.MountPoints += 4 -> 3 + aurora.MountPoints += 5 -> 4 + aurora.TrunkSize = InventoryTile.Tile1515 + aurora.TrunkOffset = 30 + + val + apc_tr = VehicleDefinition(ObjectClass.apc_tr) + apc_tr.Seats += 0 -> new SeatDefinition() + apc_tr.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + apc_tr.Seats += 1 -> new SeatDefinition() + apc_tr.Seats(1).ControlledWeapon = 11 + apc_tr.Seats += 2 -> new SeatDefinition() + apc_tr.Seats(2).ControlledWeapon = 12 + apc_tr.Seats += 3 -> new SeatDefinition() + apc_tr.Seats += 4 -> new SeatDefinition() + apc_tr.Seats += 5 -> new SeatDefinition() + apc_tr.Seats(5).ControlledWeapon = 15 + apc_tr.Seats += 6 -> new SeatDefinition() + apc_tr.Seats(6).ControlledWeapon = 16 + apc_tr.Seats += 7 -> new SeatDefinition() + apc_tr.Seats(7).ControlledWeapon = 13 + apc_tr.Seats += 8 -> new SeatDefinition() + apc_tr.Seats(8).ControlledWeapon = 14 + apc_tr.Seats += 9 -> new SeatDefinition() + apc_tr.Seats(9).ArmorRestriction = SeatArmorRestriction.MaxOnly + apc_tr.Seats += 10 -> new SeatDefinition() + apc_tr.Seats(10).ArmorRestriction = SeatArmorRestriction.MaxOnly + apc_tr.Weapons += 11 -> apc_weapon_systemc_tr + apc_tr.Weapons += 12 -> apc_weapon_systemb + apc_tr.Weapons += 13 -> apc_weapon_systema + apc_tr.Weapons += 14 -> apc_weapon_systemd_tr + apc_tr.Weapons += 15 -> apc_ballgun_r + apc_tr.Weapons += 16 -> apc_ballgun_l + apc_tr.MountPoints += 1 -> 0 + apc_tr.MountPoints += 2 -> 0 + apc_tr.MountPoints += 3 -> 1 + apc_tr.MountPoints += 4 -> 2 + apc_tr.MountPoints += 5 -> 3 + apc_tr.MountPoints += 6 -> 4 + apc_tr.MountPoints += 7 -> 5 + apc_tr.MountPoints += 8 -> 6 + apc_tr.MountPoints += 9 -> 7 + apc_tr.MountPoints += 10 -> 8 + apc_tr.MountPoints += 11 -> 9 + apc_tr.MountPoints += 12 -> 10 + apc_tr.TrunkSize = InventoryTile.Tile2016 + apc_tr.TrunkOffset = 30 + + val + apc_nc = VehicleDefinition(ObjectClass.apc_nc) + apc_nc.Seats += 0 -> new SeatDefinition() + apc_nc.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + apc_nc.Seats += 1 -> new SeatDefinition() + apc_nc.Seats(1).ControlledWeapon = 11 + apc_nc.Seats += 2 -> new SeatDefinition() + apc_nc.Seats(2).ControlledWeapon = 12 + apc_nc.Seats += 3 -> new SeatDefinition() + apc_nc.Seats += 4 -> new SeatDefinition() + apc_nc.Seats += 5 -> new SeatDefinition() + apc_nc.Seats(5).ControlledWeapon = 15 + apc_nc.Seats += 6 -> new SeatDefinition() + apc_nc.Seats(6).ControlledWeapon = 16 + apc_nc.Seats += 7 -> new SeatDefinition() + apc_nc.Seats(7).ControlledWeapon = 13 + apc_nc.Seats += 8 -> new SeatDefinition() + apc_nc.Seats(8).ControlledWeapon = 14 + apc_nc.Seats += 9 -> new SeatDefinition() + apc_nc.Seats(9).ArmorRestriction = SeatArmorRestriction.MaxOnly + apc_nc.Seats += 10 -> new SeatDefinition() + apc_nc.Seats(10).ArmorRestriction = SeatArmorRestriction.MaxOnly + apc_nc.Weapons += 11 -> apc_weapon_systemc_nc + apc_nc.Weapons += 12 -> apc_weapon_systemb + apc_nc.Weapons += 13 -> apc_weapon_systema + apc_nc.Weapons += 14 -> apc_weapon_systemd_nc + apc_nc.Weapons += 15 -> apc_ballgun_r + apc_nc.Weapons += 16 -> apc_ballgun_l + apc_nc.MountPoints += 1 -> 0 + apc_nc.MountPoints += 2 -> 0 + apc_nc.MountPoints += 3 -> 1 + apc_nc.MountPoints += 4 -> 2 + apc_nc.MountPoints += 5 -> 3 + apc_nc.MountPoints += 6 -> 4 + apc_nc.MountPoints += 7 -> 5 + apc_nc.MountPoints += 8 -> 6 + apc_nc.MountPoints += 9 -> 7 + apc_nc.MountPoints += 10 -> 8 + apc_nc.MountPoints += 11 -> 9 + apc_nc.MountPoints += 12 -> 10 + apc_nc.TrunkSize = InventoryTile.Tile2016 + apc_nc.TrunkOffset = 30 + + val + apc_vs = VehicleDefinition(ObjectClass.apc_vs) + apc_vs.Seats += 0 -> new SeatDefinition() + apc_vs.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + apc_vs.Seats += 1 -> new SeatDefinition() + apc_vs.Seats(1).ControlledWeapon = 11 + apc_vs.Seats += 2 -> new SeatDefinition() + apc_vs.Seats(2).ControlledWeapon = 12 + apc_vs.Seats += 3 -> new SeatDefinition() + apc_vs.Seats += 4 -> new SeatDefinition() + apc_vs.Seats += 5 -> new SeatDefinition() + apc_vs.Seats(5).ControlledWeapon = 15 + apc_vs.Seats += 6 -> new SeatDefinition() + apc_vs.Seats(6).ControlledWeapon = 16 + apc_vs.Seats += 7 -> new SeatDefinition() + apc_vs.Seats(7).ControlledWeapon = 13 + apc_vs.Seats += 8 -> new SeatDefinition() + apc_vs.Seats(8).ControlledWeapon = 14 + apc_vs.Seats += 9 -> new SeatDefinition() + apc_vs.Seats(9).ArmorRestriction = SeatArmorRestriction.MaxOnly + apc_vs.Seats += 10 -> new SeatDefinition() + apc_vs.Seats(10).ArmorRestriction = SeatArmorRestriction.MaxOnly + apc_vs.Weapons += 11 -> apc_weapon_systemc_vs + apc_vs.Weapons += 12 -> apc_weapon_systemb + apc_vs.Weapons += 13 -> apc_weapon_systema + apc_vs.Weapons += 14 -> apc_weapon_systemd_vs + apc_vs.Weapons += 15 -> apc_ballgun_r + apc_vs.Weapons += 16 -> apc_ballgun_l + apc_vs.MountPoints += 1 -> 0 + apc_vs.MountPoints += 2 -> 0 + apc_vs.MountPoints += 3 -> 1 + apc_vs.MountPoints += 4 -> 2 + apc_vs.MountPoints += 5 -> 3 + apc_vs.MountPoints += 6 -> 4 + apc_vs.MountPoints += 7 -> 5 + apc_vs.MountPoints += 8 -> 6 + apc_vs.MountPoints += 9 -> 7 + apc_vs.MountPoints += 10 -> 8 + apc_vs.MountPoints += 11 -> 9 + apc_vs.MountPoints += 12 -> 10 + apc_vs.TrunkSize = InventoryTile.Tile2016 + apc_vs.TrunkOffset = 30 + + val + lightning = VehicleDefinition(ObjectClass.lightning) + lightning.Seats += 0 -> new SeatDefinition() + lightning.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + lightning.Seats(0).ControlledWeapon = 1 + lightning.Weapons += 1 -> lightning_weapon_system + lightning.MountPoints += 1 -> 0 + lightning.MountPoints += 2 -> 0 + lightning.TrunkSize = InventoryTile.Tile1511 + lightning.TrunkOffset = 30 + + val + prowler = VehicleDefinition(ObjectClass.prowler) + prowler.Seats += 0 -> new SeatDefinition() + prowler.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + prowler.Seats += 1 -> new SeatDefinition() + prowler.Seats(1).ControlledWeapon = 3 + prowler.Seats += 2 -> new SeatDefinition() + prowler.Seats(2).ControlledWeapon = 4 + prowler.Weapons += 3 -> prowler_weapon_systemA + prowler.Weapons += 4 -> prowler_weapon_systemB + prowler.MountPoints += 1 -> 0 + prowler.MountPoints += 2 -> 1 + prowler.MountPoints += 3 -> 2 + prowler.TrunkSize = InventoryTile.Tile1511 + prowler.TrunkOffset = 30 + + val + vanguard = VehicleDefinition(ObjectClass.vanguard) + vanguard.Seats += 0 -> new SeatDefinition() + vanguard.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + vanguard.Seats += 1 -> new SeatDefinition() + vanguard.Seats(1).ControlledWeapon = 2 + vanguard.Weapons += 2 -> vanguard_weapon_system + vanguard.MountPoints += 1 -> 0 + vanguard.MountPoints += 2 -> 1 + vanguard.TrunkSize = InventoryTile.Tile1511 + vanguard.TrunkOffset = 30 + + val + magrider = VehicleDefinition(ObjectClass.magrider) + magrider.Seats += 0 -> new SeatDefinition() + magrider.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + magrider.Seats(0).ControlledWeapon = 2 + magrider.Seats += 1 -> new SeatDefinition() + magrider.Seats(1).ControlledWeapon = 3 + magrider.Weapons += 2 -> particle_beam_magrider + magrider.Weapons += 3 -> heavy_rail_beam_magrider + magrider.MountPoints += 1 -> 0 + magrider.MountPoints += 2 -> 1 + magrider.TrunkSize = InventoryTile.Tile1511 + magrider.TrunkOffset = 30 + + private val utilityConverter = new UtilityVehicleConverter + val + ant = VehicleDefinition(ObjectClass.ant) + ant.Seats += 0 -> new SeatDefinition() + ant.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + ant.MountPoints += 1 -> 0 + ant.MountPoints += 2 -> 0 + ant.Packet = utilityConverter + + val + ams = VehicleDefinition(ObjectClass.ams) + ams.Seats += 0 -> new SeatDefinition() + ams.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + ams.MountPoints += 1 -> 0 + ams.MountPoints += 2 -> 0 + ams.Packet = utilityConverter + + private val variantConverter = new VariantVehicleConverter + val + router = VehicleDefinition(ObjectClass.router) + router.Seats += 0 -> new SeatDefinition() + router.MountPoints += 1 -> 0 + router.TrunkSize = InventoryTile.Tile1511 + router.TrunkOffset = 30 + router.Packet = variantConverter + + val + switchblade = VehicleDefinition(ObjectClass.switchblade) + switchblade.Seats += 0 -> new SeatDefinition() + switchblade.Seats(0).ControlledWeapon = 1 + switchblade.Weapons += 1 -> scythe + switchblade.MountPoints += 1 -> 0 + switchblade.MountPoints += 2 -> 0 + switchblade.TrunkSize = InventoryTile.Tile1511 + switchblade.TrunkOffset = 30 + switchblade.Packet = variantConverter + + val + flail = VehicleDefinition(ObjectClass.flail) + flail.Seats += 0 -> new SeatDefinition() + flail.Seats(0).ControlledWeapon = 1 + flail.Weapons += 1 -> flail_weapon + flail.MountPoints += 1 -> 0 + flail.TrunkSize = InventoryTile.Tile1511 + flail.TrunkOffset = 30 + flail.Packet = variantConverter + + val + mosquito = VehicleDefinition(ObjectClass.mosquito) + mosquito.Seats += 0 -> new SeatDefinition() + mosquito.Seats(0).Bailable = true + mosquito.Seats(0).ControlledWeapon = 1 + mosquito.Weapons += 1 -> rotarychaingun_mosquito + mosquito.MountPoints += 1 -> 0 + mosquito.MountPoints += 2 -> 0 + mosquito.TrunkSize = InventoryTile.Tile1111 + mosquito.TrunkOffset = 30 + mosquito.Packet = variantConverter + + val + lightgunship = VehicleDefinition(ObjectClass.lightgunship) + lightgunship.Seats += 0 -> new SeatDefinition() + lightgunship.Seats(0).Bailable = true + lightgunship.Seats(0).ControlledWeapon = 1 + lightgunship.Weapons += 1 -> lightgunship_weapon_system + lightgunship.MountPoints += 1 -> 0 + lightgunship.MountPoints += 2 -> 0 + lightgunship.TrunkSize = InventoryTile.Tile1511 + lightgunship.TrunkOffset = 30 + lightgunship.Packet = variantConverter + + val + wasp = VehicleDefinition(ObjectClass.wasp) + wasp.Seats += 0 -> new SeatDefinition() + wasp.Seats(0).Bailable = true + wasp.Seats(0).ControlledWeapon = 1 + wasp.Weapons += 1 -> wasp_weapon_system + wasp.MountPoints += 1 -> 0 + wasp.MountPoints += 2 -> 0 + wasp.TrunkSize = InventoryTile.Tile1111 + wasp.TrunkOffset = 30 + wasp.Packet = variantConverter + + val + liberator = VehicleDefinition(ObjectClass.liberator) + liberator.Seats += 0 -> new SeatDefinition() + liberator.Seats(0).ControlledWeapon = 3 + liberator.Seats += 1 -> new SeatDefinition() + liberator.Seats(1).ControlledWeapon = 4 + liberator.Seats += 2 -> new SeatDefinition() + liberator.Seats(2).ControlledWeapon = 5 + liberator.Weapons += 3 -> liberator_weapon_system + liberator.Weapons += 4 -> liberator_bomb_bay + liberator.Weapons += 5 -> liberator_25mm_cannon + liberator.MountPoints += 1 -> 0 + liberator.MountPoints += 2 -> 1 + liberator.MountPoints += 3 -> 1 + liberator.MountPoints += 4 -> 2 + liberator.TrunkSize = InventoryTile.Tile1515 + liberator.TrunkOffset = 30 + liberator.Packet = variantConverter + + val + vulture = VehicleDefinition(ObjectClass.vulture) + vulture.Seats += 0 -> new SeatDefinition() + vulture.Seats(0).ControlledWeapon = 3 + vulture.Seats += 1 -> new SeatDefinition() + vulture.Seats(1).ControlledWeapon = 4 + vulture.Seats += 2 -> new SeatDefinition() + vulture.Seats(2).ControlledWeapon = 5 + vulture.Weapons += 3 -> vulture_nose_weapon_system + vulture.Weapons += 4 -> vulture_bomb_bay + vulture.Weapons += 5 -> vulture_tail_cannon + vulture.MountPoints += 1 -> 0 + vulture.MountPoints += 2 -> 1 + vulture.MountPoints += 3 -> 1 + vulture.MountPoints += 4 -> 2 + vulture.TrunkSize = InventoryTile.Tile1611 + vulture.TrunkOffset = 30 + vulture.Packet = variantConverter + + val + dropship = VehicleDefinition(ObjectClass.dropship) + dropship.Seats += 0 -> new SeatDefinition() + dropship.Seats += 1 -> new SeatDefinition() + dropship.Seats(1).Bailable = true + dropship.Seats(1).ControlledWeapon = 12 + dropship.Seats += 2 -> new SeatDefinition() + dropship.Seats(2).Bailable = true + dropship.Seats(2).ControlledWeapon = 13 + dropship.Seats += 3 -> new SeatDefinition() + dropship.Seats(3).Bailable = true + dropship.Seats += 4 -> new SeatDefinition() + dropship.Seats(4).Bailable = true + dropship.Seats += 5 -> new SeatDefinition() + dropship.Seats(5).Bailable = true + dropship.Seats += 6 -> new SeatDefinition() + dropship.Seats(6).Bailable = true + dropship.Seats += 7 -> new SeatDefinition() + dropship.Seats(7).Bailable = true + dropship.Seats += 8 -> new SeatDefinition() + dropship.Seats(8).Bailable = true + dropship.Seats += 9 -> new SeatDefinition() + dropship.Seats(9).Bailable = true + dropship.Seats(9).ArmorRestriction = SeatArmorRestriction.MaxOnly + dropship.Seats += 10 -> new SeatDefinition() + dropship.Seats(10).Bailable = true + dropship.Seats(10).ArmorRestriction = SeatArmorRestriction.MaxOnly + dropship.Seats += 11 -> new SeatDefinition() + dropship.Seats(11).Bailable = true + dropship.Seats(11).ControlledWeapon = 14 + dropship.Weapons += 12 -> cannon_dropship_20mm + dropship.Weapons += 13 -> cannon_dropship_20mm + dropship.Weapons += 14 -> dropship_rear_turret + dropship.MountPoints += 1 -> 0 + dropship.MountPoints += 2 -> 11 + dropship.MountPoints += 3 -> 1 + dropship.MountPoints += 4 -> 2 + dropship.MountPoints += 5 -> 3 + dropship.MountPoints += 6 -> 4 + dropship.MountPoints += 7 -> 5 + dropship.MountPoints += 8 -> 6 + dropship.MountPoints += 9 -> 7 + dropship.MountPoints += 10 -> 8 + dropship.MountPoints += 11 -> 9 + dropship.MountPoints += 12 -> 10 + dropship.TrunkSize = InventoryTile.Tile1612 + dropship.TrunkOffset = 30 + dropship.Packet = variantConverter + + val + galaxy_gunship = VehicleDefinition(ObjectClass.galaxy_gunship) + galaxy_gunship.Seats += 0 -> new SeatDefinition() + galaxy_gunship.Seats += 1 -> new SeatDefinition() + galaxy_gunship.Seats(1).ControlledWeapon = 6 + galaxy_gunship.Seats += 2 -> new SeatDefinition() + galaxy_gunship.Seats(2).ControlledWeapon = 7 + galaxy_gunship.Seats += 3 -> new SeatDefinition() + galaxy_gunship.Seats(3).ControlledWeapon = 8 + galaxy_gunship.Seats += 4 -> new SeatDefinition() + galaxy_gunship.Seats(4).ControlledWeapon = 9 + galaxy_gunship.Seats += 5 -> new SeatDefinition() + galaxy_gunship.Seats(5).ControlledWeapon = 10 + galaxy_gunship.Weapons += 6 -> galaxy_gunship_cannon + galaxy_gunship.Weapons += 7 -> galaxy_gunship_cannon + galaxy_gunship.Weapons += 8 -> galaxy_gunship_tailgun + galaxy_gunship.Weapons += 9 -> galaxy_gunship_gun + galaxy_gunship.Weapons += 10 -> galaxy_gunship_gun + galaxy_gunship.MountPoints += 1 -> 0 + galaxy_gunship.MountPoints += 2 -> 3 + galaxy_gunship.MountPoints += 3 -> 1 + galaxy_gunship.MountPoints += 4 -> 2 + galaxy_gunship.MountPoints += 5 -> 4 + galaxy_gunship.MountPoints += 6 -> 5 + galaxy_gunship.TrunkSize = InventoryTile.Tile1816 + galaxy_gunship.TrunkOffset = 30 + galaxy_gunship.Packet = variantConverter + + val + lodestar = VehicleDefinition(ObjectClass.lodestar) + lodestar.Seats += 0 -> new SeatDefinition() + lodestar.MountPoints += 1 -> 0 + lodestar.TrunkSize = InventoryTile.Tile1612 + lodestar.TrunkOffset = 30 + lodestar.Packet = variantConverter + val phantasm = VehicleDefinition(ObjectClass.phantasm) phantasm.CanCloak = true @@ -1304,14 +2353,30 @@ object GlobalDefinitions { phantasm.Seats(3).Bailable = true phantasm.Seats += 4 -> new SeatDefinition() phantasm.Seats(4).Bailable = true - phantasm.MountPoints += 1 -> 0 //TODO add and check all - phantasm.TrunkSize = InventoryTile(11, 8) - phantasm.TrunkOffset = 30 //TODO check + phantasm.MountPoints += 1 -> 0 + phantasm.MountPoints += 2 -> 1 + phantasm.MountPoints += 3 -> 2 + phantasm.MountPoints += 4 -> 3 + phantasm.MountPoints += 5 -> 4 + phantasm.TrunkSize = InventoryTile.Tile1107 + phantasm.TrunkOffset = 30 + phantasm.Packet = variantConverter val order_terminal = new OrderTerminalDefinition val cert_terminal = new CertTerminalDefinition + val + ground_vehicle_terminal = new GroundVehicleTerminalDefinition + val + air_vehicle_terminal = new AirVehicleTerminalDefinition + val + dropship_vehicle_terminal = new DropshipVehicleTerminalDefinition + val + vehicle_terminal_combined = new VehicleTerminalCombinedDefinition + + val + spawn_pad = new ObjectDefinition(800) { Name = "spawn_pad" } val lock_external = new IFFLockDefinition diff --git a/common/src/main/scala/net/psforever/objects/InfantryLoadout.scala b/common/src/main/scala/net/psforever/objects/Loadout.scala similarity index 81% rename from common/src/main/scala/net/psforever/objects/InfantryLoadout.scala rename to common/src/main/scala/net/psforever/objects/Loadout.scala index ac1c27df7..355a7d171 100644 --- a/common/src/main/scala/net/psforever/objects/InfantryLoadout.scala +++ b/common/src/main/scala/net/psforever/objects/Loadout.scala @@ -11,7 +11,7 @@ import scala.annotation.tailrec /** * From a `Player` their current exo-suit and their `Equipment`, retain a set of instructions to reconstruct this arrangement.
*
- * `InfantryLoadout` objects are composed of the following information, as if a blueprint:
+ * `Loadout` objects are composed of the following information, as if a blueprint:
* - the avatar's current exo-suit
* - the type of specialization, called a "subtype" (mechanized assault exo-suits only)
* - the contents of the avatar's occupied holster slots
@@ -28,25 +28,24 @@ import scala.annotation.tailrec * Even a whole blueprint can be denied if the user lacks the necessary exo-suit certification. * A completely new piece of `Equipment` is constructed when the `Loadout` is regurgitated.
*
- * The fifth tab on an `order_terminal` window is for "Favorite" blueprints for `InfantryLoadout` entries. + * The fifth tab on an `order_terminal` window is for "Favorite" blueprints for `Loadout` entries. * The ten-long list is initialized with `FavoritesMessage` packets. * Specific entries are loaded or removed using `FavoritesRequest` packets. * @param player the player * @param label the name by which this inventory will be known when displayed in a Favorites list */ -class InfantryLoadout(player : Player, private val label : String) { +class Loadout(player : Player, private val label : String) { /** the exo-suit */ private val exosuit : ExoSuitType.Value = player.ExoSuit /** the MAX specialization, to differentiate the three types of MAXes who all use the same exo-suit name */ private val subtype = if(exosuit == ExoSuitType.MAX) { - import net.psforever.packet.game.objectcreate.ObjectClass - player.Holsters().head.Equipment.get.Definition.ObjectId match { - case ObjectClass.trhev_dualcycler | ObjectClass.nchev_scattercannon | ObjectClass.vshev_quasar => + player.Holsters().head.Equipment.get.Definition match { + case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.nchev_scattercannon | GlobalDefinitions.vshev_quasar => 1 - case ObjectClass.trhev_pounder | ObjectClass.nchev_falcon | ObjectClass.vshev_comet => + case GlobalDefinitions.trhev_pounder | GlobalDefinitions.nchev_falcon | GlobalDefinitions.vshev_comet => 2 - case ObjectClass.trhev_burster | ObjectClass.nchev_sparrow | ObjectClass.vshev_starfire => + case GlobalDefinitions.trhev_burster | GlobalDefinitions.nchev_sparrow | GlobalDefinitions.vshev_starfire => 3 case _ => 0 @@ -56,14 +55,14 @@ class InfantryLoadout(player : Player, private val label : String) { 0 } /** simplified representation of the holster `Equipment` */ - private val holsters : List[InfantryLoadout.SimplifiedEntry] = - InfantryLoadout.packageSimplifications(player.Holsters()) + private val holsters : List[Loadout.SimplifiedEntry] = + Loadout.packageSimplifications(player.Holsters()) /** simplified representation of the inventory `Equipment` */ - private val inventory : List[InfantryLoadout.SimplifiedEntry] = - InfantryLoadout.packageSimplifications(player.Inventory.Items.values.toList) + private val inventory : List[Loadout.SimplifiedEntry] = + Loadout.packageSimplifications(player.Inventory.Items.values.toList) /** - * The label by which this `InfantryLoadout` is called. + * The label by which this `Loadout` is called. * @return the label */ def Label : String = label @@ -87,26 +86,26 @@ class InfantryLoadout(player : Player, private val label : String) { def Subtype : Int = subtype /** - * The `Equipment` in the `Player`'s holster slots when this `InfantryLoadout` is created. + * The `Equipment` in the `Player`'s holster slots when this `Loadout` is created. * @return a `List` of the holster item blueprints */ - def Holsters : List[InfantryLoadout.SimplifiedEntry] = holsters + def Holsters : List[Loadout.SimplifiedEntry] = holsters /** - * The `Equipment` in the `Player`'s inventory region when this `InfantryLoadout` is created. + * The `Equipment` in the `Player`'s inventory region when this `Loadout` is created. * @return a `List` of the inventory item blueprints */ - def Inventory : List[InfantryLoadout.SimplifiedEntry] = inventory + def Inventory : List[Loadout.SimplifiedEntry] = inventory } -object InfantryLoadout { +object Loadout { /** * A basic `Trait` connecting all of the `Equipment` blueprints. */ sealed trait Simplification /** - * An entry in the `InfantryLoadout`, wrapping around a slot index and what is in the slot index. + * An entry in the `Loadout`, wrapping around a slot index and what is in the slot index. * @param item the `Equipment` * @param index the slot number where the `Equipment` is to be stowed * @see `InventoryItem` @@ -163,7 +162,7 @@ object InfantryLoadout { * @return a `List` of simplified `Equipment` */ private def packageSimplifications(equipment : List[InventoryItem]) : List[SimplifiedEntry] = { - recursiveInventorySimplifications(equipment.iterator) + equipment.map(entry => { SimplifiedEntry(buildSimplification(entry.obj), entry.start) }) } /** @@ -193,23 +192,6 @@ object InfantryLoadout { } } - /** - * Traverse a `Player`'s inventory and transform `Equipment` into simplified blueprints. - * @param iter an `Iterator` - * @param list an updating `List` of simplified `Equipment` blueprints; - * empty, by default - * @return a `List` of simplified `Equipment` blueprints - */ - @tailrec private def recursiveInventorySimplifications(iter : Iterator[InventoryItem], list : List[SimplifiedEntry] = Nil) : List[SimplifiedEntry] = { - if(!iter.hasNext) { - list - } - else { - val entry = iter.next - recursiveInventorySimplifications(iter, list :+ SimplifiedEntry(buildSimplification(entry.obj), entry.start)) - } - } - /** * Ammunition slots are internal connection points where `AmmoBox` units and their characteristics represent a `Tool`'s magazine. * Their simplification process has a layer of complexity that ensures that the content of the slot matches the type of content that should be in the slot. @@ -235,7 +217,7 @@ object InfantryLoadout { else { ShorthandAmmotSlot( entry.AmmoTypeIndex, - ShorthandAmmoBox(AmmoBoxDefinition(entry.Tool.Definition.AmmoTypes(entry.Definition.AmmoTypeIndices.head).id), 1) + ShorthandAmmoBox(entry.Tool.AmmoTypes(entry.Definition.AmmoTypeIndices.head), 1) ) } recursiveFireModeSimplications(iter, list :+ fmodeSimp) diff --git a/common/src/main/scala/net/psforever/objects/Player.scala b/common/src/main/scala/net/psforever/objects/Player.scala index 15572f514..37c6a2859 100644 --- a/common/src/main/scala/net/psforever/objects/Player.scala +++ b/common/src/main/scala/net/psforever/objects/Player.scala @@ -32,7 +32,7 @@ class Player(private val name : String, private var drawnSlot : Int = Player.HandsDownSlot private var lastDrawnSlot : Int = 0 - private val loadouts : Array[Option[InfantryLoadout]] = Array.fill[Option[InfantryLoadout]](10)(None) + private val loadouts : Array[Option[Loadout]] = Array.fill[Option[Loadout]](10)(None) private var bep : Long = 0 private var cep : Long = 0 @@ -230,10 +230,10 @@ class Player(private val name : String, } def SaveLoadout(label : String, line : Int) : Unit = { - loadouts(line) = Some(new InfantryLoadout(this, label)) + loadouts(line) = Some(new Loadout(this, label)) } - def LoadLoadout(line : Int) : Option[InfantryLoadout] = loadouts(line) + def LoadLoadout(line : Int) : Option[Loadout] = loadouts(line) def DeleteLoadout(line : Int) : Unit = { loadouts(line) = None @@ -551,7 +551,7 @@ object Player { player.ExoSuit = eSuit //inventory player.Inventory.Clear() - player.Inventory.Resize(esuitDef.InventoryScale.width, esuitDef.InventoryScale.height) + player.Inventory.Resize(esuitDef.InventoryScale.Width, esuitDef.InventoryScale.Height) player.Inventory.Offset = esuitDef.InventoryOffset //holsters (0 until 5).foreach(index => { player.Slot(index).Size = esuitDef.Holster(index) }) diff --git a/common/src/main/scala/net/psforever/objects/Tool.scala b/common/src/main/scala/net/psforever/objects/Tool.scala index 85b2c484c..068f13a0d 100644 --- a/common/src/main/scala/net/psforever/objects/Tool.scala +++ b/common/src/main/scala/net/psforever/objects/Tool.scala @@ -1,9 +1,8 @@ // Copyright (c) 2017 PSForever package net.psforever.objects -import net.psforever.objects.definition.{AmmoBoxDefinition, ToolDefinition} +import net.psforever.objects.definition.ToolDefinition import net.psforever.objects.equipment.{Ammo, Equipment, FireModeDefinition, FireModeSwitch} -import net.psforever.packet.game.PlanetSideGUID import scala.annotation.tailrec @@ -13,14 +12,15 @@ import scala.annotation.tailrec * "Tool" is a very mechanical name while this class is intended for various weapons and support items. * The primary trait of a `Tool` is that it has something that counts as an "ammunition," * depleted as the `Tool` is used, replaceable as long as one has an appropriate type of `AmmoBox` object. - * (The former is always called "consuming;" the latter, "reloading.")
- *
+ * (The former is always called "consuming;" the latter, "reloading.") * Some weapons Chainblade have ammunition but do not consume it. * @param toolDef the `ObjectDefinition` that constructs this item and maintains some of its immutable fields */ class Tool(private val toolDef : ToolDefinition) extends Equipment with FireModeSwitch[FireModeDefinition] { + /** index of the current fire mode on the `ToolDefinition`'s list of fire modes */ private var fireModeIndex : Int = 0 - private val ammoSlot : List[Tool.FireModeSlot] = Tool.LoadDefinition(this) + /** current ammunition slot being used by this fire mode */ + private val ammoSlots : List[Tool.FireModeSlot] = Tool.LoadDefinition(this) def FireModeIndex : Int = fireModeIndex @@ -36,24 +36,24 @@ class Tool(private val toolDef : ToolDefinition) extends Equipment with FireMode FireMode } - def AmmoTypeIndex : Int = ammoSlot(fireModeIndex).AmmoTypeIndex + def AmmoTypeIndex : Int = FireMode.AmmoTypeIndices(AmmoSlot.AmmoTypeIndex) def AmmoTypeIndex_=(index : Int) : Int = { - ammoSlot(fireModeIndex).AmmoTypeIndex = index % FireMode.AmmoTypeIndices.length + AmmoSlot.AmmoTypeIndex = index % FireMode.AmmoTypeIndices.length AmmoTypeIndex } - def AmmoType : Ammo.Value = toolDef.AmmoTypes(AmmoTypeIndex) + def AmmoType : Ammo.Value = toolDef.AmmoTypes(AmmoTypeIndex).AmmoType def NextAmmoType : Ammo.Value = { - AmmoTypeIndex = AmmoTypeIndex + 1 + AmmoSlot.AmmoTypeIndex = AmmoSlot.AmmoTypeIndex + 1 AmmoType } - def Magazine : Int = ammoSlot(fireModeIndex).Magazine + def Magazine : Int = AmmoSlot.Magazine def Magazine_=(mag : Int) : Int = { - ammoSlot(fireModeIndex).Magazine = Math.min(Math.max(0, mag), MaxMagazine) + AmmoSlot.Magazine = Math.min(Math.max(0, mag), MaxMagazine) Magazine } @@ -61,15 +61,15 @@ class Tool(private val toolDef : ToolDefinition) extends Equipment with FireMode def NextDischarge : Int = math.min(Magazine, FireMode.Chamber) - def AmmoSlots : List[Tool.FireModeSlot] = ammoSlot + def AmmoSlot : Tool.FireModeSlot = ammoSlots(FireMode.AmmoSlotIndex) - def MaxAmmoSlot : Int = ammoSlot.length + def AmmoSlots : List[Tool.FireModeSlot] = ammoSlots + + def MaxAmmoSlot : Int = ammoSlots.length def Definition : ToolDefinition = toolDef - override def toString : String = { - Tool.toString(this) - } + override def toString : String = Tool.toString(this) } object Tool { @@ -77,12 +77,6 @@ object Tool { new Tool(toolDef) } - def apply(guid : PlanetSideGUID, toolDef : ToolDefinition) : Tool = { - val obj = new Tool(toolDef) - obj.GUID = guid - obj - } - /** * Use the `*Definition` that was provided to this object to initialize its fields and settings. * @param tool the `Tool` being initialized @@ -90,10 +84,10 @@ object Tool { def LoadDefinition(tool : Tool) : List[FireModeSlot] = { val tdef : ToolDefinition = tool.Definition val maxSlot = tdef.FireModes.maxBy(fmode => fmode.AmmoSlotIndex).AmmoSlotIndex - buildFireModes(tool, (0 to maxSlot).iterator, tdef.FireModes.toList) + buildFireModes(tdef, (0 to maxSlot).iterator, tdef.FireModes.toList) } - @tailrec private def buildFireModes(tool : Tool, iter : Iterator[Int], fmodes : List[FireModeDefinition], list : List[FireModeSlot] = Nil) : List[FireModeSlot] = { + @tailrec private def buildFireModes(tdef : ToolDefinition, iter : Iterator[Int], fmodes : List[FireModeDefinition], list : List[FireModeSlot] = Nil) : List[FireModeSlot] = { if(!iter.hasNext) { list } @@ -101,9 +95,9 @@ object Tool { val index = iter.next fmodes.filter(fmode => fmode.AmmoSlotIndex == index) match { case fmode :: _ => - buildFireModes(tool, iter, fmodes, list :+ new FireModeSlot(tool, fmode)) + buildFireModes(tdef, iter, fmodes, list :+ new FireModeSlot(tdef, fmode)) case Nil => - throw new IllegalArgumentException(s"tool ${tool.Definition.Name} ammo slot #$index is missing a fire mode specification; do not skip") + throw new IllegalArgumentException(s"tool ${tdef.Name} ammo slot #$index is missing a fire mode specification; do not skip") } } } @@ -113,32 +107,45 @@ object Tool { } /** - * A hidden class that manages the specifics of the given ammunition for the current fire mode of this tool. - * It operates much closer to an "ammunition feed" rather than a fire mode. - * The relationship to fire modes is at least one-to-one and at most one-to-many. + * The `FireModeSlot` can be called the "magazine feed," an abstracted "ammunition slot." + * Most weapons will have only one ammunition slot and swap different ammunition into it as needed. + * In general to swap ammunition means to unload the onld ammunition and load the new ammunition. + * Many weapons also have one ammunition slot and multiple fire modes using the same list of ammunition + * This slot manages either of two ammunitions where one does not need to unload to be swapped to the other; + * however, the fire mod has most likely been changed. + * The Punisher - + * six ammunition types in total, + * two uniquely different types without unloading, + * two exclusive groups of ammunition divided into 2 cycled types and 4 cycled types - + * is an example of a weapon that benefits from this implementation. */ - class FireModeSlot(private val tool : Tool, private val fdef : FireModeDefinition) { - /* - By way of demonstration: - Suppressors have one fire mode, two types of ammunition, one slot (2) - MA Pistols have two fire modes, one type of ammunition, one slot (1) - Jackhammers have two fire modes, two types of ammunition, one slot (2) - Punishers have two fire modes, five types of ammunition, two slots (2, 3) - */ - - /** if this fire mode has multiple types of ammunition */ - private var ammoTypeIndex : Int = fdef.AmmoTypeIndices.head - /** a reference to the actual `AmmoBox` of this slot; will not synch up with `AmmoType` immediately */ - private var box : AmmoBox = AmmoBox(AmmoBoxDefinition(AmmoType)) //defaults to box of one round of the default type for this slot + class FireModeSlot(private val tdef : ToolDefinition, private val fdef : FireModeDefinition) { + /** + * if this fire mode has multiple types of ammunition + * this is the index of the fire mode's ammo List, not a reference to the tool's ammo List + */ + private var ammoTypeIndex : Int = 0 + /** a reference to the actual `AmmoBox` of this slot */ + private var box : AmmoBox = AmmoBox(tdef.AmmoTypes(ammoTypeIndex), fdef.Magazine) def AmmoTypeIndex : Int = ammoTypeIndex def AmmoTypeIndex_=(index : Int) : Int = { - ammoTypeIndex = index + ammoTypeIndex = index % fdef.AmmoTypeIndices.length AmmoTypeIndex } - def AmmoType : Ammo.Value = tool.Definition.AmmoTypes(ammoTypeIndex) + /** + * This is a reference to the `Ammo.Value` whose `AmmoBoxDefinition` should be loaded into `box`. + * It may not be the correct `Ammo.Value` whose `AmmoBoxDefinition` is loaded into `box` such as is the case during ammunition swaps. + * Generally, convert from this index, to the index in the fire mode's ammunition list, to the index in the `ToolDefinition`'s ammunition list. + * @return the `Ammo` type that should be loaded into the magazine right now + */ + def AmmoType : Ammo.Value = tdef.AmmoTypes(fdef.AmmoTypeIndices(ammoTypeIndex)).AmmoType + + def AllAmmoTypes : List[Ammo.Value] = { + fdef.AmmoTypeIndices.map(index => tdef.AmmoTypes(fdef.AmmoTypeIndices(index)).AmmoType).toList + } def Magazine : Int = box.Capacity @@ -159,7 +166,7 @@ object Tool { } } - def Tool : Tool = tool + def Tool : ToolDefinition = tdef def Definition : FireModeDefinition = fdef } diff --git a/common/src/main/scala/net/psforever/objects/Vehicle.scala b/common/src/main/scala/net/psforever/objects/Vehicle.scala index 19f0101db..1d6acb114 100644 --- a/common/src/main/scala/net/psforever/objects/Vehicle.scala +++ b/common/src/main/scala/net/psforever/objects/Vehicle.scala @@ -3,7 +3,7 @@ package net.psforever.objects import net.psforever.objects.definition.VehicleDefinition import net.psforever.objects.equipment.{Equipment, EquipmentSize} -import net.psforever.objects.inventory.GridInventory +import net.psforever.objects.inventory.{GridInventory, InventoryTile} import net.psforever.objects.serverobject.PlanetSideServerObject import net.psforever.objects.vehicles.{AccessPermissionGroup, Seat, Utility, VehicleLockState} import net.psforever.packet.game.PlanetSideGUID @@ -480,8 +480,12 @@ object Vehicle { vehicle.Utilities += Utility.Select(i, vehicle) } //trunk - vehicle.trunk.Resize(vdef.TrunkSize.width, vdef.TrunkSize.height) - vehicle.trunk.Offset = vdef.TrunkOffset + vdef.TrunkSize match { + case InventoryTile.None => ; + case dim => + vehicle.trunk.Resize(dim.Width, dim.Height) + vehicle.trunk.Offset = vdef.TrunkOffset + } vehicle } diff --git a/common/src/main/scala/net/psforever/objects/definition/ToolDefinition.scala b/common/src/main/scala/net/psforever/objects/definition/ToolDefinition.scala index 2dbb7303e..f40e3946a 100644 --- a/common/src/main/scala/net/psforever/objects/definition/ToolDefinition.scala +++ b/common/src/main/scala/net/psforever/objects/definition/ToolDefinition.scala @@ -2,17 +2,17 @@ package net.psforever.objects.definition import net.psforever.objects.definition.converter.ToolConverter -import net.psforever.objects.equipment.{Ammo, FireModeDefinition} +import net.psforever.objects.equipment.FireModeDefinition import scala.collection.mutable class ToolDefinition(objectId : Int) extends EquipmentDefinition(objectId) { - private val ammoTypes : mutable.ListBuffer[Ammo.Value] = new mutable.ListBuffer[Ammo.Value] + private val ammoTypes : mutable.ListBuffer[AmmoBoxDefinition] = new mutable.ListBuffer[AmmoBoxDefinition] private val fireModes : mutable.ListBuffer[FireModeDefinition] = new mutable.ListBuffer[FireModeDefinition] Name = "tool" Packet = new ToolConverter() - def AmmoTypes : mutable.ListBuffer[Ammo.Value] = ammoTypes + def AmmoTypes : mutable.ListBuffer[AmmoBoxDefinition] = ammoTypes def FireModes : mutable.ListBuffer[FireModeDefinition] = fireModes } diff --git a/common/src/main/scala/net/psforever/objects/equipment/Ammo.scala b/common/src/main/scala/net/psforever/objects/equipment/Ammo.scala index e7228abcb..55bf072a4 100644 --- a/common/src/main/scala/net/psforever/objects/equipment/Ammo.scala +++ b/common/src/main/scala/net/psforever/objects/equipment/Ammo.scala @@ -43,7 +43,7 @@ object Ammo extends Enumeration { final val fluxpod_ammo = Value(310) final val frag_cartridge = Value(327) final val frag_grenade_ammo = Value(331) - final val gauss_cannon_ammo = Value(345) + final val gauss_cannon_ammo = Value(347) final val grenade = Value(370) final val health_canister = Value(389) final val heavy_grenade_mortar = Value(391) diff --git a/common/src/main/scala/net/psforever/objects/equipment/FireModeSwitch.scala b/common/src/main/scala/net/psforever/objects/equipment/FireModeSwitch.scala index 6a3596cc5..82bc4ff8a 100644 --- a/common/src/main/scala/net/psforever/objects/equipment/FireModeSwitch.scala +++ b/common/src/main/scala/net/psforever/objects/equipment/FireModeSwitch.scala @@ -18,4 +18,4 @@ trait FireModeSwitch[Mode] { def FireMode : Mode def NextFireMode : Mode -} \ No newline at end of file +} diff --git a/common/src/main/scala/net/psforever/objects/inventory/GridInventory.scala b/common/src/main/scala/net/psforever/objects/inventory/GridInventory.scala index b513ea553..f5db0b38a 100644 --- a/common/src/main/scala/net/psforever/objects/inventory/GridInventory.scala +++ b/common/src/main/scala/net/psforever/objects/inventory/GridInventory.scala @@ -68,7 +68,7 @@ class GridInventory { * @return the number of free cells */ def Capacity : Int = { - TotalCapacity - items.values.foldLeft(0)((cnt, item) => cnt + (item.obj.Tile.width * item.obj.Tile.height)) + TotalCapacity - items.values.foldLeft(0)((cnt, item) => cnt + (item.obj.Tile.Width * item.obj.Tile.Height)) } /** @@ -112,7 +112,7 @@ class GridInventory { */ def CheckCollisions(start : Int, item : Equipment) : Try[List[Int]] = { val tile : InventoryTile = item.Tile - CheckCollisions(start, tile.width, tile.height) + CheckCollisions(start, tile.Width, tile.Height) } /** @@ -185,8 +185,8 @@ class GridInventory { val itemx : Int = actualItemStart % width val itemy : Int = actualItemStart / width val tile = item.obj.Tile - val clipsOnX : Boolean = if(itemx < startx) { itemx + tile.width > startx } else { itemx <= startw } - val clipsOnY : Boolean = if(itemy < starty) { itemy + tile.height > starty } else { itemy <= starth } + val clipsOnX : Boolean = if(itemx < startx) { itemx + tile.Width > startx } else { itemx <= startw } + val clipsOnY : Boolean = if(itemy < starty) { itemy + tile.Height > starty } else { itemy <= starth } if(clipsOnX && clipsOnY) { collisions += item } @@ -237,8 +237,8 @@ class GridInventory { * @return the grid index of the upper left corner where equipment to which the `tile` belongs should be placed */ def Fit(tile : InventoryTile) : Option[Int] = { - val tWidth = tile.width - val tHeight = tile.height + val tWidth = tile.Width + val tHeight = tile.Height val gridIter = (0 until (grid.length - (tHeight - 1) * width)) .filter(cell => grid(cell) == -1 && (width - cell%width >= tWidth)) .iterator @@ -325,7 +325,7 @@ class GridInventory { val card = InventoryItem(obj, start) items += key -> card val tile = obj.Tile - SetCells(start, tile.width, tile.height, key) + SetCells(start, tile.Width, tile.Height, key) true case _ => false @@ -348,7 +348,7 @@ class GridInventory { items.remove(key) match { case Some(item) => val tile = item.obj.Tile - SetCells(item.start, tile.width, tile.height) + SetCells(item.start, tile.Width, tile.Height) true case None => false @@ -362,7 +362,7 @@ class GridInventory { case Some(index) => val item = items.remove(index).get val tile = item.obj.Tile - SetCells(item.start, tile.width, tile.height) + SetCells(item.start, tile.Width, tile.Height) true case None => false @@ -492,11 +492,11 @@ object GridInventory { (a, b) => { val aTile = a.obj.Tile val bTile = b.obj.Tile - if(aTile.width == bTile.width) { - aTile.height > bTile.height + if(aTile.Width == bTile.Width) { + aTile.Height > bTile.Height } else { - aTile.width > bTile.width + aTile.Width > bTile.Width } } @@ -513,9 +513,9 @@ object GridInventory { private def sortKnapsack(list : List[InventoryItem], width : Int, height : Int) : Unit = { val root = new KnapsackNode(0, 0, width, height) list.foreach(item => { - findKnapsackSpace(root, item.obj.Tile.width, item.obj.Tile.height) match { + findKnapsackSpace(root, item.obj.Tile.Width, item.obj.Tile.Height) match { case Some(node) => - splitKnapsackSpace(node, item.obj.Tile.width, item.obj.Tile.height) + splitKnapsackSpace(node, item.obj.Tile.Width, item.obj.Tile.Height) item.start = node.y * width + node.x case _ => ; item.start = -1 diff --git a/common/src/main/scala/net/psforever/objects/inventory/InventoryTile.scala b/common/src/main/scala/net/psforever/objects/inventory/InventoryTile.scala index c860a0c32..ea0b58c3e 100644 --- a/common/src/main/scala/net/psforever/objects/inventory/InventoryTile.scala +++ b/common/src/main/scala/net/psforever/objects/inventory/InventoryTile.scala @@ -8,7 +8,7 @@ package net.psforever.objects.inventory * @param height the height of the tile * @throws IllegalArgumentException if either the width or the height are less than zero */ -class InventoryTile(val width : Int, val height : Int) { +class InventoryTile(private val width : Int, private val height : Int) { if(width < 0 || height < 0) throw new IllegalArgumentException(s"tile has no area - width: $width, height: $height") @@ -19,15 +19,27 @@ class InventoryTile(val width : Int, val height : Int) { object InventoryTile { final val None = InventoryTile(0,0) //technically invalid; used to indicate a vehicle with no trunk - final val Tile11 = InventoryTile(1,1) //placeholder size + final val Tile11 = InventoryTile(1,1) //occasional placeholder final val Tile22 = InventoryTile(2,2) //grenades, boomer trigger final val Tile23 = InventoryTile(2,3) //canister ammo final val Tile42 = InventoryTile(4,2) //medkit final val Tile33 = InventoryTile(3,3) //ammo box, pistols, ace final val Tile44 = InventoryTile(4,4) //large ammo box final val Tile55 = InventoryTile(5,5) //bfr ammo box + final val Tile66 = InventoryTile(6,6) //standard assault inventory final val Tile63 = InventoryTile(6,3) //rifles final val Tile93 = InventoryTile(9,3) //long-body weapons + final val Tile96 = InventoryTile(9,6) //standard exo-suit + final val Tile99 = InventoryTile(9,9) //agile exo-suit + final val Tile1107 = InventoryTile(11, 7) //uncommon small trunk capacity - phantasm + final val Tile1111 = InventoryTile(11,11) //common small trunk capacity + final val Tile1209 = InventoryTile(12, 9) //reinforced exo-suit + final val Tile1511 = InventoryTile(15,11) //common medium trunk capacity + final val Tile1515 = InventoryTile(15,15) //common large trunk capacity + final val Tile1611 = InventoryTile(16,11) //uncommon medium trunk capacity - vulture + final val Tile1612 = InventoryTile(16,12) //MAX; uncommon medium trunk capacity - lodestar + final val Tile1816 = InventoryTile(18,16) //uncommon massive trunk capacity - galaxy_gunship + final val Tile2016 = InventoryTile(20,16) //uncommon massive trunk capacity - apc def apply(w : Int, h : Int) : InventoryTile = { new InventoryTile(w, h) diff --git a/common/src/main/scala/net/psforever/objects/serverobject/PlanetSideServerObject.scala b/common/src/main/scala/net/psforever/objects/serverobject/PlanetSideServerObject.scala index f44975444..b81d8e0f6 100644 --- a/common/src/main/scala/net/psforever/objects/serverobject/PlanetSideServerObject.scala +++ b/common/src/main/scala/net/psforever/objects/serverobject/PlanetSideServerObject.scala @@ -24,7 +24,7 @@ abstract class PlanetSideServerObject extends PlanetSideGameObject { * @return the current internal `ActorRef` */ def Actor_=(control : ActorRef) : ActorRef = { - if(actor == ActorRef.noSender) { + if(actor == ActorRef.noSender || control == ActorRef.noSender) { actor = control } actor diff --git a/common/src/main/scala/net/psforever/objects/serverobject/builders/VehicleSpawnPadObjectBuilder.scala b/common/src/main/scala/net/psforever/objects/serverobject/builders/VehicleSpawnPadObjectBuilder.scala new file mode 100644 index 000000000..d50ecd248 --- /dev/null +++ b/common/src/main/scala/net/psforever/objects/serverobject/builders/VehicleSpawnPadObjectBuilder.scala @@ -0,0 +1,35 @@ +// Copyright (c) 2017 PSForever +package net.psforever.objects.serverobject.builders + +import akka.actor.Props +import net.psforever.objects.definition.ObjectDefinition +import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad} + +/** + * Wrapper `Class` designed to instantiate a `VehicleSpawnPad` server object. + * @param spdef an `ObjectDefinition` object ... + * @param id the globally unique identifier to which this `VehicleSpawnPad` will be registered + */ +class VehicleSpawnPadObjectBuilder(private val spdef : ObjectDefinition, private val id : Int) extends ServerObjectBuilder[VehicleSpawnPad] { + import akka.actor.ActorContext + import net.psforever.objects.guid.NumberPoolHub + + def Build(implicit context : ActorContext, guid : NumberPoolHub) : VehicleSpawnPad = { + val obj = VehicleSpawnPad(spdef) + guid.register(obj, id) //non-Actor GUID registration + obj.Actor = context.actorOf(Props(classOf[VehicleSpawnControl], obj), s"${spdef.Name}_${obj.GUID.guid}") + obj + } +} + +object VehicleSpawnPadObjectBuilder { + /** + * Overloaded constructor for a `DoorObjectBuilder`. + * @param spdef an `ObjectDefinition` object + * @param id a globally unique identifier + * @return a `VehicleSpawnPadObjectBuilder` object + */ + def apply(spdef : ObjectDefinition, id : Int) : VehicleSpawnPadObjectBuilder = { + new VehicleSpawnPadObjectBuilder(spdef, id) + } +} diff --git a/common/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnControl.scala b/common/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnControl.scala new file mode 100644 index 000000000..412774bf1 --- /dev/null +++ b/common/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnControl.scala @@ -0,0 +1,203 @@ +// Copyright (c) 2017 PSForever +package net.psforever.objects.serverobject.pad + +import akka.actor.{Actor, ActorRef, Cancellable} +import net.psforever.objects.{DefaultCancellable, Player, Vehicle} +import net.psforever.types.Vector3 + +import scala.concurrent.duration._ + +/** + * An `Actor` that handles messages being dispatched to a specific `VehicleSpawnPad`.
+ *
+ * A spawn pad receives vehicle orders from an attached `Terminal` object. + * At the time when the order is received, the player who submitted the order is completely visible + * and waiting back by the said `Terminal` from where the order was submitted. + * Assuming no other orders are currently being processed, the repeated self message will retrieve this as the next order. + * The player character is first made transparent with a `GenericObjectActionMessage` packet. + * The vehicle model itself is then introduced to the game and three things happen with the following order, more or less:
+ * 1. the vehicle is attached to a lifting platform that is designed to introduce the vehicle;
+ * 2. the player is seated in the vehicle's driver seat (seat 0) and is thus declared the owner;
+ * 3. various properties of the player, the vehicle, and the spawn pad itself are set `PlanetsideAttributesMessage`.
+ * When this step is finished, the lifting platform raises the vehicle and the mounted player into the game world. + * The vehicle detaches and is made to roll off the spawn pad a certain distance before being released to user control. + * That is what is supposed to happen within a certain measure of timing.
+ *
+ * The orders that are submitted to the spawn pad must be composed of at least three elements: + * 1. a player, specifically the one that submitted the order and will be declared the "owner;" + * 2. a vehicle; + * 3. a callback location for sending messages. + * @param pad the `VehicleSpawnPad` object being governed + */ +class VehicleSpawnControl(pad : VehicleSpawnPad) extends Actor { + /** an executor for progressing a vehicle order through the normal spawning logic */ + private var process : Cancellable = DefaultCancellable.obj + /** a list of vehicle orders that have been submitted for this spawn pad */ + private var orders : List[VehicleSpawnControl.OrderEntry] = List.empty[VehicleSpawnControl.OrderEntry] + /** the current vehicle order being acted upon */ + private var trackedOrder : Option[VehicleSpawnControl.OrderEntry] = None + /** how many times a spawned vehicle (spatially) disrupted the next vehicle from being spawned */ + private var blockingViolations : Int = 0 + private[this] val log = org.log4s.getLogger + private[this] def trace(msg : String) : Unit = log.trace(msg) + + + def receive : Receive = { + case VehicleSpawnPad.VehicleOrder(player, vehicle) => + trace(s"order from $player for $vehicle received") + orders = orders :+ VehicleSpawnControl.OrderEntry(player, vehicle, sender) + if(trackedOrder.isEmpty && orders.length == 1) { + self ! VehicleSpawnControl.Process.GetOrder + } + + case VehicleSpawnControl.Process.GetOrder => + process.cancel + blockingViolations = 0 + val (completeOrder, remainingOrders) : (Option[VehicleSpawnControl.OrderEntry], List[VehicleSpawnControl.OrderEntry]) = orders match { + case x :: Nil => + (Some(x), Nil) + case x :: b => + (Some(x), b) + case Nil => + (None, Nil) + } + orders = remainingOrders + completeOrder match { + case Some(entry) => + trace(s"processing order $entry") + trackedOrder = completeOrder + import scala.concurrent.ExecutionContext.Implicits.global + process = context.system.scheduler.scheduleOnce(VehicleSpawnControl.concealPlayerTimeout, self, VehicleSpawnControl.Process.ConcealPlayer) + case None => ; + } + + case VehicleSpawnControl.Process.ConcealPlayer => + process.cancel + trackedOrder match { + case Some(entry) => + if(entry.player.isAlive && entry.vehicle.Actor != ActorRef.noSender && entry.sendTo != ActorRef.noSender && entry.player.VehicleSeated.isEmpty) { + trace(s"hiding player: ${entry.player}") + entry.sendTo ! VehicleSpawnPad.ConcealPlayer + import scala.concurrent.ExecutionContext.Implicits.global + process = context.system.scheduler.scheduleOnce(VehicleSpawnControl.loadVehicleTimeout, self, VehicleSpawnControl.Process.LoadVehicle) + } + else { + trace("integral component lost; abort order fulfillment") + //TODO Unregister vehicle ... somehow + trackedOrder = None + self ! VehicleSpawnControl.Process.GetOrder + } + case None => + self ! VehicleSpawnControl.Process.GetOrder + } + + case VehicleSpawnControl.Process.LoadVehicle => + process.cancel + trackedOrder match { + case Some(entry) => + if(entry.vehicle.Actor != ActorRef.noSender && entry.sendTo != ActorRef.noSender) { + trace(s"loading vehicle: ${entry.vehicle} defined in order") + entry.sendTo ! VehicleSpawnPad.LoadVehicle(entry.vehicle, pad) + import scala.concurrent.ExecutionContext.Implicits.global + process = context.system.scheduler.scheduleOnce(VehicleSpawnControl.awaitSeatedTimeout, self, VehicleSpawnControl.Process.AwaitSeated) + } + else { + trace("owner or vehicle lost; abort order fulfillment") + //TODO Unregister vehicle ... somehow + trackedOrder = None + self ! VehicleSpawnControl.Process.GetOrder + } + + case None => + self ! VehicleSpawnControl.Process.GetOrder + } + + case VehicleSpawnControl.Process.AwaitSeated => + process.cancel + trackedOrder match { + case Some(entry) => + if(entry.sendTo != ActorRef.noSender) { + trace("owner seated in vehicle") + import scala.concurrent.ExecutionContext.Implicits.global + process = if(entry.player.VehicleOwned.contains(entry.vehicle.GUID)) { + entry.sendTo ! VehicleSpawnPad.PlayerSeatedInVehicle(entry.vehicle) + context.system.scheduler.scheduleOnce(VehicleSpawnControl.awaitClearanceTimeout, self, VehicleSpawnControl.Process.AwaitClearance) + } + else { + context.system.scheduler.scheduleOnce(VehicleSpawnControl.awaitSeatedTimeout, self, VehicleSpawnControl.Process.AwaitSeated) + } + } + else { + trace("owner lost; abort order fulfillment") + trackedOrder = None + self ! VehicleSpawnControl.Process.GetOrder + } + case None => + self ! VehicleSpawnControl.Process.GetOrder + } + + //TODO raise spawn pad rails from ground + + //TODO start auto drive away + + //TODO release auto drive away + + case VehicleSpawnControl.Process.AwaitClearance => + process.cancel + trackedOrder match { + case Some(entry) => + if(entry.sendTo == ActorRef.noSender || entry.vehicle.Actor == ActorRef.noSender) { + trace("integral component lost, but order fulfilled; process next order") + trackedOrder = None + self ! VehicleSpawnControl.Process.GetOrder + } + else if(Vector3.DistanceSquared(entry.vehicle.Position, pad.Position) > 100.0f) { //10m away from pad + trace("pad cleared; process next order") + trackedOrder = None + entry.sendTo ! VehicleSpawnPad.SpawnPadUnblocked(entry.vehicle.GUID) + self ! VehicleSpawnControl.Process.GetOrder + } + else { + trace(s"pad blocked by ${entry.vehicle} ...") + blockingViolations += 1 + entry.sendTo ! VehicleSpawnPad.SpawnPadBlockedWarning(entry.vehicle, blockingViolations) + import scala.concurrent.ExecutionContext.Implicits.global + process = context.system.scheduler.scheduleOnce(VehicleSpawnControl.awaitClearanceTimeout, self, VehicleSpawnControl.Process.AwaitClearance) + } + case None => + self ! VehicleSpawnControl.Process.GetOrder + } + + case _ => ; + } +} + +object VehicleSpawnControl { + final val concealPlayerTimeout : FiniteDuration = 2000000000L nanoseconds //2s + final val loadVehicleTimeout : FiniteDuration = 1000000000L nanoseconds //1s + final val awaitSeatedTimeout : FiniteDuration = 1000000000L nanoseconds //1s + final val awaitClearanceTimeout : FiniteDuration = 5000000000L nanoseconds //5s + + /** + * An `Enumeration` of the stages of a full vehicle spawning process, associated with certain messages passed. + * Some stages are currently TEMPORARY. + * @see VehicleSpawnPad + */ + object Process extends Enumeration { + val + GetOrder, + ConcealPlayer, + LoadVehicle, + AwaitSeated, + AwaitClearance + = Value + } + + /** + * An entry that stores vehicle spawn pad spawning tasks (called "orders"). + * @param player the player + * @param vehicle the vehicle + * @param sendTo a callback `Actor` associated with the player (in other words, `WorldSessionActor`) + */ + private final case class OrderEntry(player : Player, vehicle : Vehicle, sendTo : ActorRef) +} diff --git a/common/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala b/common/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala new file mode 100644 index 000000000..f17ed5690 --- /dev/null +++ b/common/src/main/scala/net/psforever/objects/serverobject/pad/VehicleSpawnPad.scala @@ -0,0 +1,89 @@ +// Copyright (c) 2017 PSForever +package net.psforever.objects.serverobject.pad + +import net.psforever.objects.{Player, Vehicle} +import net.psforever.objects.definition.ObjectDefinition +import net.psforever.objects.serverobject.PlanetSideServerObject +import net.psforever.packet.game.PlanetSideGUID + +/** + * A structure-owned server object that is a "spawn pad" for vehicles.
+ *
+ * Spawn pads have no purpose on their own but + * maintain the operative queue that introduces the vehicle into the game world and applies initial activity to it and + * maintain a position and a direction where the vehicle will be made to appear (as a `PlanetSideServerObject`). + * The actual functionality managed by this object is wholly found on its accompanying `Actor`. + * @param spDef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields + * @see `VehicleSpawnControl` + */ +class VehicleSpawnPad(spDef : ObjectDefinition) extends PlanetSideServerObject { + def Definition : ObjectDefinition = spDef +} + +object VehicleSpawnPad { + + /** + * Communicate to the spawn pad that it should enqueue the following vehicle. + * This is the entry point to vehicle spawn pad functionality. + * @param player the player who submitted the order (the "owner") + * @param vehicle the vehicle produced from the order + */ + final case class VehicleOrder(player : Player, vehicle : Vehicle) + + /** + * The first callback step in spawning the vehicle. + * An packet `GenericObjectActionMessage(/player/, 36)`, when used on a player character, + * will cause that player character's model to fade into transparency. + */ + final case class ConcealPlayer() + + /** + * A callback step in spawning the vehicle. + * The vehicle is properly introduced into the game world. + * If information about the vehicle itself that is important to its spawning has not yet been set, + * this callback is the last ideal situation to set that properties without having to adjust the vehicle visually. + * The primary operation that should occur is a content-appropriate `ObjectCreateMessage` packet and + * having the player sit down in the driver's seat (seat 0) of the vehicle. + * @param vehicle the vehicle being spawned + * @param pad the pad + */ + final case class LoadVehicle(vehicle : Vehicle, pad : VehicleSpawnPad) + + /** + * A TEMPORARY callback step in spawning the vehicle. + * From a state of transparency, while the vehicle is attached to the lifting platform of the spawn pad, + * the player designated the "owner" by callback is made to sit in the driver's seat (always seat 0). + * This message is the next step after that. + * @param vehicle the vehicle being spawned + */ + final case class PlayerSeatedInVehicle(vehicle : Vehicle) + + /** + * A TEMPORARY callback step in (successfully) spawning the vehicle. + * While the vehicle is still occupying the pad just after being spawned and its driver seat mounted, + * that vehicle is considered blocking the pad from being used for further spawning operations. + * This message allows the user to be made known about this blockage. + * @param vehicle the vehicle + * @param warning_count the number of times a warning period has occurred + */ + final case class SpawnPadBlockedWarning(vehicle : Vehicle, warning_count : Int) + + /** + * A TEMPORARY callback step in (successfully) spawning the vehicle. + * While the vehicle is still occupying the pad just after being spawned and its driver seat mounted, + * that vehicle is considered blocking the pad from being used for further spawning operations. + * A timeout will begin counting until the vehicle is despawned automatically for its driver's negligence. + * This message is used to clear the deconstruction countdown, primarily. + * @param vehicle_guid the vehicle + */ + final case class SpawnPadUnblocked(vehicle_guid : PlanetSideGUID) + + /** + * Overloaded constructor. + * @param spDef the spawn pad's definition entry + * @return a `VehicleSpawnPad` object + */ + def apply(spDef : ObjectDefinition) : VehicleSpawnPad = { + new VehicleSpawnPad(spDef) + } +} diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/AirVehicleTerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/AirVehicleTerminalDefinition.scala new file mode 100644 index 000000000..fd62de60c --- /dev/null +++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/AirVehicleTerminalDefinition.scala @@ -0,0 +1,18 @@ +// Copyright (c) 2017 PSForever +package net.psforever.objects.serverobject.terminals + +import net.psforever.objects.Player +import net.psforever.packet.game.ItemTransactionMessage + +class AirVehicleTerminalDefinition extends TerminalDefinition(43) { + Name = "air_vehicle_terminal" + + def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = { + flight1Vehicles.get(msg.item_name) match { + case Some(vehicle) => + Terminal.BuyVehicle(vehicle(), Nil) + case None => + Terminal.NoDeal() + } + } +} diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/BFRTerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/BFRTerminalDefinition.scala new file mode 100644 index 000000000..263067491 --- /dev/null +++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/BFRTerminalDefinition.scala @@ -0,0 +1,19 @@ +// Copyright (c) 2017 PSForever +package net.psforever.objects.serverobject.terminals + +import net.psforever.objects.Player +import net.psforever.packet.game.ItemTransactionMessage + +class BFRTerminalDefinition extends TerminalDefinition(143) { + Name = "bfr_terminal" + + def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = { + bfrVehicles.get(msg.item_name) match { + case Some(vehicle) => + //Terminal.BuyVehicle(vehicle, Nil) + Terminal.NoDeal() + case None => + Terminal.NoDeal() + } + } +} diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/CertTerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/CertTerminalDefinition.scala index 8f990196e..a1583aa0c 100644 --- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/CertTerminalDefinition.scala +++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/CertTerminalDefinition.scala @@ -81,7 +81,7 @@ class CertTerminalDefinition extends TerminalDefinition(171) { * @param msg the original packet carrying the request * @return an actionable message that explains how to process the request */ - def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = { + override def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = { certificationList.get(msg.item_name) match { case Some((cert, cost)) => Terminal.SellCertification(cert, cost) @@ -89,12 +89,4 @@ class CertTerminalDefinition extends TerminalDefinition(171) { Terminal.NoDeal() } } - - /** - * This action is not supported by this type of `Terminal`. - * @param player the player - * @param msg the original packet carrying the request - * @return `Terminal.NoEvent` always - */ - def Loadout(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.NoDeal() } diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/DropshipVehicleTerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/DropshipVehicleTerminalDefinition.scala new file mode 100644 index 000000000..7176f9785 --- /dev/null +++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/DropshipVehicleTerminalDefinition.scala @@ -0,0 +1,19 @@ +// Copyright (c) 2017 PSForever +package net.psforever.objects.serverobject.terminals + +import net.psforever.objects.Player +import net.psforever.packet.game.ItemTransactionMessage + +class DropshipVehicleTerminalDefinition extends TerminalDefinition(263) { + private val flightVehicles = flight1Vehicles ++ flight2Vehicles + Name = "dropship_vehicle_terminal" + + def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = { + flightVehicles.get(msg.item_name) match { + case Some(vehicle) => + Terminal.BuyVehicle(vehicle(), Nil) + case None => + Terminal.NoDeal() + } + } +} diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/GroundVehicleTerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/GroundVehicleTerminalDefinition.scala new file mode 100644 index 000000000..1087c575a --- /dev/null +++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/GroundVehicleTerminalDefinition.scala @@ -0,0 +1,18 @@ +// Copyright (c) 2017 PSForever +package net.psforever.objects.serverobject.terminals + +import net.psforever.objects.Player +import net.psforever.packet.game.ItemTransactionMessage + +class GroundVehicleTerminalDefinition extends TerminalDefinition(386) { + Name = "ground_vehicle_terminal" + + def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = { + groundVehicles.get(msg.item_name) match { + case Some(vehicle) => + Terminal.BuyVehicle(vehicle(), Nil) + case None => + Terminal.NoDeal() + } + } +} diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/OrderTerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/OrderTerminalDefinition.scala index cea418f0f..2735b1bb3 100644 --- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/OrderTerminalDefinition.scala +++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/OrderTerminalDefinition.scala @@ -1,7 +1,7 @@ // Copyright (c) 2017 PSForever package net.psforever.objects.serverobject.terminals -import net.psforever.objects.InfantryLoadout.Simplification +import net.psforever.objects.Loadout.Simplification import net.psforever.objects.{Player, Tool} import net.psforever.objects.definition._ import net.psforever.objects.equipment.Equipment @@ -13,7 +13,7 @@ import scala.annotation.switch /** * The definition for any `Terminal` that is of a type "order_terminal". * `Buy` and `Sell` `Equipment` items and `AmmoBox` items. - * Change `ExoSuitType` and retrieve `InfantryLoadout` entries. + * Change `ExoSuitType` and retrieve `Loadout` entries. */ class OrderTerminalDefinition extends TerminalDefinition(612) { Name = "order_terminal" @@ -75,19 +75,19 @@ class OrderTerminalDefinition extends TerminalDefinition(612) { * @param msg the original packet carrying the request * @return an actionable message that explains how to process the request */ - def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = { + override def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = { Terminal.SellEquipment() } /** * Process a `TransactionType.InfantryLoadout` action by the user. - * `InfantryLoadout` objects are blueprints composed of exo-suit specifications and simplified `Equipment`-to-slot mappings. + * `Loadout` objects are blueprints composed of exo-suit specifications and simplified `Equipment`-to-slot mappings. * If a valid loadout is found, its data is transformed back into actual `Equipment` for return to the user. * @param player the player * @param msg the original packet carrying the request * @return an actionable message that explains how to process the request */ - def Loadout(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = { + override def Loadout(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = { if(msg.item_page == 4) { //Favorites tab player.LoadLoadout(msg.unk1) match { case Some(loadout) => @@ -105,7 +105,7 @@ class OrderTerminalDefinition extends TerminalDefinition(612) { /** * Accept a simplified blueprint for some piece of `Equipment` and create an actual piece of `Equipment` based on it. - * Used specifically for the reconstruction of `Equipment` via an `InfantryLoadout`. + * Used specifically for the reconstruction of `Equipment` via an `Loadout`. * @param entry the simplified blueprint * @return some `Equipment` object * @see `TerminalDefinition.MakeTool`
@@ -115,7 +115,7 @@ class OrderTerminalDefinition extends TerminalDefinition(612) { * `TerminalDefinition.MakeKit` */ private def BuildSimplifiedPattern(entry : Simplification) : Equipment = { - import net.psforever.objects.InfantryLoadout._ + import net.psforever.objects.Loadout._ entry match { case obj : ShorthandTool => val ammo : List[AmmoBoxDefinition] = obj.ammo.map(fmode => { fmode.ammo.adef }) diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/Terminal.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/Terminal.scala index c6cba9f0c..554f09603 100644 --- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/Terminal.scala +++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/Terminal.scala @@ -136,10 +136,24 @@ object Terminal { final case class SellEquipment() extends Exchange import net.psforever.types.CertificationType + + /** + * Provide the certification type unlocked by the player. + * @param cert the certification unlocked + * @param cost the certification point cost + */ final case class LearnCertification(cert : CertificationType.Value, cost : Int) extends Exchange + /** + * Provide the certification type freed-up by the player. + * @param cert the certification returned + * @param cost the certification point cost + */ final case class SellCertification(cert : CertificationType.Value, cost : Int) extends Exchange + import net.psforever.objects.Vehicle + final case class BuyVehicle(vehicle : Vehicle, loadout: List[Any]) extends Exchange + /** * Recover a former exo-suit and `Equipment` configuration that the `Player` possessed. * A result of a processed request. diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalDefinition.scala index 5cf8ff3d4..aa98b0f74 100644 --- a/common/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalDefinition.scala +++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/TerminalDefinition.scala @@ -8,10 +8,11 @@ import net.psforever.packet.game.ItemTransactionMessage import net.psforever.types.ExoSuitType /** - * The definition for any `Terminal`. + * The basic definition for any `Terminal`. * @param objectId the object's identifier number */ abstract class TerminalDefinition(objectId : Int) extends ObjectDefinition(objectId) { + private[this] val log = org.log4s.getLogger("TerminalDefinition") Name = "terminal" /** @@ -22,12 +23,12 @@ abstract class TerminalDefinition(objectId : Int) extends ObjectDefinition(objec /** * The unimplemented functionality for this `Terminal`'s `TransactionType.Sell` activity. */ - def Sell(player: Player, msg : ItemTransactionMessage) : Terminal.Exchange + def Sell(player: Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.NoDeal() /** * The unimplemented functionality for this `Terminal`'s `TransactionType.InfantryLoadout` activity. */ - def Loadout(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange + def Loadout(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.NoDeal() /** * A `Map` of information for changing exo-suits. @@ -128,42 +129,42 @@ abstract class TerminalDefinition(objectId : Int) extends ObjectDefinition(objec * value - a curried function that builds the object */ protected val infantryWeapons : Map[String, ()=>Equipment] = Map( - "ilc9" -> MakeTool(ilc9, bullet_9mm), - "repeater" -> MakeTool(repeater, bullet_9mm), - "isp" -> MakeTool(isp, shotgun_shell), //amp - "beamer" -> MakeTool(beamer, energy_cell), - "suppressor" -> MakeTool(suppressor, bullet_9mm), - "anniversary_guna" -> MakeTool(anniversary_guna, anniversary_ammo), //tr stinger - "anniversary_gun" -> MakeTool(anniversary_gun, anniversary_ammo), //nc spear - "anniversary_gunb" -> MakeTool(anniversary_gunb, anniversary_ammo), //vs eraser - "cycler" -> MakeTool(cycler, bullet_9mm), - "gauss" -> MakeTool(gauss, bullet_9mm), - "pulsar" -> MakeTool(pulsar, energy_cell), - "punisher" -> MakeTool(punisher, List(bullet_9mm, rocket)), - "flechette" -> MakeTool(flechette, shotgun_shell), - "spiker" -> MakeTool(spiker, ancient_ammo_combo), - "frag_grenade" -> MakeTool(frag_grenade, frag_grenade_ammo), - "jammer_grenade" -> MakeTool(jammer_grenade, jammer_grenade_ammo), - "plasma_grenade" -> MakeTool(plasma_grenade, plasma_grenade_ammo), - "katana" -> MakeTool(katana, melee_ammo), - "chainblade" -> MakeTool(chainblade, melee_ammo), - "magcutter" -> MakeTool(magcutter, melee_ammo), - "forceblade" -> MakeTool(forceblade, melee_ammo), - "mini_chaingun" -> MakeTool(mini_chaingun, bullet_9mm), - "r_shotgun" -> MakeTool(r_shotgun, shotgun_shell), //jackhammer - "lasher" -> MakeTool(lasher, energy_cell), - "maelstrom" -> MakeTool(maelstrom, maelstrom_ammo), - "striker" -> MakeTool(striker, striker_missile_ammo), - "hunterseeker" -> MakeTool(hunterseeker, hunter_seeker_missile), //phoenix - "lancer" -> MakeTool(lancer, lancer_cartridge), - "phoenix" -> MakeTool(phoenix, phoenix_missile), //decimator - "rocklet" -> MakeTool(rocklet, rocket), - "thumper" -> MakeTool(thumper, frag_cartridge), - "radiator" -> MakeTool(radiator, ancient_ammo_combo), - "heavy_sniper" -> MakeTool(heavy_sniper, bolt), //hsr - "bolt_driver" -> MakeTool(bolt_driver, bolt), - "oicw" -> MakeTool(oicw, oicw_ammo), //scorpion - "flamethrower" -> MakeTool(flamethrower, flamethrower_ammo) + "ilc9" -> MakeTool(ilc9), + "repeater" -> MakeTool(repeater), + "isp" -> MakeTool(isp), //amp + "beamer" -> MakeTool(beamer), + "suppressor" -> MakeTool(suppressor), + "anniversary_guna" -> MakeTool(anniversary_guna), //tr stinger + "anniversary_gun" -> MakeTool(anniversary_gun), //nc spear + "anniversary_gunb" -> MakeTool(anniversary_gunb), //vs eraser + "cycler" -> MakeTool(cycler), + "gauss" -> MakeTool(gauss), + "pulsar" -> MakeTool(pulsar), + "punisher" -> MakeTool(punisher), + "flechette" -> MakeTool(flechette), + "spiker" -> MakeTool(spiker), + "frag_grenade" -> MakeTool(frag_grenade), + "jammer_grenade" -> MakeTool(jammer_grenade), + "plasma_grenade" -> MakeTool(plasma_grenade), + "katana" -> MakeTool(katana), + "chainblade" -> MakeTool(chainblade), + "magcutter" -> MakeTool(magcutter), + "forceblade" -> MakeTool(forceblade), + "mini_chaingun" -> MakeTool(mini_chaingun), + "r_shotgun" -> MakeTool(r_shotgun), //jackhammer + "lasher" -> MakeTool(lasher), + "maelstrom" -> MakeTool(maelstrom), + "striker" -> MakeTool(striker), + "hunterseeker" -> MakeTool(hunterseeker), //phoenix + "lancer" -> MakeTool(lancer), + "phoenix" -> MakeTool(phoenix), //decimator + "rocklet" -> MakeTool(rocklet), + "thumper" -> MakeTool(thumper), + "radiator" -> MakeTool(radiator), + "heavy_sniper" -> MakeTool(heavy_sniper), //hsr + "bolt_driver" -> MakeTool(bolt_driver), + "oicw" -> MakeTool(oicw), //scorpion + "flamethrower" -> MakeTool(flamethrower) ) /** @@ -176,20 +177,98 @@ abstract class TerminalDefinition(objectId : Int) extends ObjectDefinition(objec "super_medkit" -> MakeKit(super_medkit), "super_armorkit" -> MakeKit(super_armorkit), "super_staminakit" -> MakeKit(super_staminakit), - "medicalapplicator" -> MakeTool(medicalapplicator, health_canister), + "medicalapplicator" -> MakeTool(medicalapplicator), "bank" -> MakeTool(bank, armor_canister), - "nano_dispenser" -> MakeTool(nano_dispenser, armor_canister), + "nano_dispenser" -> MakeTool(nano_dispenser), //TODO "ace" -> MakeConstructionItem(ace), //TODO "advanced_ace" -> MakeConstructionItem(advanced_ace), "remote_electronics_kit" -> MakeSimpleItem(remote_electronics_kit), - "trek" -> MakeTool(trek, trek_ammo), + "trek" -> MakeTool(trek), "command_detonater" -> MakeSimpleItem(command_detonater), "flail_targeting_laser" -> MakeSimpleItem(flail_targeting_laser) ) + /** + * A `Map` of operations for producing a ground-based `Vehicle`. + * key - an identification string sent by the client + * value - a curried function that builds the object + */ + protected val groundVehicles : Map[String, ()=>Vehicle] = Map( + "quadassault" -> MakeVehicle(quadassault), + "fury" -> MakeVehicle(fury), + "quadstealth" -> MakeVehicle(quadstealth), + "ant" -> MakeVehicle(ant), + "ams" -> MakeVehicle(ams), + "mediumtransport" -> MakeVehicle(mediumtransport), + "two_man_assault_buggy" -> MakeVehicle(two_man_assault_buggy), + "skyguard" -> MakeVehicle(skyguard), + "lightning" -> MakeVehicle(lightning), + "threemanheavybuggy" -> MakeVehicle(threemanheavybuggy), + "battlewagon" -> MakeVehicle(battlewagon), + "apc_tr" -> MakeVehicle(apc_tr), + "prowler" -> MakeVehicle(prowler), + "twomanheavybuggy" -> MakeVehicle(twomanheavybuggy), + "thunderer" -> MakeVehicle(thunderer), + "apc_nc" -> MakeVehicle(apc_nc), + "vanguard" -> MakeVehicle(vanguard), + "twomanhoverbuggy" -> MakeVehicle(twomanhoverbuggy), + "aurora" -> MakeVehicle(aurora), + "apc_vs" -> MakeVehicle(apc_vs), + "magrider" -> MakeVehicle(magrider), + "flail" -> MakeVehicle(flail), + "switchblade" -> MakeVehicle(switchblade), + "router" -> MakeVehicle(router) + ) + + /** + * A `Map` of operations for producing most flight-based `Vehicle`. + * key - an identification string sent by the client + * value - a curried function that builds the object + */ + protected val flight1Vehicles : Map[String, ()=>Vehicle] = Map( + "mosquito" -> MakeVehicle(mosquito), + "lightgunship" -> MakeVehicle(lightgunship), + "wasp" -> MakeVehicle(wasp), + "phantasm" -> MakeVehicle(phantasm), + "vulture" -> MakeVehicle(vulture), + "liberator" -> MakeVehicle(liberator) + ) + + /** + * A `Map` of operations for producing a flight-based `Vehicle` specific to the dropship terminal. + * key - an identification string sent by the client + * value - a curried function that builds the object + */ + protected val flight2Vehicles : Map[String, ()=>Vehicle] = Map( + "dropship" -> MakeVehicle(dropship), + "galaxy_gunship" -> MakeVehicle(galaxy_gunship), + "lodestar" -> MakeVehicle(lodestar) + ) + + /** + * A `Map` of operations for producing a ground-based `Vehicle` specific to the bfr terminal. + * key - an identification string sent by the client + * value - a curried function that builds the object + */ + protected val bfrVehicles : Map[String, ()=>Vehicle] = Map( +// "colossus_gunner" -> (()=>Unit), +// "colossus_flight" -> (()=>Unit), +// "peregrine_gunner" -> (()=>Unit), +// "peregrine_flight" -> (()=>Unit), +// "aphelion_gunner" -> (()=>Unit), +// "aphelion_flight" -> (()=>Unit) + ) + /** * Create a new `Tool` from provided `EquipmentDefinition` objects. - * @param tdef the `ToolDefinition` objects + * @param tdef the `ToolDefinition` object + * @return a partial function that, when called, creates the piece of `Equipment` + */ + protected def MakeTool(tdef : ToolDefinition)() : Tool = MakeTool(tdef, Nil) + + /** + * Create a new `Tool` from provided `EquipmentDefinition` objects. + * @param tdef the `ToolDefinition` object * @param adef an `AmmoBoxDefinition` object * @return a partial function that, when called, creates the piece of `Equipment` */ @@ -200,24 +279,55 @@ abstract class TerminalDefinition(objectId : Int) extends ObjectDefinition(objec * Only use this function to create default `Tools` with the default parameters. * For example, loadouts can retain `Tool` information that utilizes alternate, valid ammunition types; * and, this method function will not construct a complete object if provided that information. - * @param tdef the `ToolDefinition` objects + * @param tdef the `ToolDefinition` object * @param adefs a `List` of `AmmoBoxDefinition` objects * @return a curried function that, when called, creates the piece of `Equipment` * @see `GlobalDefinitions` * @see `OrderTerminalDefinition.BuildSimplifiedPattern` */ - protected def MakeTool(tdef : ToolDefinition, adefs : List[AmmoBoxDefinition])() : Tool = { + protected def MakeTool(tdef : ToolDefinition, adefs : List[AmmoBoxDefinition])() : Tool = { val obj = Tool(tdef) - (0 until obj.MaxAmmoSlot).foreach(index => { - val aType = adefs(index) - val ammo = MakeAmmoBox(aType, Some(obj.Definition.FireModes(index).Magazine)) //make internal magazine, full - (obj.AmmoSlots(index).Box = ammo) match { - case Some(_) => ; //this means it worked - case None => - org.log4s.getLogger("TerminalDefinition").warn(s"plans do not match definition: trying to feed ${ammo.AmmoType} ammunition into Tool (${obj.Definition.ObjectId} @ $index)") + adefs match { + case _ :: _ => + LoadAmmunitionIntoWeapon(obj, adefs) + case Nil => ; //as-is + } + obj + } + + /** + * Given a weapon, and custom ammunition profiles, attempt to load those boxes of ammunition into the weapon.
+ *
+ * This is a customization function that should normally go unused. + * All of the information necessary to generate a `Tool` from a `Terminal` request should be available on the `ToolDefinition` object. + * The ammunition information, regardless of "customization," must satisfy the type limits of the original definition. + * As thus, to introduce very strange ammunition to a give `Tool`, + * either the definition must be modified or a different definition must be used. + * The custom ammunition is organized into order of ammunition slots based on the `FireModeDefinition` objects. + * That is: + * the first custom element is processed by the first ammunition slot; + * the second custom element is processed by the second ammunition slot; and, so forth. + * @param weapon the `Tool` object + * @param adefs a sequential `List` of ammunition to be loaded into weapon + * @see `AmmoBoxDefinition` + * @see `FireModeDefinition` + */ + private def LoadAmmunitionIntoWeapon(weapon : Tool, adefs : List[AmmoBoxDefinition]) : Unit = { + val definition = weapon.Definition + (0 until math.min(weapon.MaxAmmoSlot, adefs.length)).foreach(index => { + val ammoSlot = weapon.AmmoSlots(index) + adefs.lift(index) match { + case Some(aType) => + ammoSlot.AllAmmoTypes.indexOf(aType.AmmoType) match { + case -1 => + log.warn(s"terminal plans do not match definition: can not feed ${aType.AmmoType} ammunition into Tool (${definition.ObjectId} @ ammo $index)") + case n => + ammoSlot.AmmoTypeIndex = n + ammoSlot.Box = MakeAmmoBox(aType, Some(definition.FireModes(index).Magazine)) //make new internal magazine, full + } + case None => ; } }) - obj } /** @@ -229,11 +339,12 @@ abstract class TerminalDefinition(objectId : Int) extends ObjectDefinition(objec * @see `GlobalDefinitions` */ protected def MakeAmmoBox(adef : AmmoBoxDefinition, capacity : Option[Int] = None)() : AmmoBox = { - val obj = AmmoBox(adef) - if(capacity.isDefined) { - obj.Capacity = capacity.get + capacity match { + case Some(cap) => + AmmoBox(adef, cap) + case None => + AmmoBox(adef) } - obj } /** @@ -259,4 +370,12 @@ abstract class TerminalDefinition(objectId : Int) extends ObjectDefinition(objec * @see `GlobalDefinitions` */ protected def MakeConstructionItem(cdef : ConstructionItemDefinition)() : ConstructionItem = ConstructionItem(cdef) + + /** + * Create a new `Vehicle` from provided `VehicleDefinition` objects. + * @param vdef the `VehicleDefinition` object + * @return a curried function that, when called, creates the `Vehicle` + * @see `GlobalDefinitions` + */ + protected def MakeVehicle(vdef : VehicleDefinition)() : Vehicle = Vehicle(vdef) } diff --git a/common/src/main/scala/net/psforever/objects/serverobject/terminals/VehicleTerminalCombinedDefinition.scala b/common/src/main/scala/net/psforever/objects/serverobject/terminals/VehicleTerminalCombinedDefinition.scala new file mode 100644 index 000000000..c069545a4 --- /dev/null +++ b/common/src/main/scala/net/psforever/objects/serverobject/terminals/VehicleTerminalCombinedDefinition.scala @@ -0,0 +1,19 @@ +// Copyright (c) 2017 PSForever +package net.psforever.objects.serverobject.terminals + +import net.psforever.objects.Player +import net.psforever.packet.game.ItemTransactionMessage + +class VehicleTerminalCombinedDefinition extends TerminalDefinition(952) { + private val vehicles = groundVehicles ++ flight1Vehicles + Name = "vehicle_terminal_combined" + + def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = { + vehicles.get(msg.item_name) match { + case Some(vehicle) => + Terminal.BuyVehicle(vehicle(), Nil) + case None => + Terminal.NoDeal() + } + } +} diff --git a/common/src/main/scala/net/psforever/objects/zones/ZoneActor.scala b/common/src/main/scala/net/psforever/objects/zones/ZoneActor.scala index 022aa53d7..3e2a63fc3 100644 --- a/common/src/main/scala/net/psforever/objects/zones/ZoneActor.scala +++ b/common/src/main/scala/net/psforever/objects/zones/ZoneActor.scala @@ -2,7 +2,6 @@ package net.psforever.objects.zones import akka.actor.Actor -import net.psforever.objects.serverobject.locks.IFFLock /** * na @@ -35,8 +34,9 @@ class ZoneActor(zone : Zone) extends Actor { } }) - //check door to locks association + //check door to lock association import net.psforever.objects.serverobject.doors.Door + import net.psforever.objects.serverobject.locks.IFFLock map.DoorToLock.foreach({ case((door_guid, lock_guid)) => try { if(!guid(door_guid).get.isInstanceOf[Door]) { @@ -45,7 +45,7 @@ class ZoneActor(zone : Zone) extends Actor { } catch { case _ : Exception => - slog.error(s"expected a door, but looking for uninitialized object $door_guid") + slog.error(s"expected a door at id $door_guid, but looking for uninitialized object") } try { if(!guid(lock_guid).get.isInstanceOf[IFFLock]) { @@ -54,7 +54,31 @@ class ZoneActor(zone : Zone) extends Actor { } catch { case _ : Exception => - slog.error(s"expected an IFF locks, but looking for uninitialized object $lock_guid") + slog.error(s"expected an IFF locks at id $lock_guid, but looking for uninitialized object") + } + }) + + //check vehicle terminal to spawn pad association + import net.psforever.objects.serverobject.pad.VehicleSpawnPad + import net.psforever.objects.serverobject.terminals.Terminal + map.TerminalToSpawnPad.foreach({ case ((term_guid, pad_guid)) => + try { + if(!guid(term_guid).get.isInstanceOf[Terminal]) { //TODO check is vehicle terminal + slog.error(s"expected id $term_guid to be a terminal, but it was not") + } + } + catch { + case _ : Exception => + slog.error(s"expected a terminal at id $term_guid, but looking for uninitialized object") + } + try { + if(!guid(pad_guid).get.isInstanceOf[VehicleSpawnPad]) { + slog.error(s"expected id $pad_guid to be a spawn pad, but it was not") + } + } + catch { + case _ : Exception => + slog.error(s"expected a spawn pad at id $pad_guid, but looking for uninitialized object") } }) } diff --git a/common/src/main/scala/net/psforever/objects/zones/ZoneMap.scala b/common/src/main/scala/net/psforever/objects/zones/ZoneMap.scala index dbec207ca..35d38fe96 100644 --- a/common/src/main/scala/net/psforever/objects/zones/ZoneMap.scala +++ b/common/src/main/scala/net/psforever/objects/zones/ZoneMap.scala @@ -25,6 +25,7 @@ import net.psforever.objects.serverobject.builders.ServerObjectBuilder */ class ZoneMap(private val name : String) { private var localObjects : List[ServerObjectBuilder[_]] = List() + private var linkTerminalPad : Map[Int, Int] = Map() private var linkDoorLock : Map[Int, Int] = Map() private var linkObjectBase : Map[Int, Int] = Map() private var numBases : Int = 0 @@ -64,7 +65,13 @@ class ZoneMap(private val name : String) { def DoorToLock : Map[Int, Int] = linkDoorLock - def DoorToLock(door_guid : Int, lock_guid : Int) = { + def DoorToLock(door_guid : Int, lock_guid : Int) : Unit = { linkDoorLock = linkDoorLock ++ Map(door_guid -> lock_guid) } + + def TerminalToSpawnPad : Map[Int, Int] = linkTerminalPad + + def TerminalToSpawnPad(terminal_guid : Int, pad_guid : Int) : Unit = { + linkTerminalPad = linkTerminalPad ++ Map(terminal_guid -> pad_guid) + } } diff --git a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala index bec753054..bfc13b89f 100644 --- a/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala +++ b/common/src/main/scala/net/psforever/packet/GamePacketOpcode.scala @@ -420,7 +420,7 @@ object GamePacketOpcode extends Enumeration { case 0x53 => noDecoder(DroppodLaunchRequestMessage) case 0x54 => game.HackMessage.decode case 0x55 => noDecoder(DroppodLaunchResponseMessage) - case 0x56 => noDecoder(GenericObjectActionMessage) + case 0x56 => game.GenericObjectActionMessage.decode case 0x57 => game.AvatarVehicleTimerMessage.decode // 0x58 case 0x58 => game.AvatarImplantMessage.decode diff --git a/common/src/main/scala/net/psforever/packet/game/GenericObjectActionMessage.scala b/common/src/main/scala/net/psforever/packet/game/GenericObjectActionMessage.scala new file mode 100644 index 000000000..0c15f526f --- /dev/null +++ b/common/src/main/scala/net/psforever/packet/game/GenericObjectActionMessage.scala @@ -0,0 +1,39 @@ +// Copyright (c) 2017 PSForever +package net.psforever.packet.game + +import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket} +import scodec.bits.BitVector +import scodec.{Attempt, Codec} +import scodec.codecs._ +import shapeless.{::, HNil} + +/** + * Dispatched by the server to enact an effect on some game object. + * (Write more some other time.) + * @param object_guid the target object + * @param code the action code + */ +final case class GenericObjectActionMessage(object_guid : PlanetSideGUID, + code : Int) + extends PlanetSideGamePacket { + type Packet = GenericObjectActionMessage + def opcode = GamePacketOpcode.GenericObjectActionMessage + def encode = GenericObjectActionMessage.encode(this) +} + +object GenericObjectActionMessage extends Marshallable[GenericObjectActionMessage] { + implicit val codec : Codec[GenericObjectActionMessage] = ( + ("object_guid" | PlanetSideGUID.codec) :: + ("code" | uint8L) :: + ("ex" | bits) //"code" may extract at odd sizes + ).exmap[GenericObjectActionMessage] ( + { + case guid :: code :: _ :: HNil => + Attempt.Successful(GenericObjectActionMessage(guid, code)) + }, + { + case GenericObjectActionMessage(guid, code) => + Attempt.Successful(guid :: code :: BitVector.empty :: HNil) + } + ) +} diff --git a/common/src/main/scala/net/psforever/packet/game/PlanetsideAttributeMessage.scala b/common/src/main/scala/net/psforever/packet/game/PlanetsideAttributeMessage.scala index c61b03e7a..036bd5ff8 100644 --- a/common/src/main/scala/net/psforever/packet/game/PlanetsideAttributeMessage.scala +++ b/common/src/main/scala/net/psforever/packet/game/PlanetsideAttributeMessage.scala @@ -89,7 +89,7 @@ import scodec.codecs._ * `106 - Custom Head`
*
* Vehicles:
- * 0 - Vehicle health
+ * 0 - Vehicle base health
* 10 - Driver seat permissions (0 = Locked, 1 = Group, 3 = Empire)
* 11 - Gunner seat(s) permissions (same)
* 12 - Passenger seat(s) permissions (same)
diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectClass.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectClass.scala index 37b85c5a6..e9506fc3b 100644 --- a/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectClass.scala +++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/ObjectClass.scala @@ -347,6 +347,8 @@ object ObjectClass { final val quadstealth_destroyed = 711 final val router = 741 final val router_destroyed = 742 + final val skyguard = 784 + final val skyguard_destroyed = 785 final val switchblade = 847 final val switchblade_destroyed = 848 final val threemanheavybuggy = 862 //marauder @@ -845,7 +847,7 @@ object ObjectClass { case ObjectClass.lancer => ConstructorData.genericCodec(WeaponData.codec, "weapon") case ObjectClass.lasher => ConstructorData.genericCodec(WeaponData.codec, "weapon") case ObjectClass.liberator_25mm_cannon => ConstructorData.genericCodec(WeaponData.codec, "weapon") - case ObjectClass.liberator_bomb_bay => ConstructorData.genericCodec(WeaponData.codec(2), "weapon") + case ObjectClass.liberator_bomb_bay => ConstructorData.genericCodec(WeaponData.codec, "weapon") case ObjectClass.liberator_weapon_system => ConstructorData.genericCodec(WeaponData.codec, "weapon") case ObjectClass.lightgunship_weapon_system => ConstructorData.genericCodec(WeaponData.codec(2), "weapon") case ObjectClass.lightning_weapon_system => ConstructorData.genericCodec(WeaponData.codec(2), "weapon") @@ -888,7 +890,7 @@ object ObjectClass { case ObjectClass.rocklet => ConstructorData.genericCodec(WeaponData.codec, "weapon") case ObjectClass.rotarychaingun_mosquito => ConstructorData.genericCodec(WeaponData.codec, "weapon") case ObjectClass.scythe => ConstructorData.genericCodec(WeaponData.codec(2), "weapon") - case ObjectClass.skyguard_weapon_system => ConstructorData.genericCodec(WeaponData.codec, "weapon") + case ObjectClass.skyguard_weapon_system => ConstructorData.genericCodec(WeaponData.codec(2), "weapon") case ObjectClass.spiker => ConstructorData.genericCodec(WeaponData.codec, "weapon") case ObjectClass.spitfire_aa_weapon => ConstructorData.genericCodec(WeaponData.codec, "weapon") case ObjectClass.spitfire_weapon => ConstructorData.genericCodec(WeaponData.codec, "weapon") @@ -1245,6 +1247,8 @@ object ObjectClass { case ObjectClass.quadstealth_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage") case ObjectClass.router => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Variant), "vehicle") case ObjectClass.router_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage") + case ObjectClass.skyguard => ConstructorData.genericCodec(VehicleData.codec, "vehicle") + case ObjectClass.skyguard_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage") case ObjectClass.switchblade => ConstructorData.genericCodec(VehicleData.codec(VehicleFormat.Variant), "vehicle") case ObjectClass.switchblade_destroyed => ConstructorData.genericCodec(DestroyedVehicleData.codec, "wreckage") case ObjectClass.threemanheavybuggy => ConstructorData.genericCodec(VehicleData.codec, "vehicle") diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/Prefab.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/Prefab.scala index 8d3a60651..1a3d8aed9 100644 --- a/common/src/main/scala/net/psforever/packet/game/objectcreate/Prefab.scala +++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/Prefab.scala @@ -27,6 +27,81 @@ object Prefab { VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, driveState, false, false, false, Some(UtilityVehicleData(0)), None)(VehicleFormat.Utility) } + def apc_nc(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID, weapon3_guid : PlanetSideGUID, ammo3_guid : PlanetSideGUID, weapon4_guid : PlanetSideGUID, ammo4_guid : PlanetSideGUID, weapon5_guid : PlanetSideGUID, ammo5_guid : PlanetSideGUID, weapon6_guid : PlanetSideGUID, ammo6_guid : PlanetSideGUID) : VehicleData = { + VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None, + Some(InventoryData( + InventoryItemData(ObjectClass.apc_weapon_systemc_nc, weapon1_guid, 11, + WeaponData(0x6, 0x8, 0, ObjectClass.bullet_20mm, ammo1_guid, 0, AmmoBoxData(8)) + ) :: + InventoryItemData(ObjectClass.apc_weapon_systemb, weapon2_guid, 12, + WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo2_guid, 0, AmmoBoxData(8)) + ) :: + InventoryItemData(ObjectClass.apc_weapon_systema, weapon3_guid, 13, + WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo3_guid, 0, AmmoBoxData(8)) + ) :: + InventoryItemData(ObjectClass.apc_weapon_systemd_nc, weapon4_guid, 14, + WeaponData(0x6, 0x8, 0, ObjectClass.bullet_20mm, ammo4_guid, 0, AmmoBoxData(8)) + ) :: + InventoryItemData(ObjectClass.apc_ballgun_r, weapon5_guid, 15, + WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo5_guid, 0, AmmoBoxData(8)) + ) :: + InventoryItemData(ObjectClass.apc_ballgun_l, weapon6_guid, 16, + WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo6_guid, 0, AmmoBoxData(8)) + ) :: Nil + )) + )(VehicleFormat.Normal) + } + + def apc_tr(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID, weapon3_guid : PlanetSideGUID, ammo3_guid : PlanetSideGUID, weapon4_guid : PlanetSideGUID, ammo4_guid : PlanetSideGUID, weapon5_guid : PlanetSideGUID, ammo5_guid : PlanetSideGUID, weapon6_guid : PlanetSideGUID, ammo6_guid : PlanetSideGUID) : VehicleData = { + VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None, + Some(InventoryData( + InventoryItemData(ObjectClass.apc_weapon_systemc_tr, weapon1_guid, 11, + WeaponData(0x6, 0x8, 0, ObjectClass.bullet_15mm, ammo1_guid, 0, AmmoBoxData(8)) + ) :: + InventoryItemData(ObjectClass.apc_weapon_systemb, weapon2_guid, 12, + WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo2_guid, 0, AmmoBoxData(8)) + ) :: + InventoryItemData(ObjectClass.apc_weapon_systema, weapon3_guid, 13, + WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo3_guid, 0, AmmoBoxData(8)) + ) :: + InventoryItemData(ObjectClass.apc_weapon_systemd_tr, weapon4_guid, 14, + WeaponData(0x6, 0x8, 0, ObjectClass.bullet_15mm, ammo4_guid, 0, AmmoBoxData(8)) + ) :: + InventoryItemData(ObjectClass.apc_ballgun_r, weapon5_guid, 15, + WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo5_guid, 0, AmmoBoxData(8)) + ) :: + InventoryItemData(ObjectClass.apc_ballgun_l, weapon6_guid, 16, + WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo6_guid, 0, AmmoBoxData(8)) + ) :: Nil + )) + )(VehicleFormat.Normal) + } + + def apc_vs(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID, weapon3_guid : PlanetSideGUID, ammo3_guid : PlanetSideGUID, weapon4_guid : PlanetSideGUID, ammo4_guid : PlanetSideGUID, weapon5_guid : PlanetSideGUID, ammo5_guid : PlanetSideGUID, weapon6_guid : PlanetSideGUID, ammo6_guid : PlanetSideGUID) : VehicleData = { + VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None, + Some(InventoryData( + InventoryItemData(ObjectClass.apc_weapon_systemc_vs, weapon1_guid, 11, + WeaponData(0x6, 0x8, 0, ObjectClass.flux_cannon_thresher_battery, ammo1_guid, 0, AmmoBoxData(8)) + ) :: + InventoryItemData(ObjectClass.apc_weapon_systemb, weapon2_guid, 12, + WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo2_guid, 0, AmmoBoxData(8)) + ) :: + InventoryItemData(ObjectClass.apc_weapon_systema, weapon3_guid, 13, + WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo3_guid, 0, AmmoBoxData(8)) + ) :: + InventoryItemData(ObjectClass.apc_weapon_systemd_vs, weapon4_guid, 14, + WeaponData(0x6, 0x8, 0, ObjectClass.flux_cannon_thresher_battery, ammo4_guid, 0, AmmoBoxData(8)) + ) :: + InventoryItemData(ObjectClass.apc_ballgun_r, weapon5_guid, 15, + WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo5_guid, 0, AmmoBoxData(8)) + ) :: + InventoryItemData(ObjectClass.apc_ballgun_l, weapon6_guid, 16, + WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo6_guid, 0, AmmoBoxData(8)) + ) :: Nil + )) + )(VehicleFormat.Normal) + } + def aurora(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo11_guid : PlanetSideGUID, ammo12_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo21_guid : PlanetSideGUID, ammo22_guid : PlanetSideGUID) : VehicleData = { VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None, Some(InventoryData( @@ -118,56 +193,6 @@ object Prefab { )(VehicleFormat.Variant) } - def juggernaut(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID, weapon3_guid : PlanetSideGUID, ammo3_guid : PlanetSideGUID, weapon4_guid : PlanetSideGUID, ammo4_guid : PlanetSideGUID, weapon5_guid : PlanetSideGUID, ammo5_guid : PlanetSideGUID, weapon6_guid : PlanetSideGUID, ammo6_guid : PlanetSideGUID) : VehicleData = { - VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None, - Some(InventoryData( - InventoryItemData(ObjectClass.apc_weapon_systemc_tr, weapon1_guid, 11, - WeaponData(0x6, 0x8, 0, ObjectClass.bullet_15mm, ammo1_guid, 0, AmmoBoxData(8)) - ) :: - InventoryItemData(ObjectClass.apc_weapon_systemb, weapon2_guid, 12, - WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo2_guid, 0, AmmoBoxData(8)) - ) :: - InventoryItemData(ObjectClass.apc_weapon_systema, weapon3_guid, 13, - WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo3_guid, 0, AmmoBoxData(8)) - ) :: - InventoryItemData(ObjectClass.apc_weapon_systemd_tr, weapon4_guid, 14, - WeaponData(0x6, 0x8, 0, ObjectClass.bullet_15mm, ammo4_guid, 0, AmmoBoxData(8)) - ) :: - InventoryItemData(ObjectClass.apc_ballgun_r, weapon5_guid, 15, - WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo5_guid, 0, AmmoBoxData(8)) - ) :: - InventoryItemData(ObjectClass.apc_ballgun_l, weapon6_guid, 16, - WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo6_guid, 0, AmmoBoxData(8)) - ) :: Nil - )) - )(VehicleFormat.Normal) - } - - def leviathan(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID, weapon3_guid : PlanetSideGUID, ammo3_guid : PlanetSideGUID, weapon4_guid : PlanetSideGUID, ammo4_guid : PlanetSideGUID, weapon5_guid : PlanetSideGUID, ammo5_guid : PlanetSideGUID, weapon6_guid : PlanetSideGUID, ammo6_guid : PlanetSideGUID) : VehicleData = { - VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None, - Some(InventoryData( - InventoryItemData(ObjectClass.apc_weapon_systemc_vs, weapon1_guid, 11, - WeaponData(0x6, 0x8, 0, ObjectClass.flux_cannon_thresher_battery, ammo1_guid, 0, AmmoBoxData(8)) - ) :: - InventoryItemData(ObjectClass.apc_weapon_systemb, weapon2_guid, 12, - WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo2_guid, 0, AmmoBoxData(8)) - ) :: - InventoryItemData(ObjectClass.apc_weapon_systema, weapon3_guid, 13, - WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo3_guid, 0, AmmoBoxData(8)) - ) :: - InventoryItemData(ObjectClass.apc_weapon_systemd_vs, weapon4_guid, 14, - WeaponData(0x6, 0x8, 0, ObjectClass.flux_cannon_thresher_battery, ammo4_guid, 0, AmmoBoxData(8)) - ) :: - InventoryItemData(ObjectClass.apc_ballgun_r, weapon5_guid, 15, - WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo5_guid, 0, AmmoBoxData(8)) - ) :: - InventoryItemData(ObjectClass.apc_ballgun_l, weapon6_guid, 16, - WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo6_guid, 0, AmmoBoxData(8)) - ) :: Nil - )) - )(VehicleFormat.Normal) - } - def liberator(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID, ammo3_guid : PlanetSideGUID, weapon3_guid : PlanetSideGUID, ammo4_guid : PlanetSideGUID) : VehicleData = { VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, Some(VariantVehicleData(0)), Some(InventoryData( @@ -187,8 +212,8 @@ object Prefab { def lightgunship(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID) : VehicleData = { VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.Mobile, false, false, false, Some(VariantVehicleData(0)), Some(InventoryData( - InventoryItemData(445, weapon_guid, 1, - WeaponData(0x6, 0x8, 0, 16, ammo1_guid, 0, AmmoBoxData(8), 722, ammo2_guid,1, AmmoBoxData(8)) + InventoryItemData(ObjectClass.lightgunship_weapon_system, weapon_guid, 1, + WeaponData(0x6, 0x8, 0, ObjectClass.bullet_20mm, ammo1_guid, 0, AmmoBoxData(8), ObjectClass.reaver_rocket, ammo2_guid,1, AmmoBoxData(8)) ) :: Nil )) )(VehicleFormat.Variant) @@ -270,14 +295,6 @@ object Prefab { )(VehicleFormat.Normal) } - def router(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, terminal_guid : PlanetSideGUID) : VehicleData = { - VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.Mobile, false, false, false, Some(VariantVehicleData(0)), - Some(InventoryData( - InventoryItemData(ObjectClass.teleportpad_terminal, terminal_guid, 1, CommonTerminalData(faction, 2)) :: Nil - )) - )(VehicleFormat.Variant) - } - def quadassault(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon_guid : PlanetSideGUID, ammo_guid : PlanetSideGUID) : VehicleData = { VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, DriveState.State7, true, false, false, None, Some(InventoryData( @@ -292,6 +309,24 @@ object Prefab { VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, DriveState.State7, false, false, false, None, None)(VehicleFormat.Normal) } + def router(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, terminal_guid : PlanetSideGUID) : VehicleData = { + VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.Mobile, false, false, false, Some(VariantVehicleData(0)), + Some(InventoryData( + InventoryItemData(ObjectClass.teleportpad_terminal, terminal_guid, 1, CommonTerminalData(faction, 2)) :: Nil + )) + )(VehicleFormat.Variant) + } + + def skyguard(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID) : VehicleData = { + VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None, + Some(InventoryData( + InventoryItemData(ObjectClass.skyguard_weapon_system, weapon_guid, 2, + WeaponData(0x6, 0x8, 0, ObjectClass.skyguard_flak_cannon_ammo, ammo1_guid, 0, AmmoBoxData(8), ObjectClass.bullet_12mm, ammo2_guid, 1, AmmoBoxData(8)) + ) :: Nil + )) + )(VehicleFormat.Normal) + } + def switchblade(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, driveState : DriveState.Value, weapon_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID) : VehicleData = { VehicleData(CommonFieldData(loc, faction, 0), 0, health, false, false, DriveState.State7, true, false, false, Some(VariantVehicleData(0)), Some(InventoryData( @@ -368,31 +403,6 @@ object Prefab { )(VehicleFormat.Normal) } - def vindicator(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID, weapon3_guid : PlanetSideGUID, ammo3_guid : PlanetSideGUID, weapon4_guid : PlanetSideGUID, ammo4_guid : PlanetSideGUID, weapon5_guid : PlanetSideGUID, ammo5_guid : PlanetSideGUID, weapon6_guid : PlanetSideGUID, ammo6_guid : PlanetSideGUID) : VehicleData = { - VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, None, - Some(InventoryData( - InventoryItemData(ObjectClass.apc_weapon_systemc_nc, weapon1_guid, 11, - WeaponData(0x6, 0x8, 0, ObjectClass.bullet_20mm, ammo1_guid, 0, AmmoBoxData(8)) - ) :: - InventoryItemData(ObjectClass.apc_weapon_systemb, weapon2_guid, 12, - WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo2_guid, 0, AmmoBoxData(8)) - ) :: - InventoryItemData(ObjectClass.apc_weapon_systema, weapon3_guid, 13, - WeaponData(0x6, 0x8, 0, ObjectClass.bullet_75mm, ammo3_guid, 0, AmmoBoxData(8)) - ) :: - InventoryItemData(ObjectClass.apc_weapon_systemd_nc, weapon4_guid, 14, - WeaponData(0x6, 0x8, 0, ObjectClass.bullet_20mm, ammo4_guid, 0, AmmoBoxData(8)) - ) :: - InventoryItemData(ObjectClass.apc_ballgun_r, weapon5_guid, 15, - WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo5_guid, 0, AmmoBoxData(8)) - ) :: - InventoryItemData(ObjectClass.apc_ballgun_l, weapon6_guid, 16, - WeaponData(0x6, 0x8, 0, ObjectClass.bullet_12mm, ammo6_guid, 0, AmmoBoxData(8)) - ) :: Nil - )) - )(VehicleFormat.Normal) - } - def vulture(loc : PlacementData, faction : PlanetSideEmpire.Value, health : Int, weapon1_guid : PlanetSideGUID, ammo1_guid : PlanetSideGUID, weapon2_guid : PlanetSideGUID, ammo2_guid : PlanetSideGUID, weapon3_guid : PlanetSideGUID, ammo3_guid : PlanetSideGUID) : VehicleData = { VehicleData(CommonFieldData(loc, faction, 2), 0, health, false, false, DriveState.State7, true, false, false, Some(VariantVehicleData(0)), Some(InventoryData( diff --git a/common/src/main/scala/net/psforever/types/Vector3.scala b/common/src/main/scala/net/psforever/types/Vector3.scala index ac2b92fea..279b74110 100644 --- a/common/src/main/scala/net/psforever/types/Vector3.scala +++ b/common/src/main/scala/net/psforever/types/Vector3.scala @@ -4,11 +4,41 @@ package net.psforever.types import net.psforever.newcodecs._ import scodec.Codec import scodec.codecs._ -import shapeless.{::, HNil} final case class Vector3(x : Float, y : Float, - z : Float) + z : Float) { + /** + * Operator override for vector addition, treating `Vector3` objects as actual mathematical vectors. + * The application of this overload is "vector1 + vector2." + * @param vec the other `Vector3` object + * @return a new `Vector3` object with the summed values + */ + def +(vec : Vector3) : Vector3 = { + new Vector3(x + vec.x, y + vec.y, z + vec.z) + } + + /** + * Operator override for vector subtraction, treating `Vector3` objects as actual mathematical vectors. + * The application of this overload is "vector1 - vector2." + * @param vec the other `Vector3` object + * @return a new `Vector3` object with the difference values + */ + def -(vec : Vector3) : Vector3 = { + new Vector3(x - vec.x, y - vec.y, z - vec.z) + } + + /** + * Operator override for vector scaling, treating `Vector3` objects as actual mathematical vectors. + * The application of this overload is "vector * scalar" exclusively. + * "scalar * vector" is invalid. + * @param scalar the value to multiply this vector + * @return a new `Vector3` object + */ + def *(scalar : Float) : Vector3 = { + new Vector3(x*scalar, y*scalar, z*scalar) + } +} object Vector3 { implicit val codec_pos : Codec[Vector3] = ( @@ -28,4 +58,48 @@ object Vector3 { ("y" | floatL) :: ("z" | floatL) ).as[Vector3] + + /** + * Calculate the actual distance between two points. + * @param pos1 the first point + * @param pos2 the second point + * @return the distance + */ + def Distance(pos1 : Vector3, pos2 : Vector3) : Float = { + math.sqrt(DistanceSquared(pos1, pos2)).toFloat + } + + /** + * Calculate the squared distance between two points. + * Though some time is saved care must be taken that any comparative distance is also squared. + * @param pos1 the first point + * @param pos2 the second point + * @return the distance + */ + def DistanceSquared(pos1 : Vector3, pos2 : Vector3) : Float = { + val dvec : Vector3 = pos1 - pos2 + (dvec.x * dvec.x) + (dvec.y * dvec.y) + (dvec.z * dvec.z) + } + + /** + * Calculate the actual magnitude of a vector. + * @param vec the vector + * @return the magnitude + */ + def Magnitude(vec : Vector3) : Float = { + math.sqrt(MagnitudeSquared(vec)).toFloat + } + + /** + * Calculate the squared magnitude of a vector. + * Though some time is saved care must be taken that any comparative magnitude is also squared. + * @param vec the vector + * @return the magnitude + */ + def MagnitudeSquared(vec : Vector3) : Float = { + val dx : Float = vec.x + val dy : Float = vec.y + val dz : Float = vec.z + (dx * dx) + (dy * dy) + (dz * dz) + } } diff --git a/common/src/test/scala/Vector3Test.scala b/common/src/test/scala/Vector3Test.scala new file mode 100644 index 000000000..cedc7c066 --- /dev/null +++ b/common/src/test/scala/Vector3Test.scala @@ -0,0 +1,68 @@ +// Copyright (c) 2017 PSForever +import org.specs2.mutable._ +import net.psforever.types.Vector3 + +class Vector3Test extends Specification { + val vec = Vector3(1.3f, -2.6f, 3.9f) + + "Vector3" should { + "construct" in { + vec.x mustEqual 1.3f + vec.y mustEqual -2.6f + vec.z mustEqual 3.9f + } + + "calculate magnitude (like a vector) 1" in { + val obj = Vector3(2.0f, 0.0f, 0.0f) + Vector3.Magnitude(obj) mustEqual 2.0f + } + + "calculate magnitude (like a vector) 2" in { + val obj = Vector3(3.0f, 4.0f, 0.0f) + Vector3.Magnitude(obj) mustEqual 5.0f + } + + "calculate magnitude (like a vector) 3" in { + Vector3.Magnitude(vec) mustEqual 4.864155f + } + + "calculate square magnitude (like a vector)" in { + Vector3.MagnitudeSquared(vec) mustEqual 23.66f + } + + "calculate distance 1" in { + val obj1 = Vector3(0.0f, 0.0f, 0.0f) + val obj2 = Vector3(2.0f, 0.0f, 0.0f) + Vector3.Distance(obj1, obj2) mustEqual 2.0f + } + + "calculate distance 2" in { + val obj1 = Vector3(0.0f, 0.0f, 0.0f) + val obj2 = Vector3(2.0f, 0.0f, 0.0f) + Vector3.Distance(obj1, obj2) mustEqual Vector3.Magnitude(obj2) + } + + "calculate distance 3" in { + val obj1 = Vector3(3.0f, 4.0f, 5.0f) + val obj2 = Vector3(3.0f, 4.0f, 5.0f) + Vector3.Distance(obj1, obj2) mustEqual 0f + } + + "addition" in { + val obj1 = Vector3(3.0f, 4.0f, 5.0f) + val obj2 = Vector3(3.0f, 4.0f, 5.0f) + obj1 + obj2 mustEqual Vector3(6f, 8f, 10f) + } + + "subtraction" in { + val obj1 = Vector3(3.0f, 4.0f, 5.0f) + val obj2 = Vector3(3.0f, 4.0f, 5.0f) + obj1 - obj2 mustEqual Vector3(0f, 0f, 0f) + } + + "scalar" in { + vec * 3f mustEqual Vector3(3.8999999f, -7.7999997f, 11.700001f) + } + } +} + diff --git a/common/src/test/scala/game/GenericObjectActionMessageTest.scala b/common/src/test/scala/game/GenericObjectActionMessageTest.scala new file mode 100644 index 000000000..8ad103886 --- /dev/null +++ b/common/src/test/scala/game/GenericObjectActionMessageTest.scala @@ -0,0 +1,28 @@ +// Copyright (c) 2017 PSForever +package game + +import org.specs2.mutable._ +import net.psforever.packet._ +import net.psforever.packet.game._ +import scodec.bits._ + +class GenericObjectActionMessageTest extends Specification { + val string = hex"56 B501 24" + + "decode" in { + PacketCoding.DecodePacket(string).require match { + case GenericObjectActionMessage(object_guid, action) => + object_guid mustEqual PlanetSideGUID(437) + action mustEqual 36 + case _ => + ko + } + } + + "encode" in { + val msg = GenericObjectActionMessage(PlanetSideGUID(437), 36) + val pkt = PacketCoding.EncodePacket(msg).require.toByteVector + + pkt mustEqual string + } +} diff --git a/common/src/test/scala/objects/ConverterTest.scala b/common/src/test/scala/objects/ConverterTest.scala index 90e92a44e..b4e5ec24a 100644 --- a/common/src/test/scala/objects/ConverterTest.scala +++ b/common/src/test/scala/objects/ConverterTest.scala @@ -40,16 +40,15 @@ class ConverterTest extends Specification { "convert to packet" in { val tdef = ToolDefinition(1076) tdef.Size = EquipmentSize.Rifle - tdef.AmmoTypes += Ammo.shotgun_shell - tdef.AmmoTypes += Ammo.shotgun_shell_AP + tdef.AmmoTypes += GlobalDefinitions.shotgun_shell + tdef.AmmoTypes += GlobalDefinitions.shotgun_shell_AP tdef.FireModes += new FireModeDefinition tdef.FireModes.head.AmmoTypeIndices += 0 tdef.FireModes.head.AmmoTypeIndices += 1 tdef.FireModes.head.AmmoSlotIndex = 0 + tdef.FireModes.head.Magazine = 30 val obj : Tool = Tool(tdef) - val box = AmmoBox(PlanetSideGUID(90), new AmmoBoxDefinition(Ammo.shotgun_shell.id)) - obj.AmmoSlots.head.Box = box - obj.AmmoSlots.head.Magazine = 30 + obj.AmmoSlot.Box.GUID = PlanetSideGUID(90) obj.Definition.Packet.DetailedConstructorData(obj) match { case Success(pkt) => @@ -139,24 +138,22 @@ class ConverterTest extends Specification { Give the Player's Holster (2) the Tool Place the remaining AmmoBox into the Player's inventory in the third slot (8) */ - val bullet_9mm = AmmoBoxDefinition(28) - bullet_9mm.Capacity = 50 - val box1 = AmmoBox(PlanetSideGUID(90), bullet_9mm) - val box2 = AmmoBox(PlanetSideGUID(91), bullet_9mm) val tdef = ToolDefinition(1076) tdef.Name = "sample_weapon" tdef.Size = EquipmentSize.Rifle - tdef.AmmoTypes += Ammo.bullet_9mm + tdef.AmmoTypes += GlobalDefinitions.bullet_9mm tdef.FireModes += new FireModeDefinition tdef.FireModes.head.AmmoTypeIndices += 0 tdef.FireModes.head.AmmoSlotIndex = 0 tdef.FireModes.head.Magazine = 18 - val tool = Tool(PlanetSideGUID(92), tdef) - tool.AmmoSlots.head.Box = box1 + val tool = Tool(tdef) + tool.GUID = PlanetSideGUID(92) + tool.AmmoSlot.Box.GUID = PlanetSideGUID(90) val obj = Player(PlanetSideGUID(93), "Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5) obj.Slot(2).Equipment = tool obj.Slot(5).Equipment.get.GUID = PlanetSideGUID(94) - obj.Inventory += 8 -> box2 + obj.Inventory += 8 -> AmmoBox(GlobalDefinitions.bullet_9mm) + obj.Slot(8).Equipment.get.GUID = PlanetSideGUID(91) obj } val converter = new CharacterSelectConverter @@ -263,7 +260,7 @@ class ConverterTest extends Specification { val fury_weapon_systema_def = ToolDefinition(ObjectClass.fury_weapon_systema) fury_weapon_systema_def.Size = EquipmentSize.VehicleWeapon - fury_weapon_systema_def.AmmoTypes += Ammo.hellfire_ammo + fury_weapon_systema_def.AmmoTypes += GlobalDefinitions.hellfire_ammo fury_weapon_systema_def.FireModes += new FireModeDefinition fury_weapon_systema_def.FireModes.head.AmmoTypeIndices += 0 fury_weapon_systema_def.FireModes.head.AmmoSlotIndex = 0 diff --git a/common/src/test/scala/objects/EquipmentTest.scala b/common/src/test/scala/objects/EquipmentTest.scala index 284d0b2b7..02847c63c 100644 --- a/common/src/test/scala/objects/EquipmentTest.scala +++ b/common/src/test/scala/objects/EquipmentTest.scala @@ -10,7 +10,6 @@ import net.psforever.objects.GlobalDefinitions._ import org.specs2.mutable._ class EquipmentTest extends Specification { - "AmmoBox" should { "define" in { val obj = AmmoBoxDefinition(86) @@ -19,8 +18,8 @@ class EquipmentTest extends Specification { obj.AmmoType mustEqual Ammo.aphelion_immolation_cannon_ammo obj.Capacity mustEqual 300 - obj.Tile.width mustEqual InventoryTile.Tile44.width - obj.Tile.height mustEqual InventoryTile.Tile44.height + obj.Tile.Width mustEqual InventoryTile.Tile44.Width + obj.Tile.Height mustEqual InventoryTile.Tile44.Height obj.ObjectId mustEqual 86 } @@ -58,8 +57,8 @@ class EquipmentTest extends Specification { val obj = ToolDefinition(1076) obj.Name = "sample_weapon" obj.Size = EquipmentSize.Rifle - obj.AmmoTypes += Ammo.shotgun_shell - obj.AmmoTypes += Ammo.shotgun_shell_AP + obj.AmmoTypes += GlobalDefinitions.shotgun_shell + obj.AmmoTypes += GlobalDefinitions.shotgun_shell_AP obj.FireModes += new FireModeDefinition obj.FireModes.head.AmmoTypeIndices += 0 obj.FireModes.head.AmmoTypeIndices += 1 @@ -74,9 +73,10 @@ class EquipmentTest extends Specification { obj.FireModes(1).Magazine = 18 obj.Tile = InventoryTile.Tile93 obj.ObjectId mustEqual 1076 + obj.Name mustEqual "sample_weapon" - obj.AmmoTypes.head mustEqual Ammo.shotgun_shell - obj.AmmoTypes(1) mustEqual Ammo.shotgun_shell_AP + obj.AmmoTypes.head mustEqual GlobalDefinitions.shotgun_shell + obj.AmmoTypes(1) mustEqual GlobalDefinitions.shotgun_shell_AP obj.FireModes.head.AmmoTypeIndices.head mustEqual 0 obj.FireModes.head.AmmoTypeIndices(1) mustEqual 1 obj.FireModes.head.AmmoSlotIndex mustEqual 0 @@ -89,8 +89,8 @@ class EquipmentTest extends Specification { obj.FireModes(1).Chamber mustEqual 3 obj.FireModes(1).Magazine mustEqual 18 obj.FireModes(1).ResetAmmoIndexOnSwap mustEqual false - obj.Tile.width mustEqual InventoryTile.Tile93.width - obj.Tile.height mustEqual InventoryTile.Tile93.height + obj.Tile.Width mustEqual InventoryTile.Tile93.Width + obj.Tile.Height mustEqual InventoryTile.Tile93.Height } "construct" in { @@ -118,8 +118,8 @@ class EquipmentTest extends Specification { //explanation: sample_weapon has two fire modes; adjusting the FireMode changes between them val tdef = ToolDefinition(1076) tdef.Size = EquipmentSize.Rifle - tdef.AmmoTypes += Ammo.shotgun_shell - tdef.AmmoTypes += Ammo.shotgun_shell_AP + tdef.AmmoTypes += GlobalDefinitions.shotgun_shell + tdef.AmmoTypes += GlobalDefinitions.shotgun_shell_AP tdef.FireModes += new FireModeDefinition tdef.FireModes.head.AmmoTypeIndices += 0 tdef.FireModes.head.AmmoSlotIndex = 0 @@ -149,8 +149,8 @@ class EquipmentTest extends Specification { //explanation: obj has one fire mode and two ammunitions; adjusting the AmmoType changes between them val tdef = ToolDefinition(1076) tdef.Size = EquipmentSize.Rifle - tdef.AmmoTypes += Ammo.shotgun_shell - tdef.AmmoTypes += Ammo.shotgun_shell_AP + tdef.AmmoTypes += GlobalDefinitions.shotgun_shell + tdef.AmmoTypes += GlobalDefinitions.shotgun_shell_AP tdef.FireModes += new FireModeDefinition tdef.FireModes.head.AmmoTypeIndices += 0 tdef.FireModes.head.AmmoTypeIndices += 1 @@ -168,14 +168,54 @@ class EquipmentTest extends Specification { obj.AmmoTypeIndex mustEqual 0 obj.AmmoType mustEqual Ammo.shotgun_shell } + + "multiple ammo types and multiple fire modes, split (Punisher)" in { + val obj = Tool(GlobalDefinitions.punisher) + //ammo = 0, fmode = 0 + obj.FireModeIndex mustEqual 0 + obj.AmmoTypeIndex mustEqual 0 + obj.AmmoType mustEqual Ammo.bullet_9mm + //ammo = 2, fmode = 1 + obj.NextFireMode + obj.FireModeIndex mustEqual 1 + obj.AmmoTypeIndex mustEqual 2 + obj.AmmoType mustEqual Ammo.rocket + //ammo = 3, fmode = 1 + obj.NextAmmoType + obj.AmmoTypeIndex mustEqual 3 + obj.AmmoType mustEqual Ammo.frag_cartridge + //ammo = 4, fmode = 1 + obj.NextAmmoType + obj.AmmoTypeIndex mustEqual 4 + obj.AmmoType mustEqual Ammo.jammer_cartridge + //ammo = 0, fmode = 0 + obj.NextFireMode + obj.FireModeIndex mustEqual 0 + obj.AmmoTypeIndex mustEqual 0 + obj.AmmoType mustEqual Ammo.bullet_9mm + //ammo = 1, fmode = 0 + obj.NextAmmoType + obj.AmmoTypeIndex mustEqual 1 + obj.AmmoType mustEqual Ammo.bullet_9mm_AP + //ammo = 5, fmode = 1 + obj.NextFireMode + obj.NextAmmoType + obj.FireModeIndex mustEqual 1 + obj.AmmoTypeIndex mustEqual 5 + obj.AmmoType mustEqual Ammo.plasma_cartridge + //ammo = 2, fmode = 1 + obj.NextAmmoType + obj.AmmoTypeIndex mustEqual 2 + obj.AmmoType mustEqual Ammo.rocket + } } "Kit" should { "define" in { val sample = KitDefinition(Kits.medkit) sample.ObjectId mustEqual medkit.ObjectId - sample.Tile.width mustEqual medkit.Tile.width - sample.Tile.height mustEqual medkit.Tile.height + sample.Tile.Width mustEqual medkit.Tile.Width + sample.Tile.Height mustEqual medkit.Tile.Height } "construct" in { @@ -200,8 +240,8 @@ class EquipmentTest extends Specification { sample.Modes.head mustEqual DeployedItem.tank_traps sample.Modes(1) mustEqual DeployedItem.portable_manned_turret_tr sample.Modes(2) mustEqual DeployedItem.deployable_shield_generator - sample.Tile.width mustEqual InventoryTile.Tile63.width - sample.Tile.height mustEqual InventoryTile.Tile63.height + sample.Tile.Width mustEqual InventoryTile.Tile63.Width + sample.Tile.Height mustEqual InventoryTile.Tile63.Height } "construct" in { diff --git a/common/src/test/scala/objects/InventoryTest.scala b/common/src/test/scala/objects/InventoryTest.scala index 3af8a011d..34ec74914 100644 --- a/common/src/test/scala/objects/InventoryTest.scala +++ b/common/src/test/scala/objects/InventoryTest.scala @@ -57,8 +57,8 @@ class InventoryTest extends Specification { val obj : GridInventory = GridInventory(9, 6) obj += 0 -> bullet9mmBox1 obj.Capacity mustEqual 45 - val w = bullet9mmBox2.Tile.width - val h = bullet9mmBox2.Tile.height + val w = bullet9mmBox2.Tile.Width + val h = bullet9mmBox2.Tile.Height val list0 = obj.CheckCollisionsAsList(0, w, h) list0 match { case scala.util.Success(list) => list.length mustEqual 1 @@ -91,8 +91,8 @@ class InventoryTest extends Specification { val obj : GridInventory = GridInventory(9, 6) obj += 3 -> bullet9mmBox1 obj.Capacity mustEqual 45 - val w = bullet9mmBox2.Tile.width - val h = bullet9mmBox2.Tile.height + val w = bullet9mmBox2.Tile.Width + val h = bullet9mmBox2.Tile.Height val list0 = obj.CheckCollisionsAsList(3, w, h) list0 match { case scala.util.Success(list) => list.length mustEqual 1 @@ -125,8 +125,8 @@ class InventoryTest extends Specification { val obj : GridInventory = GridInventory(9, 6) obj += 0 -> bullet9mmBox1 obj.Capacity mustEqual 45 - val w = bullet9mmBox2.Tile.width - val h = bullet9mmBox2.Tile.height + val w = bullet9mmBox2.Tile.Width + val h = bullet9mmBox2.Tile.Height val list0 = obj.CheckCollisionsAsList(0, w, h) list0 match { case scala.util.Success(list) => list.length mustEqual 1 @@ -159,8 +159,8 @@ class InventoryTest extends Specification { val obj : GridInventory = GridInventory(9, 6) obj += 27 -> bullet9mmBox1 obj.Capacity mustEqual 45 - val w = bullet9mmBox2.Tile.width - val h = bullet9mmBox2.Tile.height + val w = bullet9mmBox2.Tile.Width + val h = bullet9mmBox2.Tile.Height val list0 = obj.CheckCollisionsAsList(27, w, h) list0 match { case scala.util.Success(list) => list.length mustEqual 1 @@ -205,8 +205,8 @@ class InventoryTest extends Specification { val obj : GridInventory = GridInventory(12, 9) obj += 39 -> bullet9mmBox1 obj.Capacity mustEqual 99 //108 - 9 - val w = bullet9mmBox2.Tile.width - val h = bullet9mmBox2.Tile.height + val w = bullet9mmBox2.Tile.Width + val h = bullet9mmBox2.Tile.Height val list0 = obj.CheckCollisionsAsList(0, w, h) list0 match { case scala.util.Success(list) => list.isEmpty mustEqual true diff --git a/common/src/test/scala/objects/VehicleSpawnPadTest.scala b/common/src/test/scala/objects/VehicleSpawnPadTest.scala new file mode 100644 index 000000000..5005661f5 --- /dev/null +++ b/common/src/test/scala/objects/VehicleSpawnPadTest.scala @@ -0,0 +1,110 @@ +// Copyright (c) 2017 PSForever +package objects + +import akka.actor.{ActorRef, Props} +import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad} +import net.psforever.objects.vehicles.VehicleControl +import net.psforever.objects.{GlobalDefinitions, Player, Vehicle} +import net.psforever.packet.game.PlanetSideGUID +import net.psforever.types.{CharacterGender, PlanetSideEmpire, Vector3} +import org.specs2.mutable.Specification + +import scala.concurrent.duration.Duration + +class VehicleSpawnPadTest extends Specification { + "VehicleSpawnPadDefinition" should { + "define" in { + GlobalDefinitions.spawn_pad.ObjectId mustEqual 800 + } + } + + "VehicleSpawnPad" should { + "construct" in { + val obj = VehicleSpawnPad(GlobalDefinitions.spawn_pad) + obj.Actor mustEqual ActorRef.noSender + obj.Definition mustEqual GlobalDefinitions.spawn_pad + } + } +} + +class VehicleSpawnControl1Test extends ActorTest() { + "VehicleSpawnControl" should { + "construct" in { + val obj = VehicleSpawnPad(GlobalDefinitions.spawn_pad) + obj.Actor = system.actorOf(Props(classOf[VehicleSpawnControl], obj), "door") + assert(obj.Actor != ActorRef.noSender) + } + } +} + +class VehicleSpawnControl2Test extends ActorTest() { + "VehicleSpawnControl" should { + "spawn a vehicle" in { + val obj = VehicleSpawnPad(GlobalDefinitions.spawn_pad) + obj.Actor = system.actorOf(Props(classOf[VehicleSpawnControl], obj), "door") + val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0) + player.Spawn + val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy) + vehicle.GUID = PlanetSideGUID(1) + vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle") + + obj.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle) + val reply = receiveOne(Duration.create(10000, "ms")) + assert(reply == VehicleSpawnPad.ConcealPlayer) //explicit: isInstanceOf does not work + + val reply2 = receiveOne(Duration.create(10000, "ms")) + assert(reply2.isInstanceOf[VehicleSpawnPad.LoadVehicle]) + assert(reply2.asInstanceOf[VehicleSpawnPad.LoadVehicle].vehicle == vehicle) + assert(reply2.asInstanceOf[VehicleSpawnPad.LoadVehicle].pad == obj) + + player.VehicleOwned = vehicle + val reply3 = receiveOne(Duration.create(10000, "ms")) + assert(reply3.isInstanceOf[VehicleSpawnPad.PlayerSeatedInVehicle]) + assert(reply3.asInstanceOf[VehicleSpawnPad.PlayerSeatedInVehicle].vehicle == vehicle) + + val reply4 = receiveOne(Duration.create(10000, "ms")) + assert(reply4.isInstanceOf[VehicleSpawnPad.SpawnPadBlockedWarning]) + assert(reply4.asInstanceOf[VehicleSpawnPad.SpawnPadBlockedWarning].vehicle == vehicle) + assert(reply4.asInstanceOf[VehicleSpawnPad.SpawnPadBlockedWarning].warning_count > 0) + + vehicle.Position = Vector3(11f, 0f, 0f) //greater than 10m + val reply5 = receiveOne(Duration.create(10000, "ms")) + assert(reply5.isInstanceOf[VehicleSpawnPad.SpawnPadUnblocked]) + assert(reply5.asInstanceOf[VehicleSpawnPad.SpawnPadUnblocked].vehicle_guid == vehicle.GUID) + } + } +} + +class VehicleSpawnControl3Test extends ActorTest() { + "VehicleSpawnControl" should { + "not spawn a vehicle if player is dead" in { + val obj = VehicleSpawnPad(GlobalDefinitions.spawn_pad) + obj.Actor = system.actorOf(Props(classOf[VehicleSpawnControl], obj), "door") + val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0) + val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy) + vehicle.GUID = PlanetSideGUID(1) + vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle") + + obj.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle) + val reply = receiveOne(Duration.create(5000, "ms")) + assert(reply == null) + } + } +} + +class VehicleSpawnControl4Test extends ActorTest() { + "VehicleSpawnControl" should { + "not spawn a vehicle if vehicle Actor is missing" in { + val obj = VehicleSpawnPad(GlobalDefinitions.spawn_pad) + obj.Actor = system.actorOf(Props(classOf[VehicleSpawnControl], obj), "door") + val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0) + player.Spawn + val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy) + vehicle.GUID = PlanetSideGUID(1) + + obj.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle) + val reply = receiveOne(Duration.create(5000, "ms")) + assert(reply == null) + } + } +} diff --git a/common/src/test/scala/objects/VehicleTest.scala b/common/src/test/scala/objects/VehicleTest.scala index d898a66e5..a61ad4312 100644 --- a/common/src/test/scala/objects/VehicleTest.scala +++ b/common/src/test/scala/objects/VehicleTest.scala @@ -44,8 +44,8 @@ class VehicleTest extends Specification { fury.Weapons.size mustEqual 1 fury.Weapons.get(0) mustEqual None fury.Weapons.get(1) mustEqual Some(GlobalDefinitions.fury_weapon_systema) - fury.TrunkSize.width mustEqual 11 - fury.TrunkSize.height mustEqual 11 + fury.TrunkSize.Width mustEqual 11 + fury.TrunkSize.Height mustEqual 11 fury.TrunkOffset mustEqual 30 } } diff --git a/common/src/test/scala/objects/terminal/AirVehicleTerminalTest.scala b/common/src/test/scala/objects/terminal/AirVehicleTerminalTest.scala new file mode 100644 index 000000000..ab1bcca82 --- /dev/null +++ b/common/src/test/scala/objects/terminal/AirVehicleTerminalTest.scala @@ -0,0 +1,37 @@ +// Copyright (c) 2017 PSForever +package objects.terminal + +import akka.actor.ActorRef +import net.psforever.objects.{GlobalDefinitions, Player, Tool} +import net.psforever.objects.serverobject.terminals.Terminal +import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID} +import net.psforever.types.{CharacterGender, PlanetSideEmpire, TransactionType} +import org.specs2.mutable.Specification + +class AirVehicleTerminalTest extends Specification { + "Air_Vehicle_Terminal" should { + val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0) + + "construct" in { + val terminal = Terminal(GlobalDefinitions.air_vehicle_terminal) + terminal.Actor mustEqual ActorRef.noSender + } + + "player can buy a reaver ('lightgunship')" in { + val terminal = Terminal(GlobalDefinitions.air_vehicle_terminal) + val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "lightgunship", 0, PlanetSideGUID(0)) + val reply = terminal.Request(player, msg) + reply.isInstanceOf[Terminal.BuyVehicle] mustEqual true + val reply2 = reply.asInstanceOf[Terminal.BuyVehicle] + reply2.vehicle.Definition mustEqual GlobalDefinitions.lightgunship + reply2.loadout mustEqual Nil //TODO + } + + "player can not buy a fake vehicle ('reaver')" in { + val terminal = Terminal(GlobalDefinitions.ground_vehicle_terminal) + val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "reaver", 0, PlanetSideGUID(0)) + + terminal.Request(player, msg) mustEqual Terminal.NoDeal() + } + } +} diff --git a/common/src/test/scala/objects/terminal/DropshipVehicleTerminalTest.scala b/common/src/test/scala/objects/terminal/DropshipVehicleTerminalTest.scala new file mode 100644 index 000000000..3446ec951 --- /dev/null +++ b/common/src/test/scala/objects/terminal/DropshipVehicleTerminalTest.scala @@ -0,0 +1,37 @@ +// Copyright (c) 2017 PSForever +package objects.terminal + +import akka.actor.ActorRef +import net.psforever.objects.{GlobalDefinitions, Player} +import net.psforever.objects.serverobject.terminals.Terminal +import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID} +import net.psforever.types.{CharacterGender, PlanetSideEmpire, TransactionType} +import org.specs2.mutable.Specification + +class DropshipVehicleTerminalTest extends Specification { + "Dropship_Vehicle_Terminal" should { + val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0) + + "construct" in { + val terminal = Terminal(GlobalDefinitions.dropship_vehicle_terminal) + terminal.Actor mustEqual ActorRef.noSender + } + + "player can buy a galaxy ('dropship')" in { + val terminal = Terminal(GlobalDefinitions.dropship_vehicle_terminal) + val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "dropship", 0, PlanetSideGUID(0)) + val reply = terminal.Request(player, msg) + reply.isInstanceOf[Terminal.BuyVehicle] mustEqual true + val reply2 = reply.asInstanceOf[Terminal.BuyVehicle] + reply2.vehicle.Definition mustEqual GlobalDefinitions.dropship + reply2.loadout mustEqual Nil //TODO + } + + "player can not buy a fake vehicle ('galaxy')" in { + val terminal = Terminal(GlobalDefinitions.dropship_vehicle_terminal) + val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "galaxy", 0, PlanetSideGUID(0)) + + terminal.Request(player, msg) mustEqual Terminal.NoDeal() + } + } +} diff --git a/common/src/test/scala/objects/terminal/GroundVehicleTerminalTest.scala b/common/src/test/scala/objects/terminal/GroundVehicleTerminalTest.scala new file mode 100644 index 000000000..0a56463b9 --- /dev/null +++ b/common/src/test/scala/objects/terminal/GroundVehicleTerminalTest.scala @@ -0,0 +1,37 @@ +// Copyright (c) 2017 PSForever +package objects.terminal + +import akka.actor.ActorRef +import net.psforever.objects.{GlobalDefinitions, Player} +import net.psforever.objects.serverobject.terminals.Terminal +import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID} +import net.psforever.types.{CharacterGender, PlanetSideEmpire, TransactionType} +import org.specs2.mutable.Specification + +class GroundVehicleTerminalTest extends Specification { + "Ground_Vehicle_Terminal" should { + val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0) + + "construct" in { + val terminal = Terminal(GlobalDefinitions.ground_vehicle_terminal) + terminal.Actor mustEqual ActorRef.noSender + } + + "player can buy a harasser ('two_man_assault_buggy')" in { + val terminal = Terminal(GlobalDefinitions.ground_vehicle_terminal) + val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "two_man_assault_buggy", 0, PlanetSideGUID(0)) + val reply = terminal.Request(player, msg) + reply.isInstanceOf[Terminal.BuyVehicle] mustEqual true + val reply2 = reply.asInstanceOf[Terminal.BuyVehicle] + reply2.vehicle.Definition mustEqual GlobalDefinitions.two_man_assault_buggy + reply2.loadout mustEqual Nil //TODO + } + + "player can not buy a fake vehicle ('harasser')" in { + val terminal = Terminal(GlobalDefinitions.ground_vehicle_terminal) + val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "harasser", 0, PlanetSideGUID(0)) + + terminal.Request(player, msg) mustEqual Terminal.NoDeal() + } + } +} diff --git a/common/src/test/scala/objects/terminal/TerminalControlTest.scala b/common/src/test/scala/objects/terminal/TerminalControlTest.scala index c5d8b0624..4d587292e 100644 --- a/common/src/test/scala/objects/terminal/TerminalControlTest.scala +++ b/common/src/test/scala/objects/terminal/TerminalControlTest.scala @@ -71,3 +71,40 @@ class CertTerminalControl3Test extends ActorTest() { assert(reply2.response == Terminal.SellCertification(CertificationType.MediumAssault, 2)) } } + +class VehicleTerminalControl1Test extends ActorTest() { + "TerminalControl can be used to buy a vehicle ('two_man_assault_buggy')" in { + val terminal = Terminal(GlobalDefinitions.ground_vehicle_terminal) + terminal.Actor = system.actorOf(Props(classOf[TerminalControl], terminal), "test-cert-term") + val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0) + val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "two_man_assault_buggy", 0, PlanetSideGUID(0)) + + terminal.Actor ! Terminal.Request(player, msg) + val reply = receiveOne(Duration.create(500, "ms")) + assert(reply.isInstanceOf[Terminal.TerminalMessage]) + val reply2 = reply.asInstanceOf[Terminal.TerminalMessage] + assert(reply2.player == player) + assert(reply2.msg == msg) + assert(reply2.response.isInstanceOf[Terminal.BuyVehicle]) + val reply3 = reply2.response.asInstanceOf[Terminal.BuyVehicle] + assert(reply3.vehicle.Definition == GlobalDefinitions.two_man_assault_buggy) + assert(reply3.loadout == Nil) //TODO + } +} + +class VehicleTerminalControl2Test extends ActorTest() { + "TerminalControl can be used to warn about not buy a vehicle ('harasser')" in { + val terminal = Terminal(GlobalDefinitions.ground_vehicle_terminal) + terminal.Actor = system.actorOf(Props(classOf[TerminalControl], terminal), "test-cert-term") + val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0) + val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "harasser", 0, PlanetSideGUID(0)) + + terminal.Actor ! Terminal.Request(player, msg) + val reply = receiveOne(Duration.create(500, "ms")) + assert(reply.isInstanceOf[Terminal.TerminalMessage]) + val reply2 = reply.asInstanceOf[Terminal.TerminalMessage] + assert(reply2.player == player) + assert(reply2.msg == msg) + assert(reply2.response == Terminal.NoDeal()) + } +} diff --git a/common/src/test/scala/objects/terminal/VehicleTerminalCombinedTest.scala b/common/src/test/scala/objects/terminal/VehicleTerminalCombinedTest.scala new file mode 100644 index 000000000..722ec6adf --- /dev/null +++ b/common/src/test/scala/objects/terminal/VehicleTerminalCombinedTest.scala @@ -0,0 +1,47 @@ +// Copyright (c) 2017 PSForever +package objects.terminal + +import akka.actor.ActorRef +import net.psforever.objects.{GlobalDefinitions, Player} +import net.psforever.objects.serverobject.terminals.Terminal +import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID} +import net.psforever.types.{CharacterGender, PlanetSideEmpire, TransactionType} +import org.specs2.mutable.Specification + +class VehicleTerminalCombinedTest extends Specification { + "Ground_Vehicle_Terminal" should { + val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0) + + "construct" in { + val terminal = Terminal(GlobalDefinitions.vehicle_terminal_combined) + terminal.Actor mustEqual ActorRef.noSender + } + + "player can buy a ground vehicle, the harasser ('two_man_assault_buggy')" in { + val terminal = Terminal(GlobalDefinitions.vehicle_terminal_combined) + val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "two_man_assault_buggy", 0, PlanetSideGUID(0)) + val reply = terminal.Request(player, msg) + reply.isInstanceOf[Terminal.BuyVehicle] mustEqual true + val reply2 = reply.asInstanceOf[Terminal.BuyVehicle] + reply2.vehicle.Definition mustEqual GlobalDefinitions.two_man_assault_buggy + reply2.loadout mustEqual Nil //TODO + } + + "player can buy a flying vehicle, the reaver ('lightgunship')" in { + val terminal = Terminal(GlobalDefinitions.vehicle_terminal_combined) + val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "lightgunship", 0, PlanetSideGUID(0)) + val reply = terminal.Request(player, msg) + reply.isInstanceOf[Terminal.BuyVehicle] mustEqual true + val reply2 = reply.asInstanceOf[Terminal.BuyVehicle] + reply2.vehicle.Definition mustEqual GlobalDefinitions.lightgunship + reply2.loadout mustEqual Nil //TODO + } + + "player can not buy a fake vehicle ('harasser')" in { + val terminal = Terminal(GlobalDefinitions.vehicle_terminal_combined) + val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "harasser", 0, PlanetSideGUID(0)) + + terminal.Request(player, msg) mustEqual Terminal.NoDeal() + } + } +} diff --git a/pslogin/src/main/scala/PsLogin.scala b/pslogin/src/main/scala/PsLogin.scala index 870f402ee..e63ef0a16 100644 --- a/pslogin/src/main/scala/PsLogin.scala +++ b/pslogin/src/main/scala/PsLogin.scala @@ -14,7 +14,8 @@ import com.typesafe.config.ConfigFactory import net.psforever.crypto.CryptoInterface import net.psforever.objects.zones._ import net.psforever.objects.guid.TaskResolver -import net.psforever.objects.serverobject.builders.{DoorObjectBuilder, IFFLockObjectBuilder, TerminalObjectBuilder} +import net.psforever.objects.serverobject.builders.{DoorObjectBuilder, IFFLockObjectBuilder, TerminalObjectBuilder, VehicleSpawnPadObjectBuilder} +import net.psforever.types.Vector3 import org.slf4j import org.fusesource.jansi.Ansi._ import org.fusesource.jansi.Ansi.Color._ @@ -244,6 +245,10 @@ object PsLogin { LocalObject(TerminalObjectBuilder(order_terminal, 853)) LocalObject(TerminalObjectBuilder(order_terminal, 855)) LocalObject(TerminalObjectBuilder(order_terminal, 860)) + LocalObject(TerminalObjectBuilder(ground_vehicle_terminal, 1063)) + LocalObject(VehicleSpawnPadObjectBuilder(spawn_pad, 500)) //TODO guid not correct + LocalObject(TerminalObjectBuilder(dropship_vehicle_terminal, 304)) + LocalObject(VehicleSpawnPadObjectBuilder(spawn_pad, 501)) //TODO guid not correct LocalBases = 30 @@ -251,8 +256,14 @@ object PsLogin { ObjectToBase(332, 29) ObjectToBase(556, 29) ObjectToBase(558, 29) + ObjectToBase(1063, 29) //TODO unowned courtyard terminal? + ObjectToBase(500, 29) //TODO unowned courtyard spawnpad? + ObjectToBase(304, 29) //TODO unowned courtyard terminal? + ObjectToBase(501, 29) //TODO unowned courtyard spawnpad? DoorToLock(330, 558) DoorToLock(332, 556) + TerminalToSpawnPad(1063, 500) + TerminalToSpawnPad(304, 501) } val home3 = new Zone("home3", map13, 13) { override def Init(implicit context : ActorContext) : Unit = { @@ -261,6 +272,19 @@ object PsLogin { import net.psforever.types.PlanetSideEmpire Base(2).get.Faction = PlanetSideEmpire.VS //HART building C Base(29).get.Faction = PlanetSideEmpire.NC //South Villa Gun Tower + + GUID(500) match { + case Some(pad) => + pad.Position = Vector3(3506.0f, 2820.0f, 92.0f) + pad.Orientation = Vector3(0f, 0f, 270.0f) + case None => ; + } + GUID(501) match { + case Some(pad) => + pad.Position = Vector3(3508.9844f, 2895.961f, 92.296875f) + pad.Orientation = Vector3(0f, 0f, 270.0f) + case None => ; + } } } diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index 9c40a2800..2808cc1cd 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -17,8 +17,9 @@ import net.psforever.objects.inventory.{GridInventory, InventoryItem} import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject} import net.psforever.objects.serverobject.doors.Door import net.psforever.objects.serverobject.locks.IFFLock +import net.psforever.objects.serverobject.pad.VehicleSpawnPad import net.psforever.objects.serverobject.terminals.Terminal -import net.psforever.objects.vehicles.{AccessPermissionGroup, Seat, VehicleLockState} +import net.psforever.objects.vehicles.{AccessPermissionGroup, VehicleLockState} import net.psforever.objects.zones.{InterstellarCluster, Zone} import net.psforever.packet.game.objectcreate._ import net.psforever.types._ @@ -45,25 +46,43 @@ class WorldSessionActor extends Actor with MDCContextAware { var continent : Zone = null var progressBarValue : Option[Float] = None - var clientKeepAlive : Cancellable = WorldSessionActor.DefaultCancellable - var progressBarUpdate : Cancellable = WorldSessionActor.DefaultCancellable + var clientKeepAlive : Cancellable = DefaultCancellable.obj + var progressBarUpdate : Cancellable = DefaultCancellable.obj override def postStop() = { if(clientKeepAlive != null) clientKeepAlive.cancel() + localService ! Service.Leave() + vehicleService ! Service.Leave() + avatarService ! Service.Leave() + LivePlayerList.Remove(sessionId) match { + case Some(tplayer) => + tplayer.VehicleSeated match { + case Some(vehicle_guid) => + vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.KickPassenger(tplayer.GUID, 0, true)) + case None => ; + } + tplayer.VehicleOwned match { + case Some(vehicle_guid) => + continent.GUID(vehicle_guid) match { + case Some(vehicle : Vehicle) => + vehicle.Owner = None + //TODO temporary solution; to un-own, permit driver seat to Empire access level + vehicle.PermissionGroup(10, VehicleLockState.Empire.id) + vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.SeatPermissions(tplayer.GUID, vehicle_guid, 10, VehicleLockState.Empire.id)) + case _ => ; + } + case None => ; + } - avatarService ! Service.Leave() - localService ! Service.Leave() - vehicleService ! Service.Leave() - LivePlayerList.Remove(sessionId) match { - case Some(tplayer) => - if(tplayer.HasGUID) { - val guid = tplayer.GUID - avatarService ! AvatarServiceMessage(tplayer.Continent, AvatarAction.ObjectDelete(guid, guid)) - taskResolver ! GUIDTask.UnregisterAvatar(tplayer)(continent.GUID) - //TODO normally, the actual player avatar persists a minute or so after the user disconnects - } - case None => ; + if(tplayer.HasGUID) { + val guid = tplayer.GUID + avatarService ! AvatarServiceMessage(tplayer.Continent, AvatarAction.ObjectDelete(guid, guid)) + taskResolver ! GUIDTask.UnregisterAvatar(tplayer)(continent.GUID) + //TODO normally, the actual player avatar persists a minute or so after the user disconnects + } + + case None => ; } } @@ -124,6 +143,11 @@ class WorldSessionActor extends Actor with MDCContextAware { sendResponse(PacketCoding.CreateGamePacket(0, ArmorChangedMessage(guid, suit, subtype))) } + case AvatarResponse.ConcealPlayer() => + if(player.GUID != guid) { + sendResponse(PacketCoding.CreateGamePacket(0, GenericObjectActionMessage(guid, 36))) + } + case AvatarResponse.EquipmentInHand(slot, item) => if(player.GUID != guid) { val definition = item.Definition @@ -186,7 +210,7 @@ class WorldSessionActor extends Actor with MDCContextAware { } else { val before = player.lastSeenStreamMessage(guid.guid) - val dist = WorldSessionActor.DistanceSquared(player.Position, msg.pos) + val dist = Vector3.DistanceSquared(player.Position, msg.pos) (msg.pos, now - before, dist) } @@ -280,9 +304,6 @@ class WorldSessionActor extends Actor with MDCContextAware { case VehicleResponse.MountVehicle(vehicle_guid, seat) => if(player.GUID != guid) { sendResponse(PacketCoding.CreateGamePacket(0, ObjectAttachMessage(vehicle_guid, guid, seat))) - if(player.VehicleOwned.contains(vehicle_guid)) { //simplistic vehicle ownership management - player.VehicleOwned = None - } } case VehicleResponse.SeatPermissions(vehicle_guid, seat_group, permission) => @@ -524,6 +545,19 @@ class WorldSessionActor extends Actor with MDCContextAware { sendResponse(PacketCoding.CreateGamePacket(0, ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Learn, false))) } + case Terminal.BuyVehicle(vehicle, loadout) => + continent.Map.TerminalToSpawnPad.get(msg.terminal_guid.guid) match { + case Some(pad_guid) => + val pad = continent.GUID(pad_guid).get.asInstanceOf[VehicleSpawnPad] + vehicle.Faction = tplayer.Faction + vehicle.Position = pad.Position + vehicle.Orientation = pad.Orientation + taskResolver ! RegisterNewVehicle(vehicle, pad) + sendResponse(PacketCoding.CreateGamePacket(0, ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Learn, true))) + case None => + log.error(s"$tplayer wanted to spawn a vehicle, but there was no spawn pad associated with terminal ${msg.terminal_guid} to accept it") + } + case Terminal.NoDeal() => log.warn(s"$tplayer made a request but the terminal rejected the order $msg") sendResponse(PacketCoding.CreateGamePacket(0, ItemTransactionResultMessage(msg.terminal_guid, msg.transaction_type, false))) @@ -533,9 +567,21 @@ class WorldSessionActor extends Actor with MDCContextAware { reply match { case Vehicle.CanSeatPlayer(vehicle, seat_num) => log.info(s"MountVehicleMsg: ${player.GUID} mounts ${vehicle.GUID} @ $seat_num") + vehicleService ! VehicleServiceMessage.UnscheduleDeconstruction(vehicle.GUID) //clear all deconstruction timers val vehicle_guid : PlanetSideGUID = vehicle.GUID tplayer.VehicleSeated = Some(vehicle_guid) if(seat_num == 0) { //simplistic vehicle ownership management + vehicle.Owner match { + case Some(owner_guid) => + continent.GUID(owner_guid) match { + case Some(previous_owner : Player) => + if(previous_owner.VehicleOwned.contains(vehicle_guid)) { + previous_owner.VehicleOwned = None //simplistic ownership management, player loses vehicle ownership + } + case _ => ; + } + case None => ; + } player.VehicleOwned = Some(vehicle_guid) vehicle.Owner = Some(player.GUID) } @@ -558,12 +604,52 @@ class WorldSessionActor extends Actor with MDCContextAware { vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.MountVehicle(player_guid, vehicle_guid, seat_num)) case Vehicle.CannotSeatPlayer(vehicle, seat_num) => - val seat : Seat = vehicle.Seat(seat_num).get log.warn(s"MountVehicleMsg: player $tplayer attempted to board vehicle ${vehicle.GUID}'s seat $seat_num, but was not allowed") case _ => ; } + case VehicleSpawnPad.ConcealPlayer => + sendResponse(PacketCoding.CreateGamePacket(0, GenericObjectActionMessage(player.GUID, 36))) + avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.ConcealPlayer(player.GUID)) + + case VehicleSpawnPad.LoadVehicle(vehicle, _/*pad*/) => + val player_guid = player.GUID + val definition = vehicle.Definition + val objedtId = definition.ObjectId + val vehicle_guid = vehicle.GUID + val vdata = definition.Packet.ConstructorData(vehicle).get + sendResponse(PacketCoding.CreateGamePacket(0, ObjectCreateMessage(objedtId, vehicle_guid, vdata))) + continent.Transport ! Zone.SpawnVehicle(vehicle) + vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.LoadVehicle(player_guid, vehicle, objedtId, vehicle_guid, vdata)) + sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(vehicle_guid, 22, 1L))) //mount points off? + //sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(vehicle_guid, 21, player_guid.guid))) //fte and ownership? + //sendResponse(PacketCoding.CreateGamePacket(0, ObjectAttachMessage(vehicle_guid, player_guid, 0))) + vehicleService ! VehicleServiceMessage.UnscheduleDeconstruction(vehicle_guid) //cancel queue timeout delay + vehicleService ! VehicleServiceMessage.DelayedVehicleDeconstruction(vehicle, continent, 21L) //temporary drive away from pad delay + vehicle.Actor ! Vehicle.TrySeatPlayer(0, player) + + case VehicleSpawnPad.PlayerSeatedInVehicle(vehicle) => + vehicleService ! VehicleServiceMessage.DelayedVehicleDeconstruction(vehicle, continent, 21L) //sitting in the vehicle clears the drive away delay + val vehicle_guid = vehicle.GUID + sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(vehicle_guid, 22, 0L))) //mount points on? + //sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(vehicle_guid, 0, vehicle.Definition.MaxHealth))) + sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(vehicle_guid, 68, 0L))) //??? + sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(vehicle_guid, 113, 0L))) //??? + ReloadVehicleAccessPermissions(vehicle) + + case VehicleSpawnPad.SpawnPadBlockedWarning(vehicle, warning_count) => + if(warning_count > 2) { + sendResponse(PacketCoding.CreateGamePacket(0, TriggerSoundMessage(TriggeredSound.Unknown14, vehicle.Position, 20, 1f))) + sendResponse(PacketCoding.CreateGamePacket(0, + ChatMsg(ChatMessageType.CMT_TELL, true, "", "\\#FYour vehicle is blocking the spawn pad, and will be deconstructed if not moved.", None)) + ) + } + + case VehicleSpawnPad.SpawnPadUnblocked(vehicle_guid) => + //vehicle has moved away from spawn pad after initial spawn + vehicleService ! VehicleServiceMessage.UnscheduleDeconstruction(vehicle_guid) //cancel temporary drive away from pad delay + case ListAccountCharacters => import net.psforever.objects.definition.converter.CharacterSelectConverter val gen : AtomicInteger = new AtomicInteger(1) @@ -605,15 +691,8 @@ class WorldSessionActor extends Actor with MDCContextAware { failWithError(s"$tplayer failed to load anywhere") } - case VehicleLoaded(vehicle) => - val definition = vehicle.Definition - val objedtId = definition.ObjectId - val vehicle_guid = vehicle.GUID - val vdata = definition.Packet.ConstructorData(vehicle).get - sendResponse(PacketCoding.CreateGamePacket(0, ObjectCreateMessage(objedtId, vehicle_guid, vdata))) - ReloadVehicleAccessPermissions(vehicle) - continent.Transport ! Zone.SpawnVehicle(vehicle) - vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.LoadVehicle(player.GUID, vehicle, objedtId, vehicle_guid, vdata)) + case VehicleLoaded(_/*vehicle*/) => ; + //currently being handled by VehicleSpawnPad.LoadVehicle during testing phase case Zone.ClientInitialization(/*initList*/_) => //TODO iterate over initList; for now, just do this @@ -795,7 +874,6 @@ class WorldSessionActor extends Actor with MDCContextAware { } var player : Player = null - var harasser : Vehicle = null //TODO used in testing def handleGamePkt(pkt : PlanetSideGamePacket) = pkt match { case ConnectToWorldRequestMessage(server, token, majorVersion, minorVersion, revision, buildDate, unk) => @@ -803,18 +881,9 @@ class WorldSessionActor extends Actor with MDCContextAware { log.info(s"New world login to $server with Token:$token. $clientVersion") //TODO begin temp player character auto-loading; remove later import net.psforever.objects.GlobalDefinitions._ - val - beamer1 = Tool(beamer) - beamer1.AmmoSlots.head.Box = AmmoBox(energy_cell, 16) - val - suppressor1 = Tool(suppressor) - suppressor1.AmmoSlots.head.Box = AmmoBox(bullet_9mm, 25) - val - forceblade1 = Tool(forceblade) - forceblade1.AmmoSlots.head.Box = AmmoBox(melee_ammo) - player = Player("TestCharacter"+sessionId.toString, PlanetSideEmpire.VS, CharacterGender.Female, 41, 1) - player.Position = Vector3(3674.8438f, 2726.789f, 91.15625f) + //player.Position = Vector3(3674.8438f, 2726.789f, 91.15625f) + player.Position = Vector3(3523.039f, 2855.5078f, 90.859375f) player.Orientation = Vector3(0f, 0f, 90f) player.Certifications += CertificationType.StandardAssault player.Certifications += CertificationType.MediumAssault @@ -823,9 +892,24 @@ class WorldSessionActor extends Actor with MDCContextAware { player.Certifications += CertificationType.ReinforcedExoSuit player.Certifications += CertificationType.ATV player.Certifications += CertificationType.Harasser - player.Slot(0).Equipment = beamer1 - player.Slot(2).Equipment = suppressor1 - player.Slot(4).Equipment = forceblade1 + // + player.Certifications += CertificationType.GroundSupport + player.Certifications += CertificationType.GroundTransport + player.Certifications += CertificationType.Flail + player.Certifications += CertificationType.Switchblade + player.Certifications += CertificationType.AssaultBuggy + player.Certifications += CertificationType.ArmoredAssault1 + player.Certifications += CertificationType.ArmoredAssault2 + player.Certifications += CertificationType.AirCavalryScout + player.Certifications += CertificationType.AirCavalryAssault + player.Certifications += CertificationType.AirCavalryInterceptor + player.Certifications += CertificationType.AirSupport + player.Certifications += CertificationType.GalaxyGunship + player.Certifications += CertificationType.Phantasm + //player.ExoSuit = ExoSuitType.Infiltrator + player.Slot(0).Equipment = Tool(beamer) + player.Slot(2).Equipment = Tool(suppressor) + player.Slot(4).Equipment = Tool(forceblade) player.Slot(6).Equipment = AmmoBox(bullet_9mm) player.Slot(9).Equipment = AmmoBox(bullet_9mm) player.Slot(12).Equipment = AmmoBox(bullet_9mm) @@ -917,21 +1001,6 @@ class WorldSessionActor extends Actor with MDCContextAware { }) ReloadVehicleAccessPermissions(vehicle) }) - //TODO begin temp vehicle auto-loading - import net.psforever.objects.GlobalDefinitions._ - if(continent.Vehicles.isEmpty) { - harasser = Vehicle(two_man_assault_buggy) - harasser.Position = Vector3(3674.8438f, 2730.789f, 91.15625f) - harasser.Faction = PlanetSideEmpire.VS - harasser.Orientation = Vector3(0f, 0f, 90f) - harasser.Weapons(2).Equipment.get.asInstanceOf[Tool].AmmoSlots.head.Box = AmmoBox(bullet_12mm, 150) - harasser.Trunk += 30 -> AmmoBox(bullet_12mm, 100) - taskResolver ! RegisterNewVehicle(harasser) - } - else { - harasser = continent.Vehicles.head //subsequent players after first - } - //TODO end temp vehicle auto-loading avatarService ! Service.Join(player.Continent) localService ! Service.Join(player.Continent) vehicleService ! Service.Join(player.Continent) @@ -1129,6 +1198,7 @@ class WorldSessionActor extends Actor with MDCContextAware { continent.GUID(object_guid) match { case Some(vehicle : Vehicle) => if(player.VehicleOwned.contains(object_guid) && vehicle.Owner.contains(player.GUID)) { + vehicleService ! VehicleServiceMessage.UnscheduleDeconstruction(object_guid) vehicleService ! VehicleServiceMessage.RequestDeleteVehicle(vehicle, continent) log.info(s"RequestDestroy: vehicle $object_guid") } @@ -1157,14 +1227,14 @@ class WorldSessionActor extends Actor with MDCContextAware { sendResponse(PacketCoding.CreateGamePacket(0, ObjectDeleteMessage(object_guid, 0))) log.info("ObjectDelete: " + msg) - case msg @ MoveItemMessage(item_guid, avatar_guid_1, avatar_guid_2, dest, unk1) => + case msg @ MoveItemMessage(item_guid, source_guid, destination_guid, dest, unk1) => player.Find(item_guid) match { case Some(index) => val indexSlot = player.Slot(index) - var itemOpt = indexSlot.Equipment //use this to short circuit + var itemOpt : Option[Equipment] = indexSlot.Equipment + //use this to short circuit val item = itemOpt.get val destSlot = player.Slot(dest) - val destItem = if((-1 < dest && dest < 5) || dest == Player.FreeHandSlot) { destSlot.Equipment match { case Some(found) => @@ -1181,20 +1251,21 @@ class WorldSessionActor extends Actor with MDCContextAware { case Success(_) | scala.util.Failure(_) => itemOpt = None; None //abort item move altogether } } - if(itemOpt.isDefined) { - log.info(s"MoveItem: $item_guid moved from $avatar_guid_1 @ $index to $avatar_guid_1 @ $dest") + log.info(s"MoveItem: $item_guid moved from $source_guid @ $index to $source_guid @ $dest") indexSlot.Equipment = None - destItem match { //do we have a swap item? + destItem match { + //do we have a swap item? case Some(entry) => //yes, swap val item2 = entry.obj player.Slot(entry.start).Equipment = None //remove item2 to make room for item destSlot.Equipment = item //in case dest and index could block each other (indexSlot.Equipment = entry.obj) match { case Some(_) => //item and item2 swapped places successfully - log.info(s"MoveItem: ${item2.GUID} swapped to $avatar_guid_1 @ $index") + log.info(s"MoveItem: ${item2.GUID} swapped to $source_guid @ $index") //we must shuffle items around cleanly to avoid causing icons to "disappear" - if(index == Player.FreeHandSlot) { //temporarily put in safe location, A -> C + if(index == Player.FreeHandSlot) { + //temporarily put in safe location, A -> C sendResponse(PacketCoding.CreateGamePacket(0, ObjectDetachMessage(player.GUID, item.GUID, Vector3(0f, 0f, 0f), 0f, 0f, 0f))) //ground } else { @@ -1217,13 +1288,13 @@ class WorldSessionActor extends Actor with MDCContextAware { case None => //just move item over destSlot.Equipment = item } - sendResponse(PacketCoding.CreateGamePacket(0, ObjectAttachMessage(avatar_guid_1, item_guid, dest))) + sendResponse(PacketCoding.CreateGamePacket(0, ObjectAttachMessage(source_guid, item_guid, dest))) if(0 <= dest && dest < 5) { avatarService ! AvatarServiceMessage(player.Continent, AvatarAction.EquipmentInHand(player.GUID, dest, item)) } } case None => - log.info(s"MoveItem: $avatar_guid_1 wanted to move the item $item_guid but could not find it") + log.info(s"MoveItem: $source_guid wanted to move the item $item_guid but could not find it") } case msg @ ChangeAmmoMessage(item_guid, unk1) => @@ -1384,6 +1455,9 @@ class WorldSessionActor extends Actor with MDCContextAware { player.VehicleSeated = None sendResponse(PacketCoding.CreateGamePacket(0, DismountVehicleMsg(player_guid, unk1, unk2))) //should be safe; replace with ObjectDetachMessage later vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.DismountVehicle(player_guid, unk1, unk2)) + if(obj.Seats.count(seat => seat.isOccupied) == 0) { + vehicleService ! VehicleServiceMessage.DelayedVehicleDeconstruction(obj, continent, 600L) //start vehicle decay (10m) + } } case None => log.warn(s"DismountVehicleMsg: can not find where player $player_guid is seated in vehicle $vehicle_guid") @@ -1409,6 +1483,9 @@ class WorldSessionActor extends Actor with MDCContextAware { seat.Occupant = None tplayer.VehicleSeated = None vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.KickPassenger(player_guid, unk1, unk2)) + if(obj.Seats.count(seat => seat.isOccupied) == 0) { + vehicleService ! VehicleServiceMessage.DelayedVehicleDeconstruction(obj, continent, 600L) //start vehicle decay (10m) + } case None => log.warn(s"DismountVehicleMsg: can not find where player $player_guid is seated in vehicle $vehicle_guid") } @@ -1733,12 +1810,16 @@ class WorldSessionActor extends Actor with MDCContextAware { * @see `RegisterVehicle` * @return a `TaskResolver.GiveTask` message */ - def RegisterNewVehicle(obj : Vehicle) : TaskResolver.GiveTask = { + def RegisterNewVehicle(obj : Vehicle, pad : VehicleSpawnPad) : TaskResolver.GiveTask = { TaskResolver.GiveTask( new Task() { private val localVehicle = obj private val localAnnounce = vehicleService private val localSession : String = sessionId.toString + private val localPad = pad.Actor + private val localPlayer = player + private val localVehicleService = vehicleService + private val localZone = continent override def isComplete : Task.Resolution.Value = { if(localVehicle.Actor != ActorRef.noSender) { @@ -1751,6 +1832,8 @@ class WorldSessionActor extends Actor with MDCContextAware { def Execute(resolver : ActorRef) : Unit = { localAnnounce ! VehicleServiceMessage.GiveActorControl(obj, localSession) + localPad ! VehicleSpawnPad.VehicleOrder(localPlayer, localVehicle) + localVehicleService ! VehicleServiceMessage.DelayedVehicleDeconstruction(localVehicle, localZone, 60L) resolver ! scala.util.Success(this) } }, List(RegisterVehicle(obj))) @@ -1945,35 +2028,4 @@ object WorldSessionActor { delta : Float, completeAction : () => Unit, tickAction : Option[() => Unit] = None) - /** - * A placeholder `Cancellable` object. - */ - private final val DefaultCancellable = new Cancellable() { - def cancel : Boolean = true - def isCancelled() : Boolean = true - } - - /** - * Calculate the actual distance between two points. - * @param pos1 the first point - * @param pos2 the second point - * @return the distance - */ - def Distance(pos1 : Vector3, pos2 : Vector3) : Float = { - math.sqrt(DistanceSquared(pos1, pos2)).toFloat - } - - /** - * Calculate the squared distance between two points. - * Though some time is saved care must be taken that any comparative distance is also squared. - * @param pos1 the first point - * @param pos2 the second point - * @return the distance - */ - def DistanceSquared(pos1 : Vector3, pos2 : Vector3) : Float = { - val dx : Float = pos1.x - pos2.x - val dy : Float = pos1.y - pos2.y - val dz : Float = pos1.z - pos2.z - (dx * dx) + (dy * dy) + (dz * dz) - } } diff --git a/pslogin/src/main/scala/services/avatar/AvatarAction.scala b/pslogin/src/main/scala/services/avatar/AvatarAction.scala index 451b38732..3b9f54e65 100644 --- a/pslogin/src/main/scala/services/avatar/AvatarAction.scala +++ b/pslogin/src/main/scala/services/avatar/AvatarAction.scala @@ -10,6 +10,7 @@ object AvatarAction { trait Action final case class ArmorChanged(player_guid : PlanetSideGUID, suit : ExoSuitType.Value, subtype : Int) extends Action + final case class ConcealPlayer(player_guid : PlanetSideGUID) extends Action //final case class DropItem(pos : Vector3, orient : Vector3, item : PlanetSideGUID) extends Action final case class EquipmentInHand(player_guid : PlanetSideGUID, slot : Int, item : Equipment) extends Action final case class EquipmentOnGround(player_guid : PlanetSideGUID, pos : Vector3, orient : Vector3, item : Equipment) extends Action diff --git a/pslogin/src/main/scala/services/avatar/AvatarResponse.scala b/pslogin/src/main/scala/services/avatar/AvatarResponse.scala index 87f37e841..75763c8c8 100644 --- a/pslogin/src/main/scala/services/avatar/AvatarResponse.scala +++ b/pslogin/src/main/scala/services/avatar/AvatarResponse.scala @@ -10,6 +10,7 @@ object AvatarResponse { trait Response final case class ArmorChanged(suit : ExoSuitType.Value, subtype : Int) extends Response + final case class ConcealPlayer() extends Response //final case class DropItem(pos : Vector3, orient : Vector3, item : PlanetSideGUID) extends Response final case class EquipmentInHand(slot : Int, item : Equipment) extends Response final case class EquipmentOnGround(pos : Vector3, orient : Vector3, item : Equipment) extends Response diff --git a/pslogin/src/main/scala/services/avatar/AvatarService.scala b/pslogin/src/main/scala/services/avatar/AvatarService.scala index 0e3c6f16f..5148b2733 100644 --- a/pslogin/src/main/scala/services/avatar/AvatarService.scala +++ b/pslogin/src/main/scala/services/avatar/AvatarService.scala @@ -33,6 +33,10 @@ class AvatarService extends Actor { AvatarEvents.publish( AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.ArmorChanged(suit, subtype)) ) + case AvatarAction.ConcealPlayer(player_guid) => + AvatarEvents.publish( + AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.ConcealPlayer()) + ) case AvatarAction.EquipmentInHand(player_guid, slot, obj) => AvatarEvents.publish( AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.EquipmentInHand(slot, obj)) diff --git a/pslogin/src/main/scala/services/local/support/DoorCloseActor.scala b/pslogin/src/main/scala/services/local/support/DoorCloseActor.scala index a2ca622cf..10413da44 100644 --- a/pslogin/src/main/scala/services/local/support/DoorCloseActor.scala +++ b/pslogin/src/main/scala/services/local/support/DoorCloseActor.scala @@ -2,6 +2,7 @@ package services.local.support import akka.actor.{Actor, Cancellable} +import net.psforever.objects.DefaultCancellable import net.psforever.objects.serverobject.doors.Door import net.psforever.objects.zones.Zone import net.psforever.packet.game.PlanetSideGUID @@ -16,7 +17,7 @@ import scala.concurrent.duration._ */ class DoorCloseActor() extends Actor { /** The periodic `Executor` that checks for doors to be closed */ - private var doorCloserTrigger : Cancellable = DoorCloseActor.DefaultCloser + private var doorCloserTrigger : Cancellable = DefaultCancellable.obj /** A `List` of currently open doors */ private var openDoors : List[DoorCloseActor.DoorEntry] = Nil //private[this] val log = org.log4s.getLogger @@ -98,11 +99,6 @@ object DoorCloseActor { /** The wait before an open door closes; as a `FiniteDuration` for `Executor` simplicity */ private final val timeout : FiniteDuration = timeout_time nanoseconds - private final val DefaultCloser : Cancellable = new Cancellable() { - override def cancel : Boolean = true - override def isCancelled : Boolean = true - } - /** * Message that carries information about a door that has been opened. * @param door the door object diff --git a/pslogin/src/main/scala/services/local/support/HackClearActor.scala b/pslogin/src/main/scala/services/local/support/HackClearActor.scala index 76a7e7f92..52a402804 100644 --- a/pslogin/src/main/scala/services/local/support/HackClearActor.scala +++ b/pslogin/src/main/scala/services/local/support/HackClearActor.scala @@ -2,6 +2,7 @@ package services.local.support import akka.actor.{Actor, Cancellable} +import net.psforever.objects.DefaultCancellable import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject} import net.psforever.objects.zones.Zone import net.psforever.packet.game.PlanetSideGUID @@ -16,7 +17,7 @@ import scala.concurrent.duration._ */ class HackClearActor() extends Actor { /** The periodic `Executor` that checks for server objects to be unhacked */ - private var clearTrigger : Cancellable = HackClearActor.DefaultClearer + private var clearTrigger : Cancellable = DefaultCancellable.obj /** A `List` of currently hacked server objects */ private var hackedObjects : List[HackClearActor.HackEntry] = Nil //private[this] val log = org.log4s.getLogger @@ -99,11 +100,6 @@ object HackClearActor { /** The wait before a server object is to unhack; as a `FiniteDuration` for `Executor` simplicity */ private final val timeout : FiniteDuration = timeout_time nanoseconds - private final val DefaultClearer : Cancellable = new Cancellable() { - override def cancel : Boolean = true - override def isCancelled : Boolean = true - } - /** * Message that carries information about a server object that has been hacked. * @param target the server object diff --git a/pslogin/src/main/scala/services/vehicle/VehicleService.scala b/pslogin/src/main/scala/services/vehicle/VehicleService.scala index 12842a95b..7f49f6eda 100644 --- a/pslogin/src/main/scala/services/vehicle/VehicleService.scala +++ b/pslogin/src/main/scala/services/vehicle/VehicleService.scala @@ -2,12 +2,13 @@ package services.vehicle import akka.actor.{Actor, ActorRef, Props} -import services.vehicle.support.{DeconstructionActor, VehicleContextActor} +import services.vehicle.support.{DeconstructionActor, DelayedDeconstructionActor, VehicleContextActor} import services.{GenericEventBus, Service} class VehicleService extends Actor { private val vehicleContext : ActorRef = context.actorOf(Props[VehicleContextActor], "vehicle-context-root") private val vehicleDecon : ActorRef = context.actorOf(Props[DeconstructionActor], "vehicle-decon-agent") + private val vehicleDelayedDecon : ActorRef = context.actorOf(Props[DelayedDeconstructionActor], "vehicle-delayed-decon-agent") vehicleDecon ! DeconstructionActor.RequestTaskResolver private [this] val log = org.log4s.getLogger @@ -79,6 +80,14 @@ class VehicleService extends Actor { case VehicleServiceMessage.RequestDeleteVehicle(vehicle, continent) => vehicleDecon ! DeconstructionActor.RequestDeleteVehicle(vehicle, continent) + //message to DelayedDeconstructionActor + case VehicleServiceMessage.DelayedVehicleDeconstruction(vehicle, zone, timeAlive) => + vehicleDelayedDecon ! DelayedDeconstructionActor.ScheduleDeconstruction(vehicle, zone, timeAlive) + + //message to DelayedDeconstructionActor + case VehicleServiceMessage.UnscheduleDeconstruction(vehicle_guid) => + vehicleDelayedDecon ! DelayedDeconstructionActor.UnscheduleDeconstruction(vehicle_guid) + //response from DeconstructionActor case DeconstructionActor.DeleteVehicle(vehicle_guid, zone_id) => VehicleEvents.publish( diff --git a/pslogin/src/main/scala/services/vehicle/VehicleServiceMessage.scala b/pslogin/src/main/scala/services/vehicle/VehicleServiceMessage.scala index c3e1c4804..48c03dab3 100644 --- a/pslogin/src/main/scala/services/vehicle/VehicleServiceMessage.scala +++ b/pslogin/src/main/scala/services/vehicle/VehicleServiceMessage.scala @@ -3,11 +3,14 @@ package services.vehicle import net.psforever.objects.Vehicle import net.psforever.objects.zones.Zone +import net.psforever.packet.game.PlanetSideGUID final case class VehicleServiceMessage(forChannel : String, actionMessage : VehicleAction.Action) object VehicleServiceMessage { + final case class DelayedVehicleDeconstruction(vehicle : Vehicle, continent : Zone, timeAlive : Long) final case class GiveActorControl(vehicle : Vehicle, actorName : String) final case class RevokeActorControl(vehicle : Vehicle) final case class RequestDeleteVehicle(vehicle : Vehicle, continent : Zone) + final case class UnscheduleDeconstruction(vehicle_guid : PlanetSideGUID) } diff --git a/pslogin/src/main/scala/services/vehicle/support/DeconstructionActor.scala b/pslogin/src/main/scala/services/vehicle/support/DeconstructionActor.scala index 4d09b9272..f19d47aa9 100644 --- a/pslogin/src/main/scala/services/vehicle/support/DeconstructionActor.scala +++ b/pslogin/src/main/scala/services/vehicle/support/DeconstructionActor.scala @@ -2,7 +2,7 @@ package services.vehicle.support import akka.actor.{Actor, ActorRef, Cancellable} -import net.psforever.objects.Vehicle +import net.psforever.objects.{DefaultCancellable, Vehicle} import net.psforever.objects.guid.TaskResolver import net.psforever.objects.vehicles.Seat import net.psforever.objects.zones.Zone @@ -20,11 +20,13 @@ import scala.concurrent.duration._ * A reference to a vehicle should be passed to this object as soon as it is going to be cleaned-up from the game world. * Once accepted, only a few seconds will remain before the vehicle is deleted. * To ensure that no players are lost in the deletion, all occupants of the vehicle are kicked out. - * Furthermore, the vehicle is rendered "dead" and inaccessible right up to the point where it is removed. + * Furthermore, the vehicle is rendered "dead" and inaccessible right up to the point where it is removed.
+ *
+ * This `Actor` is intended to sit on top of the event system that handles broadcast messaging. */ class DeconstructionActor extends Actor { /** The periodic `Executor` that scraps the next vehicle on the list */ - private var scrappingProcess : Cancellable = DeconstructionActor.DefaultProcess + private var scrappingProcess : Cancellable = DefaultCancellable.obj /** A `List` of currently doomed vehicles */ private var vehicles : List[DeconstructionActor.VehicleEntry] = Nil /** The manager that helps unregister the vehicle from its current GUID scope */ @@ -171,11 +173,6 @@ object DeconstructionActor { /** The wait before completely deleting a vehicle; as a `FiniteDuration` for `Executor` simplicity */ private final val timeout : FiniteDuration = timeout_time nanoseconds - private final val DefaultProcess : Cancellable = new Cancellable() { - override def cancel : Boolean = true - override def isCancelled : Boolean = true - } - final case class RequestTaskResolver() /** diff --git a/pslogin/src/main/scala/services/vehicle/support/DelayedDeconstructionActor.scala b/pslogin/src/main/scala/services/vehicle/support/DelayedDeconstructionActor.scala new file mode 100644 index 000000000..2c508ad8d --- /dev/null +++ b/pslogin/src/main/scala/services/vehicle/support/DelayedDeconstructionActor.scala @@ -0,0 +1,104 @@ +// Copyright (c) 2017 PSForever +package services.vehicle.support + +import akka.actor.{Actor, Cancellable} +import net.psforever.objects.{DefaultCancellable, Vehicle} +import net.psforever.objects.zones.Zone +import net.psforever.packet.game.PlanetSideGUID +import services.vehicle.VehicleServiceMessage + +import scala.concurrent.duration._ + +/** + * Maintain and curate a list of timed `vehicle` object deconstruction tasks.
+ *
+ * These tasks are queued or dismissed by player activity but they are executed independent of player activity. + * A common disconnected cause of deconstruction is neglect for an extended period of time. + * At that point, the original owner of the vehicle no longer matters. + * Deconstruction neglect, however, is averted by having someone become seated. + * A realized deconstruction is entirely based on a fixed interval after an unresolved request has been received. + * The actual process of deconstructing the vehicle and cleaning up its resources is performed by an external agent.
+ *
+ * This `Actor` is intended to sit on top of the event system that handles broadcast messaging. + */ +class DelayedDeconstructionActor extends Actor { + /** The periodic `Executor` that scraps the next vehicle on the list */ + private var monitor : Cancellable = DefaultCancellable.obj + /** A `List` of currently doomed vehicles */ + private var vehicles : List[DelayedDeconstructionActor.VehicleEntry] = Nil + private[this] val log = org.log4s.getLogger + private[this] def trace(msg : String) : Unit = log.trace(msg) + + + def receive : Receive = { + case DelayedDeconstructionActor.ScheduleDeconstruction(vehicle, zone, timeAlive) => + trace(s"delayed deconstruction order for $vehicle in $timeAlive") + vehicles = vehicles :+ DelayedDeconstructionActor.VehicleEntry(vehicle, zone, timeAlive * 1000000000L) + if(vehicles.size == 1) { //we were the only entry so the event must be started from scratch + import scala.concurrent.ExecutionContext.Implicits.global + monitor = context.system.scheduler.scheduleOnce(DelayedDeconstructionActor.periodicTest, self, DelayedDeconstructionActor.PeriodicTaskCulling) + } + + case DelayedDeconstructionActor.UnscheduleDeconstruction(vehicle_guid) => + //all tasks for this vehicle are cleared from the queue + //clear any task that is no longer valid by determination of unregistered GUID + val before = vehicles.length + vehicles = vehicles.filter(entry => { !entry.vehicle.HasGUID || entry.vehicle.GUID != vehicle_guid }) + trace(s"attempting to clear deconstruction order for vehicle $vehicle_guid, found ${before - vehicles.length}") + if(vehicles.isEmpty) { + monitor.cancel + } + + case DelayedDeconstructionActor.PeriodicTaskCulling => + //filter the list of deconstruction tasks for any that are need to be triggered + monitor.cancel + val now : Long = System.nanoTime + val (vehiclesToDecon, vehiclesRemain) = vehicles.partition(entry => { now - entry.logTime >= entry.survivalTime }) + vehicles = vehiclesRemain + trace(s"vehicle culling - ${vehiclesToDecon.length} deconstruction tasks found") + vehiclesToDecon.foreach(entry => { context.parent ! VehicleServiceMessage.RequestDeleteVehicle(entry.vehicle, entry.zone) }) + if(vehiclesRemain.nonEmpty) { + import scala.concurrent.ExecutionContext.Implicits.global + monitor = context.system.scheduler.scheduleOnce(DelayedDeconstructionActor.periodicTest, self, DelayedDeconstructionActor.PeriodicTaskCulling) + } + + case _ => ; + } +} + +object DelayedDeconstructionActor { + /** + * Timer for the repeating executor. + */ + private final val periodicTest : FiniteDuration = 5000000000L nanoseconds //5s + + /** + * Queue a future vehicle deconstruction action. + * @param vehicle the `Vehicle` object + * @param zone the `Zone` that the vehicle currently occupies + * @param survivalTime how long until the vehicle will be deconstructed in seconds + */ + final case class ScheduleDeconstruction(vehicle : Vehicle, zone : Zone, survivalTime : Long) + + /** + * Dequeue a vehicle from being deconstructed. + * @param vehicle_guid the vehicle + */ + final case class UnscheduleDeconstruction(vehicle_guid : PlanetSideGUID) + + /** + * A message the `Actor` sends to itself. + * The trigger for the periodic deconstruction task. + */ + private final case class PeriodicTaskCulling() + + /** + * An entry that stores vehicle deconstruction tasks. + * @param vehicle the `Vehicle` object + * @param zone the `Zone` that the vehicle currently occupies + * @param survivalTime how long until the vehicle will be deconstructed in nanoseconds + * @param logTime when this deconstruction request was initially created in nanoseconds; + * initialized by default to a "now" + */ + private final case class VehicleEntry(vehicle : Vehicle, zone : Zone, survivalTime : Long, logTime : Long = System.nanoTime()) +} diff --git a/pslogin/src/main/scala/services/vehicle/support/VehicleContextActor.scala b/pslogin/src/main/scala/services/vehicle/support/VehicleContextActor.scala index 756a31a34..ebc954aad 100644 --- a/pslogin/src/main/scala/services/vehicle/support/VehicleContextActor.scala +++ b/pslogin/src/main/scala/services/vehicle/support/VehicleContextActor.scala @@ -1,7 +1,7 @@ // Copyright (c) 2017 PSForever package services.vehicle.support -import akka.actor.{Actor, Props} +import akka.actor.{Actor, ActorRef, Props} import net.psforever.objects.vehicles.VehicleControl import services.vehicle.VehicleServiceMessage @@ -15,15 +15,18 @@ import services.vehicle.VehicleServiceMessage *
* The only purpose of this `Actor` is to allow vehicles to borrow a context for the purpose of `Actor` creation. * It is also be allowed to be responsible for cleaning up that context. - * (In reality, it can be cleaned up anywhere a `PoisonPill` can be sent.) + * (In reality, it can be cleaned up anywhere a `PoisonPill` can be sent.)
+ *
+ * This `Actor` is intended to sit on top of the event system that handles broadcast messaging. */ class VehicleContextActor() extends Actor { def receive : Receive = { case VehicleServiceMessage.GiveActorControl(vehicle, actorName) => - vehicle.Actor = context.actorOf(Props(classOf[VehicleControl], vehicle), s"${vehicle.Definition.Name}_$actorName") + vehicle.Actor = context.actorOf(Props(classOf[VehicleControl], vehicle), s"${vehicle.Definition.Name}_$actorName.${System.nanoTime()}") case VehicleServiceMessage.RevokeActorControl(vehicle) => vehicle.Actor ! akka.actor.PoisonPill + vehicle.Actor = ActorRef.noSender case _ => ; } From 658b4f3b072907a504b410c7693a396f11944ac9 Mon Sep 17 00:00:00 2001 From: FateJH Date: Sun, 26 Nov 2017 00:00:41 -0500 Subject: [PATCH 2/5] an attempt to shrink the size of the init function in GlobalDefinitions and not offend Travis-CI --- .../psforever/objects/GlobalDefinitions.scala | 4134 ++++++++--------- 1 file changed, 2062 insertions(+), 2072 deletions(-) diff --git a/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala b/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala index c8ac95d62..f4fe17774 100644 --- a/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala +++ b/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala @@ -13,6 +13,474 @@ import net.psforever.objects.vehicles.SeatArmorRestriction import net.psforever.types.PlanetSideEmpire object GlobalDefinitions { + /* + Implants + */ + val advanced_regen = ImplantDefinition(0) + + val targeting = ImplantDefinition(1) + + val audio_amplifier = ImplantDefinition(2) + + val darklight_vision = ImplantDefinition(3) + + val melee_booster = ImplantDefinition(4) + + val personal_shield = ImplantDefinition(5) + + val range_magnifier = ImplantDefinition(6) + + val second_wind = ImplantDefinition(7) + + val silent_run = ImplantDefinition(8) + + val surge = ImplantDefinition(9) + + /* + Equipment (locker_container, kits, ammunition, weapons) + */ + import net.psforever.packet.game.objectcreate.ObjectClass + val locker_container = new EquipmentDefinition(456) { + Name = "locker container" + Size = EquipmentSize.Inventory + Packet = new LockerContainerConverter() + } + + val medkit = KitDefinition(Kits.medkit) + + val super_medkit = KitDefinition(Kits.super_medkit) + + val super_armorkit = KitDefinition(Kits.super_armorkit) + + val super_staminakit = KitDefinition(Kits.super_staminakit) //super stimpak + + val melee_ammo = AmmoBoxDefinition(Ammo.melee_ammo) + + val frag_grenade_ammo = AmmoBoxDefinition(Ammo.frag_grenade_ammo) + + val plasma_grenade_ammo = AmmoBoxDefinition(Ammo.plasma_grenade_ammo) + + val jammer_grenade_ammo = AmmoBoxDefinition(Ammo.jammer_grenade_ammo) + + val bullet_9mm = AmmoBoxDefinition(Ammo.bullet_9mm) + + val bullet_9mm_AP = AmmoBoxDefinition(Ammo.bullet_9mm_AP) + + val shotgun_shell = AmmoBoxDefinition(Ammo.shotgun_shell) + + val shotgun_shell_AP = AmmoBoxDefinition(Ammo.shotgun_shell_AP) + + val energy_cell = AmmoBoxDefinition(Ammo.energy_cell) + + val anniversary_ammo = AmmoBoxDefinition(Ammo.anniversary_ammo) //10mm multi-phase + + val ancient_ammo_combo = AmmoBoxDefinition(Ammo.ancient_ammo_combo) + + val maelstrom_ammo = AmmoBoxDefinition(Ammo.maelstrom_ammo) + + val phoenix_missile = AmmoBoxDefinition(Ammo.phoenix_missile) //decimator missile + + val striker_missile_ammo = AmmoBoxDefinition(Ammo.striker_missile_ammo) + + val hunter_seeker_missile = AmmoBoxDefinition(Ammo.hunter_seeker_missile) //phoenix missile + + val lancer_cartridge = AmmoBoxDefinition(Ammo.lancer_cartridge) + + val rocket = AmmoBoxDefinition(Ammo.rocket) + + val frag_cartridge = AmmoBoxDefinition(Ammo.frag_cartridge) + + val plasma_cartridge = AmmoBoxDefinition(Ammo.plasma_cartridge) + + val jammer_cartridge = AmmoBoxDefinition(Ammo.jammer_cartridge) + + val bolt = AmmoBoxDefinition(Ammo.bolt) + + val oicw_ammo = AmmoBoxDefinition(Ammo.oicw_ammo) //scorpion missile + + val flamethrower_ammo = AmmoBoxDefinition(Ammo.flamethrower_ammo) + + val health_canister = AmmoBoxDefinition(Ammo.health_canister) + + val armor_canister = AmmoBoxDefinition(Ammo.armor_canister) + + val upgrade_canister = AmmoBoxDefinition(Ammo.upgrade_canister) + + val trek_ammo = AmmoBoxDefinition(Ammo.trek_ammo) + // + val bullet_35mm = AmmoBoxDefinition(Ammo.bullet_35mm) //liberator nosegun + + val ancient_ammo_vehicle = AmmoBoxDefinition(Ammo.ancient_ammo_vehicle) + // + val aphelion_laser_ammo = AmmoBoxDefinition(Ammo.aphelion_laser_ammo) + + val aphelion_immolation_cannon_ammo = AmmoBoxDefinition(Ammo.aphelion_immolation_cannon_ammo) + + val aphelion_plasma_rocket_ammo = AmmoBoxDefinition(Ammo.aphelion_plasma_rocket_ammo) + + val aphelion_ppa_ammo = AmmoBoxDefinition(Ammo.aphelion_ppa_ammo) + + val aphelion_starfire_ammo = AmmoBoxDefinition(Ammo.aphelion_starfire_ammo) + + val skyguard_flak_cannon_ammo = AmmoBoxDefinition(Ammo.skyguard_flak_cannon_ammo) + + val firebird_missile = AmmoBoxDefinition(ObjectClass.firebird_missile) + + val flux_cannon_thresher_battery = AmmoBoxDefinition(Ammo.flux_cannon_thresher_battery) + + val fluxpod_ammo = AmmoBoxDefinition(Ammo.fluxpod_ammo) + + val hellfire_ammo = AmmoBoxDefinition(Ammo.hellfire_ammo) + + val liberator_bomb = AmmoBoxDefinition(Ammo.liberator_bomb) + + val bullet_25mm = AmmoBoxDefinition(Ammo.bullet_25mm) //liberator tailgun + + val bullet_75mm = AmmoBoxDefinition(Ammo.bullet_75mm) //lightning shell + + val heavy_grenade_mortar = AmmoBoxDefinition(Ammo.heavy_grenade_mortar) //marauder and gal gunship + + val pulse_battery = AmmoBoxDefinition(Ammo.pulse_battery) + + val heavy_rail_beam_battery = AmmoBoxDefinition(Ammo.heavy_rail_beam_battery) + + val reaver_rocket = AmmoBoxDefinition(Ammo.reaver_rocket) + + val bullet_20mm = AmmoBoxDefinition(Ammo.bullet_20mm) //reaver nosegun + + val bullet_12mm = AmmoBoxDefinition(Ammo.bullet_12mm) //common + + val wasp_rocket_ammo = AmmoBoxDefinition(Ammo.wasp_rocket_ammo) + + val wasp_gun_ammo = AmmoBoxDefinition(Ammo.wasp_gun_ammo) //wasp nosegun + + val bullet_15mm = AmmoBoxDefinition(Ammo.bullet_15mm) + + val colossus_100mm_cannon_ammo = AmmoBoxDefinition(Ammo.colossus_100mm_cannon_ammo) + + val colossus_burster_ammo = AmmoBoxDefinition(Ammo.colossus_burster_ammo) + + val colossus_cluster_bomb_ammo = AmmoBoxDefinition(Ammo.colossus_cluster_bomb_ammo) //colossus mortar launcher shells + + val colossus_chaingun_ammo = AmmoBoxDefinition(Ammo.colossus_chaingun_ammo) + + val colossus_tank_cannon_ammo = AmmoBoxDefinition(Ammo.colossus_tank_cannon_ammo) + + val bullet_105mm = AmmoBoxDefinition(Ammo.bullet_105mm) //prowler 100mm cannon shell + + val gauss_cannon_ammo = AmmoBoxDefinition(Ammo.gauss_cannon_ammo) + + val peregrine_dual_machine_gun_ammo = AmmoBoxDefinition(Ammo.peregrine_dual_machine_gun_ammo) + + val peregrine_mechhammer_ammo = AmmoBoxDefinition(Ammo.peregrine_mechhammer_ammo) + + val peregrine_particle_cannon_ammo = AmmoBoxDefinition(Ammo.peregrine_particle_cannon_ammo) + + val peregrine_rocket_pod_ammo = AmmoBoxDefinition(Ammo.peregrine_rocket_pod_ammo) + + val peregrine_sparrow_ammo = AmmoBoxDefinition(Ammo.peregrine_sparrow_ammo) + + val bullet_150mm = AmmoBoxDefinition(Ammo.bullet_150mm) + init_ammo() + + val chainblade = ToolDefinition(ObjectClass.chainblade) + + val magcutter = ToolDefinition(ObjectClass.magcutter) + + val forceblade = ToolDefinition(ObjectClass.forceblade) + + val katana = ToolDefinition(ObjectClass.katana) + + val frag_grenade = ToolDefinition(ObjectClass.frag_grenade) + + val plasma_grenade = ToolDefinition(ObjectClass.plasma_grenade) + + val jammer_grenade = ToolDefinition(ObjectClass.jammer_grenade) + + val repeater = ToolDefinition(ObjectClass.repeater) + + val isp = ToolDefinition(ObjectClass.isp) //mag-scatter + + val beamer = ToolDefinition(ObjectClass.beamer) + + val ilc9 = ToolDefinition(ObjectClass.ilc9) //amp + + val suppressor = ToolDefinition(ObjectClass.suppressor) + + val punisher = ToolDefinition(ObjectClass.punisher) + + val flechette = ToolDefinition(ObjectClass.flechette) //sweeper + + val cycler = ToolDefinition(ObjectClass.cycler) + + val gauss = ToolDefinition(ObjectClass.gauss) + + val pulsar = ToolDefinition(ObjectClass.pulsar) + + val anniversary_guna = ToolDefinition(ObjectClass.anniversary_guna) //tr stinger + + val anniversary_gun = ToolDefinition(ObjectClass.anniversary_gun) //nc spear + + val anniversary_gunb = ToolDefinition(ObjectClass.anniversary_gunb) //vs eraser + + val spiker = ToolDefinition(ObjectClass.spiker) + + val mini_chaingun = ToolDefinition(ObjectClass.mini_chaingun) + + val r_shotgun = ToolDefinition(ObjectClass.r_shotgun) //jackhammer + + val lasher = ToolDefinition(ObjectClass.lasher) + + val maelstrom = ToolDefinition(ObjectClass.maelstrom) + + val phoenix = ToolDefinition(ObjectClass.phoenix) //decimator + + val striker = ToolDefinition(ObjectClass.striker) + + val hunterseeker = ToolDefinition(ObjectClass.hunterseeker) //phoenix + + val lancer = ToolDefinition(ObjectClass.lancer) + + val rocklet = ToolDefinition(ObjectClass.rocklet) + + val thumper = ToolDefinition(ObjectClass.thumper) + + val radiator = ToolDefinition(ObjectClass.radiator) + + val heavy_sniper = ToolDefinition(ObjectClass.heavy_sniper) //hsr + + val bolt_driver = ToolDefinition(ObjectClass.bolt_driver) + + val oicw = ToolDefinition(ObjectClass.oicw) //scorpion + + val flamethrower = ToolDefinition(ObjectClass.flamethrower) + + val trhev_dualcycler = ToolDefinition(ObjectClass.trhev_dualcycler) //TODO + + val trhev_pounder = ToolDefinition(ObjectClass.trhev_pounder) //TODO + + val trhev_burster = ToolDefinition(ObjectClass.trhev_burster) //TODO + + val nchev_scattercannon = ToolDefinition(ObjectClass.nchev_scattercannon) //TODO + + val nchev_falcon = ToolDefinition(ObjectClass.nchev_falcon) //TODO + + val nchev_sparrow = ToolDefinition(ObjectClass.nchev_sparrow) //TODO + + val vshev_quasar = ToolDefinition(ObjectClass.vshev_quasar) //TODO + + val vshev_comet = ToolDefinition(ObjectClass.vshev_comet) //TODO + + val vshev_starfire = ToolDefinition(ObjectClass.vshev_starfire) //TODO + + val medicalapplicator = ToolDefinition(ObjectClass.medicalapplicator) + + val nano_dispenser = ToolDefinition(ObjectClass.nano_dispenser) + + val bank = ToolDefinition(ObjectClass.bank) + + val remote_electronics_kit = SimpleItemDefinition(SItem.remote_electronics_kit) + + val trek = ToolDefinition(ObjectClass.trek) + + val flail_targeting_laser = SimpleItemDefinition(SItem.flail_targeting_laser) + + val command_detonater = SimpleItemDefinition(SItem.command_detonater) + + val ace = ConstructionItemDefinition(CItem.Unit.ace) + + val advanced_ace = ConstructionItemDefinition(CItem.Unit.advanced_ace) + + val fury_weapon_systema = ToolDefinition(ObjectClass.fury_weapon_systema) + + val quadassault_weapon_system = ToolDefinition(ObjectClass.quadassault_weapon_system) + + val scythe = ToolDefinition(ObjectClass.scythe) //TODO resolve ammo slot/pool discrepancy + + val chaingun_p = ToolDefinition(ObjectClass.chaingun_p) + + val skyguard_weapon_system = ToolDefinition(ObjectClass.skyguard_weapon_system) + + val grenade_launcher_marauder = ToolDefinition(ObjectClass.grenade_launcher_marauder) + + val advanced_missile_launcher_t = ToolDefinition(ObjectClass.advanced_missile_launcher_t) + + val flux_cannon_thresher = ToolDefinition(ObjectClass.flux_cannon_thresher) + + val mediumtransport_weapon_systemA = ToolDefinition(ObjectClass.mediumtransport_weapon_systemA) + + val mediumtransport_weapon_systemB = ToolDefinition(ObjectClass.mediumtransport_weapon_systemB) + + val battlewagon_weapon_systema = ToolDefinition(ObjectClass.battlewagon_weapon_systema) + + val battlewagon_weapon_systemb = ToolDefinition(ObjectClass.battlewagon_weapon_systemb) + + val battlewagon_weapon_systemc = ToolDefinition(ObjectClass.battlewagon_weapon_systemc) + + val battlewagon_weapon_systemd = ToolDefinition(ObjectClass.battlewagon_weapon_systemd) + + val thunderer_weapon_systema = ToolDefinition(ObjectClass.thunderer_weapon_systema) + + val thunderer_weapon_systemb = ToolDefinition(ObjectClass.thunderer_weapon_systemb) + + val aurora_weapon_systema = ToolDefinition(ObjectClass.aurora_weapon_systema) + + val aurora_weapon_systemb = ToolDefinition(ObjectClass.aurora_weapon_systemb) + + val apc_weapon_systema = ToolDefinition(ObjectClass.apc_weapon_systema) + + val apc_weapon_systemb = ToolDefinition(ObjectClass.apc_weapon_systemb) + + val apc_ballgun_r = ToolDefinition(ObjectClass.apc_ballgun_r) + + val apc_ballgun_l = ToolDefinition(ObjectClass.apc_ballgun_l) + + val apc_weapon_systemc_tr = ToolDefinition(ObjectClass.apc_weapon_systemc_tr) + + val apc_weapon_systemd_tr = ToolDefinition(ObjectClass.apc_weapon_systemd_tr) + + val apc_weapon_systemc_nc = ToolDefinition(ObjectClass.apc_weapon_systemc_nc) + + val apc_weapon_systemd_nc = ToolDefinition(ObjectClass.apc_weapon_systemd_nc) + + val apc_weapon_systemc_vs = ToolDefinition(ObjectClass.apc_weapon_systemc_vs) + + val apc_weapon_systemd_vs = ToolDefinition(ObjectClass.apc_weapon_systemd_vs) + + val lightning_weapon_system = ToolDefinition(ObjectClass.lightning_weapon_system) + + val prowler_weapon_systemA = ToolDefinition(ObjectClass.prowler_weapon_systemA) + + val prowler_weapon_systemB = ToolDefinition(ObjectClass.prowler_weapon_systemB) + + val vanguard_weapon_system = ToolDefinition(ObjectClass.vanguard_weapon_system) + + val particle_beam_magrider = ToolDefinition(ObjectClass.particle_beam_magrider) + + val heavy_rail_beam_magrider = ToolDefinition(ObjectClass.heavy_rail_beam_magrider) + + val flail_weapon = ToolDefinition(ObjectClass.flail_weapon) + + val rotarychaingun_mosquito = ToolDefinition(ObjectClass.rotarychaingun_mosquito) + + val lightgunship_weapon_system = ToolDefinition(ObjectClass.lightgunship_weapon_system) + + val wasp_weapon_system = ToolDefinition(ObjectClass.wasp_weapon_system) + + val liberator_weapon_system = ToolDefinition(ObjectClass.liberator_weapon_system) + + val liberator_bomb_bay = ToolDefinition(ObjectClass.liberator_bomb_bay) + + val liberator_25mm_cannon = ToolDefinition(ObjectClass.liberator_25mm_cannon) + + val vulture_nose_weapon_system = ToolDefinition(ObjectClass.vulture_nose_weapon_system) + + val vulture_bomb_bay = ToolDefinition(ObjectClass.vulture_bomb_bay) + + val vulture_tail_cannon = ToolDefinition(ObjectClass.vulture_tail_cannon) + + val cannon_dropship_20mm = ToolDefinition(ObjectClass.cannon_dropship_20mm) + + val dropship_rear_turret = ToolDefinition(ObjectClass.dropship_rear_turret) + + val galaxy_gunship_cannon = ToolDefinition(ObjectClass.galaxy_gunship_cannon) + + val galaxy_gunship_tailgun = ToolDefinition(ObjectClass.galaxy_gunship_tailgun) + + val galaxy_gunship_gun = ToolDefinition(ObjectClass.galaxy_gunship_gun) + init_tools() + + /* + Vehicles + */ + val fury = VehicleDefinition(ObjectClass.fury) + + val quadassault = VehicleDefinition(ObjectClass.quadassault) + + val quadstealth = VehicleDefinition(ObjectClass.quadstealth) + + val two_man_assault_buggy = VehicleDefinition(ObjectClass.two_man_assault_buggy) + + val skyguard = VehicleDefinition(ObjectClass.skyguard) + + val threemanheavybuggy = VehicleDefinition(ObjectClass.threemanheavybuggy) + + val twomanheavybuggy = VehicleDefinition(ObjectClass.twomanheavybuggy) + + val twomanhoverbuggy = VehicleDefinition(ObjectClass.twomanhoverbuggy) + + val mediumtransport = VehicleDefinition(ObjectClass.mediumtransport) + + val battlewagon = VehicleDefinition(ObjectClass.battlewagon) + + val thunderer = VehicleDefinition(ObjectClass.thunderer) + + val aurora = VehicleDefinition(ObjectClass.aurora) + + val apc_tr = VehicleDefinition(ObjectClass.apc_tr) + + val apc_nc = VehicleDefinition(ObjectClass.apc_nc) + + val apc_vs = VehicleDefinition(ObjectClass.apc_vs) + + val lightning = VehicleDefinition(ObjectClass.lightning) + + val prowler = VehicleDefinition(ObjectClass.prowler) + + val vanguard = VehicleDefinition(ObjectClass.vanguard) + + val magrider = VehicleDefinition(ObjectClass.magrider) + + val ant = VehicleDefinition(ObjectClass.ant) + + val ams = VehicleDefinition(ObjectClass.ams) + + val router = VehicleDefinition(ObjectClass.router) + + val switchblade = VehicleDefinition(ObjectClass.switchblade) + + val flail = VehicleDefinition(ObjectClass.flail) + + val mosquito = VehicleDefinition(ObjectClass.mosquito) + + val lightgunship = VehicleDefinition(ObjectClass.lightgunship) + + val wasp = VehicleDefinition(ObjectClass.wasp) + + val liberator = VehicleDefinition(ObjectClass.liberator) + + val vulture = VehicleDefinition(ObjectClass.vulture) + + val dropship = VehicleDefinition(ObjectClass.dropship) + + val galaxy_gunship = VehicleDefinition(ObjectClass.galaxy_gunship) + + val lodestar = VehicleDefinition(ObjectClass.lodestar) + + val phantasm = VehicleDefinition(ObjectClass.phantasm) + init_vehicles() + + /* + Miscellaneous + */ + val order_terminal = new OrderTerminalDefinition + + val cert_terminal = new CertTerminalDefinition + + val ground_vehicle_terminal = new GroundVehicleTerminalDefinition + + val air_vehicle_terminal = new AirVehicleTerminalDefinition + + val dropship_vehicle_terminal = new DropshipVehicleTerminalDefinition + + val vehicle_terminal_combined = new VehicleTerminalCombinedDefinition + + val spawn_pad = new ObjectDefinition(800) { Name = "spawn_pad" } + + val lock_external = new IFFLockDefinition + + val door = new DoorDefinition + /** * Given a faction, provide the standard assault melee weapon. * @param faction the faction @@ -169,7 +637,7 @@ object GlobalDefinitions { case PlanetSideEmpire.TR => trhev_dualcycler case PlanetSideEmpire.NC => nchev_scattercannon case PlanetSideEmpire.VS => vshev_quasar - case PlanetSideEmpire.NEUTRAL => suppressor //there is no common pool MAX arms + case PlanetSideEmpire.NEUTRAL => suppressor //there are no common pool MAX arms } } @@ -178,7 +646,7 @@ object GlobalDefinitions { case PlanetSideEmpire.TR => trhev_pounder case PlanetSideEmpire.NC => nchev_falcon case PlanetSideEmpire.VS => vshev_comet - case PlanetSideEmpire.NEUTRAL => suppressor //there is no common pool MAX arms + case PlanetSideEmpire.NEUTRAL => suppressor //there are no common pool MAX arms } } @@ -187,7 +655,7 @@ object GlobalDefinitions { case PlanetSideEmpire.TR => trhev_burster case PlanetSideEmpire.NC => nchev_sparrow case PlanetSideEmpire.VS => vshev_starfire - case PlanetSideEmpire.NEUTRAL => suppressor //there is no common pool MAX arms + case PlanetSideEmpire.NEUTRAL => suppressor //there are no common pool MAX arms } } @@ -301,2085 +769,1607 @@ object GlobalDefinitions { } } - /* - Implants - */ - val - advanced_regen = ImplantDefinition(0) + /** + * Initialize `AmmoBoxDefinition` globals. + */ + private def init_ammo() : Unit = { + bullet_9mm.Capacity = 50 + bullet_9mm.Tile = InventoryTile.Tile33 - val - targeting = ImplantDefinition(1) + bullet_9mm_AP.Capacity = 50 + bullet_9mm_AP.Tile = InventoryTile.Tile33 - val - audio_amplifier = ImplantDefinition(2) + shotgun_shell.Capacity = 32 + shotgun_shell.Tile = InventoryTile.Tile33 - val - darklight_vision = ImplantDefinition(3) + shotgun_shell_AP.Capacity = 32 + shotgun_shell_AP.Tile = InventoryTile.Tile33 - val - melee_booster = ImplantDefinition(4) + energy_cell.Capacity = 50 + energy_cell.Tile = InventoryTile.Tile33 - val - personal_shield = ImplantDefinition(5) + anniversary_ammo.Capacity = 30 + anniversary_ammo.Tile = InventoryTile.Tile33 - val - range_magnifier = ImplantDefinition(6) + ancient_ammo_combo.Capacity = 30 + ancient_ammo_combo.Tile = InventoryTile.Tile33 - val - second_wind = ImplantDefinition(7) + maelstrom_ammo.Capacity = 50 + maelstrom_ammo.Tile = InventoryTile.Tile33 - val - silent_run = ImplantDefinition(8) + striker_missile_ammo.Capacity = 15 + striker_missile_ammo.Tile = InventoryTile.Tile44 - val - surge = ImplantDefinition(9) + hunter_seeker_missile.Capacity = 9 + hunter_seeker_missile.Tile = InventoryTile.Tile44 - /* - Equipment (locker_container, kits, ammunition, weapons) - */ - import net.psforever.packet.game.objectcreate.ObjectClass - val - locker_container = new EquipmentDefinition(456) { - Name = "locker container" - Size = EquipmentSize.Inventory - Packet = new LockerContainerConverter() + lancer_cartridge.Capacity = 18 + lancer_cartridge.Tile = InventoryTile.Tile44 + + rocket.Capacity = 15 + rocket.Tile = InventoryTile.Tile33 + + frag_cartridge.Capacity = 12 + frag_cartridge.Tile = InventoryTile.Tile33 + + plasma_cartridge.Capacity = 12 + plasma_cartridge.Tile = InventoryTile.Tile33 + + jammer_cartridge.Capacity = 12 + jammer_cartridge.Tile = InventoryTile.Tile33 + + bolt.Capacity = 10 + bolt.Tile = InventoryTile.Tile33 + + oicw_ammo.Capacity = 10 + oicw_ammo.Tile = InventoryTile.Tile44 + + flamethrower_ammo.Capacity = 100 + flamethrower_ammo.Tile = InventoryTile.Tile44 + + health_canister.Capacity = 100 + health_canister.Tile = InventoryTile.Tile33 + + armor_canister.Capacity = 100 + armor_canister.Tile = InventoryTile.Tile33 + + upgrade_canister.Capacity = 100 + upgrade_canister.Tile = InventoryTile.Tile33 + + bullet_35mm.Capacity = 100 + bullet_35mm.Tile = InventoryTile.Tile44 + + aphelion_laser_ammo.Capacity = 165 + aphelion_laser_ammo.Tile = InventoryTile.Tile44 + + aphelion_immolation_cannon_ammo.Capacity = 100 + aphelion_immolation_cannon_ammo.Tile = InventoryTile.Tile55 + + aphelion_plasma_rocket_ammo.Capacity = 195 + aphelion_plasma_rocket_ammo.Tile = InventoryTile.Tile55 + + aphelion_ppa_ammo.Capacity = 110 + aphelion_ppa_ammo.Tile = InventoryTile.Tile44 + + aphelion_starfire_ammo.Capacity = 132 + aphelion_starfire_ammo.Tile = InventoryTile.Tile44 + + skyguard_flak_cannon_ammo.Capacity = 200 + skyguard_flak_cannon_ammo.Tile = InventoryTile.Tile44 + + firebird_missile.Capacity = 50 + firebird_missile.Tile = InventoryTile.Tile44 + + flux_cannon_thresher_battery.Capacity = 150 + flux_cannon_thresher_battery.Tile = InventoryTile.Tile44 + + fluxpod_ammo.Capacity = 80 + fluxpod_ammo.Tile = InventoryTile.Tile44 + + hellfire_ammo.Capacity = 24 + hellfire_ammo.Tile = InventoryTile.Tile44 + + liberator_bomb.Capacity = 20 + liberator_bomb.Tile = InventoryTile.Tile44 + + bullet_25mm.Capacity = 150 + bullet_25mm.Tile = InventoryTile.Tile44 + + bullet_75mm.Capacity = 100 + bullet_75mm.Tile = InventoryTile.Tile44 + + heavy_grenade_mortar.Capacity = 100 + heavy_grenade_mortar.Tile = InventoryTile.Tile44 + + pulse_battery.Capacity = 100 + pulse_battery.Tile = InventoryTile.Tile44 + + heavy_rail_beam_battery.Capacity = 100 + heavy_rail_beam_battery.Tile = InventoryTile.Tile44 + + reaver_rocket.Capacity = 12 + reaver_rocket.Tile = InventoryTile.Tile44 + + bullet_20mm.Capacity = 200 + bullet_20mm.Tile = InventoryTile.Tile44 + + bullet_12mm.Capacity = 200 + bullet_12mm.Tile = InventoryTile.Tile44 + + wasp_rocket_ammo.Capacity = 6 + wasp_rocket_ammo.Tile = InventoryTile.Tile44 + + wasp_gun_ammo.Capacity = 150 + wasp_gun_ammo.Tile = InventoryTile.Tile44 + + bullet_15mm.Capacity = 360 + bullet_15mm.Tile = InventoryTile.Tile44 + + colossus_100mm_cannon_ammo.Capacity = 90 + colossus_100mm_cannon_ammo.Tile = InventoryTile.Tile55 + + colossus_burster_ammo.Capacity = 235 + colossus_burster_ammo.Tile = InventoryTile.Tile44 + + colossus_cluster_bomb_ammo.Capacity = 150 + colossus_cluster_bomb_ammo.Tile = InventoryTile.Tile55 + + colossus_chaingun_ammo.Capacity = 600 + colossus_chaingun_ammo.Tile = InventoryTile.Tile44 + + colossus_tank_cannon_ammo.Capacity = 110 + colossus_tank_cannon_ammo.Tile = InventoryTile.Tile44 + + bullet_105mm.Capacity = 100 + bullet_105mm.Tile = InventoryTile.Tile44 + + gauss_cannon_ammo.Capacity = 15 + gauss_cannon_ammo.Tile = InventoryTile.Tile44 + + peregrine_dual_machine_gun_ammo.Capacity = 240 + peregrine_dual_machine_gun_ammo.Tile = InventoryTile.Tile44 + + peregrine_mechhammer_ammo.Capacity = 30 + peregrine_mechhammer_ammo.Tile = InventoryTile.Tile44 + + peregrine_particle_cannon_ammo.Capacity = 40 + peregrine_particle_cannon_ammo.Tile = InventoryTile.Tile55 + + peregrine_rocket_pod_ammo.Capacity = 275 + peregrine_rocket_pod_ammo.Tile = InventoryTile.Tile55 + + peregrine_sparrow_ammo.Capacity = 150 + peregrine_sparrow_ammo.Tile = InventoryTile.Tile44 + + bullet_150mm.Capacity = 50 + bullet_150mm.Tile = InventoryTile.Tile44 } - val - medkit = KitDefinition(Kits.medkit) - - val - super_medkit = KitDefinition(Kits.super_medkit) - - val - super_armorkit = KitDefinition(Kits.super_armorkit) - - val - super_staminakit = KitDefinition(Kits.super_staminakit) //super stimpak - - val - melee_ammo = AmmoBoxDefinition(Ammo.melee_ammo) - - val - frag_grenade_ammo = AmmoBoxDefinition(Ammo.frag_grenade_ammo) - - val - plasma_grenade_ammo = AmmoBoxDefinition(Ammo.plasma_grenade_ammo) - - val - jammer_grenade_ammo = AmmoBoxDefinition(Ammo.jammer_grenade_ammo) - - val - bullet_9mm = AmmoBoxDefinition(Ammo.bullet_9mm) - bullet_9mm.Capacity = 50 - bullet_9mm.Tile = InventoryTile.Tile33 - - val - bullet_9mm_AP = AmmoBoxDefinition(Ammo.bullet_9mm_AP) - bullet_9mm_AP.Capacity = 50 - bullet_9mm_AP.Tile = InventoryTile.Tile33 - - val - shotgun_shell = AmmoBoxDefinition(Ammo.shotgun_shell) - shotgun_shell.Capacity = 32 - shotgun_shell.Tile = InventoryTile.Tile33 - - val - shotgun_shell_AP = AmmoBoxDefinition(Ammo.shotgun_shell_AP) - shotgun_shell_AP.Capacity = 32 - shotgun_shell_AP.Tile = InventoryTile.Tile33 - - val - energy_cell = AmmoBoxDefinition(Ammo.energy_cell) - energy_cell.Capacity = 50 - energy_cell.Tile = InventoryTile.Tile33 - - val - anniversary_ammo = AmmoBoxDefinition(Ammo.anniversary_ammo) //10mm multi-phase - anniversary_ammo.Capacity = 30 - anniversary_ammo.Tile = InventoryTile.Tile33 - - val - ancient_ammo_combo = AmmoBoxDefinition(Ammo.ancient_ammo_combo) - ancient_ammo_combo.Capacity = 30 - ancient_ammo_combo.Tile = InventoryTile.Tile33 - - val - maelstrom_ammo = AmmoBoxDefinition(Ammo.maelstrom_ammo) - maelstrom_ammo.Capacity = 50 - maelstrom_ammo.Tile = InventoryTile.Tile33 - - val - phoenix_missile = AmmoBoxDefinition(Ammo.phoenix_missile) //decimator missile - - val - striker_missile_ammo = AmmoBoxDefinition(Ammo.striker_missile_ammo) - striker_missile_ammo.Capacity = 15 - striker_missile_ammo.Tile = InventoryTile.Tile44 - - val - hunter_seeker_missile = AmmoBoxDefinition(Ammo.hunter_seeker_missile) //phoenix missile - hunter_seeker_missile.Capacity = 9 - hunter_seeker_missile.Tile = InventoryTile.Tile44 - - val - lancer_cartridge = AmmoBoxDefinition(Ammo.lancer_cartridge) - lancer_cartridge.Capacity = 18 - lancer_cartridge.Tile = InventoryTile.Tile44 - - val - rocket = AmmoBoxDefinition(Ammo.rocket) - rocket.Capacity = 15 - rocket.Tile = InventoryTile.Tile33 - - val - frag_cartridge = AmmoBoxDefinition(Ammo.frag_cartridge) - frag_cartridge.Capacity = 12 - frag_cartridge.Tile = InventoryTile.Tile33 - - val - plasma_cartridge = AmmoBoxDefinition(Ammo.plasma_cartridge) - plasma_cartridge.Capacity = 12 - plasma_cartridge.Tile = InventoryTile.Tile33 - - val - jammer_cartridge = AmmoBoxDefinition(Ammo.jammer_cartridge) - jammer_cartridge.Capacity = 12 - jammer_cartridge.Tile = InventoryTile.Tile33 - - val - bolt = AmmoBoxDefinition(Ammo.bolt) - bolt.Capacity = 10 - bolt.Tile = InventoryTile.Tile33 - - val - oicw_ammo = AmmoBoxDefinition(Ammo.oicw_ammo) //scorpion missile - oicw_ammo.Capacity = 10 - oicw_ammo.Tile = InventoryTile.Tile44 - - val - flamethrower_ammo = AmmoBoxDefinition(Ammo.flamethrower_ammo) - flamethrower_ammo.Capacity = 100 - flamethrower_ammo.Tile = InventoryTile.Tile44 - - val - health_canister = AmmoBoxDefinition(Ammo.health_canister) - health_canister.Capacity = 100 - health_canister.Tile = InventoryTile.Tile33 - - val - armor_canister = AmmoBoxDefinition(Ammo.armor_canister) - armor_canister.Capacity = 100 - armor_canister.Tile = InventoryTile.Tile33 - - val - upgrade_canister = AmmoBoxDefinition(Ammo.upgrade_canister) - upgrade_canister.Capacity = 100 - upgrade_canister.Tile = InventoryTile.Tile33 - - val - trek_ammo = AmmoBoxDefinition(Ammo.trek_ammo) -// - val - bullet_35mm = AmmoBoxDefinition(Ammo.bullet_35mm) //liberator nosegun - bullet_35mm.Capacity = 100 - bullet_35mm.Tile = InventoryTile.Tile44 - - val ancient_ammo_vehicle = AmmoBoxDefinition(Ammo.ancient_ammo_vehicle) -// - - val - aphelion_laser_ammo = AmmoBoxDefinition(Ammo.aphelion_laser_ammo) - aphelion_laser_ammo.Capacity = 165 - aphelion_laser_ammo.Tile = InventoryTile.Tile44 - - val - aphelion_immolation_cannon_ammo = AmmoBoxDefinition(Ammo.aphelion_immolation_cannon_ammo) - aphelion_immolation_cannon_ammo.Capacity = 100 - aphelion_immolation_cannon_ammo.Tile = InventoryTile.Tile55 - - val - aphelion_plasma_rocket_ammo = AmmoBoxDefinition(Ammo.aphelion_plasma_rocket_ammo) - aphelion_plasma_rocket_ammo.Capacity = 195 - aphelion_plasma_rocket_ammo.Tile = InventoryTile.Tile55 - - val - aphelion_ppa_ammo = AmmoBoxDefinition(Ammo.aphelion_ppa_ammo) - aphelion_ppa_ammo.Capacity = 110 - aphelion_ppa_ammo.Tile = InventoryTile.Tile44 - - val - aphelion_starfire_ammo = AmmoBoxDefinition(Ammo.aphelion_starfire_ammo) - aphelion_starfire_ammo.Capacity = 132 - aphelion_starfire_ammo.Tile = InventoryTile.Tile44 - - val - skyguard_flak_cannon_ammo = AmmoBoxDefinition(Ammo.skyguard_flak_cannon_ammo) - skyguard_flak_cannon_ammo.Capacity = 200 - skyguard_flak_cannon_ammo.Tile = InventoryTile.Tile44 - - val - firebird_missile = AmmoBoxDefinition(ObjectClass.firebird_missile) - firebird_missile.Capacity = 50 - firebird_missile.Tile = InventoryTile.Tile44 - - val - flux_cannon_thresher_battery = AmmoBoxDefinition(Ammo.flux_cannon_thresher_battery) - flux_cannon_thresher_battery.Capacity = 150 - flux_cannon_thresher_battery.Tile = InventoryTile.Tile44 - - val - fluxpod_ammo = AmmoBoxDefinition(Ammo.fluxpod_ammo) - fluxpod_ammo.Capacity = 80 - fluxpod_ammo.Tile = InventoryTile.Tile44 - - val - hellfire_ammo = AmmoBoxDefinition(Ammo.hellfire_ammo) - hellfire_ammo.Capacity = 24 - hellfire_ammo.Tile = InventoryTile.Tile44 - - val - liberator_bomb = AmmoBoxDefinition(Ammo.liberator_bomb) - liberator_bomb.Capacity = 20 - liberator_bomb.Tile = InventoryTile.Tile44 - - val - bullet_25mm = AmmoBoxDefinition(Ammo.bullet_25mm) //liberator tailgun - bullet_25mm.Capacity = 150 - bullet_25mm.Tile = InventoryTile.Tile44 - - val - bullet_75mm = AmmoBoxDefinition(Ammo.bullet_75mm) //lightning shell - bullet_75mm.Capacity = 100 - bullet_75mm.Tile = InventoryTile.Tile44 - - val - heavy_grenade_mortar = AmmoBoxDefinition(Ammo.heavy_grenade_mortar) //marauder and gal gunship - heavy_grenade_mortar.Capacity = 100 - heavy_grenade_mortar.Tile = InventoryTile.Tile44 - - val - pulse_battery = AmmoBoxDefinition(Ammo.pulse_battery) - pulse_battery.Capacity = 100 - pulse_battery.Tile = InventoryTile.Tile44 - - val - heavy_rail_beam_battery = AmmoBoxDefinition(Ammo.heavy_rail_beam_battery) - heavy_rail_beam_battery.Capacity = 100 - heavy_rail_beam_battery.Tile = InventoryTile.Tile44 - - val - reaver_rocket = AmmoBoxDefinition(Ammo.reaver_rocket) - reaver_rocket.Capacity = 12 - reaver_rocket.Tile = InventoryTile.Tile44 - - val - bullet_20mm = AmmoBoxDefinition(Ammo.bullet_20mm) //reaver nosegun - bullet_20mm.Capacity = 200 - bullet_20mm.Tile = InventoryTile.Tile44 - - val - bullet_12mm = AmmoBoxDefinition(Ammo.bullet_12mm) //common - bullet_12mm.Capacity = 200 - bullet_12mm.Tile = InventoryTile.Tile44 - - val - wasp_rocket_ammo = AmmoBoxDefinition(Ammo.wasp_rocket_ammo) - wasp_rocket_ammo.Capacity = 6 - wasp_rocket_ammo.Tile = InventoryTile.Tile44 - - val - wasp_gun_ammo = AmmoBoxDefinition(Ammo.wasp_gun_ammo) //wasp nosegun - wasp_gun_ammo.Capacity = 150 - wasp_gun_ammo.Tile = InventoryTile.Tile44 - - val - bullet_15mm = AmmoBoxDefinition(Ammo.bullet_15mm) - bullet_15mm.Capacity = 360 - bullet_15mm.Tile = InventoryTile.Tile44 - - val - colossus_100mm_cannon_ammo = AmmoBoxDefinition(Ammo.colossus_100mm_cannon_ammo) - colossus_100mm_cannon_ammo.Capacity = 90 - colossus_100mm_cannon_ammo.Tile = InventoryTile.Tile55 - - val - colossus_burster_ammo = AmmoBoxDefinition(Ammo.colossus_burster_ammo) - colossus_burster_ammo.Capacity = 235 - colossus_burster_ammo.Tile = InventoryTile.Tile44 - - val - colossus_cluster_bomb_ammo = AmmoBoxDefinition(Ammo.colossus_cluster_bomb_ammo) //colossus mortar launcher shells - colossus_cluster_bomb_ammo.Capacity = 150 - colossus_cluster_bomb_ammo.Tile = InventoryTile.Tile55 - - val - colossus_chaingun_ammo = AmmoBoxDefinition(Ammo.colossus_chaingun_ammo) - colossus_chaingun_ammo.Capacity = 600 - colossus_chaingun_ammo.Tile = InventoryTile.Tile44 - - val - colossus_tank_cannon_ammo = AmmoBoxDefinition(Ammo.colossus_tank_cannon_ammo) - colossus_tank_cannon_ammo.Capacity = 110 - colossus_tank_cannon_ammo.Tile = InventoryTile.Tile44 - - val - bullet_105mm = AmmoBoxDefinition(Ammo.bullet_105mm) //prowler 100mm cannon shell - bullet_105mm.Capacity = 100 - bullet_105mm.Tile = InventoryTile.Tile44 - - val - gauss_cannon_ammo = AmmoBoxDefinition(Ammo.gauss_cannon_ammo) - gauss_cannon_ammo.Capacity = 15 - gauss_cannon_ammo.Tile = InventoryTile.Tile44 - - val - peregrine_dual_machine_gun_ammo = AmmoBoxDefinition(Ammo.peregrine_dual_machine_gun_ammo) - peregrine_dual_machine_gun_ammo.Capacity = 240 - peregrine_dual_machine_gun_ammo.Tile = InventoryTile.Tile44 - - val - peregrine_mechhammer_ammo = AmmoBoxDefinition(Ammo.peregrine_mechhammer_ammo) - peregrine_mechhammer_ammo.Capacity = 30 - peregrine_mechhammer_ammo.Tile = InventoryTile.Tile44 - - val - peregrine_particle_cannon_ammo = AmmoBoxDefinition(Ammo.peregrine_particle_cannon_ammo) - peregrine_particle_cannon_ammo.Capacity = 40 - peregrine_particle_cannon_ammo.Tile = InventoryTile.Tile55 - - val - peregrine_rocket_pod_ammo = AmmoBoxDefinition(Ammo.peregrine_rocket_pod_ammo) - peregrine_rocket_pod_ammo.Capacity = 275 - peregrine_rocket_pod_ammo.Tile = InventoryTile.Tile55 - - val - peregrine_sparrow_ammo = AmmoBoxDefinition(Ammo.peregrine_sparrow_ammo) - peregrine_sparrow_ammo.Capacity = 150 - peregrine_sparrow_ammo.Tile = InventoryTile.Tile44 - - val - bullet_150mm = AmmoBoxDefinition(Ammo.bullet_150mm) - bullet_150mm.Capacity = 50 - bullet_150mm.Tile = InventoryTile.Tile44 - - val - chainblade = ToolDefinition(ObjectClass.chainblade) - chainblade.Size = EquipmentSize.Melee - chainblade.AmmoTypes += melee_ammo - chainblade.FireModes += new FireModeDefinition - chainblade.FireModes.head.AmmoTypeIndices += 0 - chainblade.FireModes.head.AmmoSlotIndex = 0 - chainblade.FireModes.head.Magazine = 1 - chainblade.FireModes += new FireModeDefinition - chainblade.FireModes(1).AmmoTypeIndices += 0 - chainblade.FireModes(1).AmmoSlotIndex = 0 - chainblade.FireModes(1).Magazine = 1 - - val - magcutter = ToolDefinition(ObjectClass.magcutter) - magcutter.Size = EquipmentSize.Melee - magcutter.AmmoTypes += melee_ammo - magcutter.FireModes += new FireModeDefinition - magcutter.FireModes.head.AmmoTypeIndices += 0 - magcutter.FireModes.head.AmmoSlotIndex = 0 - magcutter.FireModes.head.Magazine = 1 - magcutter.FireModes += new FireModeDefinition - magcutter.FireModes(1).AmmoTypeIndices += 0 - magcutter.FireModes(1).AmmoSlotIndex = 0 - magcutter.FireModes(1).Magazine = 1 - - val - forceblade = ToolDefinition(ObjectClass.forceblade) - forceblade.Size = EquipmentSize.Melee - forceblade.AmmoTypes += melee_ammo - forceblade.FireModes += new FireModeDefinition - forceblade.FireModes.head.AmmoTypeIndices += 0 - forceblade.FireModes.head.AmmoSlotIndex = 0 - forceblade.FireModes.head.Magazine = 1 - forceblade.FireModes.head.Chamber = 0 - forceblade.FireModes += new FireModeDefinition - forceblade.FireModes(1).AmmoTypeIndices += 0 - forceblade.FireModes(1).AmmoSlotIndex = 0 - forceblade.FireModes(1).Magazine = 1 - forceblade.FireModes(1).Chamber = 0 - - val - katana = ToolDefinition(ObjectClass.katana) - katana.Size = EquipmentSize.Melee - katana.AmmoTypes += melee_ammo - katana.FireModes += new FireModeDefinition - katana.FireModes.head.AmmoTypeIndices += 0 - katana.FireModes.head.AmmoSlotIndex = 0 - katana.FireModes.head.Magazine = 1 - katana.FireModes.head.Chamber = 0 - katana.FireModes += new FireModeDefinition - katana.FireModes(1).AmmoTypeIndices += 0 - katana.FireModes(1).AmmoSlotIndex = 0 - katana.FireModes(1).Magazine = 1 - katana.FireModes(1).Chamber = 0 - - val - frag_grenade = ToolDefinition(ObjectClass.frag_grenade) - frag_grenade.Size = EquipmentSize.Pistol - frag_grenade.AmmoTypes += frag_grenade_ammo - frag_grenade.FireModes += new FireModeDefinition - frag_grenade.FireModes.head.AmmoTypeIndices += 0 - frag_grenade.FireModes.head.AmmoSlotIndex = 0 - frag_grenade.FireModes.head.Magazine = 3 - frag_grenade.FireModes += new FireModeDefinition - frag_grenade.FireModes(1).AmmoTypeIndices += 0 - frag_grenade.FireModes(1).AmmoSlotIndex = 0 - frag_grenade.FireModes(1).Magazine = 3 - frag_grenade.Tile = InventoryTile.Tile22 - - val - plasma_grenade = ToolDefinition(ObjectClass.plasma_grenade) - plasma_grenade.Size = EquipmentSize.Pistol - plasma_grenade.AmmoTypes += plasma_grenade_ammo - plasma_grenade.FireModes += new FireModeDefinition - plasma_grenade.FireModes.head.AmmoTypeIndices += 0 - plasma_grenade.FireModes.head.AmmoSlotIndex = 0 - plasma_grenade.FireModes.head.Magazine = 3 - plasma_grenade.FireModes += new FireModeDefinition - plasma_grenade.FireModes(1).AmmoTypeIndices += 0 - plasma_grenade.FireModes(1).AmmoSlotIndex = 0 - plasma_grenade.FireModes(1).Magazine = 3 - plasma_grenade.Tile = InventoryTile.Tile22 - - val - jammer_grenade = ToolDefinition(ObjectClass.jammer_grenade) - jammer_grenade.Size = EquipmentSize.Pistol - jammer_grenade.AmmoTypes += jammer_grenade_ammo - jammer_grenade.FireModes += new FireModeDefinition - jammer_grenade.FireModes.head.AmmoTypeIndices += 0 - jammer_grenade.FireModes.head.AmmoSlotIndex = 0 - jammer_grenade.FireModes.head.Magazine = 3 - jammer_grenade.FireModes += new FireModeDefinition - jammer_grenade.FireModes(1).AmmoTypeIndices += 0 - jammer_grenade.FireModes(1).AmmoSlotIndex = 0 - jammer_grenade.FireModes(1).Magazine = 3 - jammer_grenade.Tile = InventoryTile.Tile22 - - val - repeater = ToolDefinition(ObjectClass.repeater) - repeater.Size = EquipmentSize.Pistol - repeater.AmmoTypes += bullet_9mm - repeater.AmmoTypes += bullet_9mm_AP - repeater.FireModes += new FireModeDefinition - repeater.FireModes.head.AmmoTypeIndices += 0 - repeater.FireModes.head.AmmoTypeIndices += 1 - repeater.FireModes.head.AmmoSlotIndex = 0 - repeater.FireModes.head.Magazine = 20 - repeater.Tile = InventoryTile.Tile33 - - val - isp = ToolDefinition(ObjectClass.isp) //mag-scatter - isp.Size = EquipmentSize.Pistol - isp.AmmoTypes += shotgun_shell - isp.AmmoTypes += shotgun_shell_AP - isp.FireModes += new FireModeDefinition - isp.FireModes.head.AmmoTypeIndices += 0 - isp.FireModes.head.AmmoTypeIndices += 1 - isp.FireModes.head.AmmoSlotIndex = 0 - isp.FireModes.head.Magazine = 8 - isp.Tile = InventoryTile.Tile33 - - val - beamer = ToolDefinition(ObjectClass.beamer) - beamer.Size = EquipmentSize.Pistol - beamer.AmmoTypes += energy_cell - beamer.FireModes += new FireModeDefinition - beamer.FireModes.head.AmmoTypeIndices += 0 - beamer.FireModes.head.AmmoSlotIndex = 0 - beamer.FireModes.head.Magazine = 16 - beamer.FireModes += new FireModeDefinition - beamer.FireModes(1).AmmoTypeIndices += 0 - beamer.FireModes(1).AmmoSlotIndex = 0 - beamer.FireModes(1).Magazine = 16 - beamer.Tile = InventoryTile.Tile33 - - val - ilc9 = ToolDefinition(ObjectClass.ilc9) //amp - ilc9.Size = EquipmentSize.Pistol - ilc9.AmmoTypes += bullet_9mm - ilc9.AmmoTypes += bullet_9mm_AP - ilc9.FireModes += new FireModeDefinition - ilc9.FireModes.head.AmmoTypeIndices += 0 - ilc9.FireModes.head.AmmoTypeIndices += 1 - ilc9.FireModes.head.AmmoSlotIndex = 0 - ilc9.FireModes.head.Magazine = 30 - ilc9.Tile = InventoryTile.Tile33 - - val - suppressor = ToolDefinition(ObjectClass.suppressor) - suppressor.Size = EquipmentSize.Rifle - suppressor.AmmoTypes += bullet_9mm - suppressor.AmmoTypes += bullet_9mm_AP - suppressor.FireModes += new FireModeDefinition - suppressor.FireModes.head.AmmoTypeIndices += 0 - suppressor.FireModes.head.AmmoTypeIndices += 1 - suppressor.FireModes.head.AmmoSlotIndex = 0 - suppressor.FireModes.head.Magazine = 25 - suppressor.Tile = InventoryTile.Tile63 - - val - punisher = ToolDefinition(ObjectClass.punisher) - punisher.Size = EquipmentSize.Rifle - punisher.AmmoTypes += bullet_9mm - punisher.AmmoTypes += bullet_9mm_AP - punisher.AmmoTypes += rocket - punisher.AmmoTypes += frag_cartridge - punisher.AmmoTypes += jammer_cartridge - punisher.AmmoTypes += plasma_cartridge - punisher.FireModes += new FireModeDefinition - punisher.FireModes.head.AmmoTypeIndices += 0 - punisher.FireModes.head.AmmoTypeIndices += 1 - punisher.FireModes.head.AmmoSlotIndex = 0 - punisher.FireModes.head.Magazine = 30 - punisher.FireModes += new FireModeDefinition - punisher.FireModes(1).AmmoTypeIndices += 2 - punisher.FireModes(1).AmmoTypeIndices += 3 - punisher.FireModes(1).AmmoTypeIndices += 4 - punisher.FireModes(1).AmmoTypeIndices += 5 - punisher.FireModes(1).AmmoSlotIndex = 1 - punisher.FireModes(1).Magazine = 1 - punisher.Tile = InventoryTile.Tile63 - - val - flechette = ToolDefinition(ObjectClass.flechette) //sweeper - flechette.Size = EquipmentSize.Rifle - flechette.AmmoTypes += shotgun_shell - flechette.AmmoTypes += shotgun_shell_AP - flechette.FireModes += new FireModeDefinition - flechette.FireModes.head.AmmoTypeIndices += 0 - flechette.FireModes.head.AmmoTypeIndices += 1 - flechette.FireModes.head.AmmoSlotIndex = 0 - flechette.FireModes.head.Magazine = 12 //12 shells * 8 pellets = 96 - flechette.Tile = InventoryTile.Tile63 - - val - cycler = ToolDefinition(ObjectClass.cycler) - cycler.Size = EquipmentSize.Rifle - cycler.AmmoTypes += bullet_9mm - cycler.AmmoTypes += bullet_9mm_AP - cycler.FireModes += new FireModeDefinition - cycler.FireModes.head.AmmoTypeIndices += 0 - cycler.FireModes.head.AmmoTypeIndices += 1 - cycler.FireModes.head.AmmoSlotIndex = 0 - cycler.FireModes.head.Magazine = 50 - cycler.Tile = InventoryTile.Tile63 - - val - gauss = ToolDefinition(ObjectClass.gauss) - gauss.Size = EquipmentSize.Rifle - gauss.AmmoTypes += bullet_9mm - gauss.AmmoTypes += bullet_9mm_AP - gauss.FireModes += new FireModeDefinition - gauss.FireModes.head.AmmoTypeIndices += 0 - gauss.FireModes.head.AmmoTypeIndices += 1 - gauss.FireModes.head.AmmoSlotIndex = 0 - gauss.FireModes.head.Magazine = 30 - gauss.Tile = InventoryTile.Tile63 - - val - pulsar = ToolDefinition(ObjectClass.pulsar) - pulsar.Size = EquipmentSize.Rifle - pulsar.AmmoTypes += energy_cell - pulsar.FireModes += new FireModeDefinition - pulsar.FireModes.head.AmmoTypeIndices += 0 - pulsar.FireModes.head.AmmoSlotIndex = 0 - pulsar.FireModes.head.Magazine = 40 - pulsar.FireModes += new FireModeDefinition - pulsar.FireModes(1).AmmoTypeIndices += 0 - pulsar.FireModes(1).AmmoSlotIndex = 0 - pulsar.FireModes(1).Magazine = 40 - pulsar.Tile = InventoryTile.Tile63 - - val - anniversary_guna = ToolDefinition(ObjectClass.anniversary_guna) //tr stinger - anniversary_guna.Size = EquipmentSize.Pistol - anniversary_guna.AmmoTypes += anniversary_ammo - anniversary_guna.FireModes += new FireModeDefinition - anniversary_guna.FireModes.head.AmmoTypeIndices += 0 - anniversary_guna.FireModes.head.AmmoSlotIndex = 0 - anniversary_guna.FireModes.head.Magazine = 6 - anniversary_guna.FireModes += new FireModeDefinition - anniversary_guna.FireModes(1).AmmoTypeIndices += 0 - anniversary_guna.FireModes(1).AmmoSlotIndex = 0 - anniversary_guna.FireModes(1).Magazine = 6 - anniversary_guna.FireModes(1).Chamber = 6 - anniversary_guna.Tile = InventoryTile.Tile33 - - val - anniversary_gun = ToolDefinition(ObjectClass.anniversary_gun) //nc spear - anniversary_gun.Size = EquipmentSize.Pistol - anniversary_gun.AmmoTypes += anniversary_ammo - anniversary_gun.FireModes += new FireModeDefinition - anniversary_gun.FireModes.head.AmmoTypeIndices += 0 - anniversary_gun.FireModes.head.AmmoSlotIndex = 0 - anniversary_gun.FireModes.head.Magazine = 6 - anniversary_gun.FireModes += new FireModeDefinition - anniversary_gun.FireModes(1).AmmoTypeIndices += 0 - anniversary_gun.FireModes(1).AmmoSlotIndex = 0 - anniversary_gun.FireModes(1).Magazine = 6 - anniversary_gun.FireModes(1).Chamber = 6 - anniversary_gun.Tile = InventoryTile.Tile33 - - val - anniversary_gunb = ToolDefinition(ObjectClass.anniversary_gunb) //vs eraser - anniversary_gunb.Size = EquipmentSize.Pistol - anniversary_gunb.AmmoTypes += anniversary_ammo - anniversary_gunb.FireModes += new FireModeDefinition - anniversary_gunb.FireModes.head.AmmoTypeIndices += 0 - anniversary_gunb.FireModes.head.AmmoSlotIndex = 0 - anniversary_gunb.FireModes.head.Magazine = 6 - anniversary_gunb.FireModes += new FireModeDefinition - anniversary_gunb.FireModes(1).AmmoTypeIndices += 0 - anniversary_gunb.FireModes(1).AmmoSlotIndex = 0 - anniversary_gunb.FireModes(1).Magazine = 6 - anniversary_gunb.FireModes(1).Chamber = 6 - anniversary_gunb.Tile = InventoryTile.Tile33 - - val - spiker = ToolDefinition(ObjectClass.spiker) - spiker.Size = EquipmentSize.Pistol - spiker.AmmoTypes += ancient_ammo_combo - spiker.FireModes += new FireModeDefinition - spiker.FireModes.head.AmmoTypeIndices += 0 - spiker.FireModes.head.AmmoSlotIndex = 0 - spiker.FireModes.head.Magazine = 25 - spiker.Tile = InventoryTile.Tile33 - - val - mini_chaingun = ToolDefinition(ObjectClass.mini_chaingun) - mini_chaingun.Size = EquipmentSize.Rifle - mini_chaingun.AmmoTypes += bullet_9mm - mini_chaingun.AmmoTypes += bullet_9mm_AP - mini_chaingun.FireModes += new FireModeDefinition - mini_chaingun.FireModes.head.AmmoTypeIndices += 0 - mini_chaingun.FireModes.head.AmmoTypeIndices += 1 - mini_chaingun.FireModes.head.AmmoSlotIndex = 0 - mini_chaingun.FireModes.head.Magazine = 100 - mini_chaingun.Tile = InventoryTile.Tile93 - - val - r_shotgun = ToolDefinition(ObjectClass.r_shotgun) //jackhammer - r_shotgun.Size = EquipmentSize.Rifle - r_shotgun.AmmoTypes += shotgun_shell - r_shotgun.AmmoTypes += shotgun_shell_AP - r_shotgun.FireModes += new FireModeDefinition - r_shotgun.FireModes.head.AmmoTypeIndices += 0 - r_shotgun.FireModes.head.AmmoTypeIndices += 1 - r_shotgun.FireModes.head.AmmoSlotIndex = 0 - r_shotgun.FireModes.head.Magazine = 16 //16 shells * 8 pellets = 128 - r_shotgun.FireModes += new FireModeDefinition - r_shotgun.FireModes(1).AmmoTypeIndices += 0 - r_shotgun.FireModes(1).AmmoTypeIndices += 1 - r_shotgun.FireModes(1).AmmoSlotIndex = 0 - r_shotgun.FireModes(1).Magazine = 16 //16 shells * 8 pellets = 128 - r_shotgun.FireModes(1).Chamber = 3 - r_shotgun.Tile = InventoryTile.Tile93 - - val - lasher = ToolDefinition(ObjectClass.lasher) - lasher.Size = EquipmentSize.Rifle - lasher.AmmoTypes += energy_cell - lasher.FireModes += new FireModeDefinition - lasher.FireModes.head.AmmoTypeIndices += 0 - lasher.FireModes.head.AmmoSlotIndex = 0 - lasher.FireModes.head.Magazine = 35 - lasher.FireModes += new FireModeDefinition - lasher.FireModes(1).AmmoTypeIndices += 0 - lasher.FireModes(1).AmmoSlotIndex = 0 - lasher.FireModes(1).Magazine = 35 - lasher.Tile = InventoryTile.Tile93 - - val - maelstrom = ToolDefinition(ObjectClass.maelstrom) - maelstrom.Size = EquipmentSize.Rifle - maelstrom.AmmoTypes += maelstrom_ammo - maelstrom.FireModes += new FireModeDefinition - maelstrom.FireModes.head.AmmoTypeIndices += 0 - maelstrom.FireModes.head.AmmoSlotIndex = 0 - maelstrom.FireModes.head.Magazine = 150 - maelstrom.FireModes += new FireModeDefinition - maelstrom.FireModes(1).AmmoTypeIndices += 0 - maelstrom.FireModes(1).AmmoSlotIndex = 0 - maelstrom.FireModes(1).Magazine = 150 - maelstrom.FireModes += new FireModeDefinition - maelstrom.FireModes(2).AmmoTypeIndices += 0 - maelstrom.FireModes(2).AmmoSlotIndex = 0 - maelstrom.FireModes(2).Magazine = 150 - maelstrom.Tile = InventoryTile.Tile93 - - val - phoenix = ToolDefinition(ObjectClass.phoenix) //decimator - phoenix.Size = EquipmentSize.Rifle - phoenix.AmmoTypes += phoenix_missile - phoenix.FireModes += new FireModeDefinition - phoenix.FireModes.head.AmmoTypeIndices += 0 - phoenix.FireModes.head.AmmoSlotIndex = 0 - phoenix.FireModes.head.Magazine = 3 - phoenix.FireModes += new FireModeDefinition - phoenix.FireModes(1).AmmoTypeIndices += 0 - phoenix.FireModes(1).AmmoSlotIndex = 0 - phoenix.FireModes(1).Magazine = 3 - phoenix.Tile = InventoryTile.Tile93 - - val - striker = ToolDefinition(ObjectClass.striker) - striker.Size = EquipmentSize.Rifle - striker.AmmoTypes += striker_missile_ammo - striker.FireModes += new FireModeDefinition - striker.FireModes.head.AmmoTypeIndices += 0 - striker.FireModes.head.AmmoSlotIndex = 0 - striker.FireModes.head.Magazine = 5 - striker.FireModes += new FireModeDefinition - striker.FireModes(1).AmmoTypeIndices += 0 - striker.FireModes(1).AmmoSlotIndex = 0 - striker.FireModes(1).Magazine = 5 - striker.Tile = InventoryTile.Tile93 - - val - hunterseeker = ToolDefinition(ObjectClass.hunterseeker) //phoenix - hunterseeker.Size = EquipmentSize.Rifle - hunterseeker.AmmoTypes += hunter_seeker_missile - hunterseeker.FireModes += new FireModeDefinition - hunterseeker.FireModes.head.AmmoTypeIndices += 0 - hunterseeker.FireModes.head.AmmoSlotIndex = 0 - hunterseeker.FireModes.head.Magazine = 1 - hunterseeker.FireModes += new FireModeDefinition - hunterseeker.FireModes(1).AmmoTypeIndices += 0 - hunterseeker.FireModes(1).AmmoSlotIndex = 0 - hunterseeker.FireModes(1).Magazine = 1 - hunterseeker.Tile = InventoryTile.Tile93 - - val - lancer = ToolDefinition(ObjectClass.lancer) - lancer.Size = EquipmentSize.Rifle - lancer.AmmoTypes += lancer_cartridge - lancer.FireModes += new FireModeDefinition - lancer.FireModes.head.AmmoTypeIndices += 0 - lancer.FireModes.head.AmmoSlotIndex = 0 - lancer.FireModes.head.Magazine = 6 - lancer.Tile = InventoryTile.Tile93 - - val - rocklet = ToolDefinition(ObjectClass.rocklet) - rocklet.Size = EquipmentSize.Rifle - rocklet.AmmoTypes += rocket - rocklet.AmmoTypes += frag_cartridge - rocklet.FireModes += new FireModeDefinition - rocklet.FireModes.head.AmmoTypeIndices += 0 - rocklet.FireModes.head.AmmoTypeIndices += 1 - rocklet.FireModes.head.AmmoSlotIndex = 0 - rocklet.FireModes.head.Magazine = 6 - rocklet.FireModes += new FireModeDefinition - rocklet.FireModes(1).AmmoTypeIndices += 0 - rocklet.FireModes(1).AmmoTypeIndices += 1 - rocklet.FireModes(1).AmmoSlotIndex = 0 - rocklet.FireModes(1).Magazine = 6 - rocklet.FireModes(1).Chamber = 6 - rocklet.Tile = InventoryTile.Tile63 - - val - thumper = ToolDefinition(ObjectClass.thumper) - thumper.Size = EquipmentSize.Rifle - thumper.AmmoTypes += frag_cartridge - thumper.AmmoTypes += plasma_cartridge - thumper.AmmoTypes += jammer_cartridge - thumper.FireModes += new FireModeDefinition - thumper.FireModes.head.AmmoTypeIndices += 0 - thumper.FireModes.head.AmmoTypeIndices += 1 - thumper.FireModes.head.AmmoTypeIndices += 2 - thumper.FireModes.head.AmmoSlotIndex = 0 - thumper.FireModes.head.Magazine = 6 - thumper.FireModes += new FireModeDefinition - thumper.FireModes(1).AmmoTypeIndices += 0 - thumper.FireModes(1).AmmoTypeIndices += 1 - thumper.FireModes(1).AmmoTypeIndices += 2 - thumper.FireModes(1).AmmoSlotIndex = 0 - thumper.FireModes(1).Magazine = 6 - thumper.Tile = InventoryTile.Tile63 - - val - radiator = ToolDefinition(ObjectClass.radiator) - radiator.Size = EquipmentSize.Rifle - radiator.AmmoTypes += ancient_ammo_combo - radiator.FireModes += new FireModeDefinition - radiator.FireModes.head.AmmoTypeIndices += 0 - radiator.FireModes.head.AmmoSlotIndex = 0 - radiator.FireModes.head.Magazine = 25 - radiator.FireModes += new FireModeDefinition - radiator.FireModes(1).AmmoTypeIndices += 0 - radiator.FireModes(1).AmmoSlotIndex = 0 - radiator.FireModes(1).Magazine = 25 - radiator.Tile = InventoryTile.Tile63 - - val - heavy_sniper = ToolDefinition(ObjectClass.heavy_sniper) //hsr - heavy_sniper.Size = EquipmentSize.Rifle - heavy_sniper.AmmoTypes += bolt - heavy_sniper.FireModes += new FireModeDefinition - heavy_sniper.FireModes.head.AmmoTypeIndices += 0 - heavy_sniper.FireModes.head.AmmoSlotIndex = 0 - heavy_sniper.FireModes.head.Magazine = 10 - heavy_sniper.Tile = InventoryTile.Tile93 - - val - bolt_driver = ToolDefinition(ObjectClass.bolt_driver) - bolt_driver.Size = EquipmentSize.Rifle - bolt_driver.AmmoTypes += bolt - bolt_driver.FireModes += new FireModeDefinition - bolt_driver.FireModes.head.AmmoTypeIndices += 0 - bolt_driver.FireModes.head.AmmoSlotIndex = 0 - bolt_driver.FireModes.head.Magazine = 1 - bolt_driver.Tile = InventoryTile.Tile93 - - val - oicw = ToolDefinition(ObjectClass.oicw) //scorpion - oicw.Size = EquipmentSize.Rifle - oicw.AmmoTypes += oicw_ammo - oicw.FireModes += new FireModeDefinition - oicw.FireModes.head.AmmoTypeIndices += 0 - oicw.FireModes.head.AmmoSlotIndex = 0 - oicw.FireModes.head.Magazine = 1 - oicw.FireModes += new FireModeDefinition - oicw.FireModes(1).AmmoTypeIndices += 0 - oicw.FireModes(1).AmmoSlotIndex = 0 - oicw.FireModes(1).Magazine = 1 - oicw.Tile = InventoryTile.Tile93 - - val - flamethrower = ToolDefinition(ObjectClass.flamethrower) - flamethrower.Size = EquipmentSize.Rifle - flamethrower.AmmoTypes += flamethrower_ammo - flamethrower.FireModes += new FireModeDefinition - flamethrower.FireModes.head.AmmoTypeIndices += 0 - flamethrower.FireModes.head.AmmoSlotIndex = 0 - flamethrower.FireModes.head.Magazine = 100 - flamethrower.FireModes.head.Chamber = 5 - flamethrower.FireModes += new FireModeDefinition - flamethrower.FireModes(1).AmmoTypeIndices += 0 - flamethrower.FireModes(1).AmmoSlotIndex = 0 - flamethrower.FireModes(1).Magazine = 100 - flamethrower.FireModes(1).Chamber = 50 - flamethrower.Tile = InventoryTile.Tile63 - - val - trhev_dualcycler = ToolDefinition(ObjectClass.trhev_dualcycler) - - val - trhev_pounder = ToolDefinition(ObjectClass.trhev_pounder) - - val - trhev_burster = ToolDefinition(ObjectClass.trhev_burster) - - val - nchev_scattercannon = ToolDefinition(ObjectClass.nchev_scattercannon) - - val - nchev_falcon = ToolDefinition(ObjectClass.nchev_falcon) - - val - nchev_sparrow = ToolDefinition(ObjectClass.nchev_sparrow) - - val - vshev_quasar = ToolDefinition(ObjectClass.vshev_quasar) - - val - vshev_comet = ToolDefinition(ObjectClass.vshev_comet) - - val - vshev_starfire = ToolDefinition(ObjectClass.vshev_starfire) - - val - medicalapplicator = ToolDefinition(ObjectClass.medicalapplicator) - medicalapplicator.Size = EquipmentSize.Pistol - medicalapplicator.AmmoTypes += health_canister - medicalapplicator.FireModes += new FireModeDefinition - medicalapplicator.FireModes.head.AmmoTypeIndices += 0 - medicalapplicator.FireModes.head.AmmoSlotIndex = 0 - medicalapplicator.FireModes.head.Magazine = 100 - medicalapplicator.FireModes += new FireModeDefinition - medicalapplicator.FireModes(1).AmmoTypeIndices += 0 - medicalapplicator.FireModes(1).AmmoSlotIndex = 0 - medicalapplicator.FireModes(1).Magazine = 100 - medicalapplicator.Tile = InventoryTile.Tile33 - - val - nano_dispenser = ToolDefinition(ObjectClass.nano_dispenser) - nano_dispenser.Size = EquipmentSize.Rifle - nano_dispenser.AmmoTypes += armor_canister - nano_dispenser.AmmoTypes += upgrade_canister - nano_dispenser.FireModes += new FireModeDefinition - nano_dispenser.FireModes.head.AmmoTypeIndices += 0 - nano_dispenser.FireModes.head.AmmoTypeIndices += 1 - nano_dispenser.FireModes.head.AmmoSlotIndex = 0 - nano_dispenser.FireModes.head.Magazine = 100 - nano_dispenser.Tile = InventoryTile.Tile63 - - val - bank = ToolDefinition(ObjectClass.bank) - bank.Size = EquipmentSize.Pistol - bank.AmmoTypes += armor_canister - bank.FireModes += new FireModeDefinition - bank.FireModes.head.AmmoTypeIndices += 0 - bank.FireModes.head.AmmoSlotIndex = 0 - bank.FireModes.head.Magazine = 100 - bank.FireModes += new FireModeDefinition - bank.FireModes(1).AmmoTypeIndices += 0 - bank.FireModes(1).AmmoSlotIndex = 0 - bank.FireModes(1).Magazine = 100 - bank.Tile = InventoryTile.Tile33 - - val - remote_electronics_kit = SimpleItemDefinition(SItem.remote_electronics_kit) - remote_electronics_kit.Packet = new REKConverter - remote_electronics_kit.Tile = InventoryTile.Tile33 - - val - trek = ToolDefinition(ObjectClass.trek) - trek.Size = EquipmentSize.Pistol - trek.AmmoTypes += trek_ammo - trek.FireModes += new FireModeDefinition - trek.FireModes.head.AmmoTypeIndices += 0 - trek.FireModes.head.AmmoSlotIndex = 0 - trek.FireModes.head.Magazine = 4 - trek.FireModes += new FireModeDefinition - trek.FireModes(1).AmmoTypeIndices += 0 - trek.FireModes(1).AmmoSlotIndex = 0 - trek.FireModes(1).Magazine = 0 - trek.Tile = InventoryTile.Tile33 - - val - flail_targeting_laser = SimpleItemDefinition(SItem.flail_targeting_laser) - flail_targeting_laser.Packet = new CommandDetonaterConverter - flail_targeting_laser.Tile = InventoryTile.Tile33 - - val - command_detonater = SimpleItemDefinition(SItem.command_detonater) - command_detonater.Packet = new CommandDetonaterConverter - command_detonater.Tile = InventoryTile.Tile33 - - val - ace = ConstructionItemDefinition(CItem.Unit.ace) - ace.Modes += DeployedItem.boomer - ace.Modes += DeployedItem.he_mine - ace.Modes += DeployedItem.jammer_mine - ace.Modes += DeployedItem.spitfire_turret - ace.Modes += DeployedItem.spitfire_cloaked - ace.Modes += DeployedItem.spitfire_aa - ace.Modes += DeployedItem.motionalarmsensor - ace.Modes += DeployedItem.sensor_shield - ace.Tile = InventoryTile.Tile33 - - val - advanced_ace = ConstructionItemDefinition(CItem.Unit.advanced_ace) - advanced_ace.Modes += DeployedItem.tank_traps - advanced_ace.Modes += DeployedItem.portable_manned_turret - advanced_ace.Modes += DeployedItem.deployable_shield_generator - advanced_ace.Tile = InventoryTile.Tile63 - - val - fury_weapon_systema = ToolDefinition(ObjectClass.fury_weapon_systema) - fury_weapon_systema.Size = EquipmentSize.VehicleWeapon - fury_weapon_systema.AmmoTypes += hellfire_ammo - fury_weapon_systema.FireModes += new FireModeDefinition - fury_weapon_systema.FireModes.head.AmmoTypeIndices += 0 - fury_weapon_systema.FireModes.head.AmmoSlotIndex = 0 - fury_weapon_systema.FireModes.head.Magazine = 2 - - val - quadassault_weapon_system = ToolDefinition(ObjectClass.quadassault_weapon_system) - quadassault_weapon_system.Size = EquipmentSize.VehicleWeapon - quadassault_weapon_system.AmmoTypes += bullet_12mm - quadassault_weapon_system.FireModes += new FireModeDefinition - quadassault_weapon_system.FireModes.head.AmmoTypeIndices += 0 - quadassault_weapon_system.FireModes.head.AmmoSlotIndex = 0 - quadassault_weapon_system.FireModes.head.Magazine = 150 - - val - scythe = ToolDefinition(ObjectClass.scythe) //TODO resolve ammo slot/pool discrepancy - scythe.Size = EquipmentSize.VehicleWeapon - scythe.AmmoTypes += ancient_ammo_vehicle - scythe.AmmoTypes += ancient_ammo_vehicle - scythe.FireModes += new FireModeDefinition - scythe.FireModes.head.AmmoTypeIndices += 0 - scythe.FireModes.head.AmmoSlotIndex = 0 - scythe.FireModes.head.Magazine = 250 - scythe.FireModes += new FireModeDefinition - scythe.FireModes(1).AmmoTypeIndices += 0 - scythe.FireModes(1).AmmoSlotIndex = 1 //note: the scythe has two magazines using a single pool; however, it can not ammo-switch or mode-switch - scythe.FireModes(1).Magazine = 250 - - val - chaingun_p = ToolDefinition(ObjectClass.chaingun_p) - chaingun_p.Size = EquipmentSize.VehicleWeapon - chaingun_p.AmmoTypes += bullet_12mm - chaingun_p.FireModes += new FireModeDefinition - chaingun_p.FireModes.head.AmmoTypeIndices += 0 - chaingun_p.FireModes.head.AmmoSlotIndex = 0 - chaingun_p.FireModes.head.Magazine = 150 - - val - skyguard_weapon_system = ToolDefinition(ObjectClass.skyguard_weapon_system) - skyguard_weapon_system.Size = EquipmentSize.VehicleWeapon - skyguard_weapon_system.AmmoTypes += skyguard_flak_cannon_ammo - skyguard_weapon_system.AmmoTypes += bullet_12mm - skyguard_weapon_system.FireModes += new FireModeDefinition - skyguard_weapon_system.FireModes.head.AmmoTypeIndices += 0 - skyguard_weapon_system.FireModes.head.AmmoSlotIndex = 0 - skyguard_weapon_system.FireModes.head.Magazine = 40 - skyguard_weapon_system.FireModes += new FireModeDefinition - skyguard_weapon_system.FireModes(1).AmmoTypeIndices += 1 - skyguard_weapon_system.FireModes(1).AmmoSlotIndex = 1 - skyguard_weapon_system.FireModes(1).Magazine = 1 //TODO check - - val - grenade_launcher_marauder = ToolDefinition(ObjectClass.grenade_launcher_marauder) - grenade_launcher_marauder.Size = EquipmentSize.VehicleWeapon - grenade_launcher_marauder.AmmoTypes += heavy_grenade_mortar - grenade_launcher_marauder.FireModes += new FireModeDefinition - grenade_launcher_marauder.FireModes.head.AmmoTypeIndices += 0 - grenade_launcher_marauder.FireModes.head.AmmoSlotIndex = 0 - grenade_launcher_marauder.FireModes.head.Magazine = 50 - - val - advanced_missile_launcher_t = ToolDefinition(ObjectClass.advanced_missile_launcher_t) - advanced_missile_launcher_t.Size = EquipmentSize.VehicleWeapon - advanced_missile_launcher_t.AmmoTypes += firebird_missile - advanced_missile_launcher_t.FireModes += new FireModeDefinition - advanced_missile_launcher_t.FireModes.head.AmmoTypeIndices += 0 - advanced_missile_launcher_t.FireModes.head.AmmoSlotIndex = 0 - advanced_missile_launcher_t.FireModes.head.Magazine = 40 - - val - flux_cannon_thresher = ToolDefinition(ObjectClass.flux_cannon_thresher) - flux_cannon_thresher.Size = EquipmentSize.VehicleWeapon - flux_cannon_thresher.AmmoTypes += flux_cannon_thresher_battery - flux_cannon_thresher.FireModes += new FireModeDefinition - flux_cannon_thresher.FireModes.head.AmmoTypeIndices += 0 - flux_cannon_thresher.FireModes.head.AmmoSlotIndex = 0 - flux_cannon_thresher.FireModes.head.Magazine = 100 - - val - mediumtransport_weapon_systemA = ToolDefinition(ObjectClass.mediumtransport_weapon_systemA) - mediumtransport_weapon_systemA.Size = EquipmentSize.VehicleWeapon - mediumtransport_weapon_systemA.AmmoTypes += bullet_20mm - mediumtransport_weapon_systemA.FireModes += new FireModeDefinition - mediumtransport_weapon_systemA.FireModes.head.AmmoTypeIndices += 0 - mediumtransport_weapon_systemA.FireModes.head.AmmoSlotIndex = 0 - mediumtransport_weapon_systemA.FireModes.head.Magazine = 150 - - val - mediumtransport_weapon_systemB = ToolDefinition(ObjectClass.mediumtransport_weapon_systemB) - mediumtransport_weapon_systemB.Size = EquipmentSize.VehicleWeapon - mediumtransport_weapon_systemB.AmmoTypes += bullet_20mm - mediumtransport_weapon_systemB.FireModes += new FireModeDefinition - mediumtransport_weapon_systemB.FireModes.head.AmmoTypeIndices += 0 - mediumtransport_weapon_systemB.FireModes.head.AmmoSlotIndex = 0 - mediumtransport_weapon_systemB.FireModes.head.Magazine = 150 - - val - battlewagon_weapon_systema = ToolDefinition(ObjectClass.battlewagon_weapon_systema) - battlewagon_weapon_systema.Size = EquipmentSize.VehicleWeapon - battlewagon_weapon_systema.AmmoTypes += bullet_15mm - battlewagon_weapon_systema.FireModes += new FireModeDefinition - battlewagon_weapon_systema.FireModes.head.AmmoTypeIndices += 0 - battlewagon_weapon_systema.FireModes.head.AmmoSlotIndex = 0 - battlewagon_weapon_systema.FireModes.head.Magazine = 235 - - val - battlewagon_weapon_systemb = ToolDefinition(ObjectClass.battlewagon_weapon_systemb) - battlewagon_weapon_systemb.Size = EquipmentSize.VehicleWeapon - battlewagon_weapon_systemb.AmmoTypes += bullet_15mm - battlewagon_weapon_systemb.FireModes += new FireModeDefinition - battlewagon_weapon_systemb.FireModes.head.AmmoTypeIndices += 0 - battlewagon_weapon_systemb.FireModes.head.AmmoSlotIndex = 0 - battlewagon_weapon_systemb.FireModes.head.Magazine = 235 - - val - battlewagon_weapon_systemc = ToolDefinition(ObjectClass.battlewagon_weapon_systemc) - battlewagon_weapon_systemc.Size = EquipmentSize.VehicleWeapon - battlewagon_weapon_systemc.AmmoTypes += bullet_15mm - battlewagon_weapon_systemc.FireModes += new FireModeDefinition - battlewagon_weapon_systemc.FireModes.head.AmmoTypeIndices += 0 - battlewagon_weapon_systemc.FireModes.head.AmmoSlotIndex = 0 - battlewagon_weapon_systemc.FireModes.head.Magazine = 235 - - val - battlewagon_weapon_systemd = ToolDefinition(ObjectClass.battlewagon_weapon_systemd) - battlewagon_weapon_systemd.Size = EquipmentSize.VehicleWeapon - battlewagon_weapon_systemd.AmmoTypes += bullet_15mm - battlewagon_weapon_systemd.FireModes += new FireModeDefinition - battlewagon_weapon_systemd.FireModes.head.AmmoTypeIndices += 0 - battlewagon_weapon_systemd.FireModes.head.AmmoSlotIndex = 0 - battlewagon_weapon_systemd.FireModes.head.Magazine = 235 - - val - thunderer_weapon_systema = ToolDefinition(ObjectClass.thunderer_weapon_systema) - thunderer_weapon_systema.Size = EquipmentSize.VehicleWeapon - thunderer_weapon_systema.AmmoTypes += gauss_cannon_ammo - thunderer_weapon_systema.FireModes += new FireModeDefinition - thunderer_weapon_systema.FireModes.head.AmmoTypeIndices += 0 - thunderer_weapon_systema.FireModes.head.AmmoSlotIndex = 0 - thunderer_weapon_systema.FireModes.head.Magazine = 15 - - val - thunderer_weapon_systemb = ToolDefinition(ObjectClass.thunderer_weapon_systemb) - thunderer_weapon_systemb.Size = EquipmentSize.VehicleWeapon - thunderer_weapon_systemb.AmmoTypes += gauss_cannon_ammo - thunderer_weapon_systemb.FireModes += new FireModeDefinition - thunderer_weapon_systemb.FireModes.head.AmmoTypeIndices += 0 - thunderer_weapon_systemb.FireModes.head.AmmoSlotIndex = 0 - thunderer_weapon_systemb.FireModes.head.Magazine = 15 - - val - aurora_weapon_systema = ToolDefinition(ObjectClass.aurora_weapon_systema) - aurora_weapon_systema.Size = EquipmentSize.VehicleWeapon - aurora_weapon_systema.AmmoTypes += fluxpod_ammo - aurora_weapon_systema.FireModes += new FireModeDefinition - aurora_weapon_systema.FireModes.head.AmmoTypeIndices += 0 - aurora_weapon_systema.FireModes.head.AmmoSlotIndex = 0 - aurora_weapon_systema.FireModes.head.Magazine = 12 - aurora_weapon_systema.FireModes += new FireModeDefinition - aurora_weapon_systema.FireModes(1).AmmoTypeIndices += 0 - aurora_weapon_systema.FireModes(1).AmmoSlotIndex = 1 - aurora_weapon_systema.FireModes(1).Magazine = 12 - - val - aurora_weapon_systemb = ToolDefinition(ObjectClass.aurora_weapon_systemb) - aurora_weapon_systemb.Size = EquipmentSize.VehicleWeapon - aurora_weapon_systemb.AmmoTypes += fluxpod_ammo - aurora_weapon_systemb.FireModes += new FireModeDefinition - aurora_weapon_systemb.FireModes.head.AmmoTypeIndices += 0 - aurora_weapon_systemb.FireModes.head.AmmoSlotIndex = 0 - aurora_weapon_systemb.FireModes.head.Magazine = 12 - aurora_weapon_systemb.FireModes += new FireModeDefinition - aurora_weapon_systemb.FireModes(1).AmmoTypeIndices += 0 - aurora_weapon_systemb.FireModes(1).AmmoSlotIndex = 1 - aurora_weapon_systemb.FireModes(1).Magazine = 12 - - val - apc_weapon_systema = ToolDefinition(ObjectClass.apc_weapon_systema) - apc_weapon_systema.Size = EquipmentSize.VehicleWeapon - apc_weapon_systema.AmmoTypes += bullet_75mm - apc_weapon_systema.FireModes += new FireModeDefinition - apc_weapon_systema.FireModes.head.AmmoTypeIndices += 0 - apc_weapon_systema.FireModes.head.AmmoSlotIndex = 0 - apc_weapon_systema.FireModes.head.Magazine = 50 - - val - apc_weapon_systemb = ToolDefinition(ObjectClass.apc_weapon_systemb) - apc_weapon_systemb.Size = EquipmentSize.VehicleWeapon - apc_weapon_systemb.AmmoTypes += bullet_75mm - apc_weapon_systemb.FireModes += new FireModeDefinition - apc_weapon_systemb.FireModes.head.AmmoTypeIndices += 0 - apc_weapon_systemb.FireModes.head.AmmoSlotIndex = 0 - apc_weapon_systemb.FireModes.head.Magazine = 50 - - val - apc_ballgun_r = ToolDefinition(ObjectClass.apc_ballgun_r) - apc_ballgun_r.Size = EquipmentSize.VehicleWeapon - apc_ballgun_r.AmmoTypes += bullet_12mm - apc_ballgun_r.FireModes += new FireModeDefinition - apc_ballgun_r.FireModes.head.AmmoTypeIndices += 0 - apc_ballgun_r.FireModes.head.AmmoSlotIndex = 0 - apc_ballgun_r.FireModes.head.Magazine = 150 - - val - apc_ballgun_l = ToolDefinition(ObjectClass.apc_ballgun_l) - apc_ballgun_l.Size = EquipmentSize.VehicleWeapon - apc_ballgun_l.AmmoTypes += bullet_12mm - apc_ballgun_l.FireModes += new FireModeDefinition - apc_ballgun_l.FireModes.head.AmmoTypeIndices += 0 - apc_ballgun_l.FireModes.head.AmmoSlotIndex = 0 - apc_ballgun_l.FireModes.head.Magazine = 150 - - val - apc_weapon_systemc_tr = ToolDefinition(ObjectClass.apc_weapon_systemc_tr) - apc_weapon_systemc_tr.Size = EquipmentSize.VehicleWeapon - apc_weapon_systemc_tr.AmmoTypes += bullet_15mm - apc_weapon_systemc_tr.FireModes += new FireModeDefinition - apc_weapon_systemc_tr.FireModes.head.AmmoTypeIndices += 0 - apc_weapon_systemc_tr.FireModes.head.AmmoSlotIndex = 0 - apc_weapon_systemc_tr.FireModes.head.Magazine = 150 - - val - apc_weapon_systemd_tr = ToolDefinition(ObjectClass.apc_weapon_systemd_tr) - apc_weapon_systemd_tr.Size = EquipmentSize.VehicleWeapon - apc_weapon_systemd_tr.AmmoTypes += bullet_15mm - apc_weapon_systemd_tr.FireModes += new FireModeDefinition - apc_weapon_systemd_tr.FireModes.head.AmmoTypeIndices += 0 - apc_weapon_systemd_tr.FireModes.head.AmmoSlotIndex = 0 - apc_weapon_systemd_tr.FireModes.head.Magazine = 150 - - val - apc_weapon_systemc_nc = ToolDefinition(ObjectClass.apc_weapon_systemc_nc) - apc_weapon_systemc_nc.Size = EquipmentSize.VehicleWeapon - apc_weapon_systemc_nc.AmmoTypes += bullet_20mm - apc_weapon_systemc_nc.FireModes += new FireModeDefinition - apc_weapon_systemc_nc.FireModes.head.AmmoTypeIndices += 0 - apc_weapon_systemc_nc.FireModes.head.AmmoSlotIndex = 0 - apc_weapon_systemc_nc.FireModes.head.Magazine = 150 - - val - apc_weapon_systemd_nc = ToolDefinition(ObjectClass.apc_weapon_systemd_nc) - apc_weapon_systemd_nc.Size = EquipmentSize.VehicleWeapon - apc_weapon_systemd_nc.AmmoTypes += bullet_20mm - apc_weapon_systemd_nc.FireModes += new FireModeDefinition - apc_weapon_systemd_nc.FireModes.head.AmmoTypeIndices += 0 - apc_weapon_systemd_nc.FireModes.head.AmmoSlotIndex = 0 - apc_weapon_systemd_nc.FireModes.head.Magazine = 150 - - val - apc_weapon_systemc_vs = ToolDefinition(ObjectClass.apc_weapon_systemc_vs) - apc_weapon_systemc_vs.Size = EquipmentSize.VehicleWeapon - apc_weapon_systemc_vs.AmmoTypes += flux_cannon_thresher_battery - apc_weapon_systemc_vs.FireModes += new FireModeDefinition - apc_weapon_systemc_vs.FireModes.head.AmmoTypeIndices += 0 - apc_weapon_systemc_vs.FireModes.head.AmmoSlotIndex = 0 - apc_weapon_systemc_vs.FireModes.head.Magazine = 100 - - val - apc_weapon_systemd_vs = ToolDefinition(ObjectClass.apc_weapon_systemd_vs) - apc_weapon_systemd_vs.Size = EquipmentSize.VehicleWeapon - apc_weapon_systemd_vs.AmmoTypes += flux_cannon_thresher_battery - apc_weapon_systemd_vs.FireModes += new FireModeDefinition - apc_weapon_systemd_vs.FireModes.head.AmmoTypeIndices += 0 - apc_weapon_systemd_vs.FireModes.head.AmmoSlotIndex = 0 - apc_weapon_systemd_vs.FireModes.head.Magazine = 100 - - val - lightning_weapon_system = ToolDefinition(ObjectClass.lightning_weapon_system) - lightning_weapon_system.Size = EquipmentSize.VehicleWeapon - lightning_weapon_system.AmmoTypes += bullet_75mm - lightning_weapon_system.AmmoTypes += bullet_25mm - lightning_weapon_system.FireModes += new FireModeDefinition - lightning_weapon_system.FireModes.head.AmmoTypeIndices += 0 - lightning_weapon_system.FireModes.head.AmmoSlotIndex = 0 - lightning_weapon_system.FireModes.head.Magazine = 20 - lightning_weapon_system.FireModes += new FireModeDefinition - lightning_weapon_system.FireModes(1).AmmoTypeIndices += 1 - lightning_weapon_system.FireModes(1).AmmoSlotIndex = 1 - lightning_weapon_system.FireModes(1).Magazine = 1 //TODO check - - val - prowler_weapon_systemA = ToolDefinition(ObjectClass.prowler_weapon_systemA) - prowler_weapon_systemA.Size = EquipmentSize.VehicleWeapon - prowler_weapon_systemA.AmmoTypes += bullet_105mm - prowler_weapon_systemA.FireModes += new FireModeDefinition - prowler_weapon_systemA.FireModes.head.AmmoTypeIndices += 0 - prowler_weapon_systemA.FireModes.head.AmmoSlotIndex = 0 - prowler_weapon_systemA.FireModes.head.Magazine = 20 - - val - prowler_weapon_systemB = ToolDefinition(ObjectClass.prowler_weapon_systemB) - prowler_weapon_systemB.Size = EquipmentSize.VehicleWeapon - prowler_weapon_systemB.AmmoTypes += bullet_15mm - prowler_weapon_systemB.FireModes += new FireModeDefinition - prowler_weapon_systemB.FireModes.head.AmmoTypeIndices += 0 - prowler_weapon_systemB.FireModes.head.AmmoSlotIndex = 0 - prowler_weapon_systemB.FireModes.head.Magazine = 235 - - val - vanguard_weapon_system = ToolDefinition(ObjectClass.vanguard_weapon_system) - vanguard_weapon_system.Size = EquipmentSize.VehicleWeapon - vanguard_weapon_system.AmmoTypes += bullet_150mm - vanguard_weapon_system.AmmoTypes += bullet_20mm - vanguard_weapon_system.FireModes += new FireModeDefinition - vanguard_weapon_system.FireModes.head.AmmoTypeIndices += 0 - vanguard_weapon_system.FireModes.head.AmmoSlotIndex = 0 - vanguard_weapon_system.FireModes.head.Magazine = 10 - vanguard_weapon_system.FireModes += new FireModeDefinition - vanguard_weapon_system.FireModes(1).AmmoTypeIndices += 1 - vanguard_weapon_system.FireModes(1).AmmoSlotIndex = 1 - vanguard_weapon_system.FireModes(1).Magazine = 1 //TODO check - - val - particle_beam_magrider = ToolDefinition(ObjectClass.particle_beam_magrider) - particle_beam_magrider.Size = EquipmentSize.VehicleWeapon - particle_beam_magrider.AmmoTypes += pulse_battery - particle_beam_magrider.FireModes += new FireModeDefinition - particle_beam_magrider.FireModes.head.AmmoTypeIndices += 0 - particle_beam_magrider.FireModes.head.AmmoSlotIndex = 0 - particle_beam_magrider.FireModes.head.Magazine = 150 - - val - heavy_rail_beam_magrider = ToolDefinition(ObjectClass.heavy_rail_beam_magrider) - heavy_rail_beam_magrider.Size = EquipmentSize.VehicleWeapon - heavy_rail_beam_magrider.AmmoTypes += heavy_rail_beam_battery - heavy_rail_beam_magrider.FireModes += new FireModeDefinition - heavy_rail_beam_magrider.FireModes.head.AmmoTypeIndices += 0 - heavy_rail_beam_magrider.FireModes.head.AmmoSlotIndex = 0 - heavy_rail_beam_magrider.FireModes.head.Magazine = 25 - - val - flail_weapon = ToolDefinition(ObjectClass.flail_weapon) - flail_weapon.Size = EquipmentSize.VehicleWeapon - flail_weapon.AmmoTypes += ancient_ammo_vehicle - flail_weapon.FireModes += new FireModeDefinition - flail_weapon.FireModes.head.AmmoTypeIndices += 0 - flail_weapon.FireModes.head.AmmoSlotIndex = 0 - flail_weapon.FireModes.head.Magazine = 100 - - val - rotarychaingun_mosquito = ToolDefinition(ObjectClass.rotarychaingun_mosquito) - rotarychaingun_mosquito.Size = EquipmentSize.VehicleWeapon - rotarychaingun_mosquito.AmmoTypes += bullet_12mm - rotarychaingun_mosquito.FireModes += new FireModeDefinition - rotarychaingun_mosquito.FireModes.head.AmmoTypeIndices += 0 - rotarychaingun_mosquito.FireModes.head.AmmoSlotIndex = 0 - rotarychaingun_mosquito.FireModes.head.Magazine = 150 - - val - lightgunship_weapon_system = ToolDefinition(ObjectClass.lightgunship_weapon_system) - lightgunship_weapon_system.Size = EquipmentSize.VehicleWeapon - lightgunship_weapon_system.AmmoTypes += bullet_20mm - lightgunship_weapon_system.AmmoTypes += reaver_rocket - lightgunship_weapon_system.FireModes += new FireModeDefinition - lightgunship_weapon_system.FireModes.head.AmmoTypeIndices += 0 - lightgunship_weapon_system.FireModes.head.AmmoSlotIndex = 0 - lightgunship_weapon_system.FireModes.head.Magazine = 150 - lightgunship_weapon_system.FireModes += new FireModeDefinition - lightgunship_weapon_system.FireModes(1).AmmoTypeIndices += 1 - lightgunship_weapon_system.FireModes(1).AmmoSlotIndex = 1 - lightgunship_weapon_system.FireModes(1).Magazine = 1 //TODO check - - val - wasp_weapon_system = ToolDefinition(ObjectClass.wasp_weapon_system) - wasp_weapon_system.Size = EquipmentSize.VehicleWeapon - wasp_weapon_system.AmmoTypes += wasp_gun_ammo - wasp_weapon_system.AmmoTypes += wasp_rocket_ammo - wasp_weapon_system.FireModes += new FireModeDefinition - wasp_weapon_system.FireModes.head.AmmoTypeIndices += 0 - wasp_weapon_system.FireModes.head.AmmoSlotIndex = 0 - wasp_weapon_system.FireModes.head.Magazine = 30 - wasp_weapon_system.FireModes += new FireModeDefinition - wasp_weapon_system.FireModes(1).AmmoTypeIndices += 1 - wasp_weapon_system.FireModes(1).AmmoSlotIndex = 1 - wasp_weapon_system.FireModes(1).Magazine = 1 //TODO check - - val - liberator_weapon_system = ToolDefinition(ObjectClass.liberator_weapon_system) - liberator_weapon_system.Size = EquipmentSize.VehicleWeapon - liberator_weapon_system.AmmoTypes += bullet_35mm - liberator_weapon_system.FireModes += new FireModeDefinition - liberator_weapon_system.FireModes.head.AmmoTypeIndices += 0 - liberator_weapon_system.FireModes.head.AmmoSlotIndex = 0 - liberator_weapon_system.FireModes.head.Magazine = 100 - - val - liberator_bomb_bay = ToolDefinition(ObjectClass.liberator_bomb_bay) - liberator_bomb_bay.Size = EquipmentSize.VehicleWeapon - liberator_bomb_bay.AmmoTypes += liberator_bomb - liberator_bomb_bay.FireModes += new FireModeDefinition - liberator_bomb_bay.FireModes.head.AmmoTypeIndices += 0 - liberator_bomb_bay.FireModes.head.AmmoSlotIndex = 0 - liberator_bomb_bay.FireModes.head.Magazine = 10 - liberator_bomb_bay.FireModes += new FireModeDefinition - liberator_bomb_bay.FireModes(1).AmmoTypeIndices += 0 - liberator_bomb_bay.FireModes(1).AmmoSlotIndex = 0 - liberator_bomb_bay.FireModes(1).Magazine = 10 - - val - liberator_25mm_cannon = ToolDefinition(ObjectClass.liberator_25mm_cannon) - liberator_25mm_cannon.Size = EquipmentSize.VehicleWeapon - liberator_25mm_cannon.AmmoTypes += bullet_25mm - liberator_25mm_cannon.FireModes += new FireModeDefinition - liberator_25mm_cannon.FireModes.head.AmmoTypeIndices += 0 - liberator_25mm_cannon.FireModes.head.AmmoSlotIndex = 0 - liberator_25mm_cannon.FireModes.head.Magazine = 150 - - val - vulture_nose_weapon_system = ToolDefinition(ObjectClass.vulture_nose_weapon_system) - vulture_nose_weapon_system.Size = EquipmentSize.VehicleWeapon - vulture_nose_weapon_system.AmmoTypes += bullet_35mm - vulture_nose_weapon_system.FireModes += new FireModeDefinition - vulture_nose_weapon_system.FireModes.head.AmmoTypeIndices += 0 - vulture_nose_weapon_system.FireModes.head.AmmoSlotIndex = 0 - vulture_nose_weapon_system.FireModes.head.Magazine = 75 //80? - - val - vulture_bomb_bay = ToolDefinition(ObjectClass.vulture_bomb_bay) - vulture_bomb_bay.Size = EquipmentSize.VehicleWeapon - vulture_bomb_bay.AmmoTypes += liberator_bomb - vulture_bomb_bay.FireModes += new FireModeDefinition - vulture_bomb_bay.FireModes.head.AmmoTypeIndices += 0 - vulture_bomb_bay.FireModes.head.AmmoSlotIndex = 0 - vulture_bomb_bay.FireModes.head.Magazine = 10 - - val - vulture_tail_cannon = ToolDefinition(ObjectClass.vulture_tail_cannon) - vulture_tail_cannon.Size = EquipmentSize.VehicleWeapon - vulture_tail_cannon.AmmoTypes += bullet_25mm - vulture_tail_cannon.FireModes += new FireModeDefinition - vulture_tail_cannon.FireModes.head.AmmoTypeIndices += 0 - vulture_tail_cannon.FireModes.head.AmmoSlotIndex = 0 - vulture_tail_cannon.FireModes.head.Magazine = 100 - - val - cannon_dropship_20mm = ToolDefinition(ObjectClass.cannon_dropship_20mm) - cannon_dropship_20mm.Size = EquipmentSize.VehicleWeapon - cannon_dropship_20mm.AmmoTypes += bullet_20mm - cannon_dropship_20mm.FireModes += new FireModeDefinition - cannon_dropship_20mm.FireModes.head.AmmoTypeIndices += 0 - cannon_dropship_20mm.FireModes.head.AmmoSlotIndex = 0 - cannon_dropship_20mm.FireModes.head.Magazine = 250 - - val - dropship_rear_turret = ToolDefinition(ObjectClass.dropship_rear_turret) - dropship_rear_turret.Size = EquipmentSize.VehicleWeapon - dropship_rear_turret.AmmoTypes += bullet_20mm - dropship_rear_turret.FireModes += new FireModeDefinition - dropship_rear_turret.FireModes.head.AmmoTypeIndices += 0 - dropship_rear_turret.FireModes.head.AmmoSlotIndex = 0 - dropship_rear_turret.FireModes.head.Magazine = 250 - - val - galaxy_gunship_cannon = ToolDefinition(ObjectClass.galaxy_gunship_cannon) - galaxy_gunship_cannon.Size = EquipmentSize.VehicleWeapon - galaxy_gunship_cannon.AmmoTypes += heavy_grenade_mortar - galaxy_gunship_cannon.FireModes += new FireModeDefinition - galaxy_gunship_cannon.FireModes.head.AmmoTypeIndices += 0 - galaxy_gunship_cannon.FireModes.head.AmmoSlotIndex = 0 - galaxy_gunship_cannon.FireModes.head.Magazine = 50 - - val - galaxy_gunship_tailgun = ToolDefinition(ObjectClass.galaxy_gunship_tailgun) - galaxy_gunship_tailgun.Size = EquipmentSize.VehicleWeapon - galaxy_gunship_tailgun.AmmoTypes += bullet_35mm - galaxy_gunship_tailgun.FireModes += new FireModeDefinition - galaxy_gunship_tailgun.FireModes.head.AmmoTypeIndices += 0 - galaxy_gunship_tailgun.FireModes.head.AmmoSlotIndex = 0 - galaxy_gunship_tailgun.FireModes.head.Magazine = 200 - - val - galaxy_gunship_gun = ToolDefinition(ObjectClass.galaxy_gunship_gun) - galaxy_gunship_gun.Size = EquipmentSize.VehicleWeapon - galaxy_gunship_gun.AmmoTypes += bullet_35mm - galaxy_gunship_gun.FireModes += new FireModeDefinition - galaxy_gunship_gun.FireModes.head.AmmoTypeIndices += 0 - galaxy_gunship_gun.FireModes.head.AmmoSlotIndex = 0 - galaxy_gunship_gun.FireModes.head.Magazine = 200 - - val - fury = VehicleDefinition(ObjectClass.fury) - fury.Seats += 0 -> new SeatDefinition() - fury.Seats(0).Bailable = true - fury.Seats(0).ControlledWeapon = 1 - fury.Weapons += 1 -> fury_weapon_systema - fury.MountPoints += 1 -> 0 - fury.MountPoints += 2 -> 0 - fury.TrunkSize = InventoryTile.Tile1111 - fury.TrunkOffset = 30 - - val - quadassault = VehicleDefinition(ObjectClass.quadassault) - quadassault.Seats += 0 -> new SeatDefinition() - quadassault.Seats(0).Bailable = true - quadassault.Seats(0).ControlledWeapon = 1 - quadassault.Weapons += 1 -> quadassault_weapon_system - quadassault.MountPoints += 1 -> 0 - quadassault.MountPoints += 2 -> 0 - quadassault.TrunkSize = InventoryTile.Tile1111 - quadassault.TrunkOffset = 30 - - val - quadstealth = VehicleDefinition(ObjectClass.quadstealth) - quadstealth.CanCloak = true - quadstealth.Seats += 0 -> new SeatDefinition() - quadstealth.Seats(0).Bailable = true - quadstealth.CanCloak = true - quadstealth.MountPoints += 1 -> 0 - quadstealth.MountPoints += 2 -> 0 - quadstealth.TrunkSize = InventoryTile.Tile1111 - quadstealth.TrunkOffset = 30 - - val - two_man_assault_buggy = VehicleDefinition(ObjectClass.two_man_assault_buggy) - two_man_assault_buggy.Seats += 0 -> new SeatDefinition() - two_man_assault_buggy.Seats(0).Bailable = true - two_man_assault_buggy.Seats += 1 -> new SeatDefinition() - two_man_assault_buggy.Seats(1).Bailable = true - two_man_assault_buggy.Seats(1).ControlledWeapon = 2 - two_man_assault_buggy.Weapons += 2 -> chaingun_p - two_man_assault_buggy.MountPoints += 1 -> 0 - two_man_assault_buggy.MountPoints += 2 -> 1 - two_man_assault_buggy.TrunkSize = InventoryTile.Tile1111 - two_man_assault_buggy.TrunkOffset = 30 - - val - skyguard = VehicleDefinition(ObjectClass.skyguard) - skyguard.Seats += 0 -> new SeatDefinition() - skyguard.Seats(0).Bailable = true - skyguard.Seats += 1 -> new SeatDefinition() - skyguard.Seats(1).Bailable = true - skyguard.Seats(1).ControlledWeapon = 2 - skyguard.Weapons += 2 -> skyguard_weapon_system - skyguard.MountPoints += 1 -> 0 - skyguard.MountPoints += 2 -> 0 - skyguard.MountPoints += 3 -> 1 - skyguard.TrunkSize = InventoryTile.Tile1511 - skyguard.TrunkOffset = 30 - - val - threemanheavybuggy = VehicleDefinition(ObjectClass.threemanheavybuggy) - threemanheavybuggy.Seats += 0 -> new SeatDefinition() - threemanheavybuggy.Seats(0).Bailable = true - threemanheavybuggy.Seats += 1 -> new SeatDefinition() - threemanheavybuggy.Seats(1).Bailable = true - threemanheavybuggy.Seats(1).ControlledWeapon = 3 - threemanheavybuggy.Seats += 2 -> new SeatDefinition() - threemanheavybuggy.Seats(2).Bailable = true - threemanheavybuggy.Seats(2).ControlledWeapon = 4 - threemanheavybuggy.Weapons += 3 -> chaingun_p - threemanheavybuggy.Weapons += 4 -> grenade_launcher_marauder - threemanheavybuggy.MountPoints += 1 -> 0 - threemanheavybuggy.MountPoints += 2 -> 1 - threemanheavybuggy.MountPoints += 3 -> 2 - threemanheavybuggy.TrunkSize = InventoryTile.Tile1511 - threemanheavybuggy.TrunkOffset = 30 - - val - twomanheavybuggy = VehicleDefinition(ObjectClass.twomanheavybuggy) - twomanheavybuggy.Seats += 0 -> new SeatDefinition() - twomanheavybuggy.Seats(0).Bailable = true - twomanheavybuggy.Seats += 1 -> new SeatDefinition() - twomanheavybuggy.Seats(1).Bailable = true - twomanheavybuggy.Seats(1).ControlledWeapon = 2 - twomanheavybuggy.Weapons += 2 -> advanced_missile_launcher_t - twomanheavybuggy.MountPoints += 1 -> 0 - twomanheavybuggy.MountPoints += 2 -> 1 - twomanheavybuggy.TrunkSize = InventoryTile.Tile1511 - twomanheavybuggy.TrunkOffset = 30 - - val - twomanhoverbuggy = VehicleDefinition(ObjectClass.twomanhoverbuggy) - twomanhoverbuggy.Seats += 0 -> new SeatDefinition() - twomanhoverbuggy.Seats(0).Bailable = true - twomanhoverbuggy.Seats += 1 -> new SeatDefinition() - twomanhoverbuggy.Seats(1).Bailable = true - twomanhoverbuggy.Seats(1).ControlledWeapon = 2 - twomanhoverbuggy.Weapons += 2 -> flux_cannon_thresher - twomanhoverbuggy.MountPoints += 1 -> 0 - twomanhoverbuggy.MountPoints += 2 -> 1 - twomanhoverbuggy.TrunkSize = InventoryTile.Tile1511 - twomanhoverbuggy.TrunkOffset = 30 - - val - mediumtransport = VehicleDefinition(ObjectClass.mediumtransport) - mediumtransport.Seats += 0 -> new SeatDefinition() - mediumtransport.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax - mediumtransport.Seats += 1 -> new SeatDefinition() - mediumtransport.Seats(1).ControlledWeapon = 5 - mediumtransport.Seats += 2 -> new SeatDefinition() - mediumtransport.Seats(2).ControlledWeapon = 6 - mediumtransport.Seats += 3 -> new SeatDefinition() - mediumtransport.Seats += 4 -> new SeatDefinition() - mediumtransport.Weapons += 5 -> mediumtransport_weapon_systemA - mediumtransport.Weapons += 6 -> mediumtransport_weapon_systemB - mediumtransport.MountPoints += 1 -> 0 - mediumtransport.MountPoints += 2 -> 1 - mediumtransport.MountPoints += 3 -> 2 - mediumtransport.MountPoints += 4 -> 3 - mediumtransport.MountPoints += 5 -> 4 - mediumtransport.TrunkSize = InventoryTile.Tile1515 - mediumtransport.TrunkOffset = 30 - - val - battlewagon = VehicleDefinition(ObjectClass.battlewagon) - battlewagon.Seats += 0 -> new SeatDefinition() - battlewagon.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax - battlewagon.Seats += 1 -> new SeatDefinition() - battlewagon.Seats(1).ControlledWeapon = 5 - battlewagon.Seats += 2 -> new SeatDefinition() - battlewagon.Seats(2).ControlledWeapon = 6 - battlewagon.Seats += 3 -> new SeatDefinition() - battlewagon.Seats(3).ControlledWeapon = 7 - battlewagon.Seats += 4 -> new SeatDefinition() - battlewagon.Seats(4).ControlledWeapon = 8 - battlewagon.Weapons += 5 -> battlewagon_weapon_systema - battlewagon.Weapons += 6 -> battlewagon_weapon_systemb - battlewagon.Weapons += 7 -> battlewagon_weapon_systemc - battlewagon.Weapons += 8 -> battlewagon_weapon_systemd - battlewagon.MountPoints += 1 -> 0 - battlewagon.MountPoints += 2 -> 1 - battlewagon.MountPoints += 3 -> 2 - battlewagon.MountPoints += 4 -> 3 - battlewagon.MountPoints += 5 -> 4 - battlewagon.TrunkSize = InventoryTile.Tile1515 - battlewagon.TrunkOffset = 30 - - val - thunderer = VehicleDefinition(ObjectClass.thunderer) - thunderer.Seats += 0 -> new SeatDefinition() - thunderer.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax - thunderer.Seats += 1 -> new SeatDefinition() - thunderer.Seats(1).ControlledWeapon = 5 - thunderer.Seats += 2 -> new SeatDefinition() - thunderer.Seats(2).ControlledWeapon = 6 - thunderer.Seats += 3 -> new SeatDefinition() - thunderer.Seats += 4 -> new SeatDefinition() - thunderer.Weapons += 5 -> thunderer_weapon_systema - thunderer.Weapons += 6 -> thunderer_weapon_systemb - thunderer.MountPoints += 1 -> 0 - thunderer.MountPoints += 2 -> 1 - thunderer.MountPoints += 3 -> 2 - thunderer.MountPoints += 4 -> 3 - thunderer.MountPoints += 5 -> 4 - thunderer.TrunkSize = InventoryTile.Tile1515 - thunderer.TrunkOffset = 30 - - val - aurora = VehicleDefinition(ObjectClass.aurora) - aurora.Seats += 0 -> new SeatDefinition() - aurora.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax - aurora.Seats += 1 -> new SeatDefinition() - aurora.Seats(1).ControlledWeapon = 5 - aurora.Seats += 2 -> new SeatDefinition() - aurora.Seats(2).ControlledWeapon = 6 - aurora.Seats += 3 -> new SeatDefinition() - aurora.Seats += 4 -> new SeatDefinition() - aurora.Weapons += 5 -> aurora_weapon_systema - aurora.Weapons += 6 -> aurora_weapon_systemb - aurora.MountPoints += 1 -> 0 - aurora.MountPoints += 2 -> 1 - aurora.MountPoints += 3 -> 2 - aurora.MountPoints += 4 -> 3 - aurora.MountPoints += 5 -> 4 - aurora.TrunkSize = InventoryTile.Tile1515 - aurora.TrunkOffset = 30 - - val - apc_tr = VehicleDefinition(ObjectClass.apc_tr) - apc_tr.Seats += 0 -> new SeatDefinition() - apc_tr.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax - apc_tr.Seats += 1 -> new SeatDefinition() - apc_tr.Seats(1).ControlledWeapon = 11 - apc_tr.Seats += 2 -> new SeatDefinition() - apc_tr.Seats(2).ControlledWeapon = 12 - apc_tr.Seats += 3 -> new SeatDefinition() - apc_tr.Seats += 4 -> new SeatDefinition() - apc_tr.Seats += 5 -> new SeatDefinition() - apc_tr.Seats(5).ControlledWeapon = 15 - apc_tr.Seats += 6 -> new SeatDefinition() - apc_tr.Seats(6).ControlledWeapon = 16 - apc_tr.Seats += 7 -> new SeatDefinition() - apc_tr.Seats(7).ControlledWeapon = 13 - apc_tr.Seats += 8 -> new SeatDefinition() - apc_tr.Seats(8).ControlledWeapon = 14 - apc_tr.Seats += 9 -> new SeatDefinition() - apc_tr.Seats(9).ArmorRestriction = SeatArmorRestriction.MaxOnly - apc_tr.Seats += 10 -> new SeatDefinition() - apc_tr.Seats(10).ArmorRestriction = SeatArmorRestriction.MaxOnly - apc_tr.Weapons += 11 -> apc_weapon_systemc_tr - apc_tr.Weapons += 12 -> apc_weapon_systemb - apc_tr.Weapons += 13 -> apc_weapon_systema - apc_tr.Weapons += 14 -> apc_weapon_systemd_tr - apc_tr.Weapons += 15 -> apc_ballgun_r - apc_tr.Weapons += 16 -> apc_ballgun_l - apc_tr.MountPoints += 1 -> 0 - apc_tr.MountPoints += 2 -> 0 - apc_tr.MountPoints += 3 -> 1 - apc_tr.MountPoints += 4 -> 2 - apc_tr.MountPoints += 5 -> 3 - apc_tr.MountPoints += 6 -> 4 - apc_tr.MountPoints += 7 -> 5 - apc_tr.MountPoints += 8 -> 6 - apc_tr.MountPoints += 9 -> 7 - apc_tr.MountPoints += 10 -> 8 - apc_tr.MountPoints += 11 -> 9 - apc_tr.MountPoints += 12 -> 10 - apc_tr.TrunkSize = InventoryTile.Tile2016 - apc_tr.TrunkOffset = 30 - - val - apc_nc = VehicleDefinition(ObjectClass.apc_nc) - apc_nc.Seats += 0 -> new SeatDefinition() - apc_nc.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax - apc_nc.Seats += 1 -> new SeatDefinition() - apc_nc.Seats(1).ControlledWeapon = 11 - apc_nc.Seats += 2 -> new SeatDefinition() - apc_nc.Seats(2).ControlledWeapon = 12 - apc_nc.Seats += 3 -> new SeatDefinition() - apc_nc.Seats += 4 -> new SeatDefinition() - apc_nc.Seats += 5 -> new SeatDefinition() - apc_nc.Seats(5).ControlledWeapon = 15 - apc_nc.Seats += 6 -> new SeatDefinition() - apc_nc.Seats(6).ControlledWeapon = 16 - apc_nc.Seats += 7 -> new SeatDefinition() - apc_nc.Seats(7).ControlledWeapon = 13 - apc_nc.Seats += 8 -> new SeatDefinition() - apc_nc.Seats(8).ControlledWeapon = 14 - apc_nc.Seats += 9 -> new SeatDefinition() - apc_nc.Seats(9).ArmorRestriction = SeatArmorRestriction.MaxOnly - apc_nc.Seats += 10 -> new SeatDefinition() - apc_nc.Seats(10).ArmorRestriction = SeatArmorRestriction.MaxOnly - apc_nc.Weapons += 11 -> apc_weapon_systemc_nc - apc_nc.Weapons += 12 -> apc_weapon_systemb - apc_nc.Weapons += 13 -> apc_weapon_systema - apc_nc.Weapons += 14 -> apc_weapon_systemd_nc - apc_nc.Weapons += 15 -> apc_ballgun_r - apc_nc.Weapons += 16 -> apc_ballgun_l - apc_nc.MountPoints += 1 -> 0 - apc_nc.MountPoints += 2 -> 0 - apc_nc.MountPoints += 3 -> 1 - apc_nc.MountPoints += 4 -> 2 - apc_nc.MountPoints += 5 -> 3 - apc_nc.MountPoints += 6 -> 4 - apc_nc.MountPoints += 7 -> 5 - apc_nc.MountPoints += 8 -> 6 - apc_nc.MountPoints += 9 -> 7 - apc_nc.MountPoints += 10 -> 8 - apc_nc.MountPoints += 11 -> 9 - apc_nc.MountPoints += 12 -> 10 - apc_nc.TrunkSize = InventoryTile.Tile2016 - apc_nc.TrunkOffset = 30 - - val - apc_vs = VehicleDefinition(ObjectClass.apc_vs) - apc_vs.Seats += 0 -> new SeatDefinition() - apc_vs.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax - apc_vs.Seats += 1 -> new SeatDefinition() - apc_vs.Seats(1).ControlledWeapon = 11 - apc_vs.Seats += 2 -> new SeatDefinition() - apc_vs.Seats(2).ControlledWeapon = 12 - apc_vs.Seats += 3 -> new SeatDefinition() - apc_vs.Seats += 4 -> new SeatDefinition() - apc_vs.Seats += 5 -> new SeatDefinition() - apc_vs.Seats(5).ControlledWeapon = 15 - apc_vs.Seats += 6 -> new SeatDefinition() - apc_vs.Seats(6).ControlledWeapon = 16 - apc_vs.Seats += 7 -> new SeatDefinition() - apc_vs.Seats(7).ControlledWeapon = 13 - apc_vs.Seats += 8 -> new SeatDefinition() - apc_vs.Seats(8).ControlledWeapon = 14 - apc_vs.Seats += 9 -> new SeatDefinition() - apc_vs.Seats(9).ArmorRestriction = SeatArmorRestriction.MaxOnly - apc_vs.Seats += 10 -> new SeatDefinition() - apc_vs.Seats(10).ArmorRestriction = SeatArmorRestriction.MaxOnly - apc_vs.Weapons += 11 -> apc_weapon_systemc_vs - apc_vs.Weapons += 12 -> apc_weapon_systemb - apc_vs.Weapons += 13 -> apc_weapon_systema - apc_vs.Weapons += 14 -> apc_weapon_systemd_vs - apc_vs.Weapons += 15 -> apc_ballgun_r - apc_vs.Weapons += 16 -> apc_ballgun_l - apc_vs.MountPoints += 1 -> 0 - apc_vs.MountPoints += 2 -> 0 - apc_vs.MountPoints += 3 -> 1 - apc_vs.MountPoints += 4 -> 2 - apc_vs.MountPoints += 5 -> 3 - apc_vs.MountPoints += 6 -> 4 - apc_vs.MountPoints += 7 -> 5 - apc_vs.MountPoints += 8 -> 6 - apc_vs.MountPoints += 9 -> 7 - apc_vs.MountPoints += 10 -> 8 - apc_vs.MountPoints += 11 -> 9 - apc_vs.MountPoints += 12 -> 10 - apc_vs.TrunkSize = InventoryTile.Tile2016 - apc_vs.TrunkOffset = 30 - - val - lightning = VehicleDefinition(ObjectClass.lightning) - lightning.Seats += 0 -> new SeatDefinition() - lightning.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax - lightning.Seats(0).ControlledWeapon = 1 - lightning.Weapons += 1 -> lightning_weapon_system - lightning.MountPoints += 1 -> 0 - lightning.MountPoints += 2 -> 0 - lightning.TrunkSize = InventoryTile.Tile1511 - lightning.TrunkOffset = 30 - - val - prowler = VehicleDefinition(ObjectClass.prowler) - prowler.Seats += 0 -> new SeatDefinition() - prowler.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax - prowler.Seats += 1 -> new SeatDefinition() - prowler.Seats(1).ControlledWeapon = 3 - prowler.Seats += 2 -> new SeatDefinition() - prowler.Seats(2).ControlledWeapon = 4 - prowler.Weapons += 3 -> prowler_weapon_systemA - prowler.Weapons += 4 -> prowler_weapon_systemB - prowler.MountPoints += 1 -> 0 - prowler.MountPoints += 2 -> 1 - prowler.MountPoints += 3 -> 2 - prowler.TrunkSize = InventoryTile.Tile1511 - prowler.TrunkOffset = 30 - - val - vanguard = VehicleDefinition(ObjectClass.vanguard) - vanguard.Seats += 0 -> new SeatDefinition() - vanguard.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax - vanguard.Seats += 1 -> new SeatDefinition() - vanguard.Seats(1).ControlledWeapon = 2 - vanguard.Weapons += 2 -> vanguard_weapon_system - vanguard.MountPoints += 1 -> 0 - vanguard.MountPoints += 2 -> 1 - vanguard.TrunkSize = InventoryTile.Tile1511 - vanguard.TrunkOffset = 30 - - val - magrider = VehicleDefinition(ObjectClass.magrider) - magrider.Seats += 0 -> new SeatDefinition() - magrider.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax - magrider.Seats(0).ControlledWeapon = 2 - magrider.Seats += 1 -> new SeatDefinition() - magrider.Seats(1).ControlledWeapon = 3 - magrider.Weapons += 2 -> particle_beam_magrider - magrider.Weapons += 3 -> heavy_rail_beam_magrider - magrider.MountPoints += 1 -> 0 - magrider.MountPoints += 2 -> 1 - magrider.TrunkSize = InventoryTile.Tile1511 - magrider.TrunkOffset = 30 - - private val utilityConverter = new UtilityVehicleConverter - val - ant = VehicleDefinition(ObjectClass.ant) - ant.Seats += 0 -> new SeatDefinition() - ant.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax - ant.MountPoints += 1 -> 0 - ant.MountPoints += 2 -> 0 - ant.Packet = utilityConverter - - val - ams = VehicleDefinition(ObjectClass.ams) - ams.Seats += 0 -> new SeatDefinition() - ams.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax - ams.MountPoints += 1 -> 0 - ams.MountPoints += 2 -> 0 - ams.Packet = utilityConverter - - private val variantConverter = new VariantVehicleConverter - val - router = VehicleDefinition(ObjectClass.router) - router.Seats += 0 -> new SeatDefinition() - router.MountPoints += 1 -> 0 - router.TrunkSize = InventoryTile.Tile1511 - router.TrunkOffset = 30 - router.Packet = variantConverter - - val - switchblade = VehicleDefinition(ObjectClass.switchblade) - switchblade.Seats += 0 -> new SeatDefinition() - switchblade.Seats(0).ControlledWeapon = 1 - switchblade.Weapons += 1 -> scythe - switchblade.MountPoints += 1 -> 0 - switchblade.MountPoints += 2 -> 0 - switchblade.TrunkSize = InventoryTile.Tile1511 - switchblade.TrunkOffset = 30 - switchblade.Packet = variantConverter - - val - flail = VehicleDefinition(ObjectClass.flail) - flail.Seats += 0 -> new SeatDefinition() - flail.Seats(0).ControlledWeapon = 1 - flail.Weapons += 1 -> flail_weapon - flail.MountPoints += 1 -> 0 - flail.TrunkSize = InventoryTile.Tile1511 - flail.TrunkOffset = 30 - flail.Packet = variantConverter - - val - mosquito = VehicleDefinition(ObjectClass.mosquito) - mosquito.Seats += 0 -> new SeatDefinition() - mosquito.Seats(0).Bailable = true - mosquito.Seats(0).ControlledWeapon = 1 - mosquito.Weapons += 1 -> rotarychaingun_mosquito - mosquito.MountPoints += 1 -> 0 - mosquito.MountPoints += 2 -> 0 - mosquito.TrunkSize = InventoryTile.Tile1111 - mosquito.TrunkOffset = 30 - mosquito.Packet = variantConverter - - val - lightgunship = VehicleDefinition(ObjectClass.lightgunship) - lightgunship.Seats += 0 -> new SeatDefinition() - lightgunship.Seats(0).Bailable = true - lightgunship.Seats(0).ControlledWeapon = 1 - lightgunship.Weapons += 1 -> lightgunship_weapon_system - lightgunship.MountPoints += 1 -> 0 - lightgunship.MountPoints += 2 -> 0 - lightgunship.TrunkSize = InventoryTile.Tile1511 - lightgunship.TrunkOffset = 30 - lightgunship.Packet = variantConverter - - val - wasp = VehicleDefinition(ObjectClass.wasp) - wasp.Seats += 0 -> new SeatDefinition() - wasp.Seats(0).Bailable = true - wasp.Seats(0).ControlledWeapon = 1 - wasp.Weapons += 1 -> wasp_weapon_system - wasp.MountPoints += 1 -> 0 - wasp.MountPoints += 2 -> 0 - wasp.TrunkSize = InventoryTile.Tile1111 - wasp.TrunkOffset = 30 - wasp.Packet = variantConverter - - val - liberator = VehicleDefinition(ObjectClass.liberator) - liberator.Seats += 0 -> new SeatDefinition() - liberator.Seats(0).ControlledWeapon = 3 - liberator.Seats += 1 -> new SeatDefinition() - liberator.Seats(1).ControlledWeapon = 4 - liberator.Seats += 2 -> new SeatDefinition() - liberator.Seats(2).ControlledWeapon = 5 - liberator.Weapons += 3 -> liberator_weapon_system - liberator.Weapons += 4 -> liberator_bomb_bay - liberator.Weapons += 5 -> liberator_25mm_cannon - liberator.MountPoints += 1 -> 0 - liberator.MountPoints += 2 -> 1 - liberator.MountPoints += 3 -> 1 - liberator.MountPoints += 4 -> 2 - liberator.TrunkSize = InventoryTile.Tile1515 - liberator.TrunkOffset = 30 - liberator.Packet = variantConverter - - val - vulture = VehicleDefinition(ObjectClass.vulture) - vulture.Seats += 0 -> new SeatDefinition() - vulture.Seats(0).ControlledWeapon = 3 - vulture.Seats += 1 -> new SeatDefinition() - vulture.Seats(1).ControlledWeapon = 4 - vulture.Seats += 2 -> new SeatDefinition() - vulture.Seats(2).ControlledWeapon = 5 - vulture.Weapons += 3 -> vulture_nose_weapon_system - vulture.Weapons += 4 -> vulture_bomb_bay - vulture.Weapons += 5 -> vulture_tail_cannon - vulture.MountPoints += 1 -> 0 - vulture.MountPoints += 2 -> 1 - vulture.MountPoints += 3 -> 1 - vulture.MountPoints += 4 -> 2 - vulture.TrunkSize = InventoryTile.Tile1611 - vulture.TrunkOffset = 30 - vulture.Packet = variantConverter - - val - dropship = VehicleDefinition(ObjectClass.dropship) - dropship.Seats += 0 -> new SeatDefinition() - dropship.Seats += 1 -> new SeatDefinition() - dropship.Seats(1).Bailable = true - dropship.Seats(1).ControlledWeapon = 12 - dropship.Seats += 2 -> new SeatDefinition() - dropship.Seats(2).Bailable = true - dropship.Seats(2).ControlledWeapon = 13 - dropship.Seats += 3 -> new SeatDefinition() - dropship.Seats(3).Bailable = true - dropship.Seats += 4 -> new SeatDefinition() - dropship.Seats(4).Bailable = true - dropship.Seats += 5 -> new SeatDefinition() - dropship.Seats(5).Bailable = true - dropship.Seats += 6 -> new SeatDefinition() - dropship.Seats(6).Bailable = true - dropship.Seats += 7 -> new SeatDefinition() - dropship.Seats(7).Bailable = true - dropship.Seats += 8 -> new SeatDefinition() - dropship.Seats(8).Bailable = true - dropship.Seats += 9 -> new SeatDefinition() - dropship.Seats(9).Bailable = true - dropship.Seats(9).ArmorRestriction = SeatArmorRestriction.MaxOnly - dropship.Seats += 10 -> new SeatDefinition() - dropship.Seats(10).Bailable = true - dropship.Seats(10).ArmorRestriction = SeatArmorRestriction.MaxOnly - dropship.Seats += 11 -> new SeatDefinition() - dropship.Seats(11).Bailable = true - dropship.Seats(11).ControlledWeapon = 14 - dropship.Weapons += 12 -> cannon_dropship_20mm - dropship.Weapons += 13 -> cannon_dropship_20mm - dropship.Weapons += 14 -> dropship_rear_turret - dropship.MountPoints += 1 -> 0 - dropship.MountPoints += 2 -> 11 - dropship.MountPoints += 3 -> 1 - dropship.MountPoints += 4 -> 2 - dropship.MountPoints += 5 -> 3 - dropship.MountPoints += 6 -> 4 - dropship.MountPoints += 7 -> 5 - dropship.MountPoints += 8 -> 6 - dropship.MountPoints += 9 -> 7 - dropship.MountPoints += 10 -> 8 - dropship.MountPoints += 11 -> 9 - dropship.MountPoints += 12 -> 10 - dropship.TrunkSize = InventoryTile.Tile1612 - dropship.TrunkOffset = 30 - dropship.Packet = variantConverter - - val - galaxy_gunship = VehicleDefinition(ObjectClass.galaxy_gunship) - galaxy_gunship.Seats += 0 -> new SeatDefinition() - galaxy_gunship.Seats += 1 -> new SeatDefinition() - galaxy_gunship.Seats(1).ControlledWeapon = 6 - galaxy_gunship.Seats += 2 -> new SeatDefinition() - galaxy_gunship.Seats(2).ControlledWeapon = 7 - galaxy_gunship.Seats += 3 -> new SeatDefinition() - galaxy_gunship.Seats(3).ControlledWeapon = 8 - galaxy_gunship.Seats += 4 -> new SeatDefinition() - galaxy_gunship.Seats(4).ControlledWeapon = 9 - galaxy_gunship.Seats += 5 -> new SeatDefinition() - galaxy_gunship.Seats(5).ControlledWeapon = 10 - galaxy_gunship.Weapons += 6 -> galaxy_gunship_cannon - galaxy_gunship.Weapons += 7 -> galaxy_gunship_cannon - galaxy_gunship.Weapons += 8 -> galaxy_gunship_tailgun - galaxy_gunship.Weapons += 9 -> galaxy_gunship_gun - galaxy_gunship.Weapons += 10 -> galaxy_gunship_gun - galaxy_gunship.MountPoints += 1 -> 0 - galaxy_gunship.MountPoints += 2 -> 3 - galaxy_gunship.MountPoints += 3 -> 1 - galaxy_gunship.MountPoints += 4 -> 2 - galaxy_gunship.MountPoints += 5 -> 4 - galaxy_gunship.MountPoints += 6 -> 5 - galaxy_gunship.TrunkSize = InventoryTile.Tile1816 - galaxy_gunship.TrunkOffset = 30 - galaxy_gunship.Packet = variantConverter - - val - lodestar = VehicleDefinition(ObjectClass.lodestar) - lodestar.Seats += 0 -> new SeatDefinition() - lodestar.MountPoints += 1 -> 0 - lodestar.TrunkSize = InventoryTile.Tile1612 - lodestar.TrunkOffset = 30 - lodestar.Packet = variantConverter - - val - phantasm = VehicleDefinition(ObjectClass.phantasm) - phantasm.CanCloak = true - phantasm.Seats += 0 -> new SeatDefinition() - phantasm.Seats += 1 -> new SeatDefinition() - phantasm.Seats(1).Bailable = true - phantasm.Seats += 2 -> new SeatDefinition() - phantasm.Seats(2).Bailable = true - phantasm.Seats += 3 -> new SeatDefinition() - phantasm.Seats(3).Bailable = true - phantasm.Seats += 4 -> new SeatDefinition() - phantasm.Seats(4).Bailable = true - phantasm.MountPoints += 1 -> 0 - phantasm.MountPoints += 2 -> 1 - phantasm.MountPoints += 3 -> 2 - phantasm.MountPoints += 4 -> 3 - phantasm.MountPoints += 5 -> 4 - phantasm.TrunkSize = InventoryTile.Tile1107 - phantasm.TrunkOffset = 30 - phantasm.Packet = variantConverter - - val - order_terminal = new OrderTerminalDefinition - val - cert_terminal = new CertTerminalDefinition - val - ground_vehicle_terminal = new GroundVehicleTerminalDefinition - val - air_vehicle_terminal = new AirVehicleTerminalDefinition - val - dropship_vehicle_terminal = new DropshipVehicleTerminalDefinition - val - vehicle_terminal_combined = new VehicleTerminalCombinedDefinition - - val - spawn_pad = new ObjectDefinition(800) { Name = "spawn_pad" } - - val - lock_external = new IFFLockDefinition - val - door = new DoorDefinition + /** + * Initialize `ToolDefinition` globals. + */ + private def init_tools() : Unit = { + chainblade.Size = EquipmentSize.Melee + chainblade.AmmoTypes += melee_ammo + chainblade.FireModes += new FireModeDefinition + chainblade.FireModes.head.AmmoTypeIndices += 0 + chainblade.FireModes.head.AmmoSlotIndex = 0 + chainblade.FireModes.head.Magazine = 1 + chainblade.FireModes += new FireModeDefinition + chainblade.FireModes(1).AmmoTypeIndices += 0 + chainblade.FireModes(1).AmmoSlotIndex = 0 + chainblade.FireModes(1).Magazine = 1 + + magcutter.Size = EquipmentSize.Melee + magcutter.AmmoTypes += melee_ammo + magcutter.FireModes += new FireModeDefinition + magcutter.FireModes.head.AmmoTypeIndices += 0 + magcutter.FireModes.head.AmmoSlotIndex = 0 + magcutter.FireModes.head.Magazine = 1 + magcutter.FireModes += new FireModeDefinition + magcutter.FireModes(1).AmmoTypeIndices += 0 + magcutter.FireModes(1).AmmoSlotIndex = 0 + magcutter.FireModes(1).Magazine = 1 + + forceblade.Size = EquipmentSize.Melee + forceblade.AmmoTypes += melee_ammo + forceblade.FireModes += new FireModeDefinition + forceblade.FireModes.head.AmmoTypeIndices += 0 + forceblade.FireModes.head.AmmoSlotIndex = 0 + forceblade.FireModes.head.Magazine = 1 + forceblade.FireModes.head.Chamber = 0 + forceblade.FireModes += new FireModeDefinition + forceblade.FireModes(1).AmmoTypeIndices += 0 + forceblade.FireModes(1).AmmoSlotIndex = 0 + forceblade.FireModes(1).Magazine = 1 + forceblade.FireModes(1).Chamber = 0 + + katana.Size = EquipmentSize.Melee + katana.AmmoTypes += melee_ammo + katana.FireModes += new FireModeDefinition + katana.FireModes.head.AmmoTypeIndices += 0 + katana.FireModes.head.AmmoSlotIndex = 0 + katana.FireModes.head.Magazine = 1 + katana.FireModes.head.Chamber = 0 + katana.FireModes += new FireModeDefinition + katana.FireModes(1).AmmoTypeIndices += 0 + katana.FireModes(1).AmmoSlotIndex = 0 + katana.FireModes(1).Magazine = 1 + katana.FireModes(1).Chamber = 0 + + frag_grenade.Size = EquipmentSize.Pistol + frag_grenade.AmmoTypes += frag_grenade_ammo + frag_grenade.FireModes += new FireModeDefinition + frag_grenade.FireModes.head.AmmoTypeIndices += 0 + frag_grenade.FireModes.head.AmmoSlotIndex = 0 + frag_grenade.FireModes.head.Magazine = 3 + frag_grenade.FireModes += new FireModeDefinition + frag_grenade.FireModes(1).AmmoTypeIndices += 0 + frag_grenade.FireModes(1).AmmoSlotIndex = 0 + frag_grenade.FireModes(1).Magazine = 3 + frag_grenade.Tile = InventoryTile.Tile22 + + plasma_grenade.Size = EquipmentSize.Pistol + plasma_grenade.AmmoTypes += plasma_grenade_ammo + plasma_grenade.FireModes += new FireModeDefinition + plasma_grenade.FireModes.head.AmmoTypeIndices += 0 + plasma_grenade.FireModes.head.AmmoSlotIndex = 0 + plasma_grenade.FireModes.head.Magazine = 3 + plasma_grenade.FireModes += new FireModeDefinition + plasma_grenade.FireModes(1).AmmoTypeIndices += 0 + plasma_grenade.FireModes(1).AmmoSlotIndex = 0 + plasma_grenade.FireModes(1).Magazine = 3 + plasma_grenade.Tile = InventoryTile.Tile22 + + jammer_grenade.Size = EquipmentSize.Pistol + jammer_grenade.AmmoTypes += jammer_grenade_ammo + jammer_grenade.FireModes += new FireModeDefinition + jammer_grenade.FireModes.head.AmmoTypeIndices += 0 + jammer_grenade.FireModes.head.AmmoSlotIndex = 0 + jammer_grenade.FireModes.head.Magazine = 3 + jammer_grenade.FireModes += new FireModeDefinition + jammer_grenade.FireModes(1).AmmoTypeIndices += 0 + jammer_grenade.FireModes(1).AmmoSlotIndex = 0 + jammer_grenade.FireModes(1).Magazine = 3 + jammer_grenade.Tile = InventoryTile.Tile22 + + repeater.Size = EquipmentSize.Pistol + repeater.AmmoTypes += bullet_9mm + repeater.AmmoTypes += bullet_9mm_AP + repeater.FireModes += new FireModeDefinition + repeater.FireModes.head.AmmoTypeIndices += 0 + repeater.FireModes.head.AmmoTypeIndices += 1 + repeater.FireModes.head.AmmoSlotIndex = 0 + repeater.FireModes.head.Magazine = 20 + repeater.Tile = InventoryTile.Tile33 + + isp.Size = EquipmentSize.Pistol + isp.AmmoTypes += shotgun_shell + isp.AmmoTypes += shotgun_shell_AP + isp.FireModes += new FireModeDefinition + isp.FireModes.head.AmmoTypeIndices += 0 + isp.FireModes.head.AmmoTypeIndices += 1 + isp.FireModes.head.AmmoSlotIndex = 0 + isp.FireModes.head.Magazine = 8 + isp.Tile = InventoryTile.Tile33 + + beamer.Size = EquipmentSize.Pistol + beamer.AmmoTypes += energy_cell + beamer.FireModes += new FireModeDefinition + beamer.FireModes.head.AmmoTypeIndices += 0 + beamer.FireModes.head.AmmoSlotIndex = 0 + beamer.FireModes.head.Magazine = 16 + beamer.FireModes += new FireModeDefinition + beamer.FireModes(1).AmmoTypeIndices += 0 + beamer.FireModes(1).AmmoSlotIndex = 0 + beamer.FireModes(1).Magazine = 16 + beamer.Tile = InventoryTile.Tile33 + + ilc9.Size = EquipmentSize.Pistol + ilc9.AmmoTypes += bullet_9mm + ilc9.AmmoTypes += bullet_9mm_AP + ilc9.FireModes += new FireModeDefinition + ilc9.FireModes.head.AmmoTypeIndices += 0 + ilc9.FireModes.head.AmmoTypeIndices += 1 + ilc9.FireModes.head.AmmoSlotIndex = 0 + ilc9.FireModes.head.Magazine = 30 + ilc9.Tile = InventoryTile.Tile33 + + suppressor.Size = EquipmentSize.Rifle + suppressor.AmmoTypes += bullet_9mm + suppressor.AmmoTypes += bullet_9mm_AP + suppressor.FireModes += new FireModeDefinition + suppressor.FireModes.head.AmmoTypeIndices += 0 + suppressor.FireModes.head.AmmoTypeIndices += 1 + suppressor.FireModes.head.AmmoSlotIndex = 0 + suppressor.FireModes.head.Magazine = 25 + suppressor.Tile = InventoryTile.Tile63 + + punisher.Size = EquipmentSize.Rifle + punisher.AmmoTypes += bullet_9mm + punisher.AmmoTypes += bullet_9mm_AP + punisher.AmmoTypes += rocket + punisher.AmmoTypes += frag_cartridge + punisher.AmmoTypes += jammer_cartridge + punisher.AmmoTypes += plasma_cartridge + punisher.FireModes += new FireModeDefinition + punisher.FireModes.head.AmmoTypeIndices += 0 + punisher.FireModes.head.AmmoTypeIndices += 1 + punisher.FireModes.head.AmmoSlotIndex = 0 + punisher.FireModes.head.Magazine = 30 + punisher.FireModes += new FireModeDefinition + punisher.FireModes(1).AmmoTypeIndices += 2 + punisher.FireModes(1).AmmoTypeIndices += 3 + punisher.FireModes(1).AmmoTypeIndices += 4 + punisher.FireModes(1).AmmoTypeIndices += 5 + punisher.FireModes(1).AmmoSlotIndex = 1 + punisher.FireModes(1).Magazine = 1 + punisher.Tile = InventoryTile.Tile63 + + flechette.Size = EquipmentSize.Rifle + flechette.AmmoTypes += shotgun_shell + flechette.AmmoTypes += shotgun_shell_AP + flechette.FireModes += new FireModeDefinition + flechette.FireModes.head.AmmoTypeIndices += 0 + flechette.FireModes.head.AmmoTypeIndices += 1 + flechette.FireModes.head.AmmoSlotIndex = 0 + flechette.FireModes.head.Magazine = 12 //12 shells * 8 pellets = 96 + flechette.Tile = InventoryTile.Tile63 + + cycler.Size = EquipmentSize.Rifle + cycler.AmmoTypes += bullet_9mm + cycler.AmmoTypes += bullet_9mm_AP + cycler.FireModes += new FireModeDefinition + cycler.FireModes.head.AmmoTypeIndices += 0 + cycler.FireModes.head.AmmoTypeIndices += 1 + cycler.FireModes.head.AmmoSlotIndex = 0 + cycler.FireModes.head.Magazine = 50 + cycler.Tile = InventoryTile.Tile63 + + gauss.Size = EquipmentSize.Rifle + gauss.AmmoTypes += bullet_9mm + gauss.AmmoTypes += bullet_9mm_AP + gauss.FireModes += new FireModeDefinition + gauss.FireModes.head.AmmoTypeIndices += 0 + gauss.FireModes.head.AmmoTypeIndices += 1 + gauss.FireModes.head.AmmoSlotIndex = 0 + gauss.FireModes.head.Magazine = 30 + gauss.Tile = InventoryTile.Tile63 + + pulsar.Size = EquipmentSize.Rifle + pulsar.AmmoTypes += energy_cell + pulsar.FireModes += new FireModeDefinition + pulsar.FireModes.head.AmmoTypeIndices += 0 + pulsar.FireModes.head.AmmoSlotIndex = 0 + pulsar.FireModes.head.Magazine = 40 + pulsar.FireModes += new FireModeDefinition + pulsar.FireModes(1).AmmoTypeIndices += 0 + pulsar.FireModes(1).AmmoSlotIndex = 0 + pulsar.FireModes(1).Magazine = 40 + pulsar.Tile = InventoryTile.Tile63 + + anniversary_guna.Size = EquipmentSize.Pistol + anniversary_guna.AmmoTypes += anniversary_ammo + anniversary_guna.FireModes += new FireModeDefinition + anniversary_guna.FireModes.head.AmmoTypeIndices += 0 + anniversary_guna.FireModes.head.AmmoSlotIndex = 0 + anniversary_guna.FireModes.head.Magazine = 6 + anniversary_guna.FireModes += new FireModeDefinition + anniversary_guna.FireModes(1).AmmoTypeIndices += 0 + anniversary_guna.FireModes(1).AmmoSlotIndex = 0 + anniversary_guna.FireModes(1).Magazine = 6 + anniversary_guna.FireModes(1).Chamber = 6 + anniversary_guna.Tile = InventoryTile.Tile33 + + anniversary_gun.Size = EquipmentSize.Pistol + anniversary_gun.AmmoTypes += anniversary_ammo + anniversary_gun.FireModes += new FireModeDefinition + anniversary_gun.FireModes.head.AmmoTypeIndices += 0 + anniversary_gun.FireModes.head.AmmoSlotIndex = 0 + anniversary_gun.FireModes.head.Magazine = 6 + anniversary_gun.FireModes += new FireModeDefinition + anniversary_gun.FireModes(1).AmmoTypeIndices += 0 + anniversary_gun.FireModes(1).AmmoSlotIndex = 0 + anniversary_gun.FireModes(1).Magazine = 6 + anniversary_gun.FireModes(1).Chamber = 6 + anniversary_gun.Tile = InventoryTile.Tile33 + + anniversary_gunb.Size = EquipmentSize.Pistol + anniversary_gunb.AmmoTypes += anniversary_ammo + anniversary_gunb.FireModes += new FireModeDefinition + anniversary_gunb.FireModes.head.AmmoTypeIndices += 0 + anniversary_gunb.FireModes.head.AmmoSlotIndex = 0 + anniversary_gunb.FireModes.head.Magazine = 6 + anniversary_gunb.FireModes += new FireModeDefinition + anniversary_gunb.FireModes(1).AmmoTypeIndices += 0 + anniversary_gunb.FireModes(1).AmmoSlotIndex = 0 + anniversary_gunb.FireModes(1).Magazine = 6 + anniversary_gunb.FireModes(1).Chamber = 6 + anniversary_gunb.Tile = InventoryTile.Tile33 + + spiker.Size = EquipmentSize.Pistol + spiker.AmmoTypes += ancient_ammo_combo + spiker.FireModes += new FireModeDefinition + spiker.FireModes.head.AmmoTypeIndices += 0 + spiker.FireModes.head.AmmoSlotIndex = 0 + spiker.FireModes.head.Magazine = 25 + spiker.Tile = InventoryTile.Tile33 + + mini_chaingun.Size = EquipmentSize.Rifle + mini_chaingun.AmmoTypes += bullet_9mm + mini_chaingun.AmmoTypes += bullet_9mm_AP + mini_chaingun.FireModes += new FireModeDefinition + mini_chaingun.FireModes.head.AmmoTypeIndices += 0 + mini_chaingun.FireModes.head.AmmoTypeIndices += 1 + mini_chaingun.FireModes.head.AmmoSlotIndex = 0 + mini_chaingun.FireModes.head.Magazine = 100 + mini_chaingun.Tile = InventoryTile.Tile93 + + r_shotgun.Size = EquipmentSize.Rifle + r_shotgun.AmmoTypes += shotgun_shell + r_shotgun.AmmoTypes += shotgun_shell_AP + r_shotgun.FireModes += new FireModeDefinition + r_shotgun.FireModes.head.AmmoTypeIndices += 0 + r_shotgun.FireModes.head.AmmoTypeIndices += 1 + r_shotgun.FireModes.head.AmmoSlotIndex = 0 + r_shotgun.FireModes.head.Magazine = 16 //16 shells * 8 pellets = 128 + r_shotgun.FireModes += new FireModeDefinition + r_shotgun.FireModes(1).AmmoTypeIndices += 0 + r_shotgun.FireModes(1).AmmoTypeIndices += 1 + r_shotgun.FireModes(1).AmmoSlotIndex = 0 + r_shotgun.FireModes(1).Magazine = 16 //16 shells * 8 pellets = 128 + r_shotgun.FireModes(1).Chamber = 3 + r_shotgun.Tile = InventoryTile.Tile93 + + lasher.Size = EquipmentSize.Rifle + lasher.AmmoTypes += energy_cell + lasher.FireModes += new FireModeDefinition + lasher.FireModes.head.AmmoTypeIndices += 0 + lasher.FireModes.head.AmmoSlotIndex = 0 + lasher.FireModes.head.Magazine = 35 + lasher.FireModes += new FireModeDefinition + lasher.FireModes(1).AmmoTypeIndices += 0 + lasher.FireModes(1).AmmoSlotIndex = 0 + lasher.FireModes(1).Magazine = 35 + lasher.Tile = InventoryTile.Tile93 + + maelstrom.Size = EquipmentSize.Rifle + maelstrom.AmmoTypes += maelstrom_ammo + maelstrom.FireModes += new FireModeDefinition + maelstrom.FireModes.head.AmmoTypeIndices += 0 + maelstrom.FireModes.head.AmmoSlotIndex = 0 + maelstrom.FireModes.head.Magazine = 150 + maelstrom.FireModes += new FireModeDefinition + maelstrom.FireModes(1).AmmoTypeIndices += 0 + maelstrom.FireModes(1).AmmoSlotIndex = 0 + maelstrom.FireModes(1).Magazine = 150 + maelstrom.FireModes += new FireModeDefinition + maelstrom.FireModes(2).AmmoTypeIndices += 0 + maelstrom.FireModes(2).AmmoSlotIndex = 0 + maelstrom.FireModes(2).Magazine = 150 + maelstrom.Tile = InventoryTile.Tile93 + + phoenix.Size = EquipmentSize.Rifle + phoenix.AmmoTypes += phoenix_missile + phoenix.FireModes += new FireModeDefinition + phoenix.FireModes.head.AmmoTypeIndices += 0 + phoenix.FireModes.head.AmmoSlotIndex = 0 + phoenix.FireModes.head.Magazine = 3 + phoenix.FireModes += new FireModeDefinition + phoenix.FireModes(1).AmmoTypeIndices += 0 + phoenix.FireModes(1).AmmoSlotIndex = 0 + phoenix.FireModes(1).Magazine = 3 + phoenix.Tile = InventoryTile.Tile93 + + striker.Size = EquipmentSize.Rifle + striker.AmmoTypes += striker_missile_ammo + striker.FireModes += new FireModeDefinition + striker.FireModes.head.AmmoTypeIndices += 0 + striker.FireModes.head.AmmoSlotIndex = 0 + striker.FireModes.head.Magazine = 5 + striker.FireModes += new FireModeDefinition + striker.FireModes(1).AmmoTypeIndices += 0 + striker.FireModes(1).AmmoSlotIndex = 0 + striker.FireModes(1).Magazine = 5 + striker.Tile = InventoryTile.Tile93 + + hunterseeker.Size = EquipmentSize.Rifle + hunterseeker.AmmoTypes += hunter_seeker_missile + hunterseeker.FireModes += new FireModeDefinition + hunterseeker.FireModes.head.AmmoTypeIndices += 0 + hunterseeker.FireModes.head.AmmoSlotIndex = 0 + hunterseeker.FireModes.head.Magazine = 1 + hunterseeker.FireModes += new FireModeDefinition + hunterseeker.FireModes(1).AmmoTypeIndices += 0 + hunterseeker.FireModes(1).AmmoSlotIndex = 0 + hunterseeker.FireModes(1).Magazine = 1 + hunterseeker.Tile = InventoryTile.Tile93 + + lancer.Size = EquipmentSize.Rifle + lancer.AmmoTypes += lancer_cartridge + lancer.FireModes += new FireModeDefinition + lancer.FireModes.head.AmmoTypeIndices += 0 + lancer.FireModes.head.AmmoSlotIndex = 0 + lancer.FireModes.head.Magazine = 6 + lancer.Tile = InventoryTile.Tile93 + + rocklet.Size = EquipmentSize.Rifle + rocklet.AmmoTypes += rocket + rocklet.AmmoTypes += frag_cartridge + rocklet.FireModes += new FireModeDefinition + rocklet.FireModes.head.AmmoTypeIndices += 0 + rocklet.FireModes.head.AmmoTypeIndices += 1 + rocklet.FireModes.head.AmmoSlotIndex = 0 + rocklet.FireModes.head.Magazine = 6 + rocklet.FireModes += new FireModeDefinition + rocklet.FireModes(1).AmmoTypeIndices += 0 + rocklet.FireModes(1).AmmoTypeIndices += 1 + rocklet.FireModes(1).AmmoSlotIndex = 0 + rocklet.FireModes(1).Magazine = 6 + rocklet.FireModes(1).Chamber = 6 + rocklet.Tile = InventoryTile.Tile63 + + thumper.Size = EquipmentSize.Rifle + thumper.AmmoTypes += frag_cartridge + thumper.AmmoTypes += plasma_cartridge + thumper.AmmoTypes += jammer_cartridge + thumper.FireModes += new FireModeDefinition + thumper.FireModes.head.AmmoTypeIndices += 0 + thumper.FireModes.head.AmmoTypeIndices += 1 + thumper.FireModes.head.AmmoTypeIndices += 2 + thumper.FireModes.head.AmmoSlotIndex = 0 + thumper.FireModes.head.Magazine = 6 + thumper.FireModes += new FireModeDefinition + thumper.FireModes(1).AmmoTypeIndices += 0 + thumper.FireModes(1).AmmoTypeIndices += 1 + thumper.FireModes(1).AmmoTypeIndices += 2 + thumper.FireModes(1).AmmoSlotIndex = 0 + thumper.FireModes(1).Magazine = 6 + thumper.Tile = InventoryTile.Tile63 + + radiator.Size = EquipmentSize.Rifle + radiator.AmmoTypes += ancient_ammo_combo + radiator.FireModes += new FireModeDefinition + radiator.FireModes.head.AmmoTypeIndices += 0 + radiator.FireModes.head.AmmoSlotIndex = 0 + radiator.FireModes.head.Magazine = 25 + radiator.FireModes += new FireModeDefinition + radiator.FireModes(1).AmmoTypeIndices += 0 + radiator.FireModes(1).AmmoSlotIndex = 0 + radiator.FireModes(1).Magazine = 25 + radiator.Tile = InventoryTile.Tile63 + + heavy_sniper.Size = EquipmentSize.Rifle + heavy_sniper.AmmoTypes += bolt + heavy_sniper.FireModes += new FireModeDefinition + heavy_sniper.FireModes.head.AmmoTypeIndices += 0 + heavy_sniper.FireModes.head.AmmoSlotIndex = 0 + heavy_sniper.FireModes.head.Magazine = 10 + heavy_sniper.Tile = InventoryTile.Tile93 + + bolt_driver.Size = EquipmentSize.Rifle + bolt_driver.AmmoTypes += bolt + bolt_driver.FireModes += new FireModeDefinition + bolt_driver.FireModes.head.AmmoTypeIndices += 0 + bolt_driver.FireModes.head.AmmoSlotIndex = 0 + bolt_driver.FireModes.head.Magazine = 1 + bolt_driver.Tile = InventoryTile.Tile93 + + oicw.Size = EquipmentSize.Rifle + oicw.AmmoTypes += oicw_ammo + oicw.FireModes += new FireModeDefinition + oicw.FireModes.head.AmmoTypeIndices += 0 + oicw.FireModes.head.AmmoSlotIndex = 0 + oicw.FireModes.head.Magazine = 1 + oicw.FireModes += new FireModeDefinition + oicw.FireModes(1).AmmoTypeIndices += 0 + oicw.FireModes(1).AmmoSlotIndex = 0 + oicw.FireModes(1).Magazine = 1 + oicw.Tile = InventoryTile.Tile93 + + flamethrower.Size = EquipmentSize.Rifle + flamethrower.AmmoTypes += flamethrower_ammo + flamethrower.FireModes += new FireModeDefinition + flamethrower.FireModes.head.AmmoTypeIndices += 0 + flamethrower.FireModes.head.AmmoSlotIndex = 0 + flamethrower.FireModes.head.Magazine = 100 + flamethrower.FireModes.head.Chamber = 5 + flamethrower.FireModes += new FireModeDefinition + flamethrower.FireModes(1).AmmoTypeIndices += 0 + flamethrower.FireModes(1).AmmoSlotIndex = 0 + flamethrower.FireModes(1).Magazine = 100 + flamethrower.FireModes(1).Chamber = 50 + flamethrower.Tile = InventoryTile.Tile63 + + medicalapplicator.Size = EquipmentSize.Pistol + medicalapplicator.AmmoTypes += health_canister + medicalapplicator.FireModes += new FireModeDefinition + medicalapplicator.FireModes.head.AmmoTypeIndices += 0 + medicalapplicator.FireModes.head.AmmoSlotIndex = 0 + medicalapplicator.FireModes.head.Magazine = 100 + medicalapplicator.FireModes += new FireModeDefinition + medicalapplicator.FireModes(1).AmmoTypeIndices += 0 + medicalapplicator.FireModes(1).AmmoSlotIndex = 0 + medicalapplicator.FireModes(1).Magazine = 100 + medicalapplicator.Tile = InventoryTile.Tile33 + + nano_dispenser.Size = EquipmentSize.Rifle + nano_dispenser.AmmoTypes += armor_canister + nano_dispenser.AmmoTypes += upgrade_canister + nano_dispenser.FireModes += new FireModeDefinition + nano_dispenser.FireModes.head.AmmoTypeIndices += 0 + nano_dispenser.FireModes.head.AmmoTypeIndices += 1 + nano_dispenser.FireModes.head.AmmoSlotIndex = 0 + nano_dispenser.FireModes.head.Magazine = 100 + nano_dispenser.Tile = InventoryTile.Tile63 + + bank.Size = EquipmentSize.Pistol + bank.AmmoTypes += armor_canister + bank.FireModes += new FireModeDefinition + bank.FireModes.head.AmmoTypeIndices += 0 + bank.FireModes.head.AmmoSlotIndex = 0 + bank.FireModes.head.Magazine = 100 + bank.FireModes += new FireModeDefinition + bank.FireModes(1).AmmoTypeIndices += 0 + bank.FireModes(1).AmmoSlotIndex = 0 + bank.FireModes(1).Magazine = 100 + bank.Tile = InventoryTile.Tile33 + + remote_electronics_kit.Packet = new REKConverter + remote_electronics_kit.Tile = InventoryTile.Tile33 + + trek.Size = EquipmentSize.Pistol + trek.AmmoTypes += trek_ammo + trek.FireModes += new FireModeDefinition + trek.FireModes.head.AmmoTypeIndices += 0 + trek.FireModes.head.AmmoSlotIndex = 0 + trek.FireModes.head.Magazine = 4 + trek.FireModes += new FireModeDefinition + trek.FireModes(1).AmmoTypeIndices += 0 + trek.FireModes(1).AmmoSlotIndex = 0 + trek.FireModes(1).Magazine = 0 + trek.Tile = InventoryTile.Tile33 + + flail_targeting_laser.Packet = new CommandDetonaterConverter + flail_targeting_laser.Tile = InventoryTile.Tile33 + + command_detonater.Packet = new CommandDetonaterConverter + command_detonater.Tile = InventoryTile.Tile33 + + ace.Modes += DeployedItem.boomer + ace.Modes += DeployedItem.he_mine + ace.Modes += DeployedItem.jammer_mine + ace.Modes += DeployedItem.spitfire_turret + ace.Modes += DeployedItem.spitfire_cloaked + ace.Modes += DeployedItem.spitfire_aa + ace.Modes += DeployedItem.motionalarmsensor + ace.Modes += DeployedItem.sensor_shield + ace.Tile = InventoryTile.Tile33 + + advanced_ace.Modes += DeployedItem.tank_traps + advanced_ace.Modes += DeployedItem.portable_manned_turret + advanced_ace.Modes += DeployedItem.deployable_shield_generator + advanced_ace.Tile = InventoryTile.Tile63 + + fury_weapon_systema.Size = EquipmentSize.VehicleWeapon + fury_weapon_systema.AmmoTypes += hellfire_ammo + fury_weapon_systema.FireModes += new FireModeDefinition + fury_weapon_systema.FireModes.head.AmmoTypeIndices += 0 + fury_weapon_systema.FireModes.head.AmmoSlotIndex = 0 + fury_weapon_systema.FireModes.head.Magazine = 2 + + quadassault_weapon_system.Size = EquipmentSize.VehicleWeapon + quadassault_weapon_system.AmmoTypes += bullet_12mm + quadassault_weapon_system.FireModes += new FireModeDefinition + quadassault_weapon_system.FireModes.head.AmmoTypeIndices += 0 + quadassault_weapon_system.FireModes.head.AmmoSlotIndex = 0 + quadassault_weapon_system.FireModes.head.Magazine = 150 + + scythe.Size = EquipmentSize.VehicleWeapon + scythe.AmmoTypes += ancient_ammo_vehicle + scythe.AmmoTypes += ancient_ammo_vehicle + scythe.FireModes += new FireModeDefinition + scythe.FireModes.head.AmmoTypeIndices += 0 + scythe.FireModes.head.AmmoSlotIndex = 0 + scythe.FireModes.head.Magazine = 250 + scythe.FireModes += new FireModeDefinition + scythe.FireModes(1).AmmoTypeIndices += 0 + scythe.FireModes(1).AmmoSlotIndex = 1 //note: the scythe has two magazines using a single pool; however, it can not ammo-switch or mode-switch + scythe.FireModes(1).Magazine = 250 + + chaingun_p.Size = EquipmentSize.VehicleWeapon + chaingun_p.AmmoTypes += bullet_12mm + chaingun_p.FireModes += new FireModeDefinition + chaingun_p.FireModes.head.AmmoTypeIndices += 0 + chaingun_p.FireModes.head.AmmoSlotIndex = 0 + chaingun_p.FireModes.head.Magazine = 150 + + skyguard_weapon_system.Size = EquipmentSize.VehicleWeapon + skyguard_weapon_system.AmmoTypes += skyguard_flak_cannon_ammo + skyguard_weapon_system.AmmoTypes += bullet_12mm + skyguard_weapon_system.FireModes += new FireModeDefinition + skyguard_weapon_system.FireModes.head.AmmoTypeIndices += 0 + skyguard_weapon_system.FireModes.head.AmmoSlotIndex = 0 + skyguard_weapon_system.FireModes.head.Magazine = 40 + skyguard_weapon_system.FireModes += new FireModeDefinition + skyguard_weapon_system.FireModes(1).AmmoTypeIndices += 1 + skyguard_weapon_system.FireModes(1).AmmoSlotIndex = 1 + skyguard_weapon_system.FireModes(1).Magazine = 1 //TODO check + + grenade_launcher_marauder.Size = EquipmentSize.VehicleWeapon + grenade_launcher_marauder.AmmoTypes += heavy_grenade_mortar + grenade_launcher_marauder.FireModes += new FireModeDefinition + grenade_launcher_marauder.FireModes.head.AmmoTypeIndices += 0 + grenade_launcher_marauder.FireModes.head.AmmoSlotIndex = 0 + grenade_launcher_marauder.FireModes.head.Magazine = 50 + + advanced_missile_launcher_t.Size = EquipmentSize.VehicleWeapon + advanced_missile_launcher_t.AmmoTypes += firebird_missile + advanced_missile_launcher_t.FireModes += new FireModeDefinition + advanced_missile_launcher_t.FireModes.head.AmmoTypeIndices += 0 + advanced_missile_launcher_t.FireModes.head.AmmoSlotIndex = 0 + advanced_missile_launcher_t.FireModes.head.Magazine = 40 + + flux_cannon_thresher.Size = EquipmentSize.VehicleWeapon + flux_cannon_thresher.AmmoTypes += flux_cannon_thresher_battery + flux_cannon_thresher.FireModes += new FireModeDefinition + flux_cannon_thresher.FireModes.head.AmmoTypeIndices += 0 + flux_cannon_thresher.FireModes.head.AmmoSlotIndex = 0 + flux_cannon_thresher.FireModes.head.Magazine = 100 + + mediumtransport_weapon_systemA.Size = EquipmentSize.VehicleWeapon + mediumtransport_weapon_systemA.AmmoTypes += bullet_20mm + mediumtransport_weapon_systemA.FireModes += new FireModeDefinition + mediumtransport_weapon_systemA.FireModes.head.AmmoTypeIndices += 0 + mediumtransport_weapon_systemA.FireModes.head.AmmoSlotIndex = 0 + mediumtransport_weapon_systemA.FireModes.head.Magazine = 150 + + mediumtransport_weapon_systemB.Size = EquipmentSize.VehicleWeapon + mediumtransport_weapon_systemB.AmmoTypes += bullet_20mm + mediumtransport_weapon_systemB.FireModes += new FireModeDefinition + mediumtransport_weapon_systemB.FireModes.head.AmmoTypeIndices += 0 + mediumtransport_weapon_systemB.FireModes.head.AmmoSlotIndex = 0 + mediumtransport_weapon_systemB.FireModes.head.Magazine = 150 + + battlewagon_weapon_systema.Size = EquipmentSize.VehicleWeapon + battlewagon_weapon_systema.AmmoTypes += bullet_15mm + battlewagon_weapon_systema.FireModes += new FireModeDefinition + battlewagon_weapon_systema.FireModes.head.AmmoTypeIndices += 0 + battlewagon_weapon_systema.FireModes.head.AmmoSlotIndex = 0 + battlewagon_weapon_systema.FireModes.head.Magazine = 235 + + battlewagon_weapon_systemb.Size = EquipmentSize.VehicleWeapon + battlewagon_weapon_systemb.AmmoTypes += bullet_15mm + battlewagon_weapon_systemb.FireModes += new FireModeDefinition + battlewagon_weapon_systemb.FireModes.head.AmmoTypeIndices += 0 + battlewagon_weapon_systemb.FireModes.head.AmmoSlotIndex = 0 + battlewagon_weapon_systemb.FireModes.head.Magazine = 235 + + battlewagon_weapon_systemc.Size = EquipmentSize.VehicleWeapon + battlewagon_weapon_systemc.AmmoTypes += bullet_15mm + battlewagon_weapon_systemc.FireModes += new FireModeDefinition + battlewagon_weapon_systemc.FireModes.head.AmmoTypeIndices += 0 + battlewagon_weapon_systemc.FireModes.head.AmmoSlotIndex = 0 + battlewagon_weapon_systemc.FireModes.head.Magazine = 235 + + battlewagon_weapon_systemd.Size = EquipmentSize.VehicleWeapon + battlewagon_weapon_systemd.AmmoTypes += bullet_15mm + battlewagon_weapon_systemd.FireModes += new FireModeDefinition + battlewagon_weapon_systemd.FireModes.head.AmmoTypeIndices += 0 + battlewagon_weapon_systemd.FireModes.head.AmmoSlotIndex = 0 + battlewagon_weapon_systemd.FireModes.head.Magazine = 235 + + thunderer_weapon_systema.Size = EquipmentSize.VehicleWeapon + thunderer_weapon_systema.AmmoTypes += gauss_cannon_ammo + thunderer_weapon_systema.FireModes += new FireModeDefinition + thunderer_weapon_systema.FireModes.head.AmmoTypeIndices += 0 + thunderer_weapon_systema.FireModes.head.AmmoSlotIndex = 0 + thunderer_weapon_systema.FireModes.head.Magazine = 15 + + thunderer_weapon_systemb.Size = EquipmentSize.VehicleWeapon + thunderer_weapon_systemb.AmmoTypes += gauss_cannon_ammo + thunderer_weapon_systemb.FireModes += new FireModeDefinition + thunderer_weapon_systemb.FireModes.head.AmmoTypeIndices += 0 + thunderer_weapon_systemb.FireModes.head.AmmoSlotIndex = 0 + thunderer_weapon_systemb.FireModes.head.Magazine = 15 + + aurora_weapon_systema.Size = EquipmentSize.VehicleWeapon + aurora_weapon_systema.AmmoTypes += fluxpod_ammo + aurora_weapon_systema.FireModes += new FireModeDefinition + aurora_weapon_systema.FireModes.head.AmmoTypeIndices += 0 + aurora_weapon_systema.FireModes.head.AmmoSlotIndex = 0 + aurora_weapon_systema.FireModes.head.Magazine = 12 + aurora_weapon_systema.FireModes += new FireModeDefinition + aurora_weapon_systema.FireModes(1).AmmoTypeIndices += 0 + aurora_weapon_systema.FireModes(1).AmmoSlotIndex = 1 + aurora_weapon_systema.FireModes(1).Magazine = 12 + + aurora_weapon_systemb.Size = EquipmentSize.VehicleWeapon + aurora_weapon_systemb.AmmoTypes += fluxpod_ammo + aurora_weapon_systemb.FireModes += new FireModeDefinition + aurora_weapon_systemb.FireModes.head.AmmoTypeIndices += 0 + aurora_weapon_systemb.FireModes.head.AmmoSlotIndex = 0 + aurora_weapon_systemb.FireModes.head.Magazine = 12 + aurora_weapon_systemb.FireModes += new FireModeDefinition + aurora_weapon_systemb.FireModes(1).AmmoTypeIndices += 0 + aurora_weapon_systemb.FireModes(1).AmmoSlotIndex = 1 + aurora_weapon_systemb.FireModes(1).Magazine = 12 + + apc_weapon_systema.Size = EquipmentSize.VehicleWeapon + apc_weapon_systema.AmmoTypes += bullet_75mm + apc_weapon_systema.FireModes += new FireModeDefinition + apc_weapon_systema.FireModes.head.AmmoTypeIndices += 0 + apc_weapon_systema.FireModes.head.AmmoSlotIndex = 0 + apc_weapon_systema.FireModes.head.Magazine = 50 + + apc_weapon_systemb.Size = EquipmentSize.VehicleWeapon + apc_weapon_systemb.AmmoTypes += bullet_75mm + apc_weapon_systemb.FireModes += new FireModeDefinition + apc_weapon_systemb.FireModes.head.AmmoTypeIndices += 0 + apc_weapon_systemb.FireModes.head.AmmoSlotIndex = 0 + apc_weapon_systemb.FireModes.head.Magazine = 50 + + apc_ballgun_r.Size = EquipmentSize.VehicleWeapon + apc_ballgun_r.AmmoTypes += bullet_12mm + apc_ballgun_r.FireModes += new FireModeDefinition + apc_ballgun_r.FireModes.head.AmmoTypeIndices += 0 + apc_ballgun_r.FireModes.head.AmmoSlotIndex = 0 + apc_ballgun_r.FireModes.head.Magazine = 150 + + apc_ballgun_l.Size = EquipmentSize.VehicleWeapon + apc_ballgun_l.AmmoTypes += bullet_12mm + apc_ballgun_l.FireModes += new FireModeDefinition + apc_ballgun_l.FireModes.head.AmmoTypeIndices += 0 + apc_ballgun_l.FireModes.head.AmmoSlotIndex = 0 + apc_ballgun_l.FireModes.head.Magazine = 150 + + apc_weapon_systemc_tr.Size = EquipmentSize.VehicleWeapon + apc_weapon_systemc_tr.AmmoTypes += bullet_15mm + apc_weapon_systemc_tr.FireModes += new FireModeDefinition + apc_weapon_systemc_tr.FireModes.head.AmmoTypeIndices += 0 + apc_weapon_systemc_tr.FireModes.head.AmmoSlotIndex = 0 + apc_weapon_systemc_tr.FireModes.head.Magazine = 150 + + apc_weapon_systemd_tr.Size = EquipmentSize.VehicleWeapon + apc_weapon_systemd_tr.AmmoTypes += bullet_15mm + apc_weapon_systemd_tr.FireModes += new FireModeDefinition + apc_weapon_systemd_tr.FireModes.head.AmmoTypeIndices += 0 + apc_weapon_systemd_tr.FireModes.head.AmmoSlotIndex = 0 + apc_weapon_systemd_tr.FireModes.head.Magazine = 150 + + apc_weapon_systemc_nc.Size = EquipmentSize.VehicleWeapon + apc_weapon_systemc_nc.AmmoTypes += bullet_20mm + apc_weapon_systemc_nc.FireModes += new FireModeDefinition + apc_weapon_systemc_nc.FireModes.head.AmmoTypeIndices += 0 + apc_weapon_systemc_nc.FireModes.head.AmmoSlotIndex = 0 + apc_weapon_systemc_nc.FireModes.head.Magazine = 150 + + apc_weapon_systemd_nc.Size = EquipmentSize.VehicleWeapon + apc_weapon_systemd_nc.AmmoTypes += bullet_20mm + apc_weapon_systemd_nc.FireModes += new FireModeDefinition + apc_weapon_systemd_nc.FireModes.head.AmmoTypeIndices += 0 + apc_weapon_systemd_nc.FireModes.head.AmmoSlotIndex = 0 + apc_weapon_systemd_nc.FireModes.head.Magazine = 150 + + apc_weapon_systemc_vs.Size = EquipmentSize.VehicleWeapon + apc_weapon_systemc_vs.AmmoTypes += flux_cannon_thresher_battery + apc_weapon_systemc_vs.FireModes += new FireModeDefinition + apc_weapon_systemc_vs.FireModes.head.AmmoTypeIndices += 0 + apc_weapon_systemc_vs.FireModes.head.AmmoSlotIndex = 0 + apc_weapon_systemc_vs.FireModes.head.Magazine = 100 + + apc_weapon_systemd_vs.Size = EquipmentSize.VehicleWeapon + apc_weapon_systemd_vs.AmmoTypes += flux_cannon_thresher_battery + apc_weapon_systemd_vs.FireModes += new FireModeDefinition + apc_weapon_systemd_vs.FireModes.head.AmmoTypeIndices += 0 + apc_weapon_systemd_vs.FireModes.head.AmmoSlotIndex = 0 + apc_weapon_systemd_vs.FireModes.head.Magazine = 100 + + lightning_weapon_system.Size = EquipmentSize.VehicleWeapon + lightning_weapon_system.AmmoTypes += bullet_75mm + lightning_weapon_system.AmmoTypes += bullet_25mm + lightning_weapon_system.FireModes += new FireModeDefinition + lightning_weapon_system.FireModes.head.AmmoTypeIndices += 0 + lightning_weapon_system.FireModes.head.AmmoSlotIndex = 0 + lightning_weapon_system.FireModes.head.Magazine = 20 + lightning_weapon_system.FireModes += new FireModeDefinition + lightning_weapon_system.FireModes(1).AmmoTypeIndices += 1 + lightning_weapon_system.FireModes(1).AmmoSlotIndex = 1 + lightning_weapon_system.FireModes(1).Magazine = 1 //TODO check + + prowler_weapon_systemA.Size = EquipmentSize.VehicleWeapon + prowler_weapon_systemA.AmmoTypes += bullet_105mm + prowler_weapon_systemA.FireModes += new FireModeDefinition + prowler_weapon_systemA.FireModes.head.AmmoTypeIndices += 0 + prowler_weapon_systemA.FireModes.head.AmmoSlotIndex = 0 + prowler_weapon_systemA.FireModes.head.Magazine = 20 + + prowler_weapon_systemB.Size = EquipmentSize.VehicleWeapon + prowler_weapon_systemB.AmmoTypes += bullet_15mm + prowler_weapon_systemB.FireModes += new FireModeDefinition + prowler_weapon_systemB.FireModes.head.AmmoTypeIndices += 0 + prowler_weapon_systemB.FireModes.head.AmmoSlotIndex = 0 + prowler_weapon_systemB.FireModes.head.Magazine = 235 + + vanguard_weapon_system.Size = EquipmentSize.VehicleWeapon + vanguard_weapon_system.AmmoTypes += bullet_150mm + vanguard_weapon_system.AmmoTypes += bullet_20mm + vanguard_weapon_system.FireModes += new FireModeDefinition + vanguard_weapon_system.FireModes.head.AmmoTypeIndices += 0 + vanguard_weapon_system.FireModes.head.AmmoSlotIndex = 0 + vanguard_weapon_system.FireModes.head.Magazine = 10 + vanguard_weapon_system.FireModes += new FireModeDefinition + vanguard_weapon_system.FireModes(1).AmmoTypeIndices += 1 + vanguard_weapon_system.FireModes(1).AmmoSlotIndex = 1 + vanguard_weapon_system.FireModes(1).Magazine = 1 //TODO check + + particle_beam_magrider.Size = EquipmentSize.VehicleWeapon + particle_beam_magrider.AmmoTypes += pulse_battery + particle_beam_magrider.FireModes += new FireModeDefinition + particle_beam_magrider.FireModes.head.AmmoTypeIndices += 0 + particle_beam_magrider.FireModes.head.AmmoSlotIndex = 0 + particle_beam_magrider.FireModes.head.Magazine = 150 + + heavy_rail_beam_magrider.Size = EquipmentSize.VehicleWeapon + heavy_rail_beam_magrider.AmmoTypes += heavy_rail_beam_battery + heavy_rail_beam_magrider.FireModes += new FireModeDefinition + heavy_rail_beam_magrider.FireModes.head.AmmoTypeIndices += 0 + heavy_rail_beam_magrider.FireModes.head.AmmoSlotIndex = 0 + heavy_rail_beam_magrider.FireModes.head.Magazine = 25 + + flail_weapon.Size = EquipmentSize.VehicleWeapon + flail_weapon.AmmoTypes += ancient_ammo_vehicle + flail_weapon.FireModes += new FireModeDefinition + flail_weapon.FireModes.head.AmmoTypeIndices += 0 + flail_weapon.FireModes.head.AmmoSlotIndex = 0 + flail_weapon.FireModes.head.Magazine = 100 + + rotarychaingun_mosquito.Size = EquipmentSize.VehicleWeapon + rotarychaingun_mosquito.AmmoTypes += bullet_12mm + rotarychaingun_mosquito.FireModes += new FireModeDefinition + rotarychaingun_mosquito.FireModes.head.AmmoTypeIndices += 0 + rotarychaingun_mosquito.FireModes.head.AmmoSlotIndex = 0 + rotarychaingun_mosquito.FireModes.head.Magazine = 150 + + lightgunship_weapon_system.Size = EquipmentSize.VehicleWeapon + lightgunship_weapon_system.AmmoTypes += bullet_20mm + lightgunship_weapon_system.AmmoTypes += reaver_rocket + lightgunship_weapon_system.FireModes += new FireModeDefinition + lightgunship_weapon_system.FireModes.head.AmmoTypeIndices += 0 + lightgunship_weapon_system.FireModes.head.AmmoSlotIndex = 0 + lightgunship_weapon_system.FireModes.head.Magazine = 150 + lightgunship_weapon_system.FireModes += new FireModeDefinition + lightgunship_weapon_system.FireModes(1).AmmoTypeIndices += 1 + lightgunship_weapon_system.FireModes(1).AmmoSlotIndex = 1 + lightgunship_weapon_system.FireModes(1).Magazine = 1 //TODO check + + wasp_weapon_system.Size = EquipmentSize.VehicleWeapon + wasp_weapon_system.AmmoTypes += wasp_gun_ammo + wasp_weapon_system.AmmoTypes += wasp_rocket_ammo + wasp_weapon_system.FireModes += new FireModeDefinition + wasp_weapon_system.FireModes.head.AmmoTypeIndices += 0 + wasp_weapon_system.FireModes.head.AmmoSlotIndex = 0 + wasp_weapon_system.FireModes.head.Magazine = 30 + wasp_weapon_system.FireModes += new FireModeDefinition + wasp_weapon_system.FireModes(1).AmmoTypeIndices += 1 + wasp_weapon_system.FireModes(1).AmmoSlotIndex = 1 + wasp_weapon_system.FireModes(1).Magazine = 1 //TODO check + + liberator_weapon_system.Size = EquipmentSize.VehicleWeapon + liberator_weapon_system.AmmoTypes += bullet_35mm + liberator_weapon_system.FireModes += new FireModeDefinition + liberator_weapon_system.FireModes.head.AmmoTypeIndices += 0 + liberator_weapon_system.FireModes.head.AmmoSlotIndex = 0 + liberator_weapon_system.FireModes.head.Magazine = 100 + + liberator_bomb_bay.Size = EquipmentSize.VehicleWeapon + liberator_bomb_bay.AmmoTypes += liberator_bomb + liberator_bomb_bay.FireModes += new FireModeDefinition + liberator_bomb_bay.FireModes.head.AmmoTypeIndices += 0 + liberator_bomb_bay.FireModes.head.AmmoSlotIndex = 0 + liberator_bomb_bay.FireModes.head.Magazine = 10 + liberator_bomb_bay.FireModes += new FireModeDefinition + liberator_bomb_bay.FireModes(1).AmmoTypeIndices += 0 + liberator_bomb_bay.FireModes(1).AmmoSlotIndex = 0 + liberator_bomb_bay.FireModes(1).Magazine = 10 + + liberator_25mm_cannon.Size = EquipmentSize.VehicleWeapon + liberator_25mm_cannon.AmmoTypes += bullet_25mm + liberator_25mm_cannon.FireModes += new FireModeDefinition + liberator_25mm_cannon.FireModes.head.AmmoTypeIndices += 0 + liberator_25mm_cannon.FireModes.head.AmmoSlotIndex = 0 + liberator_25mm_cannon.FireModes.head.Magazine = 150 + + vulture_nose_weapon_system.Size = EquipmentSize.VehicleWeapon + vulture_nose_weapon_system.AmmoTypes += bullet_35mm + vulture_nose_weapon_system.FireModes += new FireModeDefinition + vulture_nose_weapon_system.FireModes.head.AmmoTypeIndices += 0 + vulture_nose_weapon_system.FireModes.head.AmmoSlotIndex = 0 + vulture_nose_weapon_system.FireModes.head.Magazine = 75 //80? + + vulture_bomb_bay.Size = EquipmentSize.VehicleWeapon + vulture_bomb_bay.AmmoTypes += liberator_bomb + vulture_bomb_bay.FireModes += new FireModeDefinition + vulture_bomb_bay.FireModes.head.AmmoTypeIndices += 0 + vulture_bomb_bay.FireModes.head.AmmoSlotIndex = 0 + vulture_bomb_bay.FireModes.head.Magazine = 10 + + vulture_tail_cannon.Size = EquipmentSize.VehicleWeapon + vulture_tail_cannon.AmmoTypes += bullet_25mm + vulture_tail_cannon.FireModes += new FireModeDefinition + vulture_tail_cannon.FireModes.head.AmmoTypeIndices += 0 + vulture_tail_cannon.FireModes.head.AmmoSlotIndex = 0 + vulture_tail_cannon.FireModes.head.Magazine = 100 + + cannon_dropship_20mm.Size = EquipmentSize.VehicleWeapon + cannon_dropship_20mm.AmmoTypes += bullet_20mm + cannon_dropship_20mm.FireModes += new FireModeDefinition + cannon_dropship_20mm.FireModes.head.AmmoTypeIndices += 0 + cannon_dropship_20mm.FireModes.head.AmmoSlotIndex = 0 + cannon_dropship_20mm.FireModes.head.Magazine = 250 + + dropship_rear_turret.Size = EquipmentSize.VehicleWeapon + dropship_rear_turret.AmmoTypes += bullet_20mm + dropship_rear_turret.FireModes += new FireModeDefinition + dropship_rear_turret.FireModes.head.AmmoTypeIndices += 0 + dropship_rear_turret.FireModes.head.AmmoSlotIndex = 0 + dropship_rear_turret.FireModes.head.Magazine = 250 + + galaxy_gunship_cannon.Size = EquipmentSize.VehicleWeapon + galaxy_gunship_cannon.AmmoTypes += heavy_grenade_mortar + galaxy_gunship_cannon.FireModes += new FireModeDefinition + galaxy_gunship_cannon.FireModes.head.AmmoTypeIndices += 0 + galaxy_gunship_cannon.FireModes.head.AmmoSlotIndex = 0 + galaxy_gunship_cannon.FireModes.head.Magazine = 50 + + galaxy_gunship_tailgun.Size = EquipmentSize.VehicleWeapon + galaxy_gunship_tailgun.AmmoTypes += bullet_35mm + galaxy_gunship_tailgun.FireModes += new FireModeDefinition + galaxy_gunship_tailgun.FireModes.head.AmmoTypeIndices += 0 + galaxy_gunship_tailgun.FireModes.head.AmmoSlotIndex = 0 + galaxy_gunship_tailgun.FireModes.head.Magazine = 200 + + galaxy_gunship_gun.Size = EquipmentSize.VehicleWeapon + galaxy_gunship_gun.AmmoTypes += bullet_35mm + galaxy_gunship_gun.FireModes += new FireModeDefinition + galaxy_gunship_gun.FireModes.head.AmmoTypeIndices += 0 + galaxy_gunship_gun.FireModes.head.AmmoSlotIndex = 0 + galaxy_gunship_gun.FireModes.head.Magazine = 200 + } + + /** + * Initialize `VehicleDefinition` globals. + */ + private def init_vehicles() : Unit = { + fury.Seats += 0 -> new SeatDefinition() + fury.Seats(0).Bailable = true + fury.Seats(0).ControlledWeapon = 1 + fury.Weapons += 1 -> fury_weapon_systema + fury.MountPoints += 1 -> 0 + fury.MountPoints += 2 -> 0 + fury.TrunkSize = InventoryTile.Tile1111 + fury.TrunkOffset = 30 + + quadassault.Seats += 0 -> new SeatDefinition() + quadassault.Seats(0).Bailable = true + quadassault.Seats(0).ControlledWeapon = 1 + quadassault.Weapons += 1 -> quadassault_weapon_system + quadassault.MountPoints += 1 -> 0 + quadassault.MountPoints += 2 -> 0 + quadassault.TrunkSize = InventoryTile.Tile1111 + quadassault.TrunkOffset = 30 + + quadstealth.CanCloak = true + quadstealth.Seats += 0 -> new SeatDefinition() + quadstealth.Seats(0).Bailable = true + quadstealth.CanCloak = true + quadstealth.MountPoints += 1 -> 0 + quadstealth.MountPoints += 2 -> 0 + quadstealth.TrunkSize = InventoryTile.Tile1111 + quadstealth.TrunkOffset = 30 + + two_man_assault_buggy.Seats += 0 -> new SeatDefinition() + two_man_assault_buggy.Seats(0).Bailable = true + two_man_assault_buggy.Seats += 1 -> new SeatDefinition() + two_man_assault_buggy.Seats(1).Bailable = true + two_man_assault_buggy.Seats(1).ControlledWeapon = 2 + two_man_assault_buggy.Weapons += 2 -> chaingun_p + two_man_assault_buggy.MountPoints += 1 -> 0 + two_man_assault_buggy.MountPoints += 2 -> 1 + two_man_assault_buggy.TrunkSize = InventoryTile.Tile1111 + two_man_assault_buggy.TrunkOffset = 30 + + skyguard.Seats += 0 -> new SeatDefinition() + skyguard.Seats(0).Bailable = true + skyguard.Seats += 1 -> new SeatDefinition() + skyguard.Seats(1).Bailable = true + skyguard.Seats(1).ControlledWeapon = 2 + skyguard.Weapons += 2 -> skyguard_weapon_system + skyguard.MountPoints += 1 -> 0 + skyguard.MountPoints += 2 -> 0 + skyguard.MountPoints += 3 -> 1 + skyguard.TrunkSize = InventoryTile.Tile1511 + skyguard.TrunkOffset = 30 + + threemanheavybuggy.Seats += 0 -> new SeatDefinition() + threemanheavybuggy.Seats(0).Bailable = true + threemanheavybuggy.Seats += 1 -> new SeatDefinition() + threemanheavybuggy.Seats(1).Bailable = true + threemanheavybuggy.Seats(1).ControlledWeapon = 3 + threemanheavybuggy.Seats += 2 -> new SeatDefinition() + threemanheavybuggy.Seats(2).Bailable = true + threemanheavybuggy.Seats(2).ControlledWeapon = 4 + threemanheavybuggy.Weapons += 3 -> chaingun_p + threemanheavybuggy.Weapons += 4 -> grenade_launcher_marauder + threemanheavybuggy.MountPoints += 1 -> 0 + threemanheavybuggy.MountPoints += 2 -> 1 + threemanheavybuggy.MountPoints += 3 -> 2 + threemanheavybuggy.TrunkSize = InventoryTile.Tile1511 + threemanheavybuggy.TrunkOffset = 30 + + twomanheavybuggy.Seats += 0 -> new SeatDefinition() + twomanheavybuggy.Seats(0).Bailable = true + twomanheavybuggy.Seats += 1 -> new SeatDefinition() + twomanheavybuggy.Seats(1).Bailable = true + twomanheavybuggy.Seats(1).ControlledWeapon = 2 + twomanheavybuggy.Weapons += 2 -> advanced_missile_launcher_t + twomanheavybuggy.MountPoints += 1 -> 0 + twomanheavybuggy.MountPoints += 2 -> 1 + twomanheavybuggy.TrunkSize = InventoryTile.Tile1511 + twomanheavybuggy.TrunkOffset = 30 + + twomanhoverbuggy.Seats += 0 -> new SeatDefinition() + twomanhoverbuggy.Seats(0).Bailable = true + twomanhoverbuggy.Seats += 1 -> new SeatDefinition() + twomanhoverbuggy.Seats(1).Bailable = true + twomanhoverbuggy.Seats(1).ControlledWeapon = 2 + twomanhoverbuggy.Weapons += 2 -> flux_cannon_thresher + twomanhoverbuggy.MountPoints += 1 -> 0 + twomanhoverbuggy.MountPoints += 2 -> 1 + twomanhoverbuggy.TrunkSize = InventoryTile.Tile1511 + twomanhoverbuggy.TrunkOffset = 30 + + mediumtransport.Seats += 0 -> new SeatDefinition() + mediumtransport.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + mediumtransport.Seats += 1 -> new SeatDefinition() + mediumtransport.Seats(1).ControlledWeapon = 5 + mediumtransport.Seats += 2 -> new SeatDefinition() + mediumtransport.Seats(2).ControlledWeapon = 6 + mediumtransport.Seats += 3 -> new SeatDefinition() + mediumtransport.Seats += 4 -> new SeatDefinition() + mediumtransport.Weapons += 5 -> mediumtransport_weapon_systemA + mediumtransport.Weapons += 6 -> mediumtransport_weapon_systemB + mediumtransport.MountPoints += 1 -> 0 + mediumtransport.MountPoints += 2 -> 1 + mediumtransport.MountPoints += 3 -> 2 + mediumtransport.MountPoints += 4 -> 3 + mediumtransport.MountPoints += 5 -> 4 + mediumtransport.TrunkSize = InventoryTile.Tile1515 + mediumtransport.TrunkOffset = 30 + + battlewagon.Seats += 0 -> new SeatDefinition() + battlewagon.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + battlewagon.Seats += 1 -> new SeatDefinition() + battlewagon.Seats(1).ControlledWeapon = 5 + battlewagon.Seats += 2 -> new SeatDefinition() + battlewagon.Seats(2).ControlledWeapon = 6 + battlewagon.Seats += 3 -> new SeatDefinition() + battlewagon.Seats(3).ControlledWeapon = 7 + battlewagon.Seats += 4 -> new SeatDefinition() + battlewagon.Seats(4).ControlledWeapon = 8 + battlewagon.Weapons += 5 -> battlewagon_weapon_systema + battlewagon.Weapons += 6 -> battlewagon_weapon_systemb + battlewagon.Weapons += 7 -> battlewagon_weapon_systemc + battlewagon.Weapons += 8 -> battlewagon_weapon_systemd + battlewagon.MountPoints += 1 -> 0 + battlewagon.MountPoints += 2 -> 1 + battlewagon.MountPoints += 3 -> 2 + battlewagon.MountPoints += 4 -> 3 + battlewagon.MountPoints += 5 -> 4 + battlewagon.TrunkSize = InventoryTile.Tile1515 + battlewagon.TrunkOffset = 30 + + thunderer.Seats += 0 -> new SeatDefinition() + thunderer.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + thunderer.Seats += 1 -> new SeatDefinition() + thunderer.Seats(1).ControlledWeapon = 5 + thunderer.Seats += 2 -> new SeatDefinition() + thunderer.Seats(2).ControlledWeapon = 6 + thunderer.Seats += 3 -> new SeatDefinition() + thunderer.Seats += 4 -> new SeatDefinition() + thunderer.Weapons += 5 -> thunderer_weapon_systema + thunderer.Weapons += 6 -> thunderer_weapon_systemb + thunderer.MountPoints += 1 -> 0 + thunderer.MountPoints += 2 -> 1 + thunderer.MountPoints += 3 -> 2 + thunderer.MountPoints += 4 -> 3 + thunderer.MountPoints += 5 -> 4 + thunderer.TrunkSize = InventoryTile.Tile1515 + thunderer.TrunkOffset = 30 + + aurora.Seats += 0 -> new SeatDefinition() + aurora.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + aurora.Seats += 1 -> new SeatDefinition() + aurora.Seats(1).ControlledWeapon = 5 + aurora.Seats += 2 -> new SeatDefinition() + aurora.Seats(2).ControlledWeapon = 6 + aurora.Seats += 3 -> new SeatDefinition() + aurora.Seats += 4 -> new SeatDefinition() + aurora.Weapons += 5 -> aurora_weapon_systema + aurora.Weapons += 6 -> aurora_weapon_systemb + aurora.MountPoints += 1 -> 0 + aurora.MountPoints += 2 -> 1 + aurora.MountPoints += 3 -> 2 + aurora.MountPoints += 4 -> 3 + aurora.MountPoints += 5 -> 4 + aurora.TrunkSize = InventoryTile.Tile1515 + aurora.TrunkOffset = 30 + + apc_tr.Seats += 0 -> new SeatDefinition() + apc_tr.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + apc_tr.Seats += 1 -> new SeatDefinition() + apc_tr.Seats(1).ControlledWeapon = 11 + apc_tr.Seats += 2 -> new SeatDefinition() + apc_tr.Seats(2).ControlledWeapon = 12 + apc_tr.Seats += 3 -> new SeatDefinition() + apc_tr.Seats += 4 -> new SeatDefinition() + apc_tr.Seats += 5 -> new SeatDefinition() + apc_tr.Seats(5).ControlledWeapon = 15 + apc_tr.Seats += 6 -> new SeatDefinition() + apc_tr.Seats(6).ControlledWeapon = 16 + apc_tr.Seats += 7 -> new SeatDefinition() + apc_tr.Seats(7).ControlledWeapon = 13 + apc_tr.Seats += 8 -> new SeatDefinition() + apc_tr.Seats(8).ControlledWeapon = 14 + apc_tr.Seats += 9 -> new SeatDefinition() + apc_tr.Seats(9).ArmorRestriction = SeatArmorRestriction.MaxOnly + apc_tr.Seats += 10 -> new SeatDefinition() + apc_tr.Seats(10).ArmorRestriction = SeatArmorRestriction.MaxOnly + apc_tr.Weapons += 11 -> apc_weapon_systemc_tr + apc_tr.Weapons += 12 -> apc_weapon_systemb + apc_tr.Weapons += 13 -> apc_weapon_systema + apc_tr.Weapons += 14 -> apc_weapon_systemd_tr + apc_tr.Weapons += 15 -> apc_ballgun_r + apc_tr.Weapons += 16 -> apc_ballgun_l + apc_tr.MountPoints += 1 -> 0 + apc_tr.MountPoints += 2 -> 0 + apc_tr.MountPoints += 3 -> 1 + apc_tr.MountPoints += 4 -> 2 + apc_tr.MountPoints += 5 -> 3 + apc_tr.MountPoints += 6 -> 4 + apc_tr.MountPoints += 7 -> 5 + apc_tr.MountPoints += 8 -> 6 + apc_tr.MountPoints += 9 -> 7 + apc_tr.MountPoints += 10 -> 8 + apc_tr.MountPoints += 11 -> 9 + apc_tr.MountPoints += 12 -> 10 + apc_tr.TrunkSize = InventoryTile.Tile2016 + apc_tr.TrunkOffset = 30 + + apc_nc.Seats += 0 -> new SeatDefinition() + apc_nc.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + apc_nc.Seats += 1 -> new SeatDefinition() + apc_nc.Seats(1).ControlledWeapon = 11 + apc_nc.Seats += 2 -> new SeatDefinition() + apc_nc.Seats(2).ControlledWeapon = 12 + apc_nc.Seats += 3 -> new SeatDefinition() + apc_nc.Seats += 4 -> new SeatDefinition() + apc_nc.Seats += 5 -> new SeatDefinition() + apc_nc.Seats(5).ControlledWeapon = 15 + apc_nc.Seats += 6 -> new SeatDefinition() + apc_nc.Seats(6).ControlledWeapon = 16 + apc_nc.Seats += 7 -> new SeatDefinition() + apc_nc.Seats(7).ControlledWeapon = 13 + apc_nc.Seats += 8 -> new SeatDefinition() + apc_nc.Seats(8).ControlledWeapon = 14 + apc_nc.Seats += 9 -> new SeatDefinition() + apc_nc.Seats(9).ArmorRestriction = SeatArmorRestriction.MaxOnly + apc_nc.Seats += 10 -> new SeatDefinition() + apc_nc.Seats(10).ArmorRestriction = SeatArmorRestriction.MaxOnly + apc_nc.Weapons += 11 -> apc_weapon_systemc_nc + apc_nc.Weapons += 12 -> apc_weapon_systemb + apc_nc.Weapons += 13 -> apc_weapon_systema + apc_nc.Weapons += 14 -> apc_weapon_systemd_nc + apc_nc.Weapons += 15 -> apc_ballgun_r + apc_nc.Weapons += 16 -> apc_ballgun_l + apc_nc.MountPoints += 1 -> 0 + apc_nc.MountPoints += 2 -> 0 + apc_nc.MountPoints += 3 -> 1 + apc_nc.MountPoints += 4 -> 2 + apc_nc.MountPoints += 5 -> 3 + apc_nc.MountPoints += 6 -> 4 + apc_nc.MountPoints += 7 -> 5 + apc_nc.MountPoints += 8 -> 6 + apc_nc.MountPoints += 9 -> 7 + apc_nc.MountPoints += 10 -> 8 + apc_nc.MountPoints += 11 -> 9 + apc_nc.MountPoints += 12 -> 10 + apc_nc.TrunkSize = InventoryTile.Tile2016 + apc_nc.TrunkOffset = 30 + + apc_vs.Seats += 0 -> new SeatDefinition() + apc_vs.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + apc_vs.Seats += 1 -> new SeatDefinition() + apc_vs.Seats(1).ControlledWeapon = 11 + apc_vs.Seats += 2 -> new SeatDefinition() + apc_vs.Seats(2).ControlledWeapon = 12 + apc_vs.Seats += 3 -> new SeatDefinition() + apc_vs.Seats += 4 -> new SeatDefinition() + apc_vs.Seats += 5 -> new SeatDefinition() + apc_vs.Seats(5).ControlledWeapon = 15 + apc_vs.Seats += 6 -> new SeatDefinition() + apc_vs.Seats(6).ControlledWeapon = 16 + apc_vs.Seats += 7 -> new SeatDefinition() + apc_vs.Seats(7).ControlledWeapon = 13 + apc_vs.Seats += 8 -> new SeatDefinition() + apc_vs.Seats(8).ControlledWeapon = 14 + apc_vs.Seats += 9 -> new SeatDefinition() + apc_vs.Seats(9).ArmorRestriction = SeatArmorRestriction.MaxOnly + apc_vs.Seats += 10 -> new SeatDefinition() + apc_vs.Seats(10).ArmorRestriction = SeatArmorRestriction.MaxOnly + apc_vs.Weapons += 11 -> apc_weapon_systemc_vs + apc_vs.Weapons += 12 -> apc_weapon_systemb + apc_vs.Weapons += 13 -> apc_weapon_systema + apc_vs.Weapons += 14 -> apc_weapon_systemd_vs + apc_vs.Weapons += 15 -> apc_ballgun_r + apc_vs.Weapons += 16 -> apc_ballgun_l + apc_vs.MountPoints += 1 -> 0 + apc_vs.MountPoints += 2 -> 0 + apc_vs.MountPoints += 3 -> 1 + apc_vs.MountPoints += 4 -> 2 + apc_vs.MountPoints += 5 -> 3 + apc_vs.MountPoints += 6 -> 4 + apc_vs.MountPoints += 7 -> 5 + apc_vs.MountPoints += 8 -> 6 + apc_vs.MountPoints += 9 -> 7 + apc_vs.MountPoints += 10 -> 8 + apc_vs.MountPoints += 11 -> 9 + apc_vs.MountPoints += 12 -> 10 + apc_vs.TrunkSize = InventoryTile.Tile2016 + apc_vs.TrunkOffset = 30 + + lightning.Seats += 0 -> new SeatDefinition() + lightning.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + lightning.Seats(0).ControlledWeapon = 1 + lightning.Weapons += 1 -> lightning_weapon_system + lightning.MountPoints += 1 -> 0 + lightning.MountPoints += 2 -> 0 + lightning.TrunkSize = InventoryTile.Tile1511 + lightning.TrunkOffset = 30 + + prowler.Seats += 0 -> new SeatDefinition() + prowler.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + prowler.Seats += 1 -> new SeatDefinition() + prowler.Seats(1).ControlledWeapon = 3 + prowler.Seats += 2 -> new SeatDefinition() + prowler.Seats(2).ControlledWeapon = 4 + prowler.Weapons += 3 -> prowler_weapon_systemA + prowler.Weapons += 4 -> prowler_weapon_systemB + prowler.MountPoints += 1 -> 0 + prowler.MountPoints += 2 -> 1 + prowler.MountPoints += 3 -> 2 + prowler.TrunkSize = InventoryTile.Tile1511 + prowler.TrunkOffset = 30 + + vanguard.Seats += 0 -> new SeatDefinition() + vanguard.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + vanguard.Seats += 1 -> new SeatDefinition() + vanguard.Seats(1).ControlledWeapon = 2 + vanguard.Weapons += 2 -> vanguard_weapon_system + vanguard.MountPoints += 1 -> 0 + vanguard.MountPoints += 2 -> 1 + vanguard.TrunkSize = InventoryTile.Tile1511 + vanguard.TrunkOffset = 30 + + magrider.Seats += 0 -> new SeatDefinition() + magrider.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + magrider.Seats(0).ControlledWeapon = 2 + magrider.Seats += 1 -> new SeatDefinition() + magrider.Seats(1).ControlledWeapon = 3 + magrider.Weapons += 2 -> particle_beam_magrider + magrider.Weapons += 3 -> heavy_rail_beam_magrider + magrider.MountPoints += 1 -> 0 + magrider.MountPoints += 2 -> 1 + magrider.TrunkSize = InventoryTile.Tile1511 + magrider.TrunkOffset = 30 + + val utilityConverter = new UtilityVehicleConverter + ant.Seats += 0 -> new SeatDefinition() + ant.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + ant.MountPoints += 1 -> 0 + ant.MountPoints += 2 -> 0 + ant.Packet = utilityConverter + + ams.Seats += 0 -> new SeatDefinition() + ams.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax + ams.MountPoints += 1 -> 0 + ams.MountPoints += 2 -> 0 + ams.Packet = utilityConverter + + val variantConverter = new VariantVehicleConverter + router.Seats += 0 -> new SeatDefinition() + router.MountPoints += 1 -> 0 + router.TrunkSize = InventoryTile.Tile1511 + router.TrunkOffset = 30 + router.Packet = variantConverter + + switchblade.Seats += 0 -> new SeatDefinition() + switchblade.Seats(0).ControlledWeapon = 1 + switchblade.Weapons += 1 -> scythe + switchblade.MountPoints += 1 -> 0 + switchblade.MountPoints += 2 -> 0 + switchblade.TrunkSize = InventoryTile.Tile1511 + switchblade.TrunkOffset = 30 + switchblade.Packet = variantConverter + + flail.Seats += 0 -> new SeatDefinition() + flail.Seats(0).ControlledWeapon = 1 + flail.Weapons += 1 -> flail_weapon + flail.MountPoints += 1 -> 0 + flail.TrunkSize = InventoryTile.Tile1511 + flail.TrunkOffset = 30 + flail.Packet = variantConverter + + mosquito.Seats += 0 -> new SeatDefinition() + mosquito.Seats(0).Bailable = true + mosquito.Seats(0).ControlledWeapon = 1 + mosquito.Weapons += 1 -> rotarychaingun_mosquito + mosquito.MountPoints += 1 -> 0 + mosquito.MountPoints += 2 -> 0 + mosquito.TrunkSize = InventoryTile.Tile1111 + mosquito.TrunkOffset = 30 + mosquito.Packet = variantConverter + + lightgunship.Seats += 0 -> new SeatDefinition() + lightgunship.Seats(0).Bailable = true + lightgunship.Seats(0).ControlledWeapon = 1 + lightgunship.Weapons += 1 -> lightgunship_weapon_system + lightgunship.MountPoints += 1 -> 0 + lightgunship.MountPoints += 2 -> 0 + lightgunship.TrunkSize = InventoryTile.Tile1511 + lightgunship.TrunkOffset = 30 + lightgunship.Packet = variantConverter + + wasp.Seats += 0 -> new SeatDefinition() + wasp.Seats(0).Bailable = true + wasp.Seats(0).ControlledWeapon = 1 + wasp.Weapons += 1 -> wasp_weapon_system + wasp.MountPoints += 1 -> 0 + wasp.MountPoints += 2 -> 0 + wasp.TrunkSize = InventoryTile.Tile1111 + wasp.TrunkOffset = 30 + wasp.Packet = variantConverter + + liberator.Seats += 0 -> new SeatDefinition() + liberator.Seats(0).ControlledWeapon = 3 + liberator.Seats += 1 -> new SeatDefinition() + liberator.Seats(1).ControlledWeapon = 4 + liberator.Seats += 2 -> new SeatDefinition() + liberator.Seats(2).ControlledWeapon = 5 + liberator.Weapons += 3 -> liberator_weapon_system + liberator.Weapons += 4 -> liberator_bomb_bay + liberator.Weapons += 5 -> liberator_25mm_cannon + liberator.MountPoints += 1 -> 0 + liberator.MountPoints += 2 -> 1 + liberator.MountPoints += 3 -> 1 + liberator.MountPoints += 4 -> 2 + liberator.TrunkSize = InventoryTile.Tile1515 + liberator.TrunkOffset = 30 + liberator.Packet = variantConverter + + vulture.Seats += 0 -> new SeatDefinition() + vulture.Seats(0).ControlledWeapon = 3 + vulture.Seats += 1 -> new SeatDefinition() + vulture.Seats(1).ControlledWeapon = 4 + vulture.Seats += 2 -> new SeatDefinition() + vulture.Seats(2).ControlledWeapon = 5 + vulture.Weapons += 3 -> vulture_nose_weapon_system + vulture.Weapons += 4 -> vulture_bomb_bay + vulture.Weapons += 5 -> vulture_tail_cannon + vulture.MountPoints += 1 -> 0 + vulture.MountPoints += 2 -> 1 + vulture.MountPoints += 3 -> 1 + vulture.MountPoints += 4 -> 2 + vulture.TrunkSize = InventoryTile.Tile1611 + vulture.TrunkOffset = 30 + vulture.Packet = variantConverter + + dropship.Seats += 0 -> new SeatDefinition() + dropship.Seats += 1 -> new SeatDefinition() + dropship.Seats(1).Bailable = true + dropship.Seats(1).ControlledWeapon = 12 + dropship.Seats += 2 -> new SeatDefinition() + dropship.Seats(2).Bailable = true + dropship.Seats(2).ControlledWeapon = 13 + dropship.Seats += 3 -> new SeatDefinition() + dropship.Seats(3).Bailable = true + dropship.Seats += 4 -> new SeatDefinition() + dropship.Seats(4).Bailable = true + dropship.Seats += 5 -> new SeatDefinition() + dropship.Seats(5).Bailable = true + dropship.Seats += 6 -> new SeatDefinition() + dropship.Seats(6).Bailable = true + dropship.Seats += 7 -> new SeatDefinition() + dropship.Seats(7).Bailable = true + dropship.Seats += 8 -> new SeatDefinition() + dropship.Seats(8).Bailable = true + dropship.Seats += 9 -> new SeatDefinition() + dropship.Seats(9).Bailable = true + dropship.Seats(9).ArmorRestriction = SeatArmorRestriction.MaxOnly + dropship.Seats += 10 -> new SeatDefinition() + dropship.Seats(10).Bailable = true + dropship.Seats(10).ArmorRestriction = SeatArmorRestriction.MaxOnly + dropship.Seats += 11 -> new SeatDefinition() + dropship.Seats(11).Bailable = true + dropship.Seats(11).ControlledWeapon = 14 + dropship.Weapons += 12 -> cannon_dropship_20mm + dropship.Weapons += 13 -> cannon_dropship_20mm + dropship.Weapons += 14 -> dropship_rear_turret + dropship.MountPoints += 1 -> 0 + dropship.MountPoints += 2 -> 11 + dropship.MountPoints += 3 -> 1 + dropship.MountPoints += 4 -> 2 + dropship.MountPoints += 5 -> 3 + dropship.MountPoints += 6 -> 4 + dropship.MountPoints += 7 -> 5 + dropship.MountPoints += 8 -> 6 + dropship.MountPoints += 9 -> 7 + dropship.MountPoints += 10 -> 8 + dropship.MountPoints += 11 -> 9 + dropship.MountPoints += 12 -> 10 + dropship.TrunkSize = InventoryTile.Tile1612 + dropship.TrunkOffset = 30 + dropship.Packet = variantConverter + + galaxy_gunship.Seats += 0 -> new SeatDefinition() + galaxy_gunship.Seats += 1 -> new SeatDefinition() + galaxy_gunship.Seats(1).ControlledWeapon = 6 + galaxy_gunship.Seats += 2 -> new SeatDefinition() + galaxy_gunship.Seats(2).ControlledWeapon = 7 + galaxy_gunship.Seats += 3 -> new SeatDefinition() + galaxy_gunship.Seats(3).ControlledWeapon = 8 + galaxy_gunship.Seats += 4 -> new SeatDefinition() + galaxy_gunship.Seats(4).ControlledWeapon = 9 + galaxy_gunship.Seats += 5 -> new SeatDefinition() + galaxy_gunship.Seats(5).ControlledWeapon = 10 + galaxy_gunship.Weapons += 6 -> galaxy_gunship_cannon + galaxy_gunship.Weapons += 7 -> galaxy_gunship_cannon + galaxy_gunship.Weapons += 8 -> galaxy_gunship_tailgun + galaxy_gunship.Weapons += 9 -> galaxy_gunship_gun + galaxy_gunship.Weapons += 10 -> galaxy_gunship_gun + galaxy_gunship.MountPoints += 1 -> 0 + galaxy_gunship.MountPoints += 2 -> 3 + galaxy_gunship.MountPoints += 3 -> 1 + galaxy_gunship.MountPoints += 4 -> 2 + galaxy_gunship.MountPoints += 5 -> 4 + galaxy_gunship.MountPoints += 6 -> 5 + galaxy_gunship.TrunkSize = InventoryTile.Tile1816 + galaxy_gunship.TrunkOffset = 30 + galaxy_gunship.Packet = variantConverter + + lodestar.Seats += 0 -> new SeatDefinition() + lodestar.MountPoints += 1 -> 0 + lodestar.TrunkSize = InventoryTile.Tile1612 + lodestar.TrunkOffset = 30 + lodestar.Packet = variantConverter + + phantasm.CanCloak = true + phantasm.Seats += 0 -> new SeatDefinition() + phantasm.Seats += 1 -> new SeatDefinition() + phantasm.Seats(1).Bailable = true + phantasm.Seats += 2 -> new SeatDefinition() + phantasm.Seats(2).Bailable = true + phantasm.Seats += 3 -> new SeatDefinition() + phantasm.Seats(3).Bailable = true + phantasm.Seats += 4 -> new SeatDefinition() + phantasm.Seats(4).Bailable = true + phantasm.MountPoints += 1 -> 0 + phantasm.MountPoints += 2 -> 1 + phantasm.MountPoints += 3 -> 2 + phantasm.MountPoints += 4 -> 3 + phantasm.MountPoints += 5 -> 4 + phantasm.TrunkSize = InventoryTile.Tile1107 + phantasm.TrunkOffset = 30 + phantasm.Packet = variantConverter + } } From c3b3e8a6e6c7444cc7cd3d8d2ac1e71d5924d804 Mon Sep 17 00:00:00 2001 From: FateJH Date: Mon, 27 Nov 2017 19:17:58 -0500 Subject: [PATCH 3/5] spawn pad livelock due to client crash --- .../scala/services/vehicle/support/DeconstructionActor.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pslogin/src/main/scala/services/vehicle/support/DeconstructionActor.scala b/pslogin/src/main/scala/services/vehicle/support/DeconstructionActor.scala index f19d47aa9..366f79da7 100644 --- a/pslogin/src/main/scala/services/vehicle/support/DeconstructionActor.scala +++ b/pslogin/src/main/scala/services/vehicle/support/DeconstructionActor.scala @@ -61,7 +61,9 @@ class DeconstructionActor extends Actor { case Some(tplayer) => seat.Occupant = None tplayer.VehicleSeated = None - context.parent ! VehicleServiceMessage(zone_id, VehicleAction.KickPassenger(tplayer.GUID, 4, false)) + if(tplayer.HasGUID) { + context.parent ! VehicleServiceMessage(zone_id, VehicleAction.KickPassenger(tplayer.GUID, 4, false)) + } case None => ; } }) From ab2e2959b55050768e737f57ca1f9491ef4dedd3 Mon Sep 17 00:00:00 2001 From: FateJH Date: Tue, 28 Nov 2017 19:33:52 -0500 Subject: [PATCH 4/5] modified dismount vehicle conditions --- .../src/main/scala/WorldSessionActor.scala | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index 2808cc1cd..5c650542e 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -1441,6 +1441,10 @@ class WorldSessionActor extends Actor with MDCContextAware { //TODO optimize this later log.info(s"DismountVehicleMsg: $msg") if(player.GUID == player_guid) { + //common warning for this section + def dismountWarning(msg : String) : Unit = { + log.warn(s"$msg; a vehicle may not know that a player is no longer sitting it in") + } //normally disembarking from a seat player.VehicleSeated match { case Some(vehicle_guid) => @@ -1448,26 +1452,27 @@ class WorldSessionActor extends Actor with MDCContextAware { case Some(obj : Vehicle) => obj.Seats.find(seat => seat.Occupant.contains(player)) match { case Some(seat) => - val vel = obj.Velocity.getOrElse(new Vector3(0f, 0f, 0f)) - val total_vel : Int = math.abs(vel.x * vel.y * vel.z).toInt - if(seat.Bailable || obj.Velocity.isEmpty || total_vel == 0) { + val vel = obj.Velocity.getOrElse(Vector3(0f, 0f, 0f)) + val has_vel : Int = math.abs(vel.x * vel.y * vel.z).toInt + if(seat.Bailable || obj.Velocity.isEmpty || has_vel == 0) { //ugh, float comparison seat.Occupant = None - player.VehicleSeated = None - sendResponse(PacketCoding.CreateGamePacket(0, DismountVehicleMsg(player_guid, unk1, unk2))) //should be safe; replace with ObjectDetachMessage later - vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.DismountVehicle(player_guid, unk1, unk2)) if(obj.Seats.count(seat => seat.isOccupied) == 0) { vehicleService ! VehicleServiceMessage.DelayedVehicleDeconstruction(obj, continent, 600L) //start vehicle decay (10m) } } case None => - log.warn(s"DismountVehicleMsg: can not find where player $player_guid is seated in vehicle $vehicle_guid") + dismountWarning(s"DismountVehicleMsg: can not find where player $player_guid is seated in vehicle $vehicle_guid") } case _ => - log.warn(s"DismountVehicleMsg: can not find vehicle $vehicle_guid") + dismountWarning(s"DismountVehicleMsg: can not find vehicle $vehicle_guid") } case None => - log.warn(s"DismountVehicleMsg: player $player_guid not considered seated in a vehicle") + dismountWarning(s"DismountVehicleMsg: player $player_guid not considered seated in a vehicle") } + //should be safe + player.VehicleSeated = None + sendResponse(PacketCoding.CreateGamePacket(0, DismountVehicleMsg(player_guid, unk1, unk2))) + vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.DismountVehicle(player_guid, unk1, unk2)) } else { //kicking someone else out of a seat; need to own that seat From e62adc4bc16b2f42530587943a9f9851b7a9c9cf Mon Sep 17 00:00:00 2001 From: FateJH Date: Tue, 28 Nov 2017 22:37:06 -0500 Subject: [PATCH 5/5] broke up GUIDTask tests into separate files; attempting to increase code coverage by modifying the first registering test --- .../src/test/scala/objects/GUIDTaskTest.scala | 245 ------------------ .../guidtask/GUIDTaskRegister1Test.scala | 52 ++++ .../guidtask/GUIDTaskRegister2Test.scala | 18 ++ .../guidtask/GUIDTaskRegister3Test.scala | 21 ++ .../guidtask/GUIDTaskRegister4Test.scala | 28 ++ .../guidtask/GUIDTaskRegister5Test.scala | 39 +++ .../scala/objects/guidtask/GUIDTaskTest.scala | 45 ++++ .../guidtask/GUIDTaskUnregister1Test.scala | 18 ++ .../guidtask/GUIDTaskUnregister2Test.scala | 19 ++ .../guidtask/GUIDTaskUnregister3Test.scala | 23 ++ .../guidtask/GUIDTaskUnregister4Test.scala | 32 +++ .../guidtask/GUIDTaskUnregister5Test.scala | 44 ++++ 12 files changed, 339 insertions(+), 245 deletions(-) delete mode 100644 common/src/test/scala/objects/GUIDTaskTest.scala create mode 100644 common/src/test/scala/objects/guidtask/GUIDTaskRegister1Test.scala create mode 100644 common/src/test/scala/objects/guidtask/GUIDTaskRegister2Test.scala create mode 100644 common/src/test/scala/objects/guidtask/GUIDTaskRegister3Test.scala create mode 100644 common/src/test/scala/objects/guidtask/GUIDTaskRegister4Test.scala create mode 100644 common/src/test/scala/objects/guidtask/GUIDTaskRegister5Test.scala create mode 100644 common/src/test/scala/objects/guidtask/GUIDTaskTest.scala create mode 100644 common/src/test/scala/objects/guidtask/GUIDTaskUnregister1Test.scala create mode 100644 common/src/test/scala/objects/guidtask/GUIDTaskUnregister2Test.scala create mode 100644 common/src/test/scala/objects/guidtask/GUIDTaskUnregister3Test.scala create mode 100644 common/src/test/scala/objects/guidtask/GUIDTaskUnregister4Test.scala create mode 100644 common/src/test/scala/objects/guidtask/GUIDTaskUnregister5Test.scala diff --git a/common/src/test/scala/objects/GUIDTaskTest.scala b/common/src/test/scala/objects/GUIDTaskTest.scala deleted file mode 100644 index 1ea187dee..000000000 --- a/common/src/test/scala/objects/GUIDTaskTest.scala +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright (c) 2017 PSForever -package objects - -import java.util.logging.LogManager - -import akka.actor.{ActorRef, ActorSystem, Props} -import akka.testkit.TestProbe -import net.psforever.objects._ -import net.psforever.objects.entity.IdentifiableEntity -import net.psforever.objects.guid.actor.{NumberPoolActor, UniqueNumberSystem} -import net.psforever.objects.guid.selector.RandomSelector -import net.psforever.objects.guid.source.LimitedNumberSource -import net.psforever.objects.guid.{GUIDTask, NumberPoolHub, Task, TaskResolver} -import net.psforever.types.{CharacterGender, PlanetSideEmpire} - -class GUIDTaskRegister1Test extends ActorTest() { - "RegisterObjectTask" in { - val (_, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup - val obj = new GUIDTaskTest.TestObject - - assert(!obj.HasGUID) - taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.RegisterObjectTask(obj)(uns))) - probe.expectMsg(scala.util.Success) - assert(obj.HasGUID) - } -} - -class GUIDTaskRegister2Test extends ActorTest() { - "RegisterEquipment -> RegisterObjectTask" in { - val (_, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup - val obj = AmmoBox(GlobalDefinitions.energy_cell) - - assert(!obj.HasGUID) - taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.RegisterEquipment(obj)(uns))) - probe.expectMsg(scala.util.Success) - assert(obj.HasGUID) - } -} - -class GUIDTaskRegister3Test extends ActorTest() { - "RegisterEquipment -> RegisterTool" in { - val (_, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup - val obj = Tool(GlobalDefinitions.beamer) - obj.AmmoSlots.head.Box = AmmoBox(GlobalDefinitions.energy_cell) - - assert(!obj.HasGUID) - assert(!obj.AmmoSlots.head.Box.HasGUID) - taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.RegisterEquipment(obj)(uns))) - probe.expectMsg(scala.util.Success) - assert(obj.HasGUID) - assert(obj.AmmoSlots.head.Box.HasGUID) - } -} - -class GUIDTaskRegister4Test extends ActorTest() { - "RegisterVehicle" in { - val (_, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup - val obj = Vehicle(GlobalDefinitions.fury) - val obj_wep = obj.WeaponControlledFromSeat(0).get - val obj_wep_ammo = (obj.WeaponControlledFromSeat(0).get.asInstanceOf[Tool].AmmoSlots.head.Box = AmmoBox(GlobalDefinitions.hellfire_ammo)).get - obj.Trunk += 30 -> AmmoBox(GlobalDefinitions.hellfire_ammo) - val obj_trunk_ammo = obj.Trunk.Items(0).obj - - assert(!obj.HasGUID) - assert(!obj_wep.HasGUID) - assert(!obj_wep_ammo.HasGUID) - assert(!obj_trunk_ammo.HasGUID) - taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.RegisterVehicle(obj)(uns))) - probe.expectMsg(scala.util.Success) - assert(obj.HasGUID) - assert(obj_wep.HasGUID) - assert(obj_wep_ammo.HasGUID) - assert(obj_trunk_ammo.HasGUID) - } -} - -class GUIDTaskRegister5Test extends ActorTest() { - "RegisterAvatar" in { - val (_, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup - val obj = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0) - val obj_wep = Tool(GlobalDefinitions.beamer) - obj.Slot(0).Equipment = obj_wep - val obj_wep_ammo = AmmoBox(GlobalDefinitions.energy_cell) - obj_wep.AmmoSlots.head.Box = obj_wep_ammo - val obj_inv_ammo = AmmoBox(GlobalDefinitions.energy_cell) - obj.Slot(6).Equipment = obj_inv_ammo - val obj_locker = obj.Slot(5).Equipment.get - val obj_locker_ammo = AmmoBox(GlobalDefinitions.energy_cell) - obj_locker.asInstanceOf[LockerContainer].Inventory += 0 -> obj_locker_ammo - - assert(!obj.HasGUID) - assert(!obj_wep.HasGUID) - assert(!obj_wep_ammo.HasGUID) - assert(!obj_inv_ammo.HasGUID) - assert(!obj_locker.HasGUID) - assert(!obj_locker_ammo.HasGUID) - taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.RegisterAvatar(obj)(uns))) - probe.expectMsg(scala.util.Success) - assert(obj.HasGUID) - assert(obj_wep.HasGUID) - assert(obj_wep_ammo.HasGUID) - assert(obj_inv_ammo.HasGUID) - assert(obj_locker.HasGUID) - assert(obj_locker_ammo.HasGUID) - } -} - -class GUIDTaskUnregister1Test extends ActorTest() { - "UnregisterObjectTask" in { - val (guid, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup - val obj = new GUIDTaskTest.TestObject - guid.register(obj, "dynamic") - - assert(obj.HasGUID) - taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.UnregisterObjectTask(obj)(uns))) - probe.expectMsg(scala.util.Success) - assert(!obj.HasGUID) - } -} - -class GUIDTaskUnregister2Test extends ActorTest() { - "UnregisterEquipment -> UnregisterObjectTask" in { - val (guid, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup - val obj = AmmoBox(GlobalDefinitions.energy_cell) - guid.register(obj, "dynamic") - - assert(obj.HasGUID) - taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.UnregisterEquipment(obj)(uns))) - probe.expectMsg(scala.util.Success) - assert(!obj.HasGUID) - } -} - -class GUIDTaskUnregister3Test extends ActorTest() { - "UnregisterEquipment -> UnregisterTool" in { - val (guid, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup - val obj = Tool(GlobalDefinitions.beamer) - obj.AmmoSlots.head.Box = AmmoBox(GlobalDefinitions.energy_cell) - guid.register(obj, "dynamic") - guid.register(obj.AmmoSlots.head.Box, "dynamic") - - assert(obj.HasGUID) - assert(obj.AmmoSlots.head.Box.HasGUID) - taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.UnregisterEquipment(obj)(uns))) - probe.expectMsg(scala.util.Success) - assert(!obj.HasGUID) - assert(!obj.AmmoSlots.head.Box.HasGUID) - } -} - -class GUIDTaskUnregister4Test extends ActorTest() { - "RegisterVehicle" in { - val (guid, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup - val obj = Vehicle(GlobalDefinitions.fury) - val obj_wep = obj.WeaponControlledFromSeat(0).get - val obj_wep_ammo = (obj.WeaponControlledFromSeat(0).get.asInstanceOf[Tool].AmmoSlots.head.Box = AmmoBox(GlobalDefinitions.hellfire_ammo)).get - obj.Trunk += 30 -> AmmoBox(GlobalDefinitions.hellfire_ammo) - val obj_trunk_ammo = obj.Trunk.Items(0).obj - guid.register(obj, "dynamic") - guid.register(obj_wep, "dynamic") - guid.register(obj_wep_ammo, "dynamic") - guid.register(obj_trunk_ammo, "dynamic") - - assert(obj.HasGUID) - assert(obj_wep.HasGUID) - assert(obj_wep_ammo.HasGUID) - assert(obj_trunk_ammo.HasGUID) - taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.UnregisterVehicle(obj)(uns))) - probe.expectMsg(scala.util.Success) - assert(!obj.HasGUID) - assert(!obj_wep.HasGUID) - assert(!obj_wep_ammo.HasGUID) - assert(!obj_trunk_ammo.HasGUID) - } -} - -class GUIDTaskUnregister5Test extends ActorTest() { - "UnregisterAvatar" in { - val (guid, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup - val obj = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0) - val obj_wep = Tool(GlobalDefinitions.beamer) - obj.Slot(0).Equipment = obj_wep - val obj_wep_ammo = AmmoBox(GlobalDefinitions.energy_cell) - obj_wep.AmmoSlots.head.Box = obj_wep_ammo - val obj_inv_ammo = AmmoBox(GlobalDefinitions.energy_cell) - obj.Slot(6).Equipment = obj_inv_ammo - val obj_locker = obj.Slot(5).Equipment.get - val obj_locker_ammo = AmmoBox(GlobalDefinitions.energy_cell) - obj_locker.asInstanceOf[LockerContainer].Inventory += 0 -> obj_locker_ammo - guid.register(obj, "dynamic") - guid.register(obj_wep, "dynamic") - guid.register(obj_wep_ammo, "dynamic") - guid.register(obj_inv_ammo, "dynamic") - guid.register(obj_locker, "dynamic") - guid.register(obj_locker_ammo, "dynamic") - - assert(obj.HasGUID) - assert(obj_wep.HasGUID) - assert(obj_wep_ammo.HasGUID) - assert(obj_inv_ammo.HasGUID) - assert(obj_locker.HasGUID) - assert(obj_locker_ammo.HasGUID) - taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.UnregisterAvatar(obj)(uns))) - probe.expectMsg(scala.util.Success) - assert(!obj.HasGUID) - assert(!obj_wep.HasGUID) - assert(!obj_wep_ammo.HasGUID) - assert(!obj_inv_ammo.HasGUID) - assert(!obj_locker.HasGUID) - assert(!obj_locker_ammo.HasGUID) - } -} - -object GUIDTaskTest { - class TestObject extends IdentifiableEntity - - class RegisterTestTask(probe : ActorRef) extends Task { - def Execute(resolver : ActorRef) : Unit = { - probe ! scala.util.Success - resolver ! scala.util.Success(this) - } - } - - def CommonTestSetup(implicit system : ActorSystem) : (NumberPoolHub, ActorRef, ActorRef, TestProbe) = { - import akka.actor.Props - import akka.routing.RandomPool - import akka.testkit.TestProbe - - val guid : NumberPoolHub = new NumberPoolHub(new LimitedNumberSource(110)) - guid.AddPool("dynamic", (1 to 100).toList).Selector = new RandomSelector //TODO name is hardcoded for now - val uns = system.actorOf(RandomPool(25).props(Props(classOf[UniqueNumberSystem], guid, GUIDTaskTest.AllocateNumberPoolActors(guid))), "uns") - val taskResolver = system.actorOf(RandomPool(15).props(Props[TaskResolver]), "resolver") - LogManager.getLogManager.reset() //suppresses any internal loggers created by the above elements - (guid, uns, taskResolver, TestProbe()) - } - - /** - * @see `UniqueNumberSystem.AllocateNumberPoolActors(NumberPoolHub)(implicit ActorContext)` - */ - def AllocateNumberPoolActors(poolSource : NumberPoolHub)(implicit system : ActorSystem) : Map[String, ActorRef] = { - poolSource.Pools.map({ case ((pname, pool)) => - pname -> system.actorOf(Props(classOf[NumberPoolActor], pool), pname) - }).toMap - } -} diff --git a/common/src/test/scala/objects/guidtask/GUIDTaskRegister1Test.scala b/common/src/test/scala/objects/guidtask/GUIDTaskRegister1Test.scala new file mode 100644 index 000000000..803a60241 --- /dev/null +++ b/common/src/test/scala/objects/guidtask/GUIDTaskRegister1Test.scala @@ -0,0 +1,52 @@ +// Copyright (c) 2017 PSForever +package objects.guidtask + +import akka.actor.{Actor, ActorSystem, Props} +import net.psforever.objects.guid.{GUIDTask, TaskResolver} +import org.specs2.mutable.Specification + +import scala.concurrent.Await +import akka.pattern.ask +import akka.util.Timeout +import scala.concurrent.duration._ + +class GUIDTaskRegister1Test extends Specification { + "RegisterObjectTask" should { + "register (1)" in { + val system = ActorSystem("sys") + val test = system.actorOf(Props(classOf[GUIDTaskRegister1TestActor], system), "test") + + implicit val timeout = Timeout(5 seconds) + val future = test ? "test" + val result = Await.result(future, timeout.duration).asInstanceOf[String] + result mustEqual "success" + } + } +} + +private class GUIDTaskRegister1TestActor(implicit system : ActorSystem) extends Actor { + def receive : Receive = { + case "test" => + val (_, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup + val obj = new GUIDTaskTest.TestObject + + assert(!obj.HasGUID) + taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.RegisterObjectTask(obj)(uns))) + probe.expectMsg(scala.util.Success) + assert(obj.HasGUID) + sender ! "success" + case _ => ; + } +} + +//class GUIDTaskRegister1Test extends ActorTest() { +// "RegisterObjectTask" in { +// val (_, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup +// val obj = new GUIDTaskTest.TestObject +// +// assert(!obj.HasGUID) +// taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.RegisterObjectTask(obj)(uns))) +// probe.expectMsg(scala.util.Success) +// assert(obj.HasGUID) +// } +//} diff --git a/common/src/test/scala/objects/guidtask/GUIDTaskRegister2Test.scala b/common/src/test/scala/objects/guidtask/GUIDTaskRegister2Test.scala new file mode 100644 index 000000000..e6ffb6ebc --- /dev/null +++ b/common/src/test/scala/objects/guidtask/GUIDTaskRegister2Test.scala @@ -0,0 +1,18 @@ +// Copyright (c) 2017 PSForever +package objects.guidtask + +import net.psforever.objects._ +import net.psforever.objects.guid.{GUIDTask, TaskResolver} +import objects.ActorTest + +class GUIDTaskRegister2Test extends ActorTest() { + "RegisterEquipment -> RegisterObjectTask" in { + val (_, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup + val obj = AmmoBox(GlobalDefinitions.energy_cell) + + assert(!obj.HasGUID) + taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.RegisterEquipment(obj)(uns))) + probe.expectMsg(scala.util.Success) + assert(obj.HasGUID) + } +} diff --git a/common/src/test/scala/objects/guidtask/GUIDTaskRegister3Test.scala b/common/src/test/scala/objects/guidtask/GUIDTaskRegister3Test.scala new file mode 100644 index 000000000..58b3ce484 --- /dev/null +++ b/common/src/test/scala/objects/guidtask/GUIDTaskRegister3Test.scala @@ -0,0 +1,21 @@ +// Copyright (c) 2017 PSForever +package objects.guidtask + +import net.psforever.objects._ +import net.psforever.objects.guid.{GUIDTask, TaskResolver} +import objects.ActorTest + +class GUIDTaskRegister3Test extends ActorTest() { + "RegisterEquipment -> RegisterTool" in { + val (_, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup + val obj = Tool(GlobalDefinitions.beamer) + obj.AmmoSlots.head.Box = AmmoBox(GlobalDefinitions.energy_cell) + + assert(!obj.HasGUID) + assert(!obj.AmmoSlots.head.Box.HasGUID) + taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.RegisterEquipment(obj)(uns))) + probe.expectMsg(scala.util.Success) + assert(obj.HasGUID) + assert(obj.AmmoSlots.head.Box.HasGUID) + } +} diff --git a/common/src/test/scala/objects/guidtask/GUIDTaskRegister4Test.scala b/common/src/test/scala/objects/guidtask/GUIDTaskRegister4Test.scala new file mode 100644 index 000000000..1eab3dbf5 --- /dev/null +++ b/common/src/test/scala/objects/guidtask/GUIDTaskRegister4Test.scala @@ -0,0 +1,28 @@ +// Copyright (c) 2017 PSForever +package objects.guidtask + +import net.psforever.objects._ +import net.psforever.objects.guid.{GUIDTask, TaskResolver} +import objects.ActorTest + +class GUIDTaskRegister4Test extends ActorTest() { + "RegisterVehicle" in { + val (_, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup + val obj = Vehicle(GlobalDefinitions.fury) + val obj_wep = obj.WeaponControlledFromSeat(0).get + val obj_wep_ammo = (obj.WeaponControlledFromSeat(0).get.asInstanceOf[Tool].AmmoSlots.head.Box = AmmoBox(GlobalDefinitions.hellfire_ammo)).get + obj.Trunk += 30 -> AmmoBox(GlobalDefinitions.hellfire_ammo) + val obj_trunk_ammo = obj.Trunk.Items(0).obj + + assert(!obj.HasGUID) + assert(!obj_wep.HasGUID) + assert(!obj_wep_ammo.HasGUID) + assert(!obj_trunk_ammo.HasGUID) + taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.RegisterVehicle(obj)(uns))) + probe.expectMsg(scala.util.Success) + assert(obj.HasGUID) + assert(obj_wep.HasGUID) + assert(obj_wep_ammo.HasGUID) + assert(obj_trunk_ammo.HasGUID) + } +} diff --git a/common/src/test/scala/objects/guidtask/GUIDTaskRegister5Test.scala b/common/src/test/scala/objects/guidtask/GUIDTaskRegister5Test.scala new file mode 100644 index 000000000..a96b55dd2 --- /dev/null +++ b/common/src/test/scala/objects/guidtask/GUIDTaskRegister5Test.scala @@ -0,0 +1,39 @@ +// Copyright (c) 2017 PSForever +package objects.guidtask + + +import net.psforever.objects._ +import net.psforever.objects.guid.{GUIDTask, TaskResolver} +import net.psforever.types.{CharacterGender, PlanetSideEmpire} +import objects.ActorTest + +class GUIDTaskRegister5Test extends ActorTest() { + "RegisterAvatar" in { + val (_, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup + val obj = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0) + val obj_wep = Tool(GlobalDefinitions.beamer) + obj.Slot(0).Equipment = obj_wep + val obj_wep_ammo = AmmoBox(GlobalDefinitions.energy_cell) + obj_wep.AmmoSlots.head.Box = obj_wep_ammo + val obj_inv_ammo = AmmoBox(GlobalDefinitions.energy_cell) + obj.Slot(6).Equipment = obj_inv_ammo + val obj_locker = obj.Slot(5).Equipment.get + val obj_locker_ammo = AmmoBox(GlobalDefinitions.energy_cell) + obj_locker.asInstanceOf[LockerContainer].Inventory += 0 -> obj_locker_ammo + + assert(!obj.HasGUID) + assert(!obj_wep.HasGUID) + assert(!obj_wep_ammo.HasGUID) + assert(!obj_inv_ammo.HasGUID) + assert(!obj_locker.HasGUID) + assert(!obj_locker_ammo.HasGUID) + taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.RegisterAvatar(obj)(uns))) + probe.expectMsg(scala.util.Success) + assert(obj.HasGUID) + assert(obj_wep.HasGUID) + assert(obj_wep_ammo.HasGUID) + assert(obj_inv_ammo.HasGUID) + assert(obj_locker.HasGUID) + assert(obj_locker_ammo.HasGUID) + } +} diff --git a/common/src/test/scala/objects/guidtask/GUIDTaskTest.scala b/common/src/test/scala/objects/guidtask/GUIDTaskTest.scala new file mode 100644 index 000000000..f67ce2722 --- /dev/null +++ b/common/src/test/scala/objects/guidtask/GUIDTaskTest.scala @@ -0,0 +1,45 @@ +// Copyright (c) 2017 PSForever +package objects.guidtask + +import java.util.logging.LogManager + +import akka.actor.{ActorRef, ActorSystem, Props} +import akka.testkit.TestProbe +import net.psforever.objects.entity.IdentifiableEntity +import net.psforever.objects.guid.actor.{NumberPoolActor, UniqueNumberSystem} +import net.psforever.objects.guid.selector.RandomSelector +import net.psforever.objects.guid.source.LimitedNumberSource +import net.psforever.objects.guid.{NumberPoolHub, Task, TaskResolver} + +object GUIDTaskTest { + class TestObject extends IdentifiableEntity + + class RegisterTestTask(probe : ActorRef) extends Task { + def Execute(resolver : ActorRef) : Unit = { + probe ! scala.util.Success + resolver ! scala.util.Success(this) + } + } + + def CommonTestSetup(implicit system : ActorSystem) : (NumberPoolHub, ActorRef, ActorRef, TestProbe) = { + import akka.actor.Props + import akka.routing.RandomPool + import akka.testkit.TestProbe + + val guid : NumberPoolHub = new NumberPoolHub(new LimitedNumberSource(110)) + guid.AddPool("dynamic", (1 to 100).toList).Selector = new RandomSelector //TODO name is hardcoded for now + val uns = system.actorOf(RandomPool(25).props(Props(classOf[UniqueNumberSystem], guid, GUIDTaskTest.AllocateNumberPoolActors(guid))), "uns") + val taskResolver = system.actorOf(RandomPool(15).props(Props[TaskResolver]), "resolver") + LogManager.getLogManager.reset() //suppresses any internal loggers created by the above elements + (guid, uns, taskResolver, TestProbe()) + } + + /** + * @see `UniqueNumberSystem.AllocateNumberPoolActors(NumberPoolHub)(implicit ActorContext)` + */ + def AllocateNumberPoolActors(poolSource : NumberPoolHub)(implicit system : ActorSystem) : Map[String, ActorRef] = { + poolSource.Pools.map({ case ((pname, pool)) => + pname -> system.actorOf(Props(classOf[NumberPoolActor], pool), pname) + }).toMap + } +} diff --git a/common/src/test/scala/objects/guidtask/GUIDTaskUnregister1Test.scala b/common/src/test/scala/objects/guidtask/GUIDTaskUnregister1Test.scala new file mode 100644 index 000000000..5de6f2e37 --- /dev/null +++ b/common/src/test/scala/objects/guidtask/GUIDTaskUnregister1Test.scala @@ -0,0 +1,18 @@ +// Copyright (c) 2017 PSForever +package objects.guidtask + +import net.psforever.objects.guid.{GUIDTask, TaskResolver} +import objects.ActorTest + +class GUIDTaskUnregister1Test extends ActorTest() { + "UnregisterObjectTask" in { + val (guid, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup + val obj = new GUIDTaskTest.TestObject + guid.register(obj, "dynamic") + + assert(obj.HasGUID) + taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.UnregisterObjectTask(obj)(uns))) + probe.expectMsg(scala.util.Success) + assert(!obj.HasGUID) + } +} diff --git a/common/src/test/scala/objects/guidtask/GUIDTaskUnregister2Test.scala b/common/src/test/scala/objects/guidtask/GUIDTaskUnregister2Test.scala new file mode 100644 index 000000000..71dcc480b --- /dev/null +++ b/common/src/test/scala/objects/guidtask/GUIDTaskUnregister2Test.scala @@ -0,0 +1,19 @@ +// Copyright (c) 2017 PSForever +package objects.guidtask + +import net.psforever.objects._ +import net.psforever.objects.guid.{GUIDTask, TaskResolver} +import objects.ActorTest + +class GUIDTaskUnregister2Test extends ActorTest() { + "UnregisterEquipment -> UnregisterObjectTask" in { + val (guid, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup + val obj = AmmoBox(GlobalDefinitions.energy_cell) + guid.register(obj, "dynamic") + + assert(obj.HasGUID) + taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.UnregisterEquipment(obj)(uns))) + probe.expectMsg(scala.util.Success) + assert(!obj.HasGUID) + } +} diff --git a/common/src/test/scala/objects/guidtask/GUIDTaskUnregister3Test.scala b/common/src/test/scala/objects/guidtask/GUIDTaskUnregister3Test.scala new file mode 100644 index 000000000..3f0fd9011 --- /dev/null +++ b/common/src/test/scala/objects/guidtask/GUIDTaskUnregister3Test.scala @@ -0,0 +1,23 @@ +// Copyright (c) 2017 PSForever +package objects.guidtask + +import net.psforever.objects._ +import net.psforever.objects.guid.{GUIDTask, TaskResolver} +import objects.ActorTest + +class GUIDTaskUnregister3Test extends ActorTest() { + "UnregisterEquipment -> UnregisterTool" in { + val (guid, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup + val obj = Tool(GlobalDefinitions.beamer) + obj.AmmoSlots.head.Box = AmmoBox(GlobalDefinitions.energy_cell) + guid.register(obj, "dynamic") + guid.register(obj.AmmoSlots.head.Box, "dynamic") + + assert(obj.HasGUID) + assert(obj.AmmoSlots.head.Box.HasGUID) + taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.UnregisterEquipment(obj)(uns))) + probe.expectMsg(scala.util.Success) + assert(!obj.HasGUID) + assert(!obj.AmmoSlots.head.Box.HasGUID) + } +} diff --git a/common/src/test/scala/objects/guidtask/GUIDTaskUnregister4Test.scala b/common/src/test/scala/objects/guidtask/GUIDTaskUnregister4Test.scala new file mode 100644 index 000000000..e52eeab79 --- /dev/null +++ b/common/src/test/scala/objects/guidtask/GUIDTaskUnregister4Test.scala @@ -0,0 +1,32 @@ +// Copyright (c) 2017 PSForever +package objects.guidtask + +import net.psforever.objects._ +import net.psforever.objects.guid.{GUIDTask, TaskResolver} +import objects.ActorTest + +class GUIDTaskUnregister4Test extends ActorTest() { + "RegisterVehicle" in { + val (guid, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup + val obj = Vehicle(GlobalDefinitions.fury) + val obj_wep = obj.WeaponControlledFromSeat(0).get + val obj_wep_ammo = (obj.WeaponControlledFromSeat(0).get.asInstanceOf[Tool].AmmoSlots.head.Box = AmmoBox(GlobalDefinitions.hellfire_ammo)).get + obj.Trunk += 30 -> AmmoBox(GlobalDefinitions.hellfire_ammo) + val obj_trunk_ammo = obj.Trunk.Items(0).obj + guid.register(obj, "dynamic") + guid.register(obj_wep, "dynamic") + guid.register(obj_wep_ammo, "dynamic") + guid.register(obj_trunk_ammo, "dynamic") + + assert(obj.HasGUID) + assert(obj_wep.HasGUID) + assert(obj_wep_ammo.HasGUID) + assert(obj_trunk_ammo.HasGUID) + taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.UnregisterVehicle(obj)(uns))) + probe.expectMsg(scala.util.Success) + assert(!obj.HasGUID) + assert(!obj_wep.HasGUID) + assert(!obj_wep_ammo.HasGUID) + assert(!obj_trunk_ammo.HasGUID) + } +} diff --git a/common/src/test/scala/objects/guidtask/GUIDTaskUnregister5Test.scala b/common/src/test/scala/objects/guidtask/GUIDTaskUnregister5Test.scala new file mode 100644 index 000000000..b4d28ab47 --- /dev/null +++ b/common/src/test/scala/objects/guidtask/GUIDTaskUnregister5Test.scala @@ -0,0 +1,44 @@ +// Copyright (c) 2017 PSForever +package objects.guidtask + +import net.psforever.objects._ +import net.psforever.objects.guid.{GUIDTask, TaskResolver} +import net.psforever.types.{CharacterGender, PlanetSideEmpire} +import objects.ActorTest + +class GUIDTaskUnregister5Test extends ActorTest() { + "UnregisterAvatar" in { + val (guid, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup + val obj = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0) + val obj_wep = Tool(GlobalDefinitions.beamer) + obj.Slot(0).Equipment = obj_wep + val obj_wep_ammo = AmmoBox(GlobalDefinitions.energy_cell) + obj_wep.AmmoSlots.head.Box = obj_wep_ammo + val obj_inv_ammo = AmmoBox(GlobalDefinitions.energy_cell) + obj.Slot(6).Equipment = obj_inv_ammo + val obj_locker = obj.Slot(5).Equipment.get + val obj_locker_ammo = AmmoBox(GlobalDefinitions.energy_cell) + obj_locker.asInstanceOf[LockerContainer].Inventory += 0 -> obj_locker_ammo + guid.register(obj, "dynamic") + guid.register(obj_wep, "dynamic") + guid.register(obj_wep_ammo, "dynamic") + guid.register(obj_inv_ammo, "dynamic") + guid.register(obj_locker, "dynamic") + guid.register(obj_locker_ammo, "dynamic") + + assert(obj.HasGUID) + assert(obj_wep.HasGUID) + assert(obj_wep_ammo.HasGUID) + assert(obj_inv_ammo.HasGUID) + assert(obj_locker.HasGUID) + assert(obj_locker_ammo.HasGUID) + taskResolver ! TaskResolver.GiveTask(new GUIDTaskTest.RegisterTestTask(probe.ref), List(GUIDTask.UnregisterAvatar(obj)(uns))) + probe.expectMsg(scala.util.Success) + assert(!obj.HasGUID) + assert(!obj_wep.HasGUID) + assert(!obj_wep_ammo.HasGUID) + assert(!obj_inv_ammo.HasGUID) + assert(!obj_locker.HasGUID) + assert(!obj_locker_ammo.HasGUID) + } +}