public static bool Prefix(SAMLauncher __instance)
    {
        if (!Networker.isHost)
        {
            return(true);
        }
        Debug.Log("Beginning sam launch prefix.");
        int j = 0;

        Missile[] missiles = (Missile[])Traverse.Create(__instance).Field("missiles").GetValue();
        for (int i = 0; i < missiles.Length; i++)
        {
            if (missiles[i] != null)
            {
                Debug.Log("Found a suitable missile to attach a sender to.");
                MissileNetworker_Sender missileSender = missiles[i].gameObject.AddComponent <MissileNetworker_Sender>();
                missileSender.networkUID = Networker.GenerateNetworkUID();
                SAMHelper.SAMmissile     = missileSender.networkUID;
                return(true);
            }
        }
        Debug.Log("Could not find a suitable missile to attach a sender to.");
        SAMHelper.SAMmissile = 0;
        return(true);
        // __state = 0;
    }
    public void WeaponSet_Result(Packet packet)
    {
        Message_WeaponSet_Result message = (Message_WeaponSet_Result)((PacketSingle)packet).message;

        if (message.UID != networkUID)
        {
            return;
        }

        if (Networker.isHost && packet.networkUID != networkUID)
        {
            //Debug.Log("Generating UIDS for any missiles the new vehicle has");
            for (int i = 0; i < message.hpLoadout.Length; i++)
            {
                for (int j = 0; j < message.hpLoadout[i].missileUIDS.Length; j++)
                {
                    if (message.hpLoadout[i].missileUIDS[j] != 0)
                    {
                        //Storing the old one
                        ulong clientsUID = message.hpLoadout[i].missileUIDS[j];
                        //Generating a new global UID for that missile
                        message.hpLoadout[i].missileUIDS[j] = Networker.GenerateNetworkUID();
                        //Sending it back to that client
                        NetworkSenderThread.Instance.SendPacketToSpecificPlayer(PlayerManager.GetPlayerCSteamID(message.UID),
                                                                                new Message_RequestNetworkUID(clientsUID, message.hpLoadout[i].missileUIDS[j]),
                                                                                EP2PSend.k_EP2PSendReliable);
                    }
                }
            }
        }

        PlaneEquippableManager.SetLoadout(gameObject, networkUID, message.normalizedFuel, message.hpLoadout, message.cmLoadout);
        noAmmo = false;
        if (Networker.isHost)
        {
            NetworkSenderThread.Instance.SendPacketAsHostToAllButOneSpecificClient(PlayerManager.GetPlayerCSteamID(message.UID),
                                                                                   message,
                                                                                   Steamworks.EP2PSend.k_EP2PSendReliable);
        }
    }
    public static List <Player> players = new List <Player>(); //This is the list of players
    /// <summary>
    /// This runs when the map has finished loading and hopefully
    /// when the player first can interact with the vehicle.
    /// </summary>
    /// <param name="customMap"></param>
    public static void MapLoaded(VTMapCustom customMap = null) //Clients and Hosts
    {
        Debug.Log("The map has loaded");
        gameLoaded = true;
        //As a client, when the map has loaded we are going to request a spawn point from the host
        SetPrefabs();
        if (!Networker.isHost)
        {
            Networker.SendP2P(Networker.hostID, new Message(MessageType.RequestSpawn), EP2PSend.k_EP2PSendReliable);
        }
        else
        {
            hostLoaded = true;
            GameObject localVehicle = VTOLAPI.instance.GetPlayersVehicleGameObject();
            if (localVehicle != null)
            {
                GenerateSpawns(localVehicle.transform);
                localUID = Networker.GenerateNetworkUID();
                SendSpawnVehicle(localVehicle, localVehicle.transform.position, localVehicle.transform.rotation.eulerAngles, localUID);
            }
            else
            {
                Debug.Log("Local vehicle for host was null");
            }
            if (spawnRequestQueue.Count != 0)
            {
                SpawnRequestQueue();
            }
            Networker.alreadyInGame = true;
        }

        if (playersToSpawnQueue.Count != 0)
        {
            for (int i = 0; i < playersToSpawnQueue.Count; i++)
            {
                SpawnVehicle(playersToSpawnQueue.Dequeue());
            }
        }
    }
Beispiel #4
0
    public static List <HPInfo> generateHpInfoListFromWeaponManager(WeaponManager weaponManager, HPInfoListGenerateNetworkType networkType, ulong networkID = 0)
    {
        List <HPInfo> hpInfos = new List <HPInfo>();
        HPEquippable  lastEquippable;

        bool playerFlag = weaponManager.actor.isPlayer;

        for (int i = 0; i < weaponManager.equipCount; i++)
        {
            //Debug.Log("Weapon Manager, Equip " + i);
            lastEquippable = weaponManager.GetEquip(i);
            if (lastEquippable == null) //If this is null, it means there isn't any weapon in that slot.
            {
                continue;
            }
            //Debug.Log("Last Equippable = " + lastEquippable.fullName);
            List <ulong> missileUIDS = new List <ulong>();
            if (lastEquippable is HPEquipMissileLauncher HPml)
            {
                //Debug.Log("This last equip is a missile launcher");
                if (HPml.ml == null)
                {
                    Debug.LogError("The Missile Launcher was null on this Missile Launcher");
                    Debug.LogError("Type was = " + lastEquippable.weaponType);
                    continue;
                }
                if (HPml.ml.missiles == null)
                {
                    Debug.LogError("The missile list is null");
                    continue;
                }
                //Debug.Log($"This has {HPml.ml.missiles.Length} missiles");
                for (int j = 0; j < HPml.ml.missiles.Length; j++)
                {
                    //There shouldn't be any shot missiles, but if so this skips them as they are null.
                    if (HPml.ml.missiles[j] == null)
                    {
                        missileUIDS.Add(0);
                        //Debug.LogError("It seems there was a missile shot as it was null");
                        continue;
                    }
                    //Debug.Log("Adding Missle Networker to missile");
                    switch (networkType)
                    {
                    case HPInfoListGenerateNetworkType.generate:
                        MissileNetworker_Sender mnSender = HPml.ml.missiles[j].gameObject.AddComponent <MissileNetworker_Sender>();
                        mnSender.networkUID = Networker.GenerateNetworkUID();
                        missileUIDS.Add(mnSender.networkUID);
                        if (playerFlag)
                        {
                            HPml.ml.missiles[j].gameObject.name = Steamworks.SteamFriends.GetPersonaName() + "'s " + HPml.ml.missiles[j].gameObject.name;
                        }
                        break;

                    case HPInfoListGenerateNetworkType.sender:
                        MissileNetworker_Sender sender = HPml.ml.missiles[j].gameObject.GetComponent <MissileNetworker_Sender>();
                        if (playerFlag)
                        {
                            HPml.ml.missiles[j].gameObject.name = Steamworks.SteamFriends.GetPersonaName() + "'s " + HPml.ml.missiles[j].gameObject.name;
                        }
                        if (sender != null)
                        {
                            missileUIDS.Add(sender.networkUID);
                        }
                        else
                        {
                            Debug.LogError($"Failed to get NetworkUID for missile ({HPml.ml.missiles[j].gameObject.name})");
                        }
                        break;

                    case HPInfoListGenerateNetworkType.receiver:
                        MissileNetworker_Receiver reciever = HPml.ml.missiles[j].gameObject.GetComponent <MissileNetworker_Receiver>();
                        if (reciever != null)
                        {
                            missileUIDS.Add(reciever.networkUID);
                        }
                        else
                        {
                            Debug.LogError($"Receiver null, Failed to get NetworkUID for missile ({HPml.ml.missiles[j].gameObject.name})");
                        }
                        break;
                    }
                }
            }
            else if (lastEquippable is HPEquipGunTurret HPm230 && networkID != 0)
            {
                switch (networkType)
                {
                case HPInfoListGenerateNetworkType.generate:
                    Debug.Log("Added m230 turret sender");
                    TurretNetworker_Sender sender = HPm230.gameObject.AddComponent <TurretNetworker_Sender>();
                    sender.networkUID = networkID;
                    sender.turret     = HPm230.GetComponent <ModuleTurret>();
                    break;

                default:
                    break;
                }
            }

            hpInfos.Add(new HPInfo(
                            lastEquippable.gameObject.name.Replace("(Clone)", ""),
                            lastEquippable.hardpointIdx,
                            lastEquippable.weaponType,
                            missileUIDS.ToArray()));
        }

        return(hpInfos);
    }
Beispiel #5
0
    public static List <Player> players = new List <Player>(); //This is the list of players
    /// <summary>
    /// This runs when the map has finished loading and hopefully
    /// when the player first can interact with the vehicle.
    /// </summary>
    public static IEnumerator MapLoaded()
    {
        Debug.Log("map loading started");
        while (VTMapManager.fetch == null || !VTMapManager.fetch.scenarioReady || FlightSceneManager.instance.switchingScene)
        {
            yield return(null);
        }
        Debug.Log("The map has loaded");
        gameLoaded = true;
        // As a client, when the map has loaded we are going to request a spawn point from the host
        SetPrefabs();

        carrierStart = FlightSceneManager.instance.playerActor.unitSpawn.unitSpawner.linkedToCarrier;

        if (!Networker.isHost)
        {
            FlightSceneManager.instance.playerActor.gameObject.transform.parent = null;
            Debug.Log($"Sending spawn request to host, host id: {Networker.hostID}, client id: {SteamUser.GetSteamID().m_SteamID}");
            Debug.Log("Killing all units currently on the map.");
            List <Actor> allActors = new List <Actor>();
            foreach (var actor in TargetManager.instance.allActors)
            {
                if (!actor.isPlayer)
                {
                    allActors.Add(actor);
                }
            }
            foreach (var actor in allActors)
            {
                TargetManager.instance.UnregisterActor(actor);
                GameObject.Destroy(actor.gameObject);
            }
            VTScenario.current.units.units.Clear();
            VTScenario.current.units.alliedUnits.Clear();
            VTScenario.current.units.enemyUnits.Clear();
            VTScenario.current.groups.DestroyAll();


            if (teamLeftie)
            {
                foreach (AirportManager airportManager in VTMapManager.fetch.airports)
                {
                    if (airportManager.team == Teams.Allied)
                    {
                        airportManager.team = Teams.Enemy;
                    }
                    else
                    if (airportManager.team == Teams.Enemy)
                    {
                        airportManager.team = Teams.Allied;
                    }
                }
            }


            var rearmPoints = GameObject.FindObjectsOfType <ReArmingPoint>();
            //back up option below

            if (teamLeftie)
            {
                foreach (ReArmingPoint rep in rearmPoints)
                {
                    if (rep.team == Teams.Allied)
                    {
                        rep.team      = Teams.Enemy;
                        rep.canArm    = true;
                        rep.canRefuel = true;
                    }
                    else
                    if (rep.team == Teams.Enemy)
                    {
                        rep.team = Teams.Allied;

                        rep.canArm    = true;
                        rep.canRefuel = true;
                    }
                }
            }


            Message_RequestSpawn msg = new Message_RequestSpawn(teamLeftie, SteamUser.GetSteamID().m_SteamID);
            NetworkSenderThread.Instance.SendPacketToSpecificPlayer(Networker.hostID, msg, EP2PSend.k_EP2PSendReliable);

            /*foreach (var actor in TargetManager.instance.allActors)
             * {
             *  VTScenario.current.units.AddSpawner(actor.unitSpawn.unitSpawner);
             * }*/
        }
        else
        {
            Debug.Log("Starting map loaded host routines");
            Networker.hostLoaded = true;
            Networker.hostReady  = true;
            foreach (var actor in TargetManager.instance.allActors)
            {
                AIManager.setupAIAircraft(actor);
            }
            NetworkSenderThread.Instance.SendPacketAsHostToAllClients(new Message_HostLoaded(true), EP2PSend.k_EP2PSendReliable);
            GameObject localVehicle = VTOLAPI.GetPlayersVehicleGameObject();
            if (localVehicle != null)
            {
                GenerateSpawns(localVehicle.transform);
                localUID = Networker.GenerateNetworkUID();
                UIDNetworker_Sender hostSender = localVehicle.AddComponent <UIDNetworker_Sender>();
                hostSender.networkUID = localUID;
                Debug.Log($"The host's uID is {localUID}");


                Transform hostTrans = localVehicle.transform;
                ///uncomment to randomise host spawn//
                ///

                localVehicle.transform.position = hostTrans.position;

                SpawnLocalVehicleAndInformOtherClients(localVehicle, hostTrans.transform.position, hostTrans.transform.rotation, localUID, 0);
            }
            else
            {
                Debug.Log("Local vehicle for host was null");
            }
            if (spawnRequestQueue.Count != 0)
            {
                SpawnRequestQueue();
            }
            Networker.alreadyInGame = true;
        }

        while (AIManager.AIsToSpawnQueue.Count > 0)
        {
            AIManager.SpawnAIVehicle(AIManager.AIsToSpawnQueue.Dequeue());
        }
        SpawnPlayersInPlayerSpawnQueue();


        if (!Networker.isHost)
        {
            // If the player is not the host, they only need a receiver?
            Debug.Log($"Player not the host, adding world data receiver");
            worldData = new GameObject();
            worldData.AddComponent <WorldDataNetworker_Receiver>();
        }
        else
        {
            // If the player is the host, setup the sender so they can send world data
            Debug.Log($"Player is the host, setting up the world data sender");
            worldData = new GameObject();
            worldData.AddComponent <WorldDataNetworker_Sender>();
        }
    }
Beispiel #6
0
    /// <summary>
    /// When the user has received a message of spawn player vehicle,
    /// this creates the player vehicle and removes any thing which shouldn't
    /// be on it.
    /// </summary>
    /// <param name="packet">The message</param>
    public static void SpawnPlayerVehicle(Packet packet, CSteamID sender) //Both, but never spawns the local vehicle, only executes spawn vehicle messages from other clients
    {
        // We don't actually need the "sender" id, unless we're a client and want to check that the packet came from the host
        // which we're not doing right now.
        Message_SpawnPlayerVehicle message = (Message_SpawnPlayerVehicle)((PacketSingle)packet).message;

        if (message.networkID == PlayerManager.localUID)
        {
            return;
        }

        Debug.Log($"Recived a Spawn Vehicle Message from: {message.csteamID}");
        CSteamID spawnerSteamId = new CSteamID(message.csteamID);

        if (!gameLoaded)
        {
            Debug.LogWarning("Our game isn't loaded, adding spawn vehicle to queue");
            playersToSpawnQueue.Enqueue(packet);
            playersToSpawnIdQueue.Enqueue(sender);
            return;
        }
        //foreach (ulong id in spawnedVehicles)
        //{
        //    if (id == message.csteamID)
        //    {
        //        Debug.Log("Got a spawnedVehicle message for a vehicle we have already added! Returning....");
        //        return;
        //    }
        //}
        //spawnedVehicles.Add(message.csteamID);
        Debug.Log("Got a new spawnVehicle uID.");
        if (Networker.isHost)
        {
            //Debug.Log("Generating UIDS for any missiles the new vehicle has");
            for (int i = 0; i < message.hpLoadout.Length; i++)
            {
                for (int j = 0; j < message.hpLoadout[i].missileUIDS.Length; j++)
                {
                    if (message.hpLoadout[i].missileUIDS[j] != 0)
                    {
                        //Storing the old one
                        ulong clientsUID = message.hpLoadout[i].missileUIDS[j];
                        //Generating a new global UID for that missile
                        message.hpLoadout[i].missileUIDS[j] = Networker.GenerateNetworkUID();
                        //Sending it back to that client
                        NetworkSenderThread.Instance.SendPacketToSpecificPlayer(spawnerSteamId,
                                                                                new Message_RequestNetworkUID(clientsUID, message.hpLoadout[i].missileUIDS[j]),
                                                                                EP2PSend.k_EP2PSendReliable);
                    }
                }
            }

            Debug.Log("Telling other clients about new player and new player about other clients. Player count = " + players.Count);
            for (int i = 0; i < players.Count; i++)
            {
                if (players[i].cSteamID == SteamUser.GetSteamID())
                {
                    //Debug.LogWarning("Skiping this one as it's the host");
                    //Send the host player to the new player.
                    //Debug.Log($"Running host code to tell new player about host vehicle.");

                    GameObject    localVehicle       = VTOLAPI.GetPlayersVehicleGameObject();
                    WeaponManager localWeaponManager = localVehicle.GetComponent <WeaponManager>();

                    List <HPInfo> hpInfos = PlaneEquippableManager.generateHpInfoListFromWeaponManager(localWeaponManager,
                                                                                                       PlaneEquippableManager.HPInfoListGenerateNetworkType.sender);
                    CountermeasureManager cmManager = localVehicle.GetComponentInChildren <CountermeasureManager>();
                    List <int>            cm        = PlaneEquippableManager.generateCounterMeasuresFromCmManager(cmManager);
                    float fuel = PlaneEquippableManager.generateLocalFuelValue();

                    NetworkSenderThread.Instance.SendPacketToSpecificPlayer(spawnerSteamId,
                                                                            new Message_SpawnPlayerVehicle(
                                                                                players[i].vehicleType,
                                                                                VTMapManager.WorldToGlobalPoint(players[i].vehicle.transform.position),
                                                                                players[i].vehicle.transform.rotation,
                                                                                players[i].cSteamID.m_SteamID,
                                                                                players[i].vehicleUID,
                                                                                hpInfos.ToArray(),
                                                                                cm.ToArray(),
                                                                                fuel, players[i].leftie),
                                                                            EP2PSend.k_EP2PSendReliable);

                    //Debug.Log($"We have told the new player about the host and NOT the other way around.");
                    //Debug.Log($"We don't need to resync the host weapons, that's guaranteed to already be up to date.");
                    continue;
                }

                if (players[i].vehicle != null)
                {
                    PlaneNetworker_Receiver existingPlayersPR = players[i].vehicle.GetComponent <PlaneNetworker_Receiver>();
                    //We first send the new player to an existing spawned in player
                    NetworkSenderThread.Instance.SendPacketToSpecificPlayer(players[i].cSteamID, message, EP2PSend.k_EP2PSendReliable);
                    //Then we send this current player to the new player.
                    NetworkSenderThread.Instance.SendPacketToSpecificPlayer(spawnerSteamId,
                                                                            new Message_SpawnPlayerVehicle(
                                                                                players[i].vehicleType,
                                                                                VTMapManager.WorldToGlobalPoint(players[i].vehicle.transform.position),
                                                                                players[i].vehicle.transform.rotation,
                                                                                players[i].cSteamID.m_SteamID,
                                                                                players[i].vehicleUID,
                                                                                existingPlayersPR.GenerateHPInfo(),
                                                                                existingPlayersPR.GetCMS(),
                                                                                existingPlayersPR.GetFuel(), players[i].leftie),
                                                                            EP2PSend.k_EP2PSendReliable);
                    //Debug.Log($"We have told {players[i].cSteamID.m_SteamID} about the new player ({message.csteamID}) and the other way round.");

                    //We ask the existing player what their load out just incase the host's player receiver was out of sync.
                    NetworkSenderThread.Instance.SendPacketToSpecificPlayer(players[i].cSteamID,
                                                                            new Message(MessageType.WeaponsSet),
                                                                            EP2PSend.k_EP2PSendReliable);
                    //Debug.Log($"We have asked {players[i].cSteamID.m_SteamID} what their current weapons are, and now waiting for a responce."); // marsh typo response lmao
                }
                else
                {
                    Debug.Log("players[" + i + "].vehicle is null");
                }
            }
        }

        if (Networker.isHost)
        {
            Debug.Log("Telling connected client about AI units");
            AIManager.TellClientAboutAI(spawnerSteamId);
        }
        AddToPlayerList(new Player(spawnerSteamId, null, message.vehicle, message.networkID, message.leftie));

        GameObject puppet = SpawnRepresentation(message.networkID, message.position, message.rotation, message.leftie);

        if (puppet != null)
        {
            PlaneEquippableManager.SetLoadout(puppet, message.networkID, message.normalizedFuel, message.hpLoadout, message.cmLoadout);
        }
    }
Beispiel #7
0
    public static void RequestSpawn(Packet packet, CSteamID sender) //Run by Host Only
    {
        Message_RequestSpawn lastMessage = (Message_RequestSpawn)((PacketSingle)packet).message;

        Debug.Log("A player has requested for a spawn point");
        if (!Networker.hostLoaded)
        {
            Debug.Log("The host isn't ready yet, adding to queue");
            spawnRequestQueue.Enqueue(lastMessage);
            return;
        }
        if (spawnPoints == null || spawnPoints.Count == 0)
        {
            Debug.LogError("Spawn points was null, we won't be able to find any spawn point then");
            return;
        }
        Transform spawn = FindFreeSpawn(lastMessage.teaml);



        if (Networker.isHost)
        {
            Debug.Log("Telling connected client about AI units");
            AIManager.TellClientAboutAI(new CSteamID(lastMessage.senderSteamID));
        }
        GameObject localVehicle = VTOLAPI.GetPlayersVehicleGameObject();

        Debug.Log("The players spawn will be " + spawn);
        NetworkSenderThread.Instance.SendPacketToSpecificPlayer(sender, new Message_RequestSpawn_Result(new Vector3D(localVehicle.transform.position), localVehicle.transform.rotation, Networker.GenerateNetworkUID(), players.Count), EP2PSend.k_EP2PSendReliable);
    }
Beispiel #8
0
    /// <summary>
    /// This gives all the people waiting their spawn points
    /// </summary>
    private static void SpawnRequestQueue() //Run by Host Only
    {
        Debug.Log($"Giving {spawnRequestQueue.Count} people their spawns");
        Transform lastSpawn;

        while (spawnRequestQueue.Count > 0)
        {
            Message_RequestSpawn lastMessage = spawnRequestQueue.Dequeue();
            lastSpawn = FindFreeSpawn(lastMessage.teaml);
            Debug.Log("The players spawn will be " + lastSpawn);


            if (Networker.isHost)
            {
                Debug.Log("Telling connected client about AI units");
                AIManager.TellClientAboutAI(new CSteamID(lastMessage.senderSteamID));
            }
            GameObject localVehicle = VTOLAPI.GetPlayersVehicleGameObject();
            NetworkSenderThread.Instance.SendPacketToSpecificPlayer(
                new CSteamID(lastMessage.senderSteamID),
                new Message_RequestSpawn_Result(new Vector3D(localVehicle.transform.position), localVehicle.transform.rotation, Networker.GenerateNetworkUID(), players.Count),
                EP2PSend.k_EP2PSendReliable);
        }
    }
Beispiel #9
0
    public static void setupAIAircraft(Actor actor)
    {
        if (actor.role == Actor.Roles.Missile || actor.isPlayer)
        {
            return;
        }
        if (actor.name.Contains("Rearm/Refuel"))
        {
            return;
        }
        foreach (AI ai in AIManager.AIVehicles)
        {
            if (ai.actor == actor)
            {
                return;
            }
        }
        if (actor.parentActor == null)
        {
            AIManager.AIVehicles.Add(new AIManager.AI(actor.gameObject, actor.unitSpawn.unitName, actor, Networker.networkUID + 1));
            foreach (Actor child in actor.gameObject.GetComponentsInChildren <Actor>())
            {
                ulong networkUID = Networker.GenerateNetworkUID();
                Debug.Log("Adding UID senders to " + child.name + $", their uID will be {networkUID}.");
                if (!VTOLVR_Multiplayer.AIDictionaries.allActors.ContainsKey(networkUID))
                {
                    VTOLVR_Multiplayer.AIDictionaries.allActors.Add(networkUID, child);
                }
                if (!VTOLVR_Multiplayer.AIDictionaries.reverseAllActors.ContainsKey(child))
                {
                    VTOLVR_Multiplayer.AIDictionaries.reverseAllActors.Add(child, networkUID);
                }
                UIDNetworker_Sender uidSender = child.gameObject.AddComponent <UIDNetworker_Sender>();
                uidSender.networkUID = networkUID;
                Debug.Log("Added UID sender!");

                Debug.Log("Checking for locking radars");
                foreach (LockingRadar radar in child.GetComponentsInChildren <LockingRadar>())
                {
                    if (radar.GetComponent <Actor>() == child)
                    {
                        Debug.Log($"Adding radar sender to object {child.name} as it is the same game object as this actor.");
                        LockingRadarNetworker_Sender lastLockingSender = child.gameObject.AddComponent <LockingRadarNetworker_Sender>();
                        lastLockingSender.networkUID = networkUID;
                        Debug.Log("Added locking radar!");
                    }
                    else if (radar.GetComponentInParent <Actor>() == child)
                    {
                        Debug.Log($"Adding radar sender to object {child.name} as it is a child of this actor.");
                        LockingRadarNetworker_Sender lastLockingSender = child.gameObject.AddComponent <LockingRadarNetworker_Sender>();
                        lastLockingSender.networkUID = networkUID;
                        Debug.Log("Added locking radar!");
                    }
                    else
                    {
                        Debug.Log("This radar is not direct child of this actor, ignoring");
                    }
                }

                Debug.Log("Checking for health");
                if (child.gameObject.GetComponent <Health>() != null)
                {
                    Debug.Log("adding health sender to ai");
                    HealthNetworker_Sender healthNetworker = child.gameObject.AddComponent <HealthNetworker_Sender>();
                    healthNetworker.networkUID = networkUID;
                    Debug.Log("added health sender to ai!");
                }
                else
                {
                    Debug.Log(child.name + " has no health?");
                }

                Debug.Log("checking for movement type");
                if (child.gameObject.GetComponent <ShipMover>() != null)
                {
                    Debug.Log("I am a ship!");
                    ShipNetworker_Sender shipNetworker = child.gameObject.AddComponent <ShipNetworker_Sender>();
                    shipNetworker.networkUID = networkUID;
                }
                else if (child.gameObject.GetComponent <GroundUnitMover>() != null)
                {
                    Debug.Log("I am a ground mover!");
                    if (child.gameObject.GetComponent <Rigidbody>() != null)
                    {
                        GroundNetworker_Sender lastGroundSender = child.gameObject.AddComponent <GroundNetworker_Sender>();
                        lastGroundSender.networkUID = networkUID;
                    }
                }
                else if (child.gameObject.GetComponent <Rigidbody>() != null)
                {
                    Debug.Log("I am physicsy!");
                    RigidbodyNetworker_Sender lastRigidSender = child.gameObject.AddComponent <RigidbodyNetworker_Sender>();
                    lastRigidSender.networkUID = networkUID;
                    //reduced tick rate for ground Units
                    if (child.role == Actor.Roles.Ground)
                    {
                        lastRigidSender.tickRate = 0.01f;
                    }
                    if (child.role == Actor.Roles.GroundArmor)
                    {
                        lastRigidSender.tickRate = 1.0f;
                    }
                }

                Debug.Log("checking if aircraft");
                if (!child.isPlayer && child.role == Actor.Roles.Air)
                {
                    if (child.weaponManager != null)
                    {
                        PlaneEquippableManager.generateHpInfoListFromWeaponManager(child.weaponManager, PlaneEquippableManager.HPInfoListGenerateNetworkType.generate, uidSender.networkUID);
                    }
                    PlaneNetworker_Sender lastPlaneSender = child.gameObject.AddComponent <PlaneNetworker_Sender>();
                    lastPlaneSender.networkUID = networkUID;
                }

                Debug.Log("checking ext lights");
                if (child.gameObject.GetComponentInChildren <ExteriorLightsController>() != null)
                {
                    //ExtNPCLight_Sender extLight = actor.gameObject.AddComponent<ExtNPCLight_Sender>();
                    //extLight.networkUID = networkUID;
                }

                Debug.Log("checking for guns");
                if (child.gameObject.GetComponentsInChildren <Actor>().Count() <= 1)
                {//only run this code on units without subunits
                    ulong turretCount = 0;
                    foreach (ModuleTurret moduleTurret in child.gameObject.GetComponentsInChildren <ModuleTurret>())
                    {
                        TurretNetworker_Sender tSender = moduleTurret.gameObject.AddComponent <TurretNetworker_Sender>();
                        tSender.networkUID = networkUID;
                        tSender.turretID   = turretCount;
                        Debug.Log("Added turret " + turretCount + " to actor " + networkUID + " uid");
                        turretCount++;
                    }
                    ulong gunCount = 0;
                    foreach (GunTurretAI moduleTurret in child.gameObject.GetComponentsInChildren <GunTurretAI>())
                    {
                        AAANetworker_Sender gSender = moduleTurret.gameObject.AddComponent <AAANetworker_Sender>();
                        gSender.networkUID = networkUID;
                        gSender.gunID      = gunCount;
                        Debug.Log("Added gun " + gunCount + " to actor " + networkUID + " uid");
                        gunCount++;
                    }
                }

                Debug.Log("checking for IRSams");
                IRSamLauncher ml = child.gameObject.GetComponentInChildren <IRSamLauncher>();
                if (ml != null)
                {
                    List <ulong>            samIDS = new List <ulong>();
                    MissileNetworker_Sender lastSender;
                    for (int i = 0; i < ml.ml.missiles.Length; i++)
                    {
                        lastSender            = ml.ml.missiles[i].gameObject.AddComponent <MissileNetworker_Sender>();
                        lastSender.networkUID = Networker.GenerateNetworkUID();
                        samIDS.Add(lastSender.networkUID);
                    }
                    child.gameObject.AddComponent <IRSAMNetworker_Sender>().irIDs = samIDS.ToArray();
                }

                Debug.Log("checking for soldier");
                Soldier soldier = child.gameObject.GetComponentInChildren <Soldier>();
                if (soldier != null)
                {
                    if (soldier.soldierType == Soldier.SoldierTypes.IRMANPAD)
                    {
                        List <ulong>            samIDS = new List <ulong>();
                        MissileNetworker_Sender lastSender;
                        for (int i = 0; i < soldier.irMissileLauncher.missiles.Length; i++)
                        {
                            lastSender            = soldier.irMissileLauncher.missiles[i].gameObject.AddComponent <MissileNetworker_Sender>();
                            lastSender.networkUID = Networker.GenerateNetworkUID();
                            samIDS.Add(lastSender.networkUID);
                        }
                        child.gameObject.AddComponent <IRSAMNetworker_Sender>().irIDs = samIDS.ToArray();
                    }
                }

                Debug.Log("checking for airport");
                AirportManager airport = child.gameObject.GetComponent <AirportManager>();
                if (airport != null)
                {
                    AIManager.SetUpCarrier(child.gameObject, networkUID, child.team);
                }
                //if (!child.unitSpawn.unitSpawner.spawned)
                //{
                //    Debug.Log("Actor " + child.name + " isn't spawned yet, still sending.");
                //}
            }
        }
        else
        {
            Debug.Log(actor.name + " has a parent, not giving an uID sender.");
        }
    }
    /// <summary>
    /// This gives all the people waiting their spawn points
    /// </summary>
    private static void SpawnRequestQueue() //Host Only
    {
        Debug.Log($"Giving {spawnRequestQueue.Count} people their spawns");
        Transform lastSpawn;

        for (int i = 0; i < spawnRequestQueue.Count; i++)
        {
            lastSpawn = FindFreeSpawn();
            Networker.SendP2P(
                spawnRequestQueue.Dequeue(),
                new Message_RequestSpawn_Result(new Vector3D(lastSpawn.position), new Vector3D(lastSpawn.rotation.eulerAngles), Networker.GenerateNetworkUID()),
                EP2PSend.k_EP2PSendReliable);
        }
    }
    /// <summary>
    /// When the user has received a message of spawn vehicle,
    /// this creates the vehilc and removes any thing which shouldn't
    /// be on it.
    /// </summary>
    /// <param name="packet">The message</param>
    public static void SpawnVehicle(Packet packet)
    {
        Debug.Log("Recived a Spawn Vehicle Message");

        if (!gameLoaded)
        {
            Debug.LogWarning("Our game isn't loaded, adding spawn vehicle to queue");
            playersToSpawnQueue.Enqueue(packet);
            return;
        }

        Message_SpawnVehicle message = (Message_SpawnVehicle)((PacketSingle)packet).message;

        if (Networker.isHost)
        {
            Debug.Log("Generating UIDS for any missiles the new vehicle has");
            for (int i = 0; i < message.hpLoadout.Length; i++)
            {
                for (int j = 0; j < message.hpLoadout[i].missileUIDS.Length; j++)
                {
                    if (message.hpLoadout[i].missileUIDS[j] != 0)
                    {
                        //Storing the old one
                        ulong clientsUID = message.hpLoadout[i].missileUIDS[j];
                        //Generating a new global UID for that missile
                        message.hpLoadout[i].missileUIDS[j] = Networker.GenerateNetworkUID();
                        //Sending it back to that client
                        Networker.SendP2P(new CSteamID(message.csteamID),
                                          new Message_RequestNetworkUID(clientsUID, message.hpLoadout[i].missileUIDS[j]),
                                          EP2PSend.k_EP2PSendReliable);
                    }
                }
            }

            Debug.Log("Telling other clients about new player and new player about other clients. Player count = " + players.Count);
            for (int i = 0; i < players.Count; i++)
            {
                if (players[i].cSteamID == SteamUser.GetSteamID())
                {
                    Debug.LogWarning("Skiping this one as it's the host");
                    continue;
                }
                PlaneNetworker_Receiver existingPlayersPR = players[i].vehicle.GetComponent <PlaneNetworker_Receiver>();
                //We first send the new player to an existing spawned in player
                Networker.SendP2P(players[i].cSteamID, message, EP2PSend.k_EP2PSendReliable);
                //Then we send this current player to the new player.
                Networker.SendP2P(new CSteamID(message.csteamID),
                                  new Message_SpawnVehicle(
                                      players[i].vehicleName,
                                      VTMapManager.WorldToGlobalPoint(players[i].vehicle.transform.position),
                                      new Vector3D(players[i].vehicle.transform.rotation.eulerAngles),
                                      players[i].cSteamID.m_SteamID,
                                      players[i].vehicleUID,
                                      existingPlayersPR.GenerateHPInfo(),
                                      existingPlayersPR.GetCMS(),
                                      existingPlayersPR.GetFuel()),
                                  EP2PSend.k_EP2PSendReliable);
                Debug.Log($"We have told {players[i].cSteamID.m_SteamID} about the new player ({message.csteamID}) and the other way round");

                //We ask the existing player what their load out just incase the host's player receiver was out of sync.
                Networker.SendP2P(players[i].cSteamID,
                                  new Message(MessageType.WeaponsSet),
                                  EP2PSend.k_EP2PSendReliable);
                Debug.Log($"We have asked {players[i].cSteamID.m_SteamID} what their current weapons are, and now waiting for a responce.");
            }
        }

        GameObject newVehicle = null;

        switch (message.vehicle)
        {
        case VTOLVehicles.None:
            Debug.LogError("Vehcile Enum seems to be none, couldn't spawn player vehicle");
            return;

        case VTOLVehicles.AV42C:
            newVehicle = GameObject.Instantiate(av42cPrefab, message.position.toVector3, Quaternion.Euler(message.rotation.toVector3));
            break;

        case VTOLVehicles.FA26B:
            newVehicle = GameObject.Instantiate(fa26bPrefab, message.position.toVector3, Quaternion.Euler(message.rotation.toVector3));
            break;

        case VTOLVehicles.F45A:
            newVehicle = GameObject.Instantiate(f45Prefab, message.position.toVector3, Quaternion.Euler(message.rotation.toVector3));
            break;
        }
        Debug.Log("Setting vehicle name");
        newVehicle.name = $"Client [{message.csteamID}]";
        Debug.Log($"Spawned new vehicle at {newVehicle.transform.position}");

        RigidbodyNetworker_Receiver rbNetworker = newVehicle.AddComponent <RigidbodyNetworker_Receiver>();

        rbNetworker.networkUID = message.networkID;

        PlaneNetworker_Receiver planeReceiver = newVehicle.AddComponent <PlaneNetworker_Receiver>();

        planeReceiver.networkUID = message.networkID;

        if (message.vehicle == VTOLVehicles.AV42C || message.vehicle == VTOLVehicles.F45A)
        {
            Debug.Log("Adding Tilt Controller to this vehicle " + message.networkID);
            EngineTiltNetworker_Receiver tiltReceiver = newVehicle.AddComponent <EngineTiltNetworker_Receiver>();
            tiltReceiver.networkUID = message.networkID;
        }


        Rigidbody rb      = newVehicle.GetComponent <Rigidbody>();
        AIPilot   aIPilot = newVehicle.GetComponent <AIPilot>();

        Debug.Log($"Changing {newVehicle.name}'s position and rotation\nPos:{rb.position} Rotation:{rb.rotation.eulerAngles}");
        aIPilot.kPlane.SetToKinematic();
        aIPilot.kPlane.enabled = false;
        rb.interpolation       = RigidbodyInterpolation.None;
        aIPilot.commandState   = AIPilot.CommandStates.Override;


        rb.position            = message.position.toVector3;
        rb.rotation            = Quaternion.Euler(message.rotation.toVector3);
        aIPilot.kPlane.enabled = true;
        aIPilot.kPlane.SetVelocity(Vector3.zero);
        aIPilot.kPlane.SetToDynamic();
        rb.interpolation = RigidbodyInterpolation.Interpolate;

        Debug.Log($"Finished changing {newVehicle.name}\n Pos:{rb.position} Rotation:{rb.rotation.eulerAngles}");

        GameObject parent  = new GameObject("Name Tag Holder");
        GameObject nameTag = new GameObject("Name Tag");

        parent.transform.SetParent(newVehicle.transform);
        parent.transform.localRotation = Quaternion.Euler(0, 180, 0);
        nameTag.transform.SetParent(parent.transform);
        nameTag.AddComponent <Nametag>().SetText(
            SteamFriends.GetFriendPersonaName(new CSteamID(message.csteamID)),
            newVehicle.transform, VRHead.instance.transform);

        WeaponManager weaponManager = newVehicle.GetComponent <WeaponManager>();

        if (weaponManager == null)
        {
            Debug.LogError("Failed to get weapon manager on " + newVehicle.name);
        }

        List <string> hpLoadoutNames = new List <string>();

        for (int i = 0; i < message.hpLoadout.Length; i++)
        {
            hpLoadoutNames.Add(message.hpLoadout[i].hpName);
        }

        Debug.Log("Setting Loadout on this new vehicle spawned");
        for (int i = 0; i < hpLoadoutNames.Count; i++)
        {
            Debug.Log("HP " + i + " Name: " + hpLoadoutNames[i]);
        }
        Loadout loadout = new Loadout();

        loadout.normalizedFuel = message.normalizedFuel;
        loadout.hpLoadout      = hpLoadoutNames.ToArray();
        loadout.cmLoadout      = message.cmLoadout;
        weaponManager.EquipWeapons(loadout);

        FuelTank fuelTank = newVehicle.GetComponent <FuelTank>();

        if (fuelTank == null)
        {
            Debug.LogError("Failed to get fuel tank on " + newVehicle.name);
        }
        fuelTank.startingFuel = loadout.normalizedFuel * fuelTank.maxFuel;
        fuelTank.SetNormFuel(loadout.normalizedFuel);

        players.Add(new Player(new CSteamID(message.csteamID), newVehicle, message.vehicle, message.networkID));
    }
    /// <summary>
    /// Sends the message to other clients to spawn their vehicles
    /// </summary>
    /// <param name="localVehicle">The local clients gameobject</param>
    public static void SendSpawnVehicle(GameObject localVehicle, Vector3 pos, Vector3 rot, ulong UID) //Both
    {
        Debug.Log("Sending our location to spawn our vehicle");
        VTOLVehicles currentVehicle = VTOLAPI.GetPlayersVehicleEnum();

        players.Add(new Player(SteamUser.GetSteamID(), localVehicle, currentVehicle, UID));

        RigidbodyNetworker_Sender rbSender = localVehicle.AddComponent <RigidbodyNetworker_Sender>();

        rbSender.networkUID = UID;
        rbSender.spawnPos   = pos;
        rbSender.spawnRot   = rot;
        rbSender.SetSpawn();

        Debug.Log("Adding Plane Sender");
        PlaneNetworker_Sender planeSender = localVehicle.AddComponent <PlaneNetworker_Sender>();

        planeSender.networkUID = UID;

        if (currentVehicle == VTOLVehicles.AV42C || currentVehicle == VTOLVehicles.F45A)
        {
            Debug.Log("Added Tilt Updater to our vehicle");
            EngineTiltNetworker_Sender tiltSender = localVehicle.AddComponent <EngineTiltNetworker_Sender>();
            tiltSender.networkUID = UID;
        }

        if (Multiplayer.SoloTesting)
        {
            pos += new Vector3(20, 0, 0);
        }

        List <int> cm   = new List <int>();
        float      fuel = 0.65f;

        //Setting up missiles with MissileUpdate Scripts
        Debug.Log("Setting up missiles");
        WeaponManager weaponManager  = localVehicle.GetComponent <WeaponManager>();
        List <HPInfo> hpInfos        = new List <HPInfo>();
        HPEquippable  lastEquippable = null;

        for (int i = 0; i < weaponManager.equipCount; i++)
        {
            Debug.Log("Weapon Manager, Equip " + i);
            lastEquippable = weaponManager.GetEquip(i);
            if (lastEquippable == null) //If this is null, it means there isn't any weapon in that slot.
            {
                continue;
            }
            Debug.Log("Last Equippable = " + lastEquippable.fullName);
            List <ulong> missileUIDS = new List <ulong>();
            if (lastEquippable.weaponType != HPEquippable.WeaponTypes.Gun &&
                lastEquippable.weaponType != HPEquippable.WeaponTypes.Rocket)
            {
                Debug.Log("This last equip is a missile launcher");
                HPEquipMissileLauncher HPml = lastEquippable as HPEquipMissileLauncher;
                if (HPml.ml == null)
                {
                    Debug.LogError("The Missile Launcher was null on this Missile Launcher");
                    Debug.LogError("Type was = " + lastEquippable.weaponType);
                    continue;
                }
                if (HPml.ml.missiles == null)
                {
                    Debug.LogError("The missile list is null");
                    continue;
                }
                Debug.Log($"This has {HPml.ml.missiles.Length} missiles");
                for (int j = 0; j < HPml.ml.missiles.Length; j++)
                {
                    //There shouldn't be any shot missiles, but if so this skips them as they are null.
                    if (HPml.ml.missiles[j] == null)
                    {
                        missileUIDS.Add(0);
                        Debug.LogError("It seems there wa sa missile shot as it was null");
                        continue;
                    }
                    Debug.Log("Adding Missle Networker to missile");
                    MissileNetworker_Sender sender = HPml.ml.missiles[j].gameObject.AddComponent <MissileNetworker_Sender>();
                    sender.networkUID = Networker.GenerateNetworkUID();
                    missileUIDS.Add(sender.networkUID);
                }
            }

            hpInfos.Add(new HPInfo(
                            lastEquippable.gameObject.name.Replace("(Clone)", ""),
                            lastEquippable.weaponType,
                            missileUIDS.ToArray()));
        }

        //Getting Counter Measure flares.
        Debug.Log("Setting up Counter Measure");
        CountermeasureManager cmManager = localVehicle.GetComponentInChildren <CountermeasureManager>();

        for (int i = 0; i < cmManager.countermeasures.Count; i++)
        {
            cm.Add(cmManager.countermeasures[i].count);
        }

        //Getting Fuel
        if (VehicleEquipper.loadoutSet)
        {
            fuel = VehicleEquipper.loadout.normalizedFuel;
        }

        if (!Networker.isHost || Multiplayer.SoloTesting)
        {
            Networker.SendP2P(Networker.hostID,
                              new Message_SpawnVehicle(currentVehicle, new Vector3D(pos), new Vector3D(rot), SteamUser.GetSteamID().m_SteamID, UID, hpInfos.ToArray(), cm.ToArray(), fuel),
                              EP2PSend.k_EP2PSendReliable);
        }
    }
    /// <summary>
    /// This is when a client has requested a spawn point from the host,
    /// the host gets a spawn point and sends back the position
    /// </summary>
    /// <param name="packet">The Message</param>
    /// <param name="sender">The client who sent it</param>
    public static void RequestSpawn(Packet packet, CSteamID sender) //Host Only
    {
        Debug.Log("A player has requested for a spawn point");
        if (!hostLoaded)
        {
            Debug.Log("The host isn't ready yet, adding to queue");
            spawnRequestQueue.Enqueue(sender);
            return;
        }
        if (spawnPoints == null || spawnPoints.Count == 0)
        {
            Debug.LogError("Spawn points was null, we won't be able to find any spawn point then");
            return;
        }
        Transform spawn = FindFreeSpawn();

        Networker.SendP2P(sender, new Message_RequestSpawn_Result(new Vector3D(spawn.position), new Vector3D(spawn.rotation.eulerAngles), Networker.GenerateNetworkUID()), EP2PSend.k_EP2PSendReliable);
    }