diff --git a/src/main/scala/net/psforever/actors/zone/ShootingRangeTargetSpawnerActor.scala b/src/main/scala/net/psforever/actors/zone/ShootingRangeTargetSpawnerActor.scala index 14cc51557..1325caf09 100644 --- a/src/main/scala/net/psforever/actors/zone/ShootingRangeTargetSpawnerActor.scala +++ b/src/main/scala/net/psforever/actors/zone/ShootingRangeTargetSpawnerActor.scala @@ -141,8 +141,8 @@ class ShootingRangeTargetSpawnerActor(zone: Zone) extends Actor { } else { airVehicleSpawns.foreach{case (pos, yaw) => CreateVehicleTarget(pos, yaw, true)} groundVehicleSpawns.foreach{case (pos, yaw) => CreateVehicleTarget(pos, yaw, false)} - infantrySpawns.foreach{case (pos, yaw) => CreateInfantryTarget(pos, yaw, false)} - infantrySpawnsMAX.foreach{case (pos, yaw) => CreateInfantryTarget(pos, yaw, true)} + infantrySpawns.foreach{case (pos, yaw) => CreateInfantryTarget(pos, false)} + infantrySpawnsMAX.foreach{case (pos, yaw) => CreateInfantryTarget(pos, true)} log.info(s"Enabled target spawns for zone ${zone.id}") } @@ -154,7 +154,7 @@ class ShootingRangeTargetSpawnerActor(zone: Zone) extends Actor { * @param facingYaw the direction the target will be facing * @param isMAX if this target is a MAX unit */ - def CreateInfantryTarget(position: Vector3, facingYaw: Float, isMAX: Boolean): Unit = { + def CreateInfantryTarget(position: Vector3, isMAX: Boolean): Unit = { val definition = if (isMAX) GlobalDefinitions.avatar_bot_max_no_weapon else Random.nextInt(3) match { case 0 => GlobalDefinitions.avatar_bot_agile_no_weapon case 1 => GlobalDefinitions.avatar_bot_reinforced_no_weapon @@ -178,6 +178,15 @@ class ShootingRangeTargetSpawnerActor(zone: Zone) extends Actor { case 4 => CharacterVoice.Voice5 } + val facingYaw = if (isMAX) infantrySpawnsMAX.find(_._1 == position) match { + case Some((_, yaw)) => yaw + case _ => 0 + } + else infantrySpawns.find(_._1 == position) match { + case Some((_, yaw)) => yaw + case _ => 0 + } + val bot = AvatarBot(name, faction, gender, head, voice, definition) bot.Position = position bot.Orientation = Vector3(0f, 0f, facingYaw) @@ -288,7 +297,7 @@ class ShootingRangeTargetSpawnerActor(zone: Zone) extends Actor { //spawn a replacement bot context.system.scheduler.scheduleOnce( 5.seconds, - new Runnable() { override def run(): Unit = CreateInfantryTarget(bot.Position, bot.Orientation.z, bot.ExoSuit == ExoSuitType.MAX) } + new Runnable() { override def run(): Unit = CreateInfantryTarget(bot.Position, bot.ExoSuit == ExoSuitType.MAX) } ) //unregister bot (delay is to prevent ValidObjects from complaining if the bot is getting hit too quickly when it is destroyed) context.system.scheduler.scheduleOnce( diff --git a/src/main/scala/net/psforever/objects/avatar/AvatarBotActor.scala b/src/main/scala/net/psforever/objects/avatar/AvatarBotActor.scala index 94bdebfb8..486289d66 100644 --- a/src/main/scala/net/psforever/objects/avatar/AvatarBotActor.scala +++ b/src/main/scala/net/psforever/objects/avatar/AvatarBotActor.scala @@ -59,6 +59,7 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef) /** suffocating, or regaining breath? */ var submergedCondition: Option[OxygenState] = None private var canEmote = false + private var canRotate = false override def postStop(): Unit = { EndAllEffects() @@ -371,6 +372,7 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef) bot.Spawn() bot.Zone.Population ! Zone.Bots.Spawn(bot) canEmote = true + canRotate = true scheduler.scheduleAtFixedRate(new Runnable() { override def run(): Unit = tickLogic() }, 0, 250, TimeUnit.MILLISECONDS) } @@ -408,6 +410,20 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef) val zone = bot.Zone if (!bot.Destroyed && zone.AllPlayers.size > 0) { bot.zoneInteractions() + val rotateRNG = Random.nextDouble() + if (canRotate) { + if (rotateRNG > 0.95) { + val amount = 5f + Random.nextInt(10) + val finalRotation = if (Random.nextBoolean()) -amount else amount + bot.Orientation = Vector3(bot.Orientation.x, bot.Orientation.y, (bot.Orientation.z + finalRotation) % 360) + canRotate = false + //rotation cooldown + context.system.scheduler.scheduleOnce( + 2.seconds, + new Runnable() { override def run(): Unit = if (!bot.Destroyed) canRotate = true } + ) + } + } zone.AvatarEvents ! AvatarServiceMessage( zone.id, AvatarAction.PlayerState(