Beispiel #1
0
        internal void Update()
        {
            // TODO: need a reference to the whole base grid to properly determine ownership
            // TODO: use faction info from faction definition.

            if (!RemoteControl.IsControlledByFaction("GCORP"))
            {
//				return; // Maybe remove from list of bases?
            }


            // TODO: use faction info from faction definition.
            var player = DuckUtils.GetNearestPlayerToPosition(RemoteControl.GetPosition(), 1000);

            if (!DebugStopBackupGroups && player != null)
            {
                if (lastBackupRespondTime + BackupTimeDelay < MyAPIGateway.Session.GameDateTime)
                {
                    // TODO: use faction info from faction definition.
                    SpawnHelperPatrol(player);
                    waitingOnBackup       = true;
                    lastBackupRespondTime = MyAPIGateway.Session.GameDateTime;
                    // TODO: use faction info from faction definition.
                    audioSystem.PlayAudio(CalAudioClip.FacilityDetectedHostile, CalAudioClip.GCorpFacilityThreatened);
                }
            }
        }
Beispiel #2
0
        internal void UnlockTechGroupForAllPlayers(TechGroup techGroup)
        {
            if (UnlockedTechs.Contains(techGroup))
            {
                return; // Already unlocked
            }

            HashSet <MyDefinitionId> technologies;

            if (!techsForGroup.TryGetValue(techGroup, out technologies))
            {
                ModLog.Error("No technologies for group: " + techGroup);
                return;
            }

            var players = new List <IMyPlayer>();

            MyAPIGateway.Players.GetPlayers(players);
            foreach (var player in players)
            {
                foreach (var technology in technologies)
                {
                    MyVisualScriptLogicProvider.PlayerResearchUnlock(player.IdentityId, technology);
                }
            }
            UnlockedTechs.Add(techGroup);
            audioSystem.PlayAudio(GetAudioClipForTechGroup(techGroup));
        }
        private Action PlayAudioClip(IAudioClip clip)
        {
            return(() => {
                audioSystem.PlayAudio(clip);
//                ModLog.Info("PlayAudioClip(" + clip.Filename + ")");
            });
        }
Beispiel #4
0
        internal void Update()
        {
            if (timeSinceSpoken == -2)
            {
                if (DuckUtils.GetNearestPlayerToPosition(speaker.GetPosition(), 3000) != null)
                {
                    audioSystem.PlayAudio(CalAudioClip.GreetingsMartianColonists);
                    timeSinceSpoken = -1;
                }

                return;
            }

            var playerVisiting = DuckUtils.GetNearestPlayerToPosition(speaker.GetPosition(), 50) != null;

            if (timeSinceSpoken == -1 && playerVisiting)
            {
                audioSystem.PlayAudio(CalAudioClip.WelcomeMikiScrap);
                timeSinceSpoken = AudioCommentTime;
            }
            else if (timeSinceSpoken >= 0 && timeSinceSpoken < AudioMaxTime)
            {
                timeSinceSpoken++;
            }
            else if (timeSinceSpoken == AudioMaxTime && playerVisiting)
            {
                audioSystem.PlayAudioRandomChance(1.0, CalAudioClip.TellAllFriends, CalAudioClip.TiredOfGrindingCrap,
                                                  CalAudioClip.NewMikiScrapsOpen);
                timeSinceSpoken = AudioCommentTime;
            }

            var scrap = scrapIn.GetItemAmount(scrapMetal);

            if (scrap > 0)
            {
                ProcessScrap(scrap > 500 ? 500 : scrap);
            }

            if (playerVisiting)
            {
                UpdateFurnaceState();
            }
        }
Beispiel #5
0
        private void IncomingMessage(byte[] bytes)
        {
            try
            {
                var message = MyAPIGateway.Utilities.SerializeFromXML <Message>(Encoding.UTF8.GetString(bytes));
                switch (message.MessageType)
                {
                case MessageType.ClientJoined:                         // Server only
                    HandleClientJoinedMessage(message);
                    break;

                case MessageType.ClearToolbar:
                    StartWipeClientToolbar();
                    break;

                case MessageType.ToolbarClearedSuccessfully:
                    RegisteredPlayers.Add(message.PlayerId);
                    break;

                case MessageType.PlaySound:
                    audio.PlayAudio(AudioClip.GetClipFromId(message.AudioClipId));
                    break;

                case MessageType.HackingProgress:
                    hacking.ShowLocalHackingProgress(message.HackingProgressTicks);
                    break;

                case MessageType.HackingSuccess:
                    hacking.ShowLocalHackingSuccess();
                    break;

                case MessageType.HackingInterrupted:
                    hacking.ShowLocalHackingInterrupted();
                    break;

                case MessageType.HackingInterruptStopped:
                    hacking.ShowLocalHackingInterruptStopped();
                    break;

                default:
                    throw new Exception("Unrecognised message type: " + message.MessageType);
                }
            }
            catch (Exception e)
            {
                ModLog.Error(e);
            }
        }
        internal void UnlockTechGroupForAllPlayers(TechGroup techGroup)
        {
            if (UnlockedTechs.Contains(techGroup))
            {
//                ModLog.Info("UTGFAP():" + UnlockedTechs.Count.ToString() + " unlocked groups. Already contains TechGroup:"+techGroup.ToString());
                return; // Already unlocked
            }

            HashSet <MyDefinitionId> technologies;

            if (!techsForGroup.TryGetValue(techGroup, out technologies))
            {
                ModLog.Error("No technologies for group: " + techGroup);
                return;
            }
            var players = new List <IMyPlayer>();

            MyAPIGateway.Players.GetPlayers(players);
            foreach (var player in players)
            {
                foreach (var technology in technologies)
                {
                    if (bNewResearch)
                    {
                        MyVisualScriptLogicProvider.ResearchListRemoveItem(technology); // SE 1.189
                    }
                    else
                    {
//                        ModLog.Info("Old research Method: Unlock for player:" + player.IdentityId.ToString() + " tech=" + technology.ToString());
                        MyVisualScriptLogicProvider.PlayerResearchUnlock(player.IdentityId, technology);
                    }
                }
            }
            UnlockedTechs.Add(techGroup);
            audioSystem.PlayAudio(GetAudioClipForTechGroup(techGroup));
        }
Beispiel #7
0
        internal override void Update()
        {
            if (!leader.IsControlledByFaction("GCORP"))
            {
                leader     = null;
                GroupState = NpcGroupState.Disbanded;
                return;
            }
//            ModLog.Info("Backup:" + leader.EntityId.ToString() + " " + GroupState.ToString());

            if ((GroupState == NpcGroupState.Travelling || GroupState == NpcGroupState.ReturningForRepairs) &&
                Vector3D.DistanceSquared(Destination, leader.GetPosition()) < 40.0 * 40.0)
            {
                // it arrives at destination.  and nothing... get rid of it.
//                ModLog.Info(" Backup arrived at base/target and nothing found.  Disbanding");
                GroupState = NpcGroupState.Disbanding;
            }


            if (GroupState == NpcGroupState.Disbanding)
            {
                var isArmed = leader.HasUsableGun();
                if (AttemptDespawn(leader, 200))                //V26
                {
                    leader     = null;
                    GroupState = NpcGroupState.Disbanded;
                    if (isArmed)
                    {
                        ArrivalObserver.GroupArrivedIntact();
                    }
                }
                return;
            }

            if (DuckUtils.IsAnyPlayerNearPosition(leader.GetPosition(), 2000) && //V29 1000->2000  Backups were getting disbanded when player between 1000 and max spawn distance.
                (GroupState == NpcGroupState.Travelling || GroupState == NpcGroupState.Disbanding))
            {
                GroupState = NpcGroupState.InCombat;
//                ModLog.Info("Backup:" + leader.EntityId.ToString() + " Found Target:" + GroupState.ToString());
                leader.SetLightingColors(Color.Red);
                leader.RemoveFromFirstBeaconName(ReturningToBase);
                leader.AppendToFirstBeaconName(InterceptingBeaconSuffix);
                audioSystem.PlayAudio(AudioClip.TargetFoundDronesAttack, AudioClip.TargetIdentifiedUnitsConverge);
            }
            // todo: if no player nearby go searching for player vehicles near base/convoy
            // todo: if can't target player after a delay (or player under cover?), search for player vehicles near current location

            if (GroupState == NpcGroupState.InCombat)
            {
                if (!leader.HasUsableGun())
                {
//                    GroupState = NpcGroupState.Disbanding;
                    GroupState = NpcGroupState.ReturningForRepairs; //V29
//                    ModLog.Info("Backup:" + leader.EntityId.ToString() + " No Gun." + GroupState.ToString());
                    leader.SetLightingColors(GcorpBlue);
                    leader.RemoveFromFirstBeaconName(" Investigating Backup Call"); // match text in NpcGroupManager
                    leader.RemoveFromFirstBeaconName(InterceptingBeaconSuffix);
                    leader.AppendToFirstBeaconName(ReturningToBase);
                    leader.SendToPosition(Destination);
                    audioSystem.PlayAudio(AudioClip.DroneDisarmed);
                    // disbanding, but for backups we want to extra penalize for killing unit
                    heat.BackupDisabled();
                }
                else
                {
                    var player = DuckUtils.GetNearestPlayerToPosition(leader.GetPosition(), 2000);                     //V29 1250->2000
                    if (player == null)
                    {
                        GroupState = NpcGroupState.Disbanding;                         // Return to normal, cowardly players have run off or died
//                        ModLog.Info("Backup:" + leader.EntityId.ToString() + " No Players in range after Combat mode." + GroupState.ToString());
                        leader.SetLightingColors(GcorpBlue);
                        leader.RemoveFromFirstBeaconName(InterceptingBeaconSuffix);
                        leader.AppendToFirstBeaconName(ReturningToBase);
                        leader.SendToPosition(Destination);
                        audioSystem.PlayAudio(AudioClip.HostileDisappeared, AudioClip.TargetFleeingPursuit);
                    }
                    else
                    {
                        float heightModifier = 15; // Change from 2 pre V26

                        // Added V26
                        if (DuckUtils.IsPlayerUnderCover(player))
                        {
                            heightModifier = 300;
                        }
                        leader.SendToPosition(player.GetPosition(), heightModifier);
                    }
                }
            }
        }
Beispiel #8
0
        internal override void Update()
        {
            CheckEscortsAlive();

            if (!leader.IsControlledByNpcFaction())
            {
                GroupState = NpcGroupState.Disbanding;
                InitiateDisbandProtocols();
            }
            else if ((GroupState == NpcGroupState.Travelling || GroupState == NpcGroupState.InCombat) &&
                     Vector3D.DistanceSquared(Destination, leader.GetPosition()) < 200.0 * 200)    // increase to 200 to allow for variations in height.
            //                     && Vector3D.Distance(Destination, leader.GetPosition()) < 100.0)
            {
                ArrivalObserver.GroupArrivedIntact();
                audioSystem.PlayAudioRandomChance(0.1, CalAudioClip.ConvoyArrivedSafely);
                GroupState = NpcGroupState.Disbanding;
                InitiateDisbandProtocols();
                ResetBeaconNames();
            }

            if (GroupState == NpcGroupState.Disbanding)
            {
                AttemptDespawning();
                return;
            }

            if (DuckUtils.IsAnyPlayerNearPosition(leader.GetPosition(), 1000) && GroupState == NpcGroupState.Travelling)
            {
                GroupState = NpcGroupState.InCombat;
                InitiateAttackProtocols();
            }

            if (GroupState == NpcGroupState.InCombat)
            {
                var player = DuckUtils.GetNearestPlayerToPosition(leader.GetPosition(), 4000);
                if (player == null)
                {
                    GroupState = NpcGroupState.Travelling;       // Return to normal, cowardly players have run off or died
                    ResetBeaconNames();
                    if (escortDic.Count > 0)                     //todo maybe check if the escorts are actually alive? Dunno if doing this already
                    {
                        audioSystem.PlayAudio(CalAudioClip.DisengagingFromHostile, CalAudioClip.TargetLost);
                    }
                    else
                    {
                        audioSystem.PlayAudio(CalAudioClip.PursuitEvaded, CalAudioClip.SensorsLostTrack);
                    }
                }
                else
                {
                    SendArmedEscortsNearPosition(player.GetPosition());                     // Use same position as when escorting, to avoid collisions
                }
            }

            if (GroupState == NpcGroupState.Travelling)
            {
                foreach (var entry in escortDic)
                {
                    SendEscortToGrid(entry.Key, entry.Value, leader);
                }
            }
        }
Beispiel #9
0
        internal void Update()
        {
            if (!RemoteControl.IsControlledByFaction("GCORP"))
            {
                // V26
                if (!bLostProcessed)
                {
                    // first time processing
                    bLostProcessed = true;

                    // TODO: maybe do something else.
                    // maybe turn OFF all turrets
                    // explode all warheads?

                    // if base is 'lost' increase heat level
                    heatSystem.BaseCaptured();

                    // ?play audio (from mabel?) announcing base captured.
                }

                return; // Maybe remove from list of bases?
            }

            // TODO: get this value from base itself instead of hard-coding?
            var player = DuckUtils.GetNearestPlayerToPosition(RemoteControl.GetPosition(), 1300);

            // turn turrets off on bases if no player is nearby to save simspeed hits
            if (player != null)
            {
                foreach (var turret in turrets)
                {
                    turret.Enabled = true;
                }
            }
            else
            {
                foreach (var turret in turrets)
                {
                    turret.Enabled = false;
                }
            }

            int nPlayers     = 0; // number of players in range
            var playerClose1 = DuckUtils.GetNearestPlayerToPosition(RemoteControl.GetPosition(), 1200, out nPlayers);

            if (!DebugStopBackupGroups && playerClose1 != null)
            {
                if (lastBackupRespondTime + BackupTimeDelay < MyAPIGateway.Session.GameDateTime)
                {
                    //                   ModLog.Info("Heat Difficulty: " + heatSystem.HeatDifficulty);

                    // TODO: if player is INSIDE base, then do something else?
                    // V26: If player is underground, then do something else?
                    var players = new List <IMyPlayer>();
                    MyAPIGateway.Players.GetPlayers(players);
                    foreach (var aplayer in players)
                    {
                        // check each player

                        var controlled = aplayer.Controller.ControlledEntity;
                        if (controlled == null)
                        {
                            continue;
                        }
                        var distSq = Vector3D.DistanceSquared(RemoteControl.GetPosition(), controlled.Entity.GetPosition());
                        if (distSq < 100 * 100) //V29
                        {
                            if (DuckUtils.IsPlayerUnderCover(aplayer))
                            { // player is under cover 'near' the base..
                            }
                        }
                        else if (distSq < 1000 * 1000)
                        { // betwee 100->1000
                            if (DuckUtils.IsPlayerUnderground(aplayer))
                            {
                                // player is underground
                                if (heatSystem.HeatDifficulty > 1)
                                {                                     // only if difficulty is above default
//                                    ModLog.Info("Spawning Bomber");
                                    SpawnUndergroundDefense(aplayer); // on top of player
                                    // if we do this, then ground has lost integrity.. make it into an air base
                                    if (RemoteControl.CustomName.Contains("GROUND"))
                                    {
                                        RemoteControl.CustomName.Replace("GROUND", "AIR");
                                    }
                                }
                            }
                        }
                    }

//                    ModLog.Info("Backup Player Close 1");
                    SpawnHelperPatrol(playerClose1);

                    // if higher difficulty and player(s) get closer, then spawn more backup per backup event
                    if (heatSystem.HeatDifficulty > 1 || (heatSystem.MultiplayerScaling && nPlayers > 1))
                    {
                        var playerClose2 = DuckUtils.GetNearestPlayerToPosition(RemoteControl.GetPosition(), 800);
                        if (playerClose2 != null)
                        {
                            SpawnHelperPatrol(playerClose2);
//                            ModLog.Info("Backup Player Close 2");
                        }
                    }
                    if (heatSystem.HeatDifficulty > 3 || (heatSystem.MultiplayerScaling && nPlayers > 3))
                    {
                        var playerClose3 = DuckUtils.GetNearestPlayerToPosition(RemoteControl.GetPosition(), 300);
                        if (playerClose3 != null)
                        {
                            SpawnHelperPatrol(playerClose3);
//                            ModLog.Info("Backup Player Close 4");
                        }
                    }
                    lastBackupRespondTime = MyAPIGateway.Session.GameDateTime;
                    audioSystem.PlayAudio(AudioClip.FacilityDetectedHostile, AudioClip.GCorpFacilityThreatened);
                    waitingOnBackup = true;
                }
            }
        }
Beispiel #10
0
        internal override void Update()
        {
            if (!leader.IsControlledByNpcFaction())
            {
                leader     = null;
                GroupState = NpcGroupState.Disbanded;
                return;
            }

            if (GroupState == NpcGroupState.Travelling && Vector3D.Distance(Destination, leader.GetPosition()) < 40.0)
            {
                GroupState = NpcGroupState.Disbanding;
            }

            if (GroupState == NpcGroupState.Disbanding)
            {
                var isArmed = leader.HasUsableGun();
                if (AttemptDespawn(leader))
                {
                    leader     = null;
                    GroupState = NpcGroupState.Disbanded;
                    if (isArmed)
                    {
                        ArrivalObserver.GroupArrivedIntact();
                    }
                }
                return;
            }

            if (DuckUtils.IsAnyPlayerNearPosition(leader.GetPosition(), 1000) &&
                (GroupState == NpcGroupState.Travelling || GroupState == NpcGroupState.Disbanding))
            {
                GroupState = NpcGroupState.InCombat;
                leader.SetLightingColors(Color.Red);
                leader.RemoveFromFirstBeaconName(ReturningToBase);
                leader.AppendToFirstBeaconName(InterceptingBeaconSuffix);
                audioSystem.PlayAudio(CalAudioClip.TargetFoundDronesAttack, CalAudioClip.TargetIdentifiedUnitsConverge);
            }

            if (GroupState == NpcGroupState.InCombat)
            {
                if (!leader.HasUsableGun())
                {
                    GroupState = NpcGroupState.Disbanding;
                    leader.SendToPosition(Destination);
                    audioSystem.PlayAudio(CalAudioClip.DroneDisarmed);
                }
                else
                {
                    var player = DuckUtils.GetNearestPlayerToPosition(leader.GetPosition(), 1250);
                    if (player == null)
                    {
                        GroupState = NpcGroupState.Disbanding;                         // Return to normal, cowardly players have run off or died
                        // TODO: get lighting per-faction
                        leader.SetLightingColors(GcorpBlue);
                        leader.RemoveFromFirstBeaconName(InterceptingBeaconSuffix);
                        leader.AppendToFirstBeaconName(ReturningToBase);
                        leader.SendToPosition(Destination);
                        audioSystem.PlayAudio(CalAudioClip.HostileDisappeared, CalAudioClip.TargetFleeingPursuit);
                    }
                    else
                    {
                        leader.SendToPosition(player.GetPosition(), 2);
                    }
                }
            }
        }
Beispiel #11
0
        internal override void Update()
        {
            CheckEscortsAlive();
            if (!leader.IsControlledByFaction("GCORP"))
            {
                GroupState = NpcGroupState.Disbanding;
                InitiateDisbandProtocols();
            }
            else if ((GroupState == NpcGroupState.Travelling || GroupState == NpcGroupState.InCombat) &&
                     Vector3D.DistanceSquared(Destination, leader.GetPosition()) < 300.0 * 300)    // increase to 300 to allow for variations in height. V26
//                     && Vector3D.DistanceSquared(Destination, leader.GetPosition()) < 200.0*200) // increase to 200 to allow for variations in height.
//                     && Vector3D.Distance(Destination, leader.GetPosition()) < 100.0)
            {
                string sBeacons    = "";
                var    slimBlocks2 = new List <IMySlimBlock>();
                leader.GetBlocks(slimBlocks2, b => b.FatBlock is IMyBeacon);
                foreach (var slim2 in slimBlocks2)
                {
                    var beacon = slim2.FatBlock as IMyBeacon;
                    sBeacons += beacon.CustomName;
                }

                ModLog.Info("Group Arrived at destination: " + leader.CustomName + " " + sBeacons);
                ArrivalObserver.GroupArrivedIntact();
                audioSystem.PlayAudioRandomChance(0.1, AudioClip.ConvoyArrivedSafely);
                GroupState = NpcGroupState.Disbanding;
                InitiateDisbandProtocols();
                ResetBeaconNames();
            }

            // ModLogs are for DEBUG nav script
//            ModLog.Info("Convoy update:" + leader.CustomName+" ID:"+leader.EntityId.ToString() + " State:"+GroupState.ToString());
            if ((GroupState == NpcGroupState.Travelling))
            {
                var currentTime = MyAPIGateway.Session.GameDateTime;
                if (GroupSpawnTime + convoyInitiateTime < currentTime)
                {
                    leader.SetAllBeaconNames(null, 20000f);
                }
                bool bKeenAutopilotActive = false;
                var  slimBlocks           = new List <IMySlimBlock>();
                leader.GetBlocks(slimBlocks, b => b.FatBlock is IMyRemoteControl);
                IMyRemoteControl remoteControl = null;
                foreach (var slim in slimBlocks)
                {
                    remoteControl        = slim.FatBlock as IMyRemoteControl;
                    bKeenAutopilotActive = remoteControl.IsAutoPilotEnabled;
//                    ModLog.Info("Keen Autopilot:" + bKeenAutopilotActive.ToString());
                    break;
                }

                slimBlocks.Clear();
                leader.GetBlocks(slimBlocks, b => b.FatBlock is IMyProgrammableBlock);
                foreach (var slim in slimBlocks)
                {
                    var block = slim.FatBlock as IMyProgrammableBlock;
                    if (block == null)
                    {
                        continue;
                    }

                    if (block.CustomName.Contains("NAV"))
                    {
                        if (!bKeenAutopilotActive &&
                            GroupSpawnTime + convoyInitiateTime < currentTime    // delay check for mode change.
                            )
                        {
                            if (//!bKeenAutopilotActive &&
                                block.DetailedInfo.Contains("mode=0") || block.DetailedInfo.Contains("mode=-1"))
                            {
                                if (remoteControl == null)
                                {
                                    // nothing left to do.  Remove it (and try again)
                                    GroupState = NpcGroupState.Inactive; // this will cause NpcGroupManager to spawn a new convoy to replace this one.
                                    return;
                                }
                                // force it to use Keen Autopilot
                                remoteControl.ClearWaypoints();
                                remoteControl.AddWaypoint(Destination, "Target");
                                remoteControl.SpeedLimit = 10;
                                remoteControl.SetAutoPilotEnabled(true);

                                /*
                                 * // debug output
                                 * var slimBlocks2 = new List<IMySlimBlock>();
                                 * leader.GetBlocks(slimBlocks2, b => b.FatBlock is IMyBeacon);
                                 * string sBeacons = "";
                                 * foreach(var slim2 in slimBlocks2)
                                 * {
                                 *  var beacon = slim2.FatBlock as IMyBeacon;
                                 *  sBeacons += beacon.CustomName;
                                 * }
                                 *
                                 * // it didn't get the command!
                                 * //                                GroupState = NpcGroupState.Inactive; // this will cause NpcGroupManager to spawn a new convoy to replace this one.
                                 * ModLog.Info("Autopilot recovery because leader NAV not in correct mode: "+ sBeacons);
                                 */
                            }
                            break;
                        }
//                        ModLog.Info("PB:"+block.CustomName+"\n"+"DetailedInfo=:\n" + block.DetailedInfo);
                    }
                }

                // Following is just debug info

                /*
                 * leader.GetBlocks(slimBlocks, b => b.FatBlock is IMyGyro);
                 * foreach (var slim in slimBlocks)
                 * {
                 *  var block = slim.FatBlock as IMyGyro;
                 *  if (block!=null && block.CustomName.Contains("NAV"))
                 *  {
                 *      ModLog.Info("G:"+block.CustomName + "\n");
                 *  }
                 * }
                 */
            }

            if (GroupState == NpcGroupState.Disbanding)
            {
                AttemptDespawning();
                return;
            }

            if (DuckUtils.IsAnyPlayerNearPosition(leader.GetPosition(), 1000) && GroupState == NpcGroupState.Travelling)
            {
                GroupState = NpcGroupState.InCombat;
                InitiateAttackProtocols();
            }

            if (GroupState == NpcGroupState.InCombat)
            {
                var player = DuckUtils.GetNearestPlayerToPosition(leader.GetPosition(), 4000);
                if (player == null)
                {
                    GroupState = NpcGroupState.Travelling;       // Return to normal, cowardly players have run off or died
                    ResetBeaconNames();
                    if (escortDic.Count > 0)                     //todo maybe check if the escorts are actually alive? Dunno if doing this already
                    {
                        audioSystem.PlayAudio(AudioClip.DisengagingFromHostile, AudioClip.TargetLost);
                    }
                    else
                    {
                        audioSystem.PlayAudio(AudioClip.PursuitEvaded, AudioClip.SensorsLostTrack);
                    }
                }
                else
                {
                    SendArmedEscortsNearPosition(player.GetPosition());                     // Use same position as when escorting, to avoid collisions
                }
            }

            if (GroupState == NpcGroupState.Travelling)
            {
                foreach (var entry in escortDic)
                {
                    SendEscortToGrid(entry.Key, entry.Value, leader);
                }
            }
        }