void DrawDisplayedContacts()
        {
            float myAlt = (float)vessel.altitude;

            bool drewLockLabel = false;

            bool lockDirty = false;

            for(int i = 0; i < displayedTargets.Count; i++)
            {
                if(displayedTargets[i].locked && locked)
                {
                    TargetSignatureData lockedTarget = displayedTargets[i].targetData;
                    //LOCKED GUI
                    Vector2 pingPosition;
                    if(omniDisplay)
                    {
                        pingPosition = RadarUtils.WorldToRadar(lockedTarget.position, referenceTransform, radarRect, rIncrements[rangeIndex]);
                    }
                    else
                    {
                        pingPosition = RadarUtils.WorldToRadarRadial(lockedTarget.position, referenceTransform, radarRect, rIncrements[rangeIndex], displayedTargets[i].detectedByRadar.directionalFieldOfView / 2);
                    }

                    //BDGUIUtils.DrawRectangle(new Rect(pingPosition.x-(4),pingPosition.y-(4),8, 8), Color.green);
                    float vAngle = Vector3.Angle(Vector3.ProjectOnPlane(lockedTarget.velocity, referenceTransform.up), referenceTransform.forward);
                    if(referenceTransform.InverseTransformVector(lockedTarget.velocity).x < 0)
                    {
                        vAngle = -vAngle;
                    }
                    GUIUtility.RotateAroundPivot(vAngle, pingPosition);
                    Rect pingRect = new Rect(pingPosition.x - (lockIconSize / 2), pingPosition.y - (lockIconSize / 2), lockIconSize, lockIconSize);

                    Texture2D txtr = (i == lockedTargetIndexes[activeLockedTargetIndex]) ? lockIconActive : lockIcon;
                    GUI.DrawTexture(pingRect, txtr, ScaleMode.StretchToFill, true);
                    GUI.matrix = Matrix4x4.identity;
                    GUI.Label(new Rect(pingPosition.x + (lockIconSize * 0.35f) + 2, pingPosition.y, 100, 24), (lockedTarget.altitude / 1000).ToString("0"), distanceStyle);

                    if(!drewLockLabel)
                    {
                        GUI.Label(radarRect, "-LOCK-\n", lockStyle);
                        drewLockLabel = true;

                        if(slaveTurrets)
                        {
                            GUI.Label(radarRect, "TURRETS\n\n", lockStyle);
                        }
                    }

                    if(BDArmorySettings.DRAW_DEBUG_LABELS)
                    {
                        GUI.Label(new Rect(pingPosition.x + (pingSize.x / 2), pingPosition.y, 100, 24), lockedTarget.signalStrength.ToString("0.0"));
                    }

                    if(GUI.Button(pingRect, GUIContent.none, GUIStyle.none) && Time.time-guiInputTime > guiInputCooldown)
                    {
                        guiInputTime = Time.time;
                        if(i == lockedTargetIndexes[activeLockedTargetIndex])
                        {
                            //UnlockTarget(displayedTargets[i].detectedByRadar);
                            //displayedTargets[i].detectedByRadar.UnlockTargetAtPosition(displayedTargets[i].targetData.position);
                            displayedTargets[i].detectedByRadar.UnlockTargetVessel(displayedTargets[i].vessel);
                            UpdateLockedTargets();
                            lockDirty = true;
                        }
                        else
                        {
                            for(int x = 0; x < lockedTargetIndexes.Count; x++)
                            {
                                if(i == lockedTargetIndexes[x])
                                {
                                    activeLockedTargetIndex = x;
                                    break;
                                }
                            }

                            displayedTargets[i].detectedByRadar.SetActiveLock(displayedTargets[i].targetData);

                            UpdateLockedTargets();
                        }
                    }

                    //DLZ
                    if(!lockDirty)
                    {
                        int lTarInd = lockedTargetIndexes[activeLockedTargetIndex];

                        if(i == lTarInd && weaponManager && weaponManager.selectedWeapon != null)
                        {
                            if(weaponManager.selectedWeapon.GetWeaponClass() == WeaponClasses.Missile)
                            {
                                MissileLauncher currMissile = weaponManager.currentMissile;
                                if(currMissile.targetingMode == MissileLauncher.TargetingModes.Radar || currMissile.targetingMode == MissileLauncher.TargetingModes.Heat)
                                {
                                    MissileLaunchParams dlz = MissileLaunchParams.GetDynamicLaunchParams(currMissile, lockedTarget.velocity, lockedTarget.predictedPosition);
                                    float rangeToPixels = (1 / rIncrements[rangeIndex]) * radarRect.height;
                                    float dlzWidth = 12;
                                    float lineWidth = 2;
                                    float dlzX = radarRect.width - dlzWidth - lineWidth;

                                    BDGUIUtils.DrawRectangle(new Rect(dlzX, 0, dlzWidth, radarRect.height), Color.black);

                                    Rect maxRangeVertLineRect = new Rect(radarRect.width - lineWidth, Mathf.Clamp(radarRect.height - (dlz.maxLaunchRange * rangeToPixels), 0, radarRect.height), lineWidth, Mathf.Clamp(dlz.maxLaunchRange * rangeToPixels, 0, radarRect.height));
                                    BDGUIUtils.DrawRectangle(maxRangeVertLineRect, Color.green);

                                    Rect maxRangeTickRect = new Rect(dlzX, maxRangeVertLineRect.y, dlzWidth, lineWidth);
                                    BDGUIUtils.DrawRectangle(maxRangeTickRect, Color.green);

                                    Rect minRangeTickRect = new Rect(dlzX, Mathf.Clamp(radarRect.height - (dlz.minLaunchRange * rangeToPixels), 0, radarRect.height), dlzWidth, lineWidth);
                                    BDGUIUtils.DrawRectangle(minRangeTickRect, Color.green);

                                    Rect rTrTickRect = new Rect(dlzX, Mathf.Clamp(radarRect.height - (dlz.rangeTr * rangeToPixels), 0, radarRect.height), dlzWidth, lineWidth);
                                    BDGUIUtils.DrawRectangle(rTrTickRect, Color.green);

                                    Rect noEscapeLineRect = new Rect(dlzX, rTrTickRect.y, lineWidth, minRangeTickRect.y - rTrTickRect.y);
                                    BDGUIUtils.DrawRectangle(noEscapeLineRect, Color.green);

                                    float targetDistIconSize = 16;
                                    float targetDistY;
                                    if(!omniDisplay)
                                    {
                                        targetDistY = pingPosition.y - (targetDistIconSize / 2);
                                    }
                                    else
                                    {
                                        targetDistY = radarRect.height - (Vector3.Distance(lockedTarget.predictedPosition, referenceTransform.position) * rangeToPixels) - (targetDistIconSize / 2);
                                    }

                                    Rect targetDistanceRect = new Rect(dlzX - (targetDistIconSize / 2), targetDistY, targetDistIconSize, targetDistIconSize);
                                    GUIUtility.RotateAroundPivot(90, targetDistanceRect.center);
                                    GUI.DrawTexture(targetDistanceRect, BDArmorySettings.Instance.directionTriangleIcon, ScaleMode.StretchToFill, true);
                                    GUI.matrix = Matrix4x4.identity;
                                }
                            }

                        }
                    }
                }
                else
                {
                    float minusAlpha = (Mathf.Clamp01((Time.time - displayedTargets[i].targetData.timeAcquired) / displayedTargets[i].signalPersistTime) * 2) - 1;

                    //jamming
                    bool jammed = false;
                    if(displayedTargets[i].targetData.vesselJammer && displayedTargets[i].targetData.vesselJammer.jammerStrength > displayedTargets[i].targetData.signalStrength)
                    {
                        jammed = true;
                    }

                    if(pingPositionsDirty)
                    {
                        //displayedTargets[i].pingPosition = UpdatedPingPosition(displayedTargets[i].targetData.position, displayedTargets[i].detectedByRadar);
                        RadarDisplayData newData = new RadarDisplayData();
                        newData.detectedByRadar = displayedTargets[i].detectedByRadar;
                        newData.locked = displayedTargets[i].locked;
                        newData.pingPosition = UpdatedPingPosition(displayedTargets[i].targetData.position, displayedTargets[i].detectedByRadar);
                        newData.signalPersistTime = displayedTargets[i].signalPersistTime;
                        newData.targetData = displayedTargets[i].targetData;
                        newData.vessel = displayedTargets[i].vessel;
                        displayedTargets[i] = newData;
                    }
                    Vector2 pingPosition = displayedTargets[i].pingPosition;

                    Rect pingRect;
                    //draw missiles and debris as dots
                    if((displayedTargets[i].targetData.targetInfo && displayedTargets[i].targetData.targetInfo.isMissile) || displayedTargets[i].targetData.team == BDArmorySettings.BDATeams.None)
                    {
                        float mDotSize = 6;
                        pingRect = new Rect(pingPosition.x - (mDotSize / 2), pingPosition.y - (mDotSize / 2), mDotSize, mDotSize);
                        Color origGUIColor = GUI.color;
                        GUI.color = Color.white - new Color(0, 0, 0, minusAlpha);
                        GUI.DrawTexture(pingRect, BDArmorySettings.Instance.greenDotTexture, ScaleMode.StretchToFill, true);
                        GUI.color = origGUIColor;
                    }
                    //draw contacts with direction indicator
                    else if(!jammed && (displayedTargets[i].detectedByRadar.showDirectionWhileScan) && displayedTargets[i].targetData.velocity.sqrMagnitude > 100)
                    {
                        pingRect = new Rect(pingPosition.x - (lockIconSize / 2), pingPosition.y - (lockIconSize / 2), lockIconSize, lockIconSize);
                        float vAngle = Vector3.Angle(Vector3.ProjectOnPlane(displayedTargets[i].targetData.velocity, referenceTransform.up), referenceTransform.forward);
                        if(referenceTransform.InverseTransformVector(displayedTargets[i].targetData.velocity).x < 0)
                        {
                            vAngle = -vAngle;
                        }
                        GUIUtility.RotateAroundPivot(vAngle, pingPosition);
                        Color origGUIColor = GUI.color;
                        GUI.color = Color.white - new Color(0, 0, 0, minusAlpha);
                        if(weaponManager && displayedTargets[i].targetData.team == BDATargetManager.BoolToTeam(weaponManager.team))
                        {
                            GUI.DrawTexture(pingRect, friendlyContactIcon, ScaleMode.StretchToFill, true);
                        }
                        else
                        {
                            GUI.DrawTexture(pingRect, radarContactIcon, ScaleMode.StretchToFill, true);
                        }

                        GUI.matrix = Matrix4x4.identity;
                        GUI.Label(new Rect(pingPosition.x + (lockIconSize * 0.35f) + 2, pingPosition.y, 100, 24), (displayedTargets[i].targetData.altitude / 1000).ToString("0"), distanceStyle);
                        GUI.color = origGUIColor;
                    }
                    else //draw contacts as rectangles
                    {
                        int drawCount = jammed ? 4 : 1;
                        pingRect = new Rect(pingPosition.x - (pingSize.x / 2), pingPosition.y - (pingSize.y / 2), pingSize.x, pingSize.y);
                        for(int d = 0; d < drawCount; d++)
                        {
                            Rect jammedRect = new Rect(pingRect);
                            Vector3 contactPosition = displayedTargets[i].targetData.position;
                            if(jammed)
                            {
                                //jamming
                                Vector3 jammedPosition = transform.position + ((displayedTargets[i].targetData.position - transform.position).normalized * UnityEngine.Random.Range(100, rIncrements[rangeIndex]));
                                float bearingVariation = Mathf.Clamp(Mathf.Pow(32000, 2) / (displayedTargets[i].targetData.position - transform.position).sqrMagnitude, 0, 80);
                                jammedPosition = transform.position + (Quaternion.AngleAxis(UnityEngine.Random.Range(-bearingVariation, bearingVariation), referenceTransform.up) * (jammedPosition - transform.position));
                                if(omniDisplay)
                                {
                                    pingPosition = RadarUtils.WorldToRadar(jammedPosition, referenceTransform, radarRect, rIncrements[rangeIndex]);
                                }
                                else
                                {
                                    pingPosition = RadarUtils.WorldToRadarRadial(jammedPosition, referenceTransform, radarRect, rIncrements[rangeIndex], displayedTargets[i].detectedByRadar.directionalFieldOfView / 2);
                                }

                                jammedRect = new Rect(pingPosition.x - (pingSize.x / 2), pingPosition.y - (pingSize.y / 2) - (pingSize.y / 3), pingSize.x, pingSize.y / 3);
                                contactPosition = jammedPosition;
                            }

                            Color iconColor = Color.green;
                            float contactAlt = displayedTargets[i].targetData.altitude;
                            if(!omniDisplay && !jammed)
                            {
                                if(contactAlt - myAlt > 1000)
                                {
                                    iconColor = new Color(0, 0.6f, 1f, 1);
                                }
                                else if(contactAlt - myAlt < -1000)
                                {
                                    iconColor = new Color(1f, 0.68f, 0, 1);
                                }
                            }

                            if(omniDisplay)
                            {
                                Vector3 localPos = referenceTransform.InverseTransformPoint(contactPosition);
                                localPos.y = 0;
                                float angleToContact = Vector3.Angle(localPos, Vector3.forward);
                                if(localPos.x < 0) angleToContact = -angleToContact;
                                GUIUtility.RotateAroundPivot(angleToContact, pingPosition);
                            }

                            if(jammed || displayedTargets[i].targetData.team != BDATargetManager.BoolToTeam(weaponManager.team))
                            {
                                BDGUIUtils.DrawRectangle(jammedRect, iconColor - new Color(0, 0, 0, minusAlpha));
                            }
                            else
                            {
                                float friendlySize = 12;
                                Rect friendlyRect = new Rect(pingPosition.x - (friendlySize / 2), pingPosition.y - (friendlySize / 2), friendlySize, friendlySize);
                                Color origGuiColor = GUI.color;
                                GUI.color = iconColor - new Color(0, 0, 0, minusAlpha);
                                GUI.DrawTexture(friendlyRect, BDArmorySettings.Instance.greenDotTexture, ScaleMode.StretchToFill, true);
                                GUI.color = origGuiColor;
                            }

                            GUI.matrix = Matrix4x4.identity;
                        }
                    }

                    if(GUI.Button(pingRect, GUIContent.none, GUIStyle.none) && Time.time-guiInputTime > guiInputCooldown)
                    {
                        guiInputTime = Time.time;
                        TryLockTarget(displayedTargets[i]);
                    }

                    if(BDArmorySettings.DRAW_DEBUG_LABELS)
                    {
                        GUI.Label(new Rect(pingPosition.x + (pingSize.x / 2), pingPosition.y, 100, 24), displayedTargets[i].targetData.signalStrength.ToString("0.0"));
                    }
                }
            }
            pingPositionsDirty = false;
        }
        bool CheckRadarForLock(ModuleRadar radar, RadarDisplayData radarTarget)
        {
            if(!radar) return false;

            return
                (
                radar.canLock
                && (!radar.locked || radar.currentLocks < radar.maxLocks)
                && radarTarget.targetData.signalStrength > radar.minLockedSignalThreshold
                && (radar.omnidirectional || Vector3.Angle(radar.transform.up, radarTarget.targetData.predictedPosition-radar.transform.position) < radar.directionalFieldOfView/2)
            );
        }
        bool TryLockTarget(RadarDisplayData radarTarget)
        {
            if(radarTarget.locked) return false;

            ModuleRadar lockingRadar = null;
            //first try using the last radar to detect that target
            if(CheckRadarForLock(radarTarget.detectedByRadar, radarTarget))
            {
                lockingRadar = radarTarget.detectedByRadar;
            }
            else
            {
                foreach(var radar in availableRadars)
                {
                    if(CheckRadarForLock(radar, radarTarget))
                    {
                        lockingRadar = radar;
                        break;
                    }
                }
            }

            if(lockingRadar != null)
            {
                return lockingRadar.TryLockTarget(radarTarget.targetData.predictedPosition);
            }

            UpdateLockedTargets();
            StartCoroutine(UpdateLocksAfterFrame());
            return false;
        }
        public bool TryLockTarget(Vessel v)
        {
            if(!v) return false;

            foreach(var displayData in displayedTargets)
            {
                if(v == displayData.vessel)
                {
                    return TryLockTarget(displayData);
                }
            }

            RadarDisplayData newData = new RadarDisplayData();
            newData.vessel = v;
            newData.detectedByRadar = null;
            newData.targetData = new TargetSignatureData(v, 999);

            return TryLockTarget(newData);

            //return false;
        }
        public void AddRadarContact(ModuleRadar radar, TargetSignatureData contactData, bool _locked)
        {
            RadarDisplayData rData = new RadarDisplayData();
            rData.vessel = contactData.vessel;

            if(rData.vessel == vessel)
            {
                return;
            }

            rData.signalPersistTime = radar.signalPersistTime;
            rData.detectedByRadar = radar;
            rData.locked = _locked;
            rData.targetData = contactData;
            rData.pingPosition = UpdatedPingPosition(contactData.position, radar);

            if(_locked)
            {
                radar.UpdateLockedTargetInfo(contactData);
            }

            bool dontOverwrite = false;

            int replaceIndex = -1;
            for(int i = 0; i < displayedTargets.Count; i++)
            {
                if(displayedTargets[i].vessel == rData.vessel)
                {
                    if(displayedTargets[i].locked && !_locked)
                    {
                        dontOverwrite = true;
                        break;
                    }

                    replaceIndex = i;
                    break;
                }
            }

            if(replaceIndex >= 0)
            {
                displayedTargets[replaceIndex] = rData;
                //UpdateLockedTargets();
                return;
            }
            else if(dontOverwrite)
            {
                //UpdateLockedTargets();
                return;
            }
            else
            {
                displayedTargets.Add(rData);
                UpdateLockedTargets();
                return;
            }
        }