From 1f04c840d2534fa2c66e56359e9bf5a9258ffe1b Mon Sep 17 00:00:00 2001 From: FateJH Date: Wed, 10 Jan 2018 14:19:45 -0500 Subject: [PATCH] synchronized change fire mode; addsupport for fire mode in DetailedWeaponData; corrected bug with LastDrawnSlot/ObjectHeldMessage --- .../psforever/objects/GlobalDefinitions.scala | 7 +- .../scala/net/psforever/objects/Player.scala | 9 +- .../scala/net/psforever/objects/Tool.scala | 10 +- .../definition/AmmoBoxDefinition.scala | 4 +- .../objects/definition/AvatarDefinition.scala | 4 +- .../objects/definition/KitDefinition.scala | 4 +- .../objects/definition/ToolDefinition.scala | 4 +- .../definition/VehicleDefinition.scala | 4 +- .../definition/converter/ToolConverter.scala | 2 +- .../equipment/FireModeDefinition.scala | 8 - .../objectcreate/DetailedWeaponData.scala | 36 ++- .../packet/game/objectcreate/WeaponData.scala | 2 +- .../DetailedCharacterDataTest.scala | 104 ++++----- .../DetailedWeaponDataTest.scala | 2 +- .../test/scala/objects/ConverterTest.scala | 44 +++- .../test/scala/objects/EquipmentTest.scala | 3 - .../src/test/scala/objects/PlayerTest.scala | 12 +- .../src/main/scala/WorldSessionActor.scala | 215 +++++++++--------- .../scala/services/avatar/AvatarAction.scala | 4 +- .../services/avatar/AvatarResponse.scala | 4 +- .../scala/services/avatar/AvatarService.scala | 8 +- .../main/test/scala/AvatarServiceTest.scala | 67 +++++- 22 files changed, 333 insertions(+), 224 deletions(-) diff --git a/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala b/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala index 30395f27..03f64231 100644 --- a/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala +++ b/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala @@ -1032,10 +1032,12 @@ object GlobalDefinitions { chainblade.FireModes.head.AmmoTypeIndices += 0 chainblade.FireModes.head.AmmoSlotIndex = 0 chainblade.FireModes.head.Magazine = 1 + chainblade.FireModes.head.Chamber = 0 chainblade.FireModes += new FireModeDefinition chainblade.FireModes(1).AmmoTypeIndices += 0 chainblade.FireModes(1).AmmoSlotIndex = 0 chainblade.FireModes(1).Magazine = 1 + chainblade.FireModes.head.Chamber = 0 magcutter.Size = EquipmentSize.Melee magcutter.AmmoTypes += melee_ammo @@ -1043,10 +1045,12 @@ object GlobalDefinitions { magcutter.FireModes.head.AmmoTypeIndices += 0 magcutter.FireModes.head.AmmoSlotIndex = 0 magcutter.FireModes.head.Magazine = 1 + magcutter.FireModes.head.Chamber = 0 magcutter.FireModes += new FireModeDefinition magcutter.FireModes(1).AmmoTypeIndices += 0 magcutter.FireModes(1).AmmoSlotIndex = 0 magcutter.FireModes(1).Magazine = 1 + magcutter.FireModes.head.Chamber = 0 forceblade.Size = EquipmentSize.Melee forceblade.AmmoTypes += melee_ammo @@ -1583,7 +1587,8 @@ object GlobalDefinitions { trek.FireModes += new FireModeDefinition trek.FireModes(1).AmmoTypeIndices += 0 trek.FireModes(1).AmmoSlotIndex = 0 - trek.FireModes(1).Magazine = 0 + trek.FireModes(1).Magazine = 1 + trek.FireModes(1).Chamber = 0 trek.Tile = InventoryTile.Tile33 flail_targeting_laser.Packet = new CommandDetonaterConverter diff --git a/common/src/main/scala/net/psforever/objects/Player.scala b/common/src/main/scala/net/psforever/objects/Player.scala index 90efc893..52425265 100644 --- a/common/src/main/scala/net/psforever/objects/Player.scala +++ b/common/src/main/scala/net/psforever/objects/Player.scala @@ -31,7 +31,7 @@ class Player(private val name : String, private val fifthSlot : EquipmentSlot = new OffhandEquipmentSlot(EquipmentSize.Inventory) private val inventory : GridInventory = GridInventory() private var drawnSlot : Int = Player.HandsDownSlot - private var lastDrawnSlot : Int = 0 + private var lastDrawnSlot : Int = Player.HandsDownSlot private val loadouts : Array[Option[Loadout]] = Array.fill[Option[Loadout]](10)(None) @@ -325,16 +325,15 @@ class Player(private val name : String, def DrawnSlot : Int = drawnSlot - def DrawnSlot_=(slot : Int = Player.HandsDownSlot) : Int = { + def DrawnSlot_=(slot : Int) : Int = { if(slot != drawnSlot) { - val origDrawnSlot : Int = drawnSlot if(slot == Player.HandsDownSlot) { drawnSlot = slot } - else if(-1 < slot && slot < 5 && holsters(slot).Equipment.isDefined) { + else if(VisibleSlots.contains(slot) && holsters(slot).Equipment.isDefined) { drawnSlot = slot + lastDrawnSlot = slot } - lastDrawnSlot = if(-1 < origDrawnSlot && origDrawnSlot < 5) { origDrawnSlot } else { lastDrawnSlot } } DrawnSlot } diff --git a/common/src/main/scala/net/psforever/objects/Tool.scala b/common/src/main/scala/net/psforever/objects/Tool.scala index 068f13a0..df6c3df1 100644 --- a/common/src/main/scala/net/psforever/objects/Tool.scala +++ b/common/src/main/scala/net/psforever/objects/Tool.scala @@ -1,7 +1,7 @@ // Copyright (c) 2017 PSForever package net.psforever.objects -import net.psforever.objects.definition.ToolDefinition +import net.psforever.objects.definition.{AmmoBoxDefinition, ToolDefinition} import net.psforever.objects.equipment.{Ammo, Equipment, FireModeDefinition, FireModeSwitch} import scala.annotation.tailrec @@ -126,7 +126,7 @@ object Tool { */ private var ammoTypeIndex : Int = 0 /** a reference to the actual `AmmoBox` of this slot */ - private var box : AmmoBox = AmmoBox(tdef.AmmoTypes(ammoTypeIndex), fdef.Magazine) + private var box : AmmoBox = AmmoBox(AmmoDefinition, fdef.Magazine) def AmmoTypeIndex : Int = ammoTypeIndex @@ -135,13 +135,17 @@ object Tool { AmmoTypeIndex } + private def AmmoDefinition : AmmoBoxDefinition = { + tdef.AmmoTypes(fdef.AmmoTypeIndices(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 AmmoType : Ammo.Value = AmmoDefinition.AmmoType def AllAmmoTypes : List[Ammo.Value] = { fdef.AmmoTypeIndices.map(index => tdef.AmmoTypes(fdef.AmmoTypeIndices(index)).AmmoType).toList diff --git a/common/src/main/scala/net/psforever/objects/definition/AmmoBoxDefinition.scala b/common/src/main/scala/net/psforever/objects/definition/AmmoBoxDefinition.scala index 9598245f..4a7f4b96 100644 --- a/common/src/main/scala/net/psforever/objects/definition/AmmoBoxDefinition.scala +++ b/common/src/main/scala/net/psforever/objects/definition/AmmoBoxDefinition.scala @@ -10,7 +10,7 @@ class AmmoBoxDefinition(objectId : Int) extends EquipmentDefinition(objectId) { private var capacity : Int = 1 Name = "ammo box" Size = EquipmentSize.Inventory - Packet = new AmmoBoxConverter() + Packet = AmmoBoxDefinition.converter def AmmoType : Ammo.Value = ammoType @@ -23,6 +23,8 @@ class AmmoBoxDefinition(objectId : Int) extends EquipmentDefinition(objectId) { } object AmmoBoxDefinition { + private val converter = new AmmoBoxConverter() + def apply(objectId: Int) : AmmoBoxDefinition = { new AmmoBoxDefinition(objectId) } diff --git a/common/src/main/scala/net/psforever/objects/definition/AvatarDefinition.scala b/common/src/main/scala/net/psforever/objects/definition/AvatarDefinition.scala index 4f265ccf..3d26b714 100644 --- a/common/src/main/scala/net/psforever/objects/definition/AvatarDefinition.scala +++ b/common/src/main/scala/net/psforever/objects/definition/AvatarDefinition.scala @@ -10,10 +10,12 @@ import net.psforever.objects.definition.converter.AvatarConverter */ class AvatarDefinition(objectId : Int) extends ObjectDefinition(objectId) { Avatars(objectId) //let throw NoSuchElementException - Packet = new AvatarConverter() + Packet = AvatarDefinition.converter } object AvatarDefinition { + private val converter = new AvatarConverter() + def apply(objectId: Int) : AvatarDefinition = { new AvatarDefinition(objectId) } diff --git a/common/src/main/scala/net/psforever/objects/definition/KitDefinition.scala b/common/src/main/scala/net/psforever/objects/definition/KitDefinition.scala index f9d7ceae..ca318554 100644 --- a/common/src/main/scala/net/psforever/objects/definition/KitDefinition.scala +++ b/common/src/main/scala/net/psforever/objects/definition/KitDefinition.scala @@ -15,10 +15,12 @@ class KitDefinition(objectId : Int) extends EquipmentDefinition(objectId) { Size = EquipmentSize.Inventory Tile = InventoryTile.Tile42 Name = "kit" - Packet = new KitConverter() + Packet = KitDefinition.converter } object KitDefinition { + private val converter = new KitConverter() + def apply(objectId: Int) : KitDefinition = { new KitDefinition(objectId) } 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 f40e3946..54cda716 100644 --- a/common/src/main/scala/net/psforever/objects/definition/ToolDefinition.scala +++ b/common/src/main/scala/net/psforever/objects/definition/ToolDefinition.scala @@ -10,7 +10,7 @@ class ToolDefinition(objectId : Int) extends EquipmentDefinition(objectId) { 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() + Packet = ToolDefinition.converter def AmmoTypes : mutable.ListBuffer[AmmoBoxDefinition] = ammoTypes @@ -18,6 +18,8 @@ class ToolDefinition(objectId : Int) extends EquipmentDefinition(objectId) { } object ToolDefinition { + private val converter = new ToolConverter() + def apply(objectId : Int) : ToolDefinition = { new ToolDefinition(objectId) } diff --git a/common/src/main/scala/net/psforever/objects/definition/VehicleDefinition.scala b/common/src/main/scala/net/psforever/objects/definition/VehicleDefinition.scala index 708741ef..a84e97c6 100644 --- a/common/src/main/scala/net/psforever/objects/definition/VehicleDefinition.scala +++ b/common/src/main/scala/net/psforever/objects/definition/VehicleDefinition.scala @@ -26,7 +26,7 @@ class VehicleDefinition(objectId : Int) extends ObjectDefinition(objectId) { private var canCloak : Boolean = false private var canBeOwned : Boolean = true Name = "vehicle" - Packet = new VehicleConverter + Packet = VehicleDefinition.converter def MaxHealth : Int = maxHealth @@ -87,6 +87,8 @@ class VehicleDefinition(objectId : Int) extends ObjectDefinition(objectId) { } object VehicleDefinition { + private val converter = new VehicleConverter + def apply(objectId: Int) : VehicleDefinition = { new VehicleDefinition(objectId) } diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/ToolConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/ToolConverter.scala index eb386d6a..5718ff16 100644 --- a/common/src/main/scala/net/psforever/objects/definition/converter/ToolConverter.scala +++ b/common/src/main/scala/net/psforever/objects/definition/converter/ToolConverter.scala @@ -25,6 +25,6 @@ class ToolConverter extends ObjectCreateConverter[Tool]() { val box = obj.AmmoSlots(index).Box slots += InternalSlot(box.Definition.ObjectId, box.GUID, index, box.Definition.Packet.DetailedConstructorData(box).get) }) - Success(DetailedWeaponData(4,8, slots.toList)(maxSlot)) + Success(DetailedWeaponData(4,8, obj.FireModeIndex, slots.toList)(maxSlot)) } } diff --git a/common/src/main/scala/net/psforever/objects/equipment/FireModeDefinition.scala b/common/src/main/scala/net/psforever/objects/equipment/FireModeDefinition.scala index e1f7862b..423154bc 100644 --- a/common/src/main/scala/net/psforever/objects/equipment/FireModeDefinition.scala +++ b/common/src/main/scala/net/psforever/objects/equipment/FireModeDefinition.scala @@ -9,7 +9,6 @@ class FireModeDefinition { private var chamber : Int = 1 //how many rounds are queued to be fired at once, e.g., 3 for the Jackhammer's triple burst private var magazine : Int = 1 //how many rounds are queued for each reload cycle // private var target : Any = _ //target designation (self? other?) - private var resetAmmoIndexOnSwap : Boolean = false //when changing fire modes, do not attempt to match previous mode's ammo type //damage modifiers will follow here ... @@ -46,13 +45,6 @@ class FireModeDefinition { // target = setAsTarget // Target // } - - def ResetAmmoIndexOnSwap : Boolean = resetAmmoIndexOnSwap - - def ResetAmmoIndexOnSwap_=(reset : Boolean) : Boolean = { - resetAmmoIndexOnSwap = reset - ResetAmmoIndexOnSwap - } } object FireModeDefinition { diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedWeaponData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedWeaponData.scala index 9e4ecaf8..ba55ad81 100644 --- a/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedWeaponData.scala +++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/DetailedWeaponData.scala @@ -28,6 +28,7 @@ import shapeless.{::, HNil} */ final case class DetailedWeaponData(unk1 : Int, unk2 : Int, + fire_mode : Int, ammo : List[InternalSlot] )(implicit val mag_capacity : Int = 1) extends ConstructorData { override def bitsize : Long = { @@ -35,7 +36,7 @@ final case class DetailedWeaponData(unk1 : Int, for(o <- ammo) { bitsize += o.bitsize } - 61L + bitsize + 61L + bitsize //51 + 10 (from InventoryData) + ammo } } @@ -51,7 +52,21 @@ object DetailedWeaponData extends Marshallable[DetailedWeaponData] { * @return a `DetailedWeaponData` object */ def apply(unk1 : Int, unk2 : Int, cls : Int, guid : PlanetSideGUID, parentSlot : Int, ammo : DetailedAmmoBoxData) : DetailedWeaponData = - new DetailedWeaponData(unk1, unk2, InternalSlot(cls, guid, parentSlot, ammo) :: Nil) + new DetailedWeaponData(unk1, unk2, 0, InternalSlot(cls, guid, parentSlot, ammo) :: Nil) + + + /** + * Overloaded constructor for creating `DetailedWeaponData` while masking use of `InternalSlot` for its `DetailedAmmoBoxData`. + * @param unk1 na + * @param unk2 na + * @param cls the code for the type of object (ammunition) being constructed + * @param guid the globally unique id assigned to the ammunition + * @param parentSlot the slot where the ammunition is to be installed in the weapon + * @param ammo the constructor data for the ammunition + * @return a `DetailedWeaponData` object + */ + def apply(unk1 : Int, unk2 : Int, fire_mode : Int, cls : Int, guid : PlanetSideGUID, parentSlot : Int, ammo : DetailedAmmoBoxData) : DetailedWeaponData = + new DetailedWeaponData(unk1, unk2, fire_mode, InternalSlot(cls, guid, parentSlot, ammo) :: Nil) /** * A `Codec` for `DetailedWeaponData` @@ -60,17 +75,18 @@ object DetailedWeaponData extends Marshallable[DetailedWeaponData] { * @return a `WeaponData` object or a `BitVector` */ def codec(mag_capacity : Int = 1) : Codec[DetailedWeaponData] = ( - ("unk1" | uintL(3)) :: + ("unk1" | uint(3)) :: bool :: //weapon refuses to shoot if set (not weapons lock?) ("unk2" | uint4L) :: //8 - common; 4 - jammers weapons; 2 - weapon breaks; 1, 0 - safe uint24 :: - uint16 :: - uint2L :: + uint(12) :: + ("fire_mode" | uint(3)) :: //TODO size? + uint(3) :: ("ammo" | InventoryData.codec_detailed) :: bool ).exmap[DetailedWeaponData] ( { - case unk1 :: false :: unk2 :: 2 :: 0 :: 3 :: InventoryData(ammo) :: false :: HNil => + case unk1 :: false :: unk2 :: 2 :: 0 :: fmode :: 3 :: InventoryData(ammo) :: false :: HNil => val magSize = ammo.size if(mag_capacity == 0 || magSize == 0) { Attempt.failure(Err("weapon must decode some ammunition")) @@ -79,21 +95,21 @@ object DetailedWeaponData extends Marshallable[DetailedWeaponData] { Attempt.failure(Err(s"weapon decodes too much or too little ammunition - actual $magSize, expected $mag_capacity")) } else { - Attempt.successful(DetailedWeaponData(unk1, unk2, ammo)(magSize)) + Attempt.successful(DetailedWeaponData(unk1, unk2, fmode, ammo)(magSize)) } case _ => Attempt.failure(Err("invalid weapon data format")) }, { - case obj @ DetailedWeaponData(unk1, unk2, ammo) => + case obj @ DetailedWeaponData(unk1, unk2, fmode, ammo) => val magSize = ammo.size val magCapacity = obj.mag_capacity if(mag_capacity == 0 || magCapacity == 0 || magSize == 0) { Attempt.failure(Err("weapon must encode some ammunition")) } else if(magCapacity < 0 || mag_capacity < 0) { - Attempt.successful(unk1 :: false :: unk2 :: 2 :: 0 :: 3 :: InventoryData(ammo) :: false :: HNil) + Attempt.successful(unk1 :: false :: unk2 :: 2 :: 0 :: fmode :: 3 :: InventoryData(ammo) :: false :: HNil) } else { if(magCapacity != mag_capacity) { @@ -106,7 +122,7 @@ object DetailedWeaponData extends Marshallable[DetailedWeaponData] { Attempt.failure(Err("weapon encodes too much ammunition (255+ types!)")) } else { - Attempt.successful(unk1 :: false :: unk2 :: 2 :: 0 :: 3 :: InventoryData(ammo) :: false :: HNil) + Attempt.successful(unk1 :: false :: unk2 :: 2 :: 0 :: fmode :: 3 :: InventoryData(ammo) :: false :: HNil) } } diff --git a/common/src/main/scala/net/psforever/packet/game/objectcreate/WeaponData.scala b/common/src/main/scala/net/psforever/packet/game/objectcreate/WeaponData.scala index 1bd19eff..b27e53d8 100644 --- a/common/src/main/scala/net/psforever/packet/game/objectcreate/WeaponData.scala +++ b/common/src/main/scala/net/psforever/packet/game/objectcreate/WeaponData.scala @@ -102,7 +102,7 @@ object WeaponData extends Marshallable[WeaponData] { bool :: //weapon refuses to shoot if set (not weapons lock?) ("unk2" | uint4L) :: //8 - common; 4 - jammers weapons; 2 - weapon breaks; 1, 0 - safe uint(20) :: - ("fire_mode" | int(3)) :: + ("fire_mode" | int(3)) :: //TODO size? bool :: bool :: ("ammo" | InventoryData.codec) :: diff --git a/common/src/test/scala/game/objectcreatedetailed/DetailedCharacterDataTest.scala b/common/src/test/scala/game/objectcreatedetailed/DetailedCharacterDataTest.scala index 89f69019..38a31b52 100644 --- a/common/src/test/scala/game/objectcreatedetailed/DetailedCharacterDataTest.scala +++ b/common/src/test/scala/game/objectcreatedetailed/DetailedCharacterDataTest.scala @@ -652,59 +652,59 @@ class DetailedCharacterDataTest extends Specification { InventoryData( List( InternalSlot(531, PlanetSideGUID(4202), 0, - DetailedWeaponData(2, 8, List(InternalSlot(389, PlanetSideGUID(3942), 0,DetailedAmmoBoxData(8, 100)))) + DetailedWeaponData(2, 8, 0, List(InternalSlot(389, PlanetSideGUID(3942), 0,DetailedAmmoBoxData(8, 100)))) ), InternalSlot(132, PlanetSideGUID(6924), 1, - DetailedWeaponData(2, 8, List(InternalSlot(111, PlanetSideGUID(9157), 0, DetailedAmmoBoxData(8, 100)))) + DetailedWeaponData(2, 8, 0, List(InternalSlot(111, PlanetSideGUID(9157), 0, DetailedAmmoBoxData(8, 100)))) ), InternalSlot(714, PlanetSideGUID(8498), 2, - DetailedWeaponData(2, 8, List(InternalSlot(755, PlanetSideGUID(5356), 0, DetailedAmmoBoxData(8, 16)))) + DetailedWeaponData(2, 8, 0, List(InternalSlot(755, PlanetSideGUID(5356), 0, DetailedAmmoBoxData(8, 16)))) ), InternalSlot(468, PlanetSideGUID(7198), 4, - DetailedWeaponData(2, 8, List(InternalSlot(540, PlanetSideGUID(5009), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(2, 8, 0, List(InternalSlot(540, PlanetSideGUID(5009), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(456, PlanetSideGUID(5374), 5, DetailedLockerContainerData(8, Some(InventoryData(List( InternalSlot(429, PlanetSideGUID(3021), 0, - DetailedWeaponData(6, 8, List(InternalSlot(272, PlanetSideGUID(8729), 0, DetailedAmmoBoxData(8, 0)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(272, PlanetSideGUID(8729), 0, DetailedAmmoBoxData(8, 0)))) ), InternalSlot(838, PlanetSideGUID(8467), 9, - DetailedWeaponData(6, 8, List(InternalSlot(839, PlanetSideGUID(8603), 0, DetailedAmmoBoxData(8, 5)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(839, PlanetSideGUID(8603), 0, DetailedAmmoBoxData(8, 5)))) ), InternalSlot(272, PlanetSideGUID(3266), 18, DetailedAmmoBoxData(8, 27)), InternalSlot(577, PlanetSideGUID(2934), 22, - DetailedWeaponData(6, 8, List(InternalSlot(111, PlanetSideGUID(4682), 0, DetailedAmmoBoxData(8, 100)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(111, PlanetSideGUID(4682), 0, DetailedAmmoBoxData(8, 100)))) ), InternalSlot(839, PlanetSideGUID(3271), 90, DetailedAmmoBoxData(8, 15)), InternalSlot(839, PlanetSideGUID(7174), 94, DetailedAmmoBoxData(8, 6)), InternalSlot(429, PlanetSideGUID(6084), 98, - DetailedWeaponData(6, 8, List(InternalSlot(272, PlanetSideGUID(5928), 0, DetailedAmmoBoxData(8, 35)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(272, PlanetSideGUID(5928), 0, DetailedAmmoBoxData(8, 35)))) ), InternalSlot(462, PlanetSideGUID(5000), 108, - DetailedWeaponData(6, 8, List(InternalSlot(463, PlanetSideGUID(6277), 0, DetailedAmmoBoxData(8, 150)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(463, PlanetSideGUID(6277), 0, DetailedAmmoBoxData(8, 150)))) ), InternalSlot(429, PlanetSideGUID(4341), 189, - DetailedWeaponData(6, 8, List(InternalSlot(272, PlanetSideGUID(7043), 0, DetailedAmmoBoxData(8, 35)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(272, PlanetSideGUID(7043), 0, DetailedAmmoBoxData(8, 35)))) ), InternalSlot(556, PlanetSideGUID(4168), 198, - DetailedWeaponData(6, 8, List(InternalSlot(28, PlanetSideGUID(8937), 0, DetailedAmmoBoxData(8, 100)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(28, PlanetSideGUID(8937), 0, DetailedAmmoBoxData(8, 100)))) ), InternalSlot(272, PlanetSideGUID(3173), 207, DetailedAmmoBoxData(8, 50)), InternalSlot(462, PlanetSideGUID(3221), 210, - DetailedWeaponData(6, 8, List(InternalSlot(463, PlanetSideGUID(4031), 0, DetailedAmmoBoxData(8, 150)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(463, PlanetSideGUID(4031), 0, DetailedAmmoBoxData(8, 150)))) ), InternalSlot(556, PlanetSideGUID(6853), 280, - DetailedWeaponData(6, 8, List(InternalSlot(29, PlanetSideGUID(8524), 0, DetailedAmmoBoxData(8, 67)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(29, PlanetSideGUID(8524), 0, DetailedAmmoBoxData(8, 67)))) ), InternalSlot(556, PlanetSideGUID(4569), 290, - DetailedWeaponData(6, 8, List(InternalSlot(28, PlanetSideGUID(5584), 0, DetailedAmmoBoxData(8, 100)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(28, PlanetSideGUID(5584), 0, DetailedAmmoBoxData(8, 100)))) ), InternalSlot(462, PlanetSideGUID(9294), 300, - DetailedWeaponData(6, 8, List(InternalSlot(463, PlanetSideGUID(3118), 0, DetailedAmmoBoxData(8, 150)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(463, PlanetSideGUID(3118), 0, DetailedAmmoBoxData(8, 150)))) ), InternalSlot(272, PlanetSideGUID(4759), 387, DetailedAmmoBoxData(8, 50)), InternalSlot(462, PlanetSideGUID(7377), 390, - DetailedWeaponData(6, 8, List(InternalSlot(463, PlanetSideGUID(8155), 0, DetailedAmmoBoxData(8, 150)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(463, PlanetSideGUID(8155), 0, DetailedAmmoBoxData(8, 150)))) ), InternalSlot(843, PlanetSideGUID(6709), 480, DetailedAmmoBoxData(8, 1)), InternalSlot(843, PlanetSideGUID(5276), 484, DetailedAmmoBoxData(8, 1)), @@ -714,109 +714,109 @@ class DetailedCharacterDataTest extends Specification { InternalSlot(842, PlanetSideGUID(7279), 500, DetailedAmmoBoxData(8, 1)), InternalSlot(842, PlanetSideGUID(5415), 504, DetailedAmmoBoxData(8, 1)), InternalSlot(175, PlanetSideGUID(5741), 540, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(5183), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(5183), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(324, PlanetSideGUID(6208), 541, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(5029), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(5029), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(324, PlanetSideGUID(8589), 542, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(9217), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(9217), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(175, PlanetSideGUID(8901), 543, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(7633), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(7633), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(175, PlanetSideGUID(8419), 544, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(6546), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(6546), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(175, PlanetSideGUID(4715), 545, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(8453), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(8453), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(324, PlanetSideGUID(3577), 546, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(9202), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(9202), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(324, PlanetSideGUID(6003), 547, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(3260), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(3260), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(324, PlanetSideGUID(9140), 548, - DetailedWeaponData(6, 8, List(InternalSlot(540,PlanetSideGUID(3815),0,DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540,PlanetSideGUID(3815),0,DetailedAmmoBoxData(8, 1)))) ), InternalSlot(324, PlanetSideGUID(4913), 549, - DetailedWeaponData(6, 8, List(InternalSlot(540,PlanetSideGUID(7222),0,DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540,PlanetSideGUID(7222),0,DetailedAmmoBoxData(8, 1)))) ), InternalSlot(324, PlanetSideGUID(6954), 550, - DetailedWeaponData(6, 8, List(InternalSlot(540,PlanetSideGUID(2953),0,DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540,PlanetSideGUID(2953),0,DetailedAmmoBoxData(8, 1)))) ), InternalSlot(324, PlanetSideGUID(6405), 551, - DetailedWeaponData(6, 8, List(InternalSlot(540,PlanetSideGUID(4676),0,DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540,PlanetSideGUID(4676),0,DetailedAmmoBoxData(8, 1)))) ), InternalSlot(324, PlanetSideGUID(8915), 552, - DetailedWeaponData(6, 8, List(InternalSlot(540,PlanetSideGUID(4018),0,DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540,PlanetSideGUID(4018),0,DetailedAmmoBoxData(8, 1)))) ), InternalSlot(324, PlanetSideGUID(4993), 553, - DetailedWeaponData(6, 8, List(InternalSlot(540,PlanetSideGUID(6775),0,DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540,PlanetSideGUID(6775),0,DetailedAmmoBoxData(8, 1)))) ), InternalSlot(175, PlanetSideGUID(5053), 554, - DetailedWeaponData(6, 8, List(InternalSlot(540,PlanetSideGUID(6418),0,DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540,PlanetSideGUID(6418),0,DetailedAmmoBoxData(8, 1)))) ), InternalSlot(324, PlanetSideGUID(9244), 555, - DetailedWeaponData(6, 8, List(InternalSlot(540,PlanetSideGUID(3327),0,DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540,PlanetSideGUID(3327),0,DetailedAmmoBoxData(8, 1)))) ), InternalSlot(468, PlanetSideGUID(6292), 556, - DetailedWeaponData(6, 8, List(InternalSlot(540,PlanetSideGUID(6918),0,DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540,PlanetSideGUID(6918),0,DetailedAmmoBoxData(8, 1)))) ), InternalSlot(842, PlanetSideGUID(5357), 558, DetailedAmmoBoxData(8, 1)), InternalSlot(844, PlanetSideGUID(4435), 562, DetailedAmmoBoxData(8, 1)), InternalSlot(843, PlanetSideGUID(7242), 566, DetailedAmmoBoxData(8, 1)), InternalSlot(175, PlanetSideGUID(7330), 570, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(4786), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(4786), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(468, PlanetSideGUID(7415), 571, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(6536), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(6536), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(175, PlanetSideGUID(3949), 572, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(7526), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(7526), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(175, PlanetSideGUID(3805), 573, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(7358), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(7358), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(324, PlanetSideGUID(4493), 574, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(6852), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(6852), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(324, PlanetSideGUID(5762), 575, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(3463), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(3463), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(175, PlanetSideGUID(3315), 576, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(7619), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(7619), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(324, PlanetSideGUID(6263), 577, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(5912), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(5912), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(468, PlanetSideGUID(4028), 578, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(8021), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(8021), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(175, PlanetSideGUID(2843), 579, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(7250), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(7250), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(175, PlanetSideGUID(9143), 580, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(5195), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(5195), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(468, PlanetSideGUID(5024), 581, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(4287), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(4287), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(468, PlanetSideGUID(6582), 582, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(4915), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(4915), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(468, PlanetSideGUID(6425), 583, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(8872), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(8872), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(468, PlanetSideGUID(4431), 584, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(4191), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(4191), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(175, PlanetSideGUID(8339), 585, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(7317), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(7317), 0, DetailedAmmoBoxData(8, 1)))) ), InternalSlot(175, PlanetSideGUID(3277), 586, - DetailedWeaponData(6, 8, List(InternalSlot(540, PlanetSideGUID(6469), 0, DetailedAmmoBoxData(8, 1)))) + DetailedWeaponData(6, 8, 0, List(InternalSlot(540, PlanetSideGUID(6469), 0, DetailedAmmoBoxData(8, 1)))) ) )))) ), @@ -825,11 +825,11 @@ class DetailedCharacterDataTest extends Specification { InternalSlot(728, PlanetSideGUID(7181), 12, DetailedREKData(4, 16)), InternalSlot(536, PlanetSideGUID(4077), 33, DetailedAmmoBoxData(8, 1)), InternalSlot(680, PlanetSideGUID(4377), 37, - DetailedWeaponData(2, 8, List(InternalSlot(681, PlanetSideGUID(8905), 0, DetailedAmmoBoxData(8, 3)))) + DetailedWeaponData(2, 8, 0, List(InternalSlot(681, PlanetSideGUID(8905), 0, DetailedAmmoBoxData(8, 3)))) ), InternalSlot(32, PlanetSideGUID(5523), 39, DetailedACEData(4)), InternalSlot(673, PlanetSideGUID(3661), 60, - DetailedWeaponData(2, 8, List(InternalSlot(674, PlanetSideGUID(8542), 0, DetailedAmmoBoxData(8, 3)))) + DetailedWeaponData(2, 8, 0, List(InternalSlot(674, PlanetSideGUID(8542), 0, DetailedAmmoBoxData(8, 3)))) ) ) ) diff --git a/common/src/test/scala/game/objectcreatedetailed/DetailedWeaponDataTest.scala b/common/src/test/scala/game/objectcreatedetailed/DetailedWeaponDataTest.scala index 90c92a2a..05cb8fd5 100644 --- a/common/src/test/scala/game/objectcreatedetailed/DetailedWeaponDataTest.scala +++ b/common/src/test/scala/game/objectcreatedetailed/DetailedWeaponDataTest.scala @@ -72,7 +72,7 @@ class DetailedWeaponDataTest extends Specification { } "encode (punisher)" in { - val obj = DetailedWeaponData(0, 8, + val obj = DetailedWeaponData(0, 8, 0, DetailedAmmoBoxData(ObjectClass.bullet_9mm, PlanetSideGUID(1693), 0, DetailedAmmoBoxData(8, 30)) :: DetailedAmmoBoxData(ObjectClass.jammer_cartridge, PlanetSideGUID(1564), 1, DetailedAmmoBoxData(8, 1)) :: Nil diff --git a/common/src/test/scala/objects/ConverterTest.scala b/common/src/test/scala/objects/ConverterTest.scala index f9a22fde..b6ea3619 100644 --- a/common/src/test/scala/objects/ConverterTest.scala +++ b/common/src/test/scala/objects/ConverterTest.scala @@ -37,22 +37,13 @@ class ConverterTest extends Specification { } "Tool" should { - "convert to packet" in { - val tdef = ToolDefinition(1076) - tdef.Size = EquipmentSize.Rifle - 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) + "convert to packet (1 fire mode slot)" in { + val obj : Tool = Tool(GlobalDefinitions.flechette) obj.AmmoSlot.Box.GUID = PlanetSideGUID(90) obj.Definition.Packet.DetailedConstructorData(obj) match { case Success(pkt) => - pkt mustEqual DetailedWeaponData(4,8, Ammo.shotgun_shell.id, PlanetSideGUID(90), 0, DetailedAmmoBoxData(8, 30)) + pkt mustEqual DetailedWeaponData(4,8, Ammo.shotgun_shell.id, PlanetSideGUID(90), 0, DetailedAmmoBoxData(8, 12)) case _ => ko } @@ -63,6 +54,35 @@ class ConverterTest extends Specification { ko } } + + "convert to packet (2 fire mode slots)" in { + val obj : Tool = Tool(GlobalDefinitions.punisher) + obj.AmmoSlots.head.Box.GUID = PlanetSideGUID(90) + obj.AmmoSlots(1).Box.GUID = PlanetSideGUID(91) + + obj.Definition.Packet.DetailedConstructorData(obj) match { + case Success(pkt) => + pkt mustEqual DetailedWeaponData(4,8, 0, + List( + InternalSlot(Ammo.bullet_9mm.id, PlanetSideGUID(90), 0, DetailedAmmoBoxData(8, 30)), + InternalSlot(Ammo.rocket.id, PlanetSideGUID(91), 1, DetailedAmmoBoxData(8, 1)) + ) + ) + case _ => + ko + } + obj.Definition.Packet.ConstructorData(obj) match { + case Success(pkt) => + pkt mustEqual WeaponData(4,8, 0, + List( + InternalSlot(Ammo.bullet_9mm.id, PlanetSideGUID(90), 0, AmmoBoxData()), + InternalSlot(Ammo.rocket.id, PlanetSideGUID(91), 1, AmmoBoxData()) + ) + ) + case _ => + ko + } + } } "Kit" should { diff --git a/common/src/test/scala/objects/EquipmentTest.scala b/common/src/test/scala/objects/EquipmentTest.scala index 3fbe4501..ff44aab7 100644 --- a/common/src/test/scala/objects/EquipmentTest.scala +++ b/common/src/test/scala/objects/EquipmentTest.scala @@ -114,7 +114,6 @@ class EquipmentTest extends Specification { obj.FireModes.head.AmmoTypeIndices += 1 obj.FireModes.head.AmmoSlotIndex = 0 obj.FireModes.head.Magazine = 18 - obj.FireModes.head.ResetAmmoIndexOnSwap = true obj.FireModes += FireModeDefinition() obj.FireModes(1).AmmoTypeIndices += 0 obj.FireModes(1).AmmoTypeIndices += 1 @@ -132,13 +131,11 @@ class EquipmentTest extends Specification { obj.FireModes.head.AmmoSlotIndex mustEqual 0 obj.FireModes.head.Chamber mustEqual 1 obj.FireModes.head.Magazine mustEqual 18 - obj.FireModes.head.ResetAmmoIndexOnSwap mustEqual true obj.FireModes(1).AmmoTypeIndices.head mustEqual 0 obj.FireModes(1).AmmoTypeIndices(1) mustEqual 1 obj.FireModes(1).AmmoSlotIndex mustEqual 1 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 } diff --git a/common/src/test/scala/objects/PlayerTest.scala b/common/src/test/scala/objects/PlayerTest.scala index 2e737e96..d082fe2f 100644 --- a/common/src/test/scala/objects/PlayerTest.scala +++ b/common/src/test/scala/objects/PlayerTest.scala @@ -114,15 +114,15 @@ class PlayerTest extends Specification { obj.Slot(1).Size = EquipmentSize.Pistol obj.Slot(1).Equipment = wep2 obj.DrawnSlot mustEqual Player.HandsDownSlot //default value - obj.LastDrawnSlot mustEqual 0 //default value + obj.LastDrawnSlot mustEqual Player.HandsDownSlot //default value obj.DrawnSlot = 1 obj.DrawnSlot mustEqual 1 - obj.LastDrawnSlot mustEqual 0 //default value; sorry + obj.LastDrawnSlot mustEqual 1 obj.DrawnSlot = 0 obj.DrawnSlot mustEqual 0 - obj.LastDrawnSlot mustEqual 1 + obj.LastDrawnSlot mustEqual 0 obj.DrawnSlot = Player.HandsDownSlot obj.DrawnSlot mustEqual Player.HandsDownSlot @@ -130,15 +130,15 @@ class PlayerTest extends Specification { obj.DrawnSlot = 1 obj.DrawnSlot mustEqual 1 - obj.LastDrawnSlot mustEqual 0 + obj.LastDrawnSlot mustEqual 1 obj.DrawnSlot = 0 obj.DrawnSlot mustEqual 0 - obj.LastDrawnSlot mustEqual 1 + obj.LastDrawnSlot mustEqual 0 obj.DrawnSlot = 1 obj.DrawnSlot mustEqual 1 - obj.LastDrawnSlot mustEqual 0 + obj.LastDrawnSlot mustEqual 1 obj.DrawnSlot = Player.HandsDownSlot obj.DrawnSlot mustEqual Player.HandsDownSlot diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index e1127d25..d3c82104 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -62,6 +62,7 @@ class WorldSessionActor extends Actor with MDCContextAware { case Some(tplayer) => tplayer.VehicleSeated match { case Some(vehicle_guid) => + //TODO do this at some other time vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.KickPassenger(tplayer.GUID, 0, true, vehicle_guid)) case None => ; } @@ -146,9 +147,12 @@ class WorldSessionActor extends Actor with MDCContextAware { sendResponse(PacketCoding.CreateGamePacket(0, ArmorChangedMessage(guid, suit, subtype))) } - case AvatarResponse.ChangeAmmo(weapon_guid, weapon_slot, ammo_id, ammo_guid, ammo_data) => + case AvatarResponse.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) => if(player.GUID != guid) { sendResponse(PacketCoding.CreateGamePacket(0, + ObjectDetachMessage(weapon_guid, previous_guid, Vector3(0,0,0), 0f, 0f, 0f) + )) + sendResponse(PacketCoding.CreateGamePacket(0, ObjectCreateMessage( ammo_id, ammo_guid, @@ -159,6 +163,11 @@ class WorldSessionActor extends Actor with MDCContextAware { sendResponse(PacketCoding.CreateGamePacket(0, ChangeAmmoMessage(weapon_guid, 1))) } + case AvatarResponse.ChangeFireMode(item_guid, mode) => + if(player.GUID != guid) { + sendResponse(PacketCoding.CreateGamePacket(0, ChangeFireModeMessage(item_guid, mode))) + } + case AvatarResponse.ChangeFireState_Start(weapon_guid) => if(player.GUID != guid) { sendResponse(PacketCoding.CreateGamePacket(0, ChangeFireStateMessage_Start(weapon_guid))) @@ -214,7 +223,7 @@ class WorldSessionActor extends Actor with MDCContextAware { case AvatarResponse.ObjectHeld(slot) => if(player.GUID != guid) { - sendResponse(PacketCoding.CreateGamePacket(0, ObjectHeldMessage(guid, slot, true))) + sendResponse(PacketCoding.CreateGamePacket(0, ObjectHeldMessage(guid, slot, false))) } case AvatarResponse.PlanetsideAttribute(attribute_type, attribute_value) => @@ -237,9 +246,10 @@ class WorldSessionActor extends Actor with MDCContextAware { if(spectating || ((distanceSq < 900 || weaponInHand) && time > 200) || (distanceSq < 10000 && time > 500) || - (distanceSq < 160000 && (msg.is_jumping || time < 200)) || - (distanceSq < 160000 && (msg.vel.isEmpty || Vector3.MagnitudeSquared(msg.vel.get).toInt == 0) && time > 2000) || - (distanceSq < 160000 && time > 1000) || + (distanceSq < 160000 && ( + (msg.is_jumping || time < 200)) || + ((msg.vel.isEmpty || Vector3.MagnitudeSquared(msg.vel.get).toInt == 0) && time > 2000) || + (time > 1000)) || (distanceSq > 160000 && time > 5000)) { sendResponse( @@ -976,7 +986,7 @@ class WorldSessionActor extends Actor with MDCContextAware { ) ) ) - if(-1 < slot && slot < 5) { + if(tplayer.VisibleSlots.contains(slot)) { avatarService ! AvatarServiceMessage(tplayer.Continent, AvatarAction.EquipmentInHand(player_guid, slot, item)) } case None => @@ -1124,11 +1134,11 @@ class WorldSessionActor extends Actor with MDCContextAware { AwardBattleExperiencePoints(player, 1000000L) // player.ExoSuit = ExoSuitType.MAX //TODO strange issue; divide number above by 10 when uncommenting player.Slot(0).Equipment = Tool(GlobalDefinitions.StandardPistol(player.Faction)) - player.Slot(2).Equipment = Tool(suppressor) + player.Slot(2).Equipment = Tool(punisher) //suppressor player.Slot(4).Equipment = Tool(GlobalDefinitions.StandardMelee(player.Faction)) - player.Slot(6).Equipment = AmmoBox(bullet_9mm) + player.Slot(6).Equipment = AmmoBox(frag_cartridge) //bullet_9mm player.Slot(9).Equipment = AmmoBox(bullet_9mm) - player.Slot(12).Equipment = AmmoBox(bullet_9mm) + //player.Slot(12).Equipment = AmmoBox(bullet_9mm) player.Slot(33).Equipment = AmmoBox(bullet_9mm_AP) player.Slot(36).Equipment = AmmoBox(GlobalDefinitions.StandardPistolAmmo(player.Faction)) player.Slot(39).Equipment = SimpleItem(remote_electronics_kit) @@ -1347,34 +1357,7 @@ class WorldSessionActor extends Actor with MDCContextAware { case msg @ ChangeAmmoMessage(item_guid, unk1) => log.info("ChangeAmmo: " + msg) - (player.VehicleSeated match { - case Some(vehicle_guid) => //weapon is vehicle turret? - continent.GUID(vehicle_guid) match { - case Some(vehicle : Vehicle) => - vehicle.PassengerInSeat(player) match { - case Some(seat_num) => - vehicle.WeaponControlledFromSeat(seat_num) match { - case Some(item : Tool) => - //TODO check that item controlled by seat is item_guid? - (Some(vehicle), Some(item)) - case _ => ; - (None, None) - } - case None => ; - (None, None) - } - case _ => ; - (None, None) - } - case None => //not in vehicle; weapon in hand? - player.Slot(player.DrawnSlot).Equipment match { - //TODO check that item in hand is item_guid? - case Some(item : Tool) => - (Some(player), Some(item)) - case _ => ; - (None, None) - } - }) match { + FindContainedWeapon match { case (Some(obj), Some(tool : Tool)) => val originalAmmoType = tool.AmmoType val fullMagazine = tool.MaxMagazine @@ -1414,6 +1397,14 @@ class WorldSessionActor extends Actor with MDCContextAware { tool.AmmoSlots(ammoSlotIndex).Box = box //put replacement ammo in tool sendResponse(PacketCoding.CreateGamePacket(0, ObjectAttachMessage(tool.GUID, box.GUID, ammoSlotIndex))) + //announce swapped ammunition box in weapon + val previous_box_guid = previousBox.GUID + val boxDef = box.Definition + val box_guid = box.GUID + val tool_guid = tool.GUID + sendResponse(PacketCoding.CreateGamePacket(0, ChangeAmmoMessage(tool_guid, box.Capacity))) + avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.ChangeAmmo(player.GUID, tool_guid, ammoSlotIndex,previous_box_guid, boxDef.ObjectId, box.GUID, boxDef.Packet.ConstructorData(box).get)) + //handle inventory contents box.Capacity = (if(sumReloadValue <= fullMagazine) { sumReloadValue @@ -1454,6 +1445,7 @@ class WorldSessionActor extends Actor with MDCContextAware { } previousBox.Capacity = capacity } + if(previousBox.Capacity > 0) { //TODO split previousBox into AmmoBox objects of appropriate max capacity, e.g., 100 9mm -> 2 x 50 9mm obj.Inventory.Fit(previousBox.Definition.Tile) match { @@ -1463,7 +1455,7 @@ class WorldSessionActor extends Actor with MDCContextAware { log.info(s"ChangeAmmo: dropping ammo box $previousBox") val pos = player.Position val orient = player.Orientation - sendResponse(PacketCoding.CreateGamePacket(0, ObjectDetachMessage(Service.defaultPlayerGUID, previousBox.GUID, pos, 0f, 0f, orient.z))) + sendResponse(PacketCoding.CreateGamePacket(0, ObjectDetachMessage(Service.defaultPlayerGUID, previous_box_guid, pos, 0f, 0f, orient.z))) val orient2 = Vector3(0f, 0f, orient.z) continent.Ground ! Zone.DropItemOnGround(previousBox, pos, orient2) val objDef = previousBox.Definition @@ -1473,13 +1465,6 @@ class WorldSessionActor extends Actor with MDCContextAware { else { taskResolver ! GUIDTask.UnregisterObjectTask(previousBox)(continent.GUID) } - - //announce swapped ammunition box in weapon - val boxDef = box.Definition - val box_guid = box.GUID - val tool_guid = tool.GUID - sendResponse(PacketCoding.CreateGamePacket(0, ChangeAmmoMessage(tool_guid, box.Capacity))) - avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.ChangeAmmo(player.GUID, tool_guid, ammoSlotIndex, boxDef.ObjectId, box.GUID, boxDef.Packet.ConstructorData(box).get)) } } } @@ -1493,6 +1478,26 @@ class WorldSessionActor extends Actor with MDCContextAware { case msg @ ChangeFireModeMessage(item_guid, fire_mode) => log.info("ChangeFireMode: " + msg) + FindContainedWeapon match { + case (_, Some(tool : Tool)) => + val originalModeIndex = tool.FireModeIndex + tool.NextFireMode + val modeIndex = tool.FireModeIndex + val tool_guid = tool.GUID + if(originalModeIndex != modeIndex) { + log.info(s"ChangeFireMode: changing $tool_guid to fire mode $modeIndex") + sendResponse(PacketCoding.CreateGamePacket(0, ChangeFireModeMessage(tool_guid, modeIndex))) + avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.ChangeFireMode(player.GUID, tool_guid, modeIndex)) + } + else { + tool.FireModeIndex = originalModeIndex + sendResponse(PacketCoding.CreateGamePacket(0, ChangeFireModeMessage(tool_guid, originalModeIndex))) + } + case (_, Some(_)) => + log.error(s"ChangeFireMode: the object that was found for $item_guid was not a Tool") + case (_, None) => + log.error(s"ChangeFireMode: can not find $item_guid") + } case msg @ ChangeFireStateMessage_Start(item_guid) => log.info("ChangeFireState_Start: " + msg) @@ -1539,34 +1544,7 @@ class WorldSessionActor extends Actor with MDCContextAware { case msg @ ReloadMessage(item_guid, ammo_clip, unk1) => log.info("Reload: " + msg) - (player.VehicleSeated match { - case Some(vehicle_guid) => //weapon is vehicle turret? - continent.GUID(vehicle_guid) match { - case Some(vehicle : Vehicle) => - vehicle.PassengerInSeat(player) match { - case Some(seat_num) => - vehicle.WeaponControlledFromSeat(seat_num) match { - case Some(item : Tool) => - //TODO check that item controlled by seat is item_guid? - (Some(vehicle), Some(item)) - case _ => ; - (None, None) - } - case None => ; - (None, None) - } - case _ => ; - (None, None) - } - case None => //not in vehicle; weapon in hand? - player.Slot(player.DrawnSlot).Equipment match { - //TODO check that item in hand is item_guid? - case Some(item : Tool) => - (Some(player), Some(item)) - case _ => ; - (None, None) - } - }) match { + FindContainedWeapon match { case (Some(obj), Some(tool : Tool)) => val currentMagazine : Int = tool.Magazine val magazineSize : Int = tool.MaxMagazine @@ -1616,7 +1594,7 @@ class WorldSessionActor extends Actor with MDCContextAware { val before = player.DrawnSlot //TODO remove this kludge; explore how to stop BuyExoSuit(Max) sending a tardy ObjectHeldMessage(me, 255) if(player.ExoSuit != ExoSuitType.MAX && (player.DrawnSlot = held_holsters) != before) { - avatarService ! AvatarServiceMessage(player.Continent, AvatarAction.ObjectHeld(player.GUID, held_holsters)) + avatarService ! AvatarServiceMessage(player.Continent, AvatarAction.ObjectHeld(player.GUID, player.LastDrawnSlot)) } case msg @ AvatarJumpMessage(state) => @@ -1913,22 +1891,7 @@ class WorldSessionActor extends Actor with MDCContextAware { case msg @ WeaponDryFireMessage(weapon_guid) => log.info("WeaponDryFireMessage: "+msg) - (player.VehicleSeated match { - case Some(vehicle_guid) => - continent.GUID(vehicle_guid) match { - case Some(obj : Vehicle) => - obj.PassengerInSeat(player) match { - case Some(seat_num) => - obj.WeaponControlledFromSeat(seat_num) - case None => - None - } - case _ => - None - } - case None => - player.Slot(player.DrawnSlot).Equipment - }) match { + FindWeapon match { case Some(tool : Tool) => avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.WeaponDryFire(player.GUID, weapon_guid)) case _ => ; @@ -1936,22 +1899,7 @@ class WorldSessionActor extends Actor with MDCContextAware { case msg @ WeaponFireMessage(seq_time, weapon_guid, projectile_guid, shot_origin, unk1, unk2, unk3, unk4, unk5, unk6, unk7) => log.info("WeaponFire: " + msg) - (player.VehicleSeated match { - case Some(vehicle_guid) => - continent.GUID(vehicle_guid) match { - case Some(obj : Vehicle) => - obj.PassengerInSeat(player) match { - case Some(seat_num) => - obj.WeaponControlledFromSeat(seat_num) - case None => - None - } - case _ => - None - } - case None => - player.Slot(player.DrawnSlot).Equipment - }) match { + FindWeapon match { case Some(tool : Tool) => if(tool.Magazine <= 0) { //safety: enforce ammunition depletion tool.Magazine = 0 @@ -1963,7 +1911,7 @@ class WorldSessionActor extends Actor with MDCContextAware { } else { //shooting tool.Magazine = tool.Magazine - 1 - //TODO other stuff + //TODO other stuff? } case _ => ; } @@ -2654,6 +2602,59 @@ class WorldSessionActor extends Actor with MDCContextAware { }) } + /** + * Check two locations for a controlled piece of equipment that is associated with the `player`.
+ *
+ * The first location is dependent on whether the avatar is in a vehicle. + * Some vehicle seats may have a "controlled weapon" which counts as the first location to be checked. + * The second location is dependent on whether the avatar has a raised hand. + * That is only possible if the player has something in their hand at the moment, hence the second location. + * Players do have a concept called a "last drawn slot" (hand) but that former location is not eligible.
+ *
+ * Along with any discovered item, a containing object such that the statement:
+ * `container.Find(object) = Some(slot)`
+ * ... will return a proper result. + * For a seat controlled weapon, the vehicle is returned. + * For the player's hand, the player is returned. + * @return a `Tuple` of the returned values; + * the first value is a `Container` object; + * the second value is an `Equipment` object in the former + */ + def FindContainedWeapon : (Option[PlanetSideGameObject with Container], Option[Equipment]) = { + player.VehicleSeated match { + case Some(vehicle_guid) => //weapon is vehicle turret? + continent.GUID(vehicle_guid) match { + case Some(vehicle : Vehicle) => + vehicle.PassengerInSeat(player) match { + case Some(seat_num) => + vehicle.WeaponControlledFromSeat(seat_num) match { + case Some(item : Tool) => + (Some(vehicle), Some(item)) + case _ => ; + (None, None) + } + case None => ; + (None, None) + } + case _ => ; + (None, None) + } + case None => //not in vehicle; weapon in hand? + player.Slot(player.DrawnSlot).Equipment match { + case Some(item : Tool) => + (Some(player), Some(item)) + case _ => ; + (None, None) + } + } + } + + /** + * Runs `FindContainedWeapon` but ignores the `Container` object output. + * @return an `Equipment` object + */ + def FindWeapon : Option[Equipment] = FindContainedWeapon._2 + /** * Within a specified `Container`, find the smallest number of `AmmoBox` objects of a certain type of `Ammo` * whose sum capacities is greater than, or equal to, a `desiredAmount`.
diff --git a/pslogin/src/main/scala/services/avatar/AvatarAction.scala b/pslogin/src/main/scala/services/avatar/AvatarAction.scala index 9a09742a..13ece68e 100644 --- a/pslogin/src/main/scala/services/avatar/AvatarAction.scala +++ b/pslogin/src/main/scala/services/avatar/AvatarAction.scala @@ -10,11 +10,11 @@ object AvatarAction { trait Action final case class ArmorChanged(player_guid : PlanetSideGUID, suit : ExoSuitType.Value, subtype : Int) extends Action - final case class ChangeAmmo(player_guid : PlanetSideGUID, weapon_guid : PlanetSideGUID, weapon_slot : Int, ammo_id : Int, ammo_guid : PlanetSideGUID, ammo_data : ConstructorData) extends Action + final case class ChangeAmmo(player_guid : PlanetSideGUID, weapon_guid : PlanetSideGUID, weapon_slot : Int, old_ammo_guid : PlanetSideGUID, ammo_id : Int, ammo_guid : PlanetSideGUID, ammo_data : ConstructorData) extends Action + final case class ChangeFireMode(player_guid : PlanetSideGUID, item_guid : PlanetSideGUID, mode : Int) extends Action final case class ChangeFireState_Start(player_guid : PlanetSideGUID, weapon_guid : PlanetSideGUID) extends Action final case class ChangeFireState_Stop(player_guid : PlanetSideGUID, weapon_guid : PlanetSideGUID) 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_id : Int, item_guid : PlanetSideGUID, item_data : ConstructorData) extends Action final case class LoadPlayer(player_guid : PlanetSideGUID, pdata : ConstructorData) extends Action diff --git a/pslogin/src/main/scala/services/avatar/AvatarResponse.scala b/pslogin/src/main/scala/services/avatar/AvatarResponse.scala index 1da7fcba..0ffe562f 100644 --- a/pslogin/src/main/scala/services/avatar/AvatarResponse.scala +++ b/pslogin/src/main/scala/services/avatar/AvatarResponse.scala @@ -10,11 +10,11 @@ object AvatarResponse { trait Response final case class ArmorChanged(suit : ExoSuitType.Value, subtype : Int) extends Response - final case class ChangeAmmo(weapon_guid : PlanetSideGUID, weapon_slot : Int, ammo_id : Int, ammo_guid : PlanetSideGUID, ammo_data : ConstructorData) extends Response + final case class ChangeAmmo(weapon_guid : PlanetSideGUID, weapon_slot : Int, old_ammo_guid : PlanetSideGUID, ammo_id : Int, ammo_guid : PlanetSideGUID, ammo_data : ConstructorData) extends Response + final case class ChangeFireMode(item_guid : PlanetSideGUID, mode : Int) extends Response final case class ChangeFireState_Start(weapon_guid : PlanetSideGUID) extends Response final case class ChangeFireState_Stop(weapon_guid : PlanetSideGUID) 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_id : Int, item_guid : PlanetSideGUID, item_data : ConstructorData) extends Response final case class LoadPlayer(pdata : ConstructorData) extends Response diff --git a/pslogin/src/main/scala/services/avatar/AvatarService.scala b/pslogin/src/main/scala/services/avatar/AvatarService.scala index 5e47c3e8..dcf24902 100644 --- a/pslogin/src/main/scala/services/avatar/AvatarService.scala +++ b/pslogin/src/main/scala/services/avatar/AvatarService.scala @@ -39,9 +39,13 @@ class AvatarService extends Actor { AvatarEvents.publish( AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.ArmorChanged(suit, subtype)) ) - case AvatarAction.ChangeAmmo(player_guid, weapon_guid, weapon_slot, ammo_id, ammo_guid, ammo_data) => + case AvatarAction.ChangeAmmo(player_guid, weapon_guid, weapon_slot, old_ammo_guid, ammo_id, ammo_guid, ammo_data) => AvatarEvents.publish( - AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.ChangeAmmo(weapon_guid, weapon_slot, ammo_id, ammo_guid, ammo_data)) + AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.ChangeAmmo(weapon_guid, weapon_slot, old_ammo_guid, ammo_id, ammo_guid, ammo_data)) + ) + case AvatarAction.ChangeFireMode(player_guid, item_guid, mode) => + AvatarEvents.publish( + AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.ChangeFireMode(item_guid, mode)) ) case AvatarAction.ChangeFireState_Start(player_guid, weapon_guid) => AvatarEvents.publish( diff --git a/pslogin/src/main/test/scala/AvatarServiceTest.scala b/pslogin/src/main/test/scala/AvatarServiceTest.scala index 6bbdb9bf..d4b01f89 100644 --- a/pslogin/src/main/test/scala/AvatarServiceTest.scala +++ b/pslogin/src/main/test/scala/AvatarServiceTest.scala @@ -15,7 +15,7 @@ class AvatarService0Test extends ActorTest { } } -class AvatarService1ATest extends ActorTest { +class AvatarService1_1Test extends ActorTest { "AvatarService" should { "subscribe" in { val service = system.actorOf(Props[AvatarService], "service") @@ -25,7 +25,7 @@ class AvatarService1ATest extends ActorTest { } } -class AvatarService1BTest extends ActorTest { +class AvatarService1_2Test extends ActorTest { "AvatarService" should { "subscribe" in { val service = system.actorOf(Props[AvatarService], "service") @@ -36,7 +36,7 @@ class AvatarService1BTest extends ActorTest { } } -class AvatarService1CTest extends ActorTest { +class AvatarService1_3Test extends ActorTest { "AvatarService" should { "subscribe" in { val service = system.actorOf(Props[AvatarService], "service") @@ -183,6 +183,67 @@ class AvatarServiceCTest extends ActorTest { } } +class AvatarServiceDTest extends ActorTest { + val ammoDef = GlobalDefinitions.energy_cell + val ammoBox = AmmoBox(ammoDef) + + "AvatarService" should { + "pass ChangeAmmo" in { + val service = system.actorOf(Props[AvatarService], "service") + service ! Service.Join("test") + service ! AvatarServiceMessage("test", AvatarAction.ChangeAmmo(PlanetSideGUID(10), PlanetSideGUID(40), 0, PlanetSideGUID(40), ammoDef.ObjectId, PlanetSideGUID(41), ammoDef.Packet.ConstructorData(ammoBox).get)) + expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ChangeAmmo(PlanetSideGUID(40), 0, PlanetSideGUID(40), ammoDef.ObjectId, PlanetSideGUID(41), ammoDef.Packet.ConstructorData(ammoBox).get))) + } + } +} + +class AvatarServiceETest extends ActorTest { + val ammoDef = GlobalDefinitions.energy_cell + val ammoBox = AmmoBox(ammoDef) + + "AvatarService" should { + "pass ChangeFireMode" in { + val service = system.actorOf(Props[AvatarService], "service") + service ! Service.Join("test") + service ! AvatarServiceMessage("test", AvatarAction.ChangeFireMode(PlanetSideGUID(10), PlanetSideGUID(40), 0)) + expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ChangeFireMode(PlanetSideGUID(40), 0))) + } + } +} + +class AvatarServiceF_1Test extends ActorTest { + "AvatarService" should { + "pass ChangeFireState_Start" in { + val service = system.actorOf(Props[AvatarService], "service") + service ! Service.Join("test") + service ! AvatarServiceMessage("test", AvatarAction.ChangeFireState_Start(PlanetSideGUID(10), PlanetSideGUID(40))) + expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ChangeFireState_Start(PlanetSideGUID(40)))) + } + } +} + +class AvatarServiceF_2Test extends ActorTest { + "AvatarService" should { + "pass ChangeFireState_Stop" in { + val service = system.actorOf(Props[AvatarService], "service") + service ! Service.Join("test") + service ! AvatarServiceMessage("test", AvatarAction.ChangeFireState_Stop(PlanetSideGUID(10), PlanetSideGUID(40))) + expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ChangeFireState_Stop(PlanetSideGUID(40)))) + } + } +} + +class AvatarService01Test extends ActorTest { + "AvatarService" should { + "pass WeaponDryFire" in { + val service = system.actorOf(Props[AvatarService], "service") + service ! Service.Join("test") + service ! AvatarServiceMessage("test", AvatarAction.WeaponDryFire(PlanetSideGUID(10), PlanetSideGUID(40))) + expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.WeaponDryFire(PlanetSideGUID(40)))) + } + } +} + object AvatarServiceTest { //decoy }