Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs
T
Joonas Rikkonen 58a14fd054 178a853...bd9a92d
commit bd9a92df11a8d83d0d0087ce64422f2fba3f6f99
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Sat Feb 2 20:07:36 2019 +0200

    v0.8.9.2

commit 4e1d5fa3744fb8cab80cb006a433d2efe7685562
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Sat Feb 2 19:20:03 2019 +0200

    Moved humpback's cargo spawn position a bit to prevent the cargo from falling down the hatch under it.

commit f0ec5530b0c7ecbdaaf8bd266d9a57fac2c92fe9
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Sat Feb 2 19:18:41 2019 +0200

    Fixed structure BodyOffset not being taken into account when generating the collider for the sub. Caused the button outside Orca's button to be impossible to interact with.

commit 1360f5511522280d03d608c8eb6f56fb6608aab5
Author: ezjamsen <ezjames.fi@gmail.com>
Date:   Sat Feb 2 19:10:37 2019 +0200

    Halved the status effect for damage to submerged items. This might be a bit too generous, let's see.

commit 06afb668bc816a345dbd12899b819843549e908a
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Sat Feb 2 18:22:00 2019 +0200

    Changed mantis loading tip to mud raptor, fixed a glaring error in one of the npc conversations

commit d2dfa960dd5fa43426eb4dfd02de6c497ae9d838
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Sat Feb 2 18:17:17 2019 +0200

    Fixed water flow forces occasionally being way too high due to bugged force calculation logic when water is flowing from a hull to the one below it. + Added a hard cap to flow forces to prevent this from happening again. Closes #572

commit 21754b39ded247e8c9837d58c6de9658f56a9772
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Sat Feb 2 17:24:48 2019 +0200

    Entities cannot be placed in the sub editor when the cursor is on a UI element. Fixes an entity being placed when selecting an item from them menu while something else is already selected. Closes #1023

commit 97d0cf92f738a058fa0140ec841549a5d6c746a3
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Sat Feb 2 16:59:56 2019 +0200

    Fixed a typo in one of the affliction descriptions

commit ddccbdc9a438199d3cb796789dd9915cc305ec5b
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Sat Feb 2 16:59:18 2019 +0200

    Fixed sliders buttons becoming invisible when pressed

commit bc28473a1c61698c9447825b1c5a13edd6e7bf6c
Merge: 2d212802e f3dfe5990
Author: ezjamsen <ezjames.fi@gmail.com>
Date:   Sat Feb 2 16:45:33 2019 +0200

    Merge branch 'dev' of https://github.com/Regalis11/Barotrauma into dev

commit 2d212802ea945c6cbd1c889d304595b68692e05c
Author: ezjamsen <ezjames.fi@gmail.com>
Date:   Sat Feb 2 16:44:30 2019 +0200

    corrected the condition at which railgun and coilgun loaders can be repaired

commit f3dfe5990a03cb3c577635dffb25883085d919f1
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Sat Feb 2 16:41:34 2019 +0200

    Fixed second submarine overlapping with the outpost at the end of the level in combat missions.

commit 1f224e9b7cae3f94e9b6937d66c171edbd8ef523
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Sat Feb 2 15:35:22 2019 +0200

    Fixed sub/mode selection setting tickboxes

commit 0eb99486454c1bb47b51b20e4d23f42f4147dd8d
Merge: ff90fdb35 80785d627
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Sat Feb 2 15:08:18 2019 +0200

    Merge branch 'dev' of https://github.com/Regalis11/Barotrauma into dev

commit ff90fdb352af6800d0dcf224816cf9e831184f1e
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Sat Feb 2 15:08:12 2019 +0200

    Don't do chat message similarity tests on order messages (caused spam kicks way too easily when giving orders or reporting things)

commit af8a350c7998ae2c729b4354c3c02cbcf75cabde
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Sat Feb 2 15:06:42 2019 +0200

    Fixed Huskappendage.xml not being copied to the output directory

commit df3af76d909099e9c9e59f74b1f5b3b381303a99
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Sat Feb 2 14:06:19 2019 +0200

    Revert "Ignore anything but the content path when checking the filepath cases." Doesn't work correctly if there's a folder named "Content" in some subfolder (e.g. "Mods/SomeMod/Content") or if checking file paths somewhere else than the content folder (Submarines, Data, NewWorkshopItem, Mods...)

    This reverts commit 123e84ea1ac6f4392c293d0d5c64b857bfc4eb30.

commit 80785d627c82948ce1784654070a0da8f732ca33
Author: ezjamsen <ezjames.fi@gmail.com>
Date:   Sat Feb 2 14:43:36 2019 +0200

    added better visual feedback when reactor is in poor condition

commit e450872721d8e0b47b3ae5792292ea2071a8eefe
Author: ezjamsen <ezjames.fi@gmail.com>
Date:   Sat Feb 2 14:40:42 2019 +0200

    added a small stun effect to railgun shells

commit 05792285eab781990bdc3b658a9217ff38704d1e
Author: ezjamsen <ezjames.fi@gmail.com>
Date:   Sat Feb 2 14:40:03 2019 +0200

    added a little extra fuel, moved the position of guns to hull to prevent players getting caught under them

commit 8c85c33023b6cec1c18b8743d1f05fd4fc8c2ea7
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Sat Feb 2 13:58:55 2019 +0200

    Fixed crashing when attempting to use active sonar in the sub editor. Closes #1024

commit d71225d8c58fb285cbf207549b77cabdc7e1df11
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Fri Feb 1 18:27:06 2019 +0200

    Fixed crashing when selecting an item in a fabricator that's linked to containers, but not set to display the contents of the containers

commit a6fa5d82c7b1505932b8283ccfef75798b839d92
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Fri Feb 1 18:07:40 2019 +0200

    Fixed "can't create and entity event for Hull" error messages when attempting to remove a hull with fire sources in it in MP

commit 72737c6d3eb7ca7daf5e5d84fdcbc1f060b79b10
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Fri Feb 1 18:05:04 2019 +0200

    Filename case fix part 913, fixed rewards mentioned in mission descriptions not matching the actual reward of the mission.

commit a148c7843f2805b1757d231bcf028bafdbc22187
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Fri Feb 1 17:56:18 2019 +0200

    Attempt to forward steam query port when UPnP is enabled

commit 3e73d705c221a417f60baf76c8c7d100391f7802
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Fri Feb 1 17:44:34 2019 +0200

    Removed the "training" button from the main menu (not needed, tutorial is now implemented directly in the SP campaign)

commit 1f07c3f1b4de0bb09fe11e9834faeea30e4afade
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Fri Feb 1 17:33:01 2019 +0200

    Fixed crewmanager UI elements hidden outside the extents of the crew list overlapping with other UI elements

commit aa0c5f4e90b57a8ee3f152b9aeba1e73c7c539c0
Merge: 123e84ea1 73f51a405
Author: itchyOwl <lauri.harkanen@gmail.com>
Date:   Fri Feb 1 16:21:27 2019 +0200

    Merge branch 'dev' of https://github.com/Regalis11/Barotrauma into dev

commit 123e84ea1ac6f4392c293d0d5c64b857bfc4eb30
Author: itchyOwl <lauri.harkanen@gmail.com>
Date:   Fri Feb 1 16:21:19 2019 +0200

    Ignore anything but the content path when checking the filepath cases.

commit 73f51a4055ca7fd1cd65570a51d88db1f1272d23
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Fri Feb 1 15:20:15 2019 +0200

    Don't show the "incorrect case" errors in non-linux release builds. It seems that Path.GetFullPath may return paths with an incorrect case on Windows (try changing the case of any of the game's parent folders to repro).

commit 5a598129a9d63c5185529107d469404c35be59c5
Author: ezjamsen <ezjames.fi@gmail.com>
Date:   Fri Feb 1 11:29:41 2019 +0200

    Renamed hull areas... again.
2019-03-18 21:09:32 +02:00

1077 lines
47 KiB
C#

using Barotrauma.Networking;
using FarseerPhysics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
partial class Sonar : Powered, IServerSerializable, IClientSerializable
{
private bool unsentChanges;
private float networkUpdateTimer;
private GUITickBox activeTickBox, passiveTickBox;
private GUITextBlock signalWarningText;
private GUIScrollBar zoomSlider;
private GUITickBox directionalTickBox;
private GUIScrollBar directionalSlider;
private GUIComponent activeControlsContainer;
private GUICustomComponent sonarView;
private float displayBorderSize;
private List<SonarBlip> sonarBlips;
private float prevPingRadius;
private float prevPassivePingRadius;
private Vector2 center;
private float displayScale;
private float zoomSqrt;
//Vector2 = vector from the ping source to the position of the disruption
//float = strength of the disruption, between 0-1
List<Pair<Vector2, float>> disruptedDirections = new List<Pair<Vector2, float>>();
private static Color[] blipColorGradient =
{
Color.TransparentBlack,
new Color(0, 50, 160),
new Color(0, 133, 166),
new Color(2, 159, 30),
new Color(255, 255, 255)
};
public Vector2 DisplayOffset { get; private set; }
public float DisplayRadius { get; private set; }
partial void InitProjSpecific(XElement element)
{
sonarBlips = new List<SonarBlip>();
int viewSize = (int)Math.Min(GuiFrame.Rect.Width - 150, GuiFrame.Rect.Height * 0.9f);
sonarView = new GUICustomComponent(new RectTransform(new Point(viewSize), GuiFrame.RectTransform, Anchor.CenterLeft),
(spriteBatch, guiCustomComponent) => { DrawSonar(spriteBatch, guiCustomComponent.Rect); }, null);
var controlContainer = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.35f), GuiFrame.RectTransform, Anchor.TopLeft)
{ MinSize = new Point(150, 0), AbsoluteOffset = new Point((int)(viewSize * 0.9f), 0) }, "SonarFrame");
controlContainer.RectTransform.SetAsFirstChild();
var paddedControlContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), controlContainer.RectTransform, Anchor.Center))
{
RelativeSpacing = 0.03f,
Stretch = true
};
passiveTickBox = new GUITickBox(new RectTransform(new Vector2(0.3f, 0.2f), paddedControlContainer.RectTransform), TextManager.Get("SonarPassive"), style: "GUIRadioButton")
{
ToolTip = TextManager.Get("SonarTipPassive"),
Selected = true
};
activeTickBox = new GUITickBox(new RectTransform(new Vector2(0.3f, 0.2f), paddedControlContainer.RectTransform), TextManager.Get("SonarActive"), style: "GUIRadioButton")
{
ToolTip = TextManager.Get("SonarTipActive"),
OnSelected = (GUITickBox box) =>
{
if (GameMain.Server != null)
{
unsentChanges = true;
}
else if (GameMain.Client != null)
{
unsentChanges = true;
correctionTimer = CorrectionDelay;
}
IsActive = box.Selected;
return true;
}
};
var zoomContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.2f), paddedControlContainer.RectTransform), isHorizontal: true);
new GUITextBlock(new RectTransform(new Vector2(0.35f, 1.0f), zoomContainer.RectTransform), TextManager.Get("SonarZoom"), font: GUI.SmallFont)
{
Padding = Vector4.Zero
};
zoomSlider = new GUIScrollBar(new RectTransform(new Vector2(0.65f, 1.0f), zoomContainer.RectTransform), barSize: 0.1f, isHorizontal: true)
{
OnMoved = (scrollbar, scroll) =>
{
zoom = MathHelper.Lerp(MinZoom, MaxZoom, scroll);
if (GameMain.Server != null)
{
unsentChanges = true;
}
else if (GameMain.Client != null)
{
unsentChanges = true;
correctionTimer = CorrectionDelay;
}
return true;
}
};
var activeControls = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.6f), paddedControlContainer.RectTransform) { RelativeOffset = new Vector2(0.1f, 0.0f) }, "InnerFrame");
activeControlsContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.8f), activeControls.RectTransform, Anchor.Center))
{
RelativeSpacing = 0.03f,
Stretch = true
};
directionalTickBox = new GUITickBox(new RectTransform(new Vector2(0.3f, 0.3f), activeControlsContainer.RectTransform), TextManager.Get("SonarDirectionalPing"))
{
OnSelected = (tickBox) =>
{
useDirectionalPing = tickBox.Selected;
if (GameMain.Server != null)
{
unsentChanges = true;
}
else if (GameMain.Client != null)
{
unsentChanges = true;
correctionTimer = CorrectionDelay;
}
return true;
}
};
directionalSlider = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.3f), activeControlsContainer.RectTransform), barSize: 0.1f, isHorizontal: true)
{
OnMoved = (scrollbar, scroll) =>
{
float pingAngle = MathHelper.Lerp(0.0f, MathHelper.TwoPi, scroll);
pingDirection = new Vector2((float)Math.Cos(pingAngle), (float)Math.Sin(pingAngle));
if (GameMain.Server != null)
{
unsentChanges = true;
}
else if (GameMain.Client != null)
{
unsentChanges = true;
correctionTimer = CorrectionDelay;
}
return true;
}
};
signalWarningText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), paddedControlContainer.RectTransform), "", Color.Orange, textAlignment: Alignment.Center);
GUITickBox.CreateRadioButtonGroup(new List<GUITickBox>() { activeTickBox, passiveTickBox });
GuiFrame.CanBeFocused = false;
}
public override void OnItemLoaded()
{
zoomSlider.BarScroll = MathUtils.InverseLerp(MinZoom, MaxZoom, zoom);
//make the sonarView customcomponent render the steering view so it gets drawn in front of the sonar
item.GetComponent<Steering>()?.AttachToSonarHUD(sonarView);
}
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
{
if (unsentChanges)
{
if (networkUpdateTimer <= 0.0f)
{
#if CLIENT
if (GameMain.Client != null)
{
item.CreateClientEvent(this);
correctionTimer = CorrectionDelay;
}
#endif
if (GameMain.Server != null)
{
item.CreateServerEvent(this);
}
networkUpdateTimer = 0.1f;
unsentChanges = false;
}
}
networkUpdateTimer -= deltaTime;
if (sonarView.Rect.Contains(PlayerInput.MousePosition))
{
float scrollSpeed = PlayerInput.ScrollWheelSpeed / 1000.0f;
if (Math.Abs(scrollSpeed) > 0.0001f)
{
zoomSlider.BarScroll += PlayerInput.ScrollWheelSpeed / 1000.0f;
zoomSlider.OnMoved(zoomSlider, zoomSlider.BarScroll);
}
}
float distort = 1.0f - item.Condition / 100.0f;
for (int i = sonarBlips.Count - 1; i >= 0; i--)
{
sonarBlips[i].FadeTimer -= deltaTime * MathHelper.Lerp(0.5f, 2.0f, distort);
sonarBlips[i].Position += sonarBlips[i].Velocity * deltaTime;
if (sonarBlips[i].FadeTimer <= 0.0f) sonarBlips.RemoveAt(i);
}
foreach (GUIComponent component in activeControlsContainer.Parent.GetAllChildren())
{
if (component is GUITextBlock textBlock)
{
textBlock.TextColor = IsActive ? textBlock.Style.textColor : textBlock.Style.textColor * 0.5f;
}
}
//sonar view can only get focus when the cursor is inside the circle
sonarView.CanBeFocused =
Vector2.DistanceSquared(sonarView.Rect.Center.ToVector2(), PlayerInput.MousePosition) <
(sonarView.Rect.Width / 2 * sonarView.Rect.Width / 2);
if (UseTransducers && connectedTransducers.Count == 0)
{
return;
}
Vector2 transducerCenter = UseTransducers ? GetTransducerCenter() : item.WorldPosition;
transducerCenter += DisplayOffset;
if (Level.Loaded != null)
{
Dictionary<LevelTrigger, Vector2> levelTriggerFlows = new Dictionary<LevelTrigger, Vector2>();
foreach (LevelObject levelObject in Level.Loaded.LevelObjectManager.GetAllObjects(transducerCenter, range * pingState / zoom))
{
//gather all nearby triggers that are causing the water to flow into the dictionary
foreach (LevelTrigger trigger in levelObject.Triggers)
{
Vector2 flow = trigger.GetWaterFlowVelocity();
//ignore ones that are barely doing anything (flow^2 < 1)
if (flow.LengthSquared() > 1.0f) levelTriggerFlows.Add(trigger, flow);
}
}
foreach (KeyValuePair<LevelTrigger, Vector2> triggerFlow in levelTriggerFlows)
{
LevelTrigger trigger = triggerFlow.Key;
Vector2 flow = triggerFlow.Value;
float flowMagnitude = flow.Length();
if (Rand.Range(0.0f, 1.0f) < flowMagnitude / 1000.0f)
{
float edgeDist = Rand.Range(0.0f, 1.0f);
Vector2 blipPos = trigger.WorldPosition + Rand.Vector(trigger.ColliderRadius * edgeDist);
Vector2 blipVel = flow;
if (trigger.ForceFalloff) flow *= (1.0f - edgeDist);
//go through other triggers in range and add the flows of the ones that the blip is inside
foreach (KeyValuePair<LevelTrigger, Vector2> triggerFlow2 in levelTriggerFlows)
{
LevelTrigger trigger2 = triggerFlow2.Key;
if (trigger2 != trigger && Vector2.DistanceSquared(blipPos, trigger2.WorldPosition) < trigger2.ColliderRadius * trigger2.ColliderRadius)
{
Vector2 trigger2flow = triggerFlow2.Value;
if (trigger2.ForceFalloff) trigger2flow *= (1.0f - Vector2.Distance(blipPos, trigger2.WorldPosition) / trigger2.ColliderRadius);
blipVel += trigger2flow;
}
}
var flowBlip = new SonarBlip(blipPos, Rand.Range(0.5f, 1.0f), 1.0f)
{
Velocity = blipVel * Rand.Range(1.0f, 5.0f),
Size = new Vector2(MathHelper.Lerp(0.4f, 5f, flowMagnitude / 500.0f), 0.2f),
Rotation = (float)Math.Atan2(-blipVel.Y, blipVel.X)
};
sonarBlips.Add(flowBlip);
}
}
}
if (IsActive)
{
float pingRadius = DisplayRadius * pingState / zoom;
UpdateDisruptions(transducerCenter, pingRadius / displayScale, prevPingRadius / displayScale);
Ping(transducerCenter, transducerCenter,
pingRadius, prevPingRadius, displayScale, range / zoom, passive: false, pingStrength: 2.0f);
prevPingRadius = pingRadius;
return;
}
float passivePingRadius = (float)Math.Sin(Timing.TotalTime * 10);
if (passivePingRadius > 0.0f)
{
disruptedDirections.Clear();
foreach (AITarget t in AITarget.List)
{
if (t.SoundRange <= 0.0f || !t.Enabled) continue;
if (Vector2.DistanceSquared(t.WorldPosition, transducerCenter) < t.SoundRange * t.SoundRange)
{
Ping(t.WorldPosition, transducerCenter,
t.SoundRange * passivePingRadius * 0.2f, t.SoundRange * prevPassivePingRadius * 0.2f, displayScale, t.SoundRange,
passive: true, pingStrength: 0.5f);
sonarBlips.Add(new SonarBlip(t.WorldPosition, 1.0f, 1.0f));
}
}
}
prevPassivePingRadius = passivePingRadius;
}
private void DrawSonar(SpriteBatch spriteBatch, Rectangle rect)
{
displayBorderSize = 0.2f;
center = rect.Center.ToVector2();
DisplayRadius = (rect.Width / 2.0f) * (1.0f - displayBorderSize);
displayScale = DisplayRadius / range * zoom;
if (screenBackground != null)
{
screenBackground.Draw(spriteBatch, center, 0.0f, rect.Width / screenBackground.size.X);
}
if (IsActive)
{
if (isLastPingDirectional && directionalPingCircle != null)
{
directionalPingCircle.Draw(spriteBatch, center, Color.White * (1.0f - pingState),
rotate: MathUtils.VectorToAngle(lastPingDirection),
scale: (DisplayRadius / directionalPingCircle.size.X) * pingState);
}
else
{
pingCircle.Draw(spriteBatch, center, Color.White * (1.0f - pingState), 0.0f, (DisplayRadius * 2 / pingCircle.size.X) * pingState);
}
}
float signalStrength = 1.0f;
if (UseTransducers)
{
signalStrength = 0.0f;
foreach (ConnectedTransducer connectedTransducer in connectedTransducers)
{
signalStrength = Math.Max(signalStrength, connectedTransducer.SignalStrength);
}
}
Vector2 transducerCenter = UseTransducers && connectedTransducers.Count > 0 ? GetTransducerCenter() : item.WorldPosition;
if (item.Submarine != null && !DetectSubmarineWalls)
{
DrawDockingPorts(spriteBatch, transducerCenter, signalStrength);
transducerCenter += DisplayOffset;
DrawOwnSubmarineBorders(spriteBatch, transducerCenter, signalStrength);
}
else
{
DisplayOffset = Vector2.Zero;
}
if (sonarBlips.Count > 0)
{
zoomSqrt = (float)Math.Sqrt(zoom);
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive);
foreach (SonarBlip sonarBlip in sonarBlips)
{
DrawBlip(spriteBatch, sonarBlip, transducerCenter, center, sonarBlip.FadeTimer / 2.0f * signalStrength);
}
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
}
if (useDirectionalPing && IsActive)
{
Vector2 sector1 = MathUtils.RotatePointAroundTarget(pingDirection * DisplayRadius, Vector2.Zero, DirectionalPingSector * 0.5f);
Vector2 sector2 = MathUtils.RotatePointAroundTarget(pingDirection * DisplayRadius, Vector2.Zero, -DirectionalPingSector * 0.5f);
GUI.DrawLine(spriteBatch, center, center + sector1, Color.LightCyan * 0.2f, width: 3);
GUI.DrawLine(spriteBatch, center, center + sector2, Color.LightCyan * 0.2f, width: 3);
}
if (GameMain.DebugDraw)
{
GUI.DrawString(spriteBatch, rect.Location.ToVector2(), sonarBlips.Count.ToString(), Color.White);
}
if (screenOverlay != null)
{
screenOverlay.Draw(spriteBatch, center, 0.0f, rect.Width / screenOverlay.size.X);
}
if (signalStrength <= 0.5f)
{
signalWarningText.Text = TextManager.Get(signalStrength <= 0.0f ? "SonarNoSignal" : "SonarSignalWeak");
signalWarningText.Color = signalStrength <= 0.0f ? Color.Red : Color.Orange;
signalWarningText.Visible = true;
}
else
{
signalWarningText.Visible = false;
}
if (GameMain.GameSession == null) return;
DrawMarker(spriteBatch,
GameMain.GameSession.StartLocation.Name,
(Level.Loaded.StartPosition - transducerCenter), displayScale, center, (rect.Width * 0.5f));
DrawMarker(spriteBatch,
GameMain.GameSession.EndLocation.Name,
(Level.Loaded.EndPosition - transducerCenter), displayScale, center, (rect.Width * 0.5f));
foreach (AITarget aiTarget in AITarget.List)
{
if (!aiTarget.Enabled) continue;
if (string.IsNullOrEmpty(aiTarget.SonarLabel) || aiTarget.SoundRange <= 0.0f) continue;
if (Vector2.DistanceSquared(aiTarget.WorldPosition, transducerCenter) < aiTarget.SoundRange * aiTarget.SoundRange)
{
DrawMarker(spriteBatch,
aiTarget.SonarLabel,
aiTarget.WorldPosition - transducerCenter, displayScale, center, (rect.Width * 0.47f));
}
}
if (GameMain.GameSession.Mission != null)
{
var mission = GameMain.GameSession.Mission;
if (!string.IsNullOrWhiteSpace(mission.SonarLabel) && mission.SonarPosition != Vector2.Zero)
{
DrawMarker(spriteBatch,
mission.SonarLabel,
mission.SonarPosition - transducerCenter, displayScale, center, (rect.Width * 0.47f));
}
}
foreach (Submarine sub in Submarine.Loaded)
{
if (!sub.OnSonar) continue;
if (UseTransducers ?
connectedTransducers.Any(t => sub == t.Transducer.Item.Submarine || sub.DockedTo.Contains(t.Transducer.Item.Submarine)) :
(sub == item.Submarine || sub.DockedTo.Contains(item.Submarine)))
{
continue;
}
if (sub.WorldPosition.Y > Level.Loaded.Size.Y) continue;
DrawMarker(spriteBatch, sub.Name, sub.WorldPosition - transducerCenter, displayScale, center, (rect.Width * 0.45f));
}
if (GameMain.DebugDraw)
{
var steering = item.GetComponent<Steering>();
steering?.DebugDrawHUD(spriteBatch, transducerCenter, displayScale, DisplayRadius, center);
}
}
private void DrawOwnSubmarineBorders(SpriteBatch spriteBatch, Vector2 transducerCenter, float signalStrength)
{
float simScale = displayScale * Physics.DisplayToSimRation * zoom;
foreach (Submarine submarine in Submarine.Loaded)
{
if (UseTransducers ?
!connectedTransducers.Any(t => submarine == t.Transducer.Item.Submarine || submarine.DockedTo.Contains(t.Transducer.Item.Submarine)) :
submarine != item.Submarine && !submarine.DockedTo.Contains(item.Submarine)) continue;
if (submarine.HullVertices == null) continue;
Vector2 offset = ConvertUnits.ToSimUnits(submarine.WorldPosition - transducerCenter);
for (int i = 0; i < submarine.HullVertices.Count; i++)
{
Vector2 start = (submarine.HullVertices[i] + offset) * simScale;
start.Y = -start.Y;
Vector2 end = (submarine.HullVertices[(i + 1) % submarine.HullVertices.Count] + offset) * simScale;
end.Y = -end.Y;
DrawLine(spriteBatch, start, end, Color.LightBlue * signalStrength * 0.5f, width: 3);
}
}
}
private void DrawLine(SpriteBatch spriteBatch, Vector2 start, Vector2 end, Color color, int width)
{
bool startOutside = start.LengthSquared() > DisplayRadius * DisplayRadius;
bool endOutside = end.LengthSquared() > DisplayRadius * DisplayRadius;
if (startOutside && endOutside)
{
return;
}
else if (startOutside)
{
if (MathUtils.GetLineCircleIntersections(Vector2.Zero, DisplayRadius, end, start, true, out Vector2? intersection1, out Vector2? intersection2) == 1)
{
GUI.DrawLine(spriteBatch, center + intersection1.Value, center + end, color, width: width);
}
}
else if (endOutside)
{
if (MathUtils.GetLineCircleIntersections(Vector2.Zero, DisplayRadius, start, end, true, out Vector2? intersection1, out Vector2? intersection2) == 1)
{
GUI.DrawLine(spriteBatch, center + start, center + intersection1.Value, color, width: width);
}
}
else
{
GUI.DrawLine(spriteBatch, center + start, center + end, color, width: width);
}
}
private void DrawDockingPorts(SpriteBatch spriteBatch, Vector2 transducerCenter, float signalStrength)
{
float scale = displayScale * zoom;
Steering steering = item.GetComponent<Steering>();
if (steering != null && steering.DockingModeEnabled)
{
DisplayOffset =
Vector2.Lerp(DisplayOffset,
(steering.DockingSource.Item.WorldPosition + steering.DockingTarget.Item.WorldPosition) / 2.0f - transducerCenter,
0.1f);
transducerCenter += DisplayOffset;
Vector2 sourcePortDiff = (steering.DockingSource.Item.WorldPosition - transducerCenter) * scale;
Vector2 sourcePortPos = new Vector2(sourcePortDiff.X, -sourcePortDiff.Y);
Vector2 targetPortDiff = (steering.DockingTarget.Item.WorldPosition - transducerCenter) * scale;
Vector2 targetPortPos = new Vector2(targetPortDiff.X, -targetPortDiff.Y);
Vector2 midPos = (sourcePortPos + targetPortPos) / 2.0f;
System.Diagnostics.Debug.Assert(steering.DockingSource.IsHorizontal == steering.DockingTarget.IsHorizontal);
float xDist = Math.Abs(steering.DockingSource.Item.WorldPosition.X - steering.DockingTarget.Item.WorldPosition.X);
float normalizedXDist = xDist / steering.DockingSource.DistanceTolerance.X;
float yDist = Math.Abs(steering.DockingSource.Item.WorldPosition.Y - steering.DockingTarget.Item.WorldPosition.Y);
float normalizedYDist = yDist / steering.DockingSource.DistanceTolerance.Y;
Color xColor = normalizedXDist <= 1.0f ? Color.Lime : Color.Lerp(Color.Orange, Color.Red, normalizedXDist - 1.0f);
Color yColor = normalizedYDist <= 1.0f ? Color.Lime : Color.Lerp(Color.Orange, Color.Red, normalizedYDist - 1.0f);
if (steering.DockingSource.IsHorizontal)
{
if (yDist < steering.DockingSource.DistanceTolerance.Y)
{
DrawLine(spriteBatch, sourcePortPos, new Vector2(targetPortPos.X, sourcePortPos.Y), xColor, width: 3);
}
else
{
DrawLine(spriteBatch, sourcePortPos, new Vector2(midPos.X, sourcePortPos.Y), xColor, width: 3);
DrawLine(spriteBatch, targetPortPos, new Vector2(midPos.X, targetPortPos.Y), xColor, width: 3);
DrawLine(spriteBatch, new Vector2(midPos.X, sourcePortPos.Y), new Vector2(midPos.X, targetPortPos.Y), yColor, width: 3);
}
}
else
{
if (xDist < steering.DockingSource.DistanceTolerance.X)
{
DrawLine(spriteBatch, sourcePortPos, new Vector2(sourcePortPos.X, targetPortPos.Y), yColor, width: 3);
}
else
{
DrawLine(spriteBatch, sourcePortPos, new Vector2(sourcePortPos.X, midPos.Y), yColor, width: 3);
DrawLine(spriteBatch, targetPortPos, new Vector2(targetPortPos.X, midPos.Y), yColor, width: 3);
DrawLine(spriteBatch, new Vector2(sourcePortPos.X, midPos.Y), new Vector2(targetPortPos.X, midPos.Y), xColor, width: 3);
}
}
}
else
{
DisplayOffset = Vector2.Lerp(DisplayOffset, Vector2.Zero, 0.1f);
}
foreach (DockingPort dockingPort in DockingPort.List)
{
if (Level.Loaded != null && dockingPort.Item.Submarine.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
Vector2 offset = (dockingPort.Item.WorldPosition - transducerCenter) * scale;
offset.Y = -offset.Y;
if (offset.LengthSquared() > DisplayRadius * DisplayRadius) { continue; }
Vector2 size = dockingPort.Item.Rect.Size.ToVector2() * scale;
if (dockingPort.IsHorizontal)
{
size.X = 0.0f;
}
else
{
size.Y = 0.0f;
}
GUI.DrawLine(spriteBatch, center + offset - size / 2, center + offset + size / 2, Color.LightGreen, width: (int)(zoom));
}
}
private void UpdateDisruptions(Vector2 pingSource, float worldPingRadius, float worldPrevPingRadius)
{
float worldPingRadiusSqr = worldPingRadius * worldPingRadius;
float worldPrevPingRadiusSqr = worldPrevPingRadius * worldPrevPingRadius;
disruptedDirections.Clear();
if (Level.Loaded == null) { return; }
foreach (LevelObject levelObject in Level.Loaded.LevelObjectManager.GetAllObjects(pingSource, range * pingState))
{
if (levelObject.ActivePrefab?.SonarDisruption <= 0.0f) { continue; }
float disruptionStrength = levelObject.ActivePrefab.SonarDisruption;
Vector2 disruptionPos = new Vector2(levelObject.Position.X, levelObject.Position.Y);
float disruptionDist = Vector2.Distance(pingSource, disruptionPos);
disruptedDirections.Add(new Pair<Vector2, float>((disruptionPos - pingSource) / disruptionDist, disruptionStrength));
if (disruptionDist > worldPrevPingRadius && disruptionDist <= worldPingRadius)
{
for (int i = 0; i < disruptionStrength * Level.GridCellSize * 0.02f; i++)
{
var blip = new SonarBlip(disruptionPos + Rand.Vector(Rand.Range(0.0f, Level.GridCellSize * 4 * disruptionStrength)), MathHelper.Lerp(1.0f, 1.5f, disruptionStrength), Rand.Range(1.0f, 2.0f + disruptionStrength));
sonarBlips.Add(blip);
}
}
}
}
private void Ping(Vector2 pingSource, Vector2 transducerPos, float pingRadius, float prevPingRadius, float displayScale, float range, bool passive,
float pingStrength = 1.0f)
{
float prevPingRadiusSqr = prevPingRadius * prevPingRadius;
float pingRadiusSqr = pingRadius * pingRadius;
//inside a hull -> only show the edges of the hull
if (item.CurrentHull != null && DetectSubmarineWalls)
{
CreateBlipsForLine(
new Vector2(item.CurrentHull.WorldRect.X, item.CurrentHull.WorldRect.Y),
new Vector2(item.CurrentHull.WorldRect.Right, item.CurrentHull.WorldRect.Y),
transducerPos,
pingRadius, prevPingRadius, 50.0f, 5.0f, range, 2.0f, passive);
CreateBlipsForLine(
new Vector2(item.CurrentHull.WorldRect.X, item.CurrentHull.WorldRect.Y - item.CurrentHull.Rect.Height),
new Vector2(item.CurrentHull.WorldRect.Right, item.CurrentHull.WorldRect.Y - item.CurrentHull.Rect.Height),
transducerPos,
pingRadius, prevPingRadius, 50.0f, 5.0f, range, 2.0f, passive);
CreateBlipsForLine(
new Vector2(item.CurrentHull.WorldRect.X, item.CurrentHull.WorldRect.Y),
new Vector2(item.CurrentHull.WorldRect.X, item.CurrentHull.WorldRect.Y - item.CurrentHull.Rect.Height),
transducerPos,
pingRadius, prevPingRadius, 50.0f, 5.0f, range, 2.0f, passive);
CreateBlipsForLine(
new Vector2(item.CurrentHull.WorldRect.Right, item.CurrentHull.WorldRect.Y),
new Vector2(item.CurrentHull.WorldRect.Right, item.CurrentHull.WorldRect.Y - item.CurrentHull.Rect.Height),
transducerPos,
pingRadius, prevPingRadius, 50.0f, 5.0f, range, 2.0f, passive);
return;
}
foreach (Submarine submarine in Submarine.Loaded)
{
if (submarine.HullVertices == null) continue;
if (!DetectSubmarineWalls)
{
if (UseTransducers)
{
if (connectedTransducers.Any(t => submarine == t.Transducer.Item.Submarine ||
submarine.DockedTo.Contains(t.Transducer.Item.Submarine))) continue;
}
else
{
if (item.Submarine == submarine) continue;
if (item.Submarine != null && item.Submarine.DockedTo.Contains(submarine)) continue;
}
}
for (int i = 0; i < submarine.HullVertices.Count; i++)
{
Vector2 start = ConvertUnits.ToDisplayUnits(submarine.HullVertices[i]);
Vector2 end = ConvertUnits.ToDisplayUnits(submarine.HullVertices[(i + 1) % submarine.HullVertices.Count]);
if (item.Submarine == submarine)
{
start += Rand.Vector(500.0f);
end += Rand.Vector(500.0f);
}
CreateBlipsForLine(
start + submarine.WorldPosition,
end + submarine.WorldPosition,
transducerPos,
pingRadius, prevPingRadius,
200.0f, 2.0f, range, 1.0f, passive);
}
}
if (Level.Loaded != null && (item.CurrentHull == null || !DetectSubmarineWalls))
{
if (Level.Loaded.Size.Y - pingSource.Y < range)
{
CreateBlipsForLine(
new Vector2(pingSource.X - range, Level.Loaded.Size.Y),
new Vector2(pingSource.X + range, Level.Loaded.Size.Y),
transducerPos,
pingRadius, prevPingRadius,
250.0f, 150.0f, range, pingStrength, passive);
}
List<Voronoi2.VoronoiCell> cells = Level.Loaded.GetCells(pingSource, 7);
foreach (Voronoi2.VoronoiCell cell in cells)
{
foreach (Voronoi2.GraphEdge edge in cell.Edges)
{
if (!edge.IsSolid) continue;
float cellDot = Vector2.Dot(cell.Center - pingSource, (edge.Center + cell.Translation) - cell.Center);
if (cellDot > 0) continue;
float facingDot = Vector2.Dot(
Vector2.Normalize(edge.Point1 - edge.Point2),
Vector2.Normalize(cell.Center - pingSource));
CreateBlipsForLine(
edge.Point1 + cell.Translation,
edge.Point2 + cell.Translation,
transducerPos,
pingRadius, prevPingRadius,
350.0f, 3.0f * (Math.Abs(facingDot) + 1.0f), range, pingStrength, passive);
}
}
foreach (RuinGeneration.Ruin ruin in Level.Loaded.Ruins)
{
if (!MathUtils.CircleIntersectsRectangle(pingSource, range, ruin.Area)) continue;
foreach (var ruinShape in ruin.RuinShapes)
{
foreach (RuinGeneration.Line wall in ruinShape.Walls)
{
float cellDot = Vector2.Dot(
Vector2.Normalize(ruinShape.Center - pingSource),
Vector2.Normalize((wall.A + wall.B) / 2.0f - ruinShape.Center));
if (cellDot > 0) continue;
CreateBlipsForLine(
wall.A, wall.B,
transducerPos,
pingRadius, prevPingRadius,
100.0f, 1000.0f, range, pingStrength, passive);
}
}
}
}
foreach (Item item in Item.ItemList)
{
if (item.CurrentHull == null && item.Prefab.SonarSize > 0.0f)
{
float pointDist = ((item.WorldPosition - pingSource) * displayScale).LengthSquared();
if (pointDist > prevPingRadiusSqr && pointDist < pingRadiusSqr)
{
var blip = new SonarBlip(
item.WorldPosition + Rand.Vector(item.Prefab.SonarSize),
MathHelper.Clamp(item.Prefab.SonarSize, 0.1f, pingStrength),
MathHelper.Clamp(item.Prefab.SonarSize * 0.1f, 0.1f, 10.0f));
if (!passive && !CheckBlipVisibility(blip, transducerPos)) continue;
sonarBlips.Add(blip);
}
}
}
foreach (Character c in Character.CharacterList)
{
if (c.AnimController.CurrentHull != null || !c.Enabled) continue;
if (DetectSubmarineWalls && c.AnimController.CurrentHull == null && item.CurrentHull != null) continue;
foreach (Limb limb in c.AnimController.Limbs)
{
float pointDist = ((limb.WorldPosition - pingSource) * displayScale).LengthSquared();
if (limb.SimPosition == Vector2.Zero || pointDist > DisplayRadius * DisplayRadius) continue;
if (pointDist > prevPingRadiusSqr && pointDist < pingRadiusSqr)
{
var blip = new SonarBlip(
limb.WorldPosition + Rand.Vector(limb.Mass / 10.0f),
MathHelper.Clamp(limb.Mass, 0.1f, pingStrength),
MathHelper.Clamp(limb.Mass * 0.1f, 0.1f, 2.0f));
if (!passive && !CheckBlipVisibility(blip, transducerPos)) continue;
sonarBlips.Add(blip);
}
}
}
}
private void CreateBlipsForLine(Vector2 point1, Vector2 point2, Vector2 transducerPos, float pingRadius, float prevPingRadius,
float lineStep, float zStep, float range, float pingStrength, bool passive)
{
lineStep /= zoom;
zStep /= zoom;
range *= displayScale;
float length = (point1 - point2).Length();
Vector2 lineDir = (point2 - point1) / length;
for (float x = 0; x < length; x += lineStep * Rand.Range(0.8f, 1.2f))
{
Vector2 point = point1 + lineDir * x;
//point += cell.Translation;
Vector2 pointDiff = point - transducerPos;
float pointDist = pointDiff.Length();
float displayPointDist = pointDist * displayScale;
if (displayPointDist > DisplayRadius) continue;
if (displayPointDist < prevPingRadius || displayPointDist > pingRadius) continue;
bool disrupted = false;
foreach (Pair<Vector2, float> disruptDir in disruptedDirections)
{
float dot = Vector2.Dot(pointDiff / pointDist, disruptDir.First);
if (dot > 1.0f - disruptDir.Second)
{
disrupted = true;
break;
}
}
if (disrupted) continue;
float alpha = pingStrength * Rand.Range(1.5f, 2.0f);
for (float z = 0; z < DisplayRadius - displayPointDist; z += zStep)
{
Vector2 pos = point + Rand.Vector(150.0f / zoom) + Vector2.Normalize(point - item.WorldPosition) * z / displayScale;
float fadeTimer = alpha * (1.0f - displayPointDist / range);
int minDist = (int)(200 / zoom);
sonarBlips.RemoveAll(b => b.FadeTimer < fadeTimer && Math.Abs(pos.X - b.Position.X) < minDist && Math.Abs(pos.Y - b.Position.Y) < minDist);
var blip = new SonarBlip(pos, fadeTimer, 1.0f + ((displayPointDist + z) / DisplayRadius));
if (!passive && !CheckBlipVisibility(blip, transducerPos)) continue;
sonarBlips.Add(blip);
zStep += 0.5f / zoom;
if (z == 0)
{
alpha = Math.Min(alpha - 0.5f, 1.5f);
}
else
{
alpha -= 0.1f;
}
if (alpha < 0) break;
}
}
}
private bool CheckBlipVisibility(SonarBlip blip, Vector2 transducerPos)
{
Vector2 pos = (blip.Position - transducerPos) * displayScale * zoom;
pos.Y = -pos.Y;
float posDistSqr = pos.LengthSquared();
if (posDistSqr > DisplayRadius * DisplayRadius)
{
blip.FadeTimer = 0.0f;
return false;
}
Vector2 dir = pos / (float)Math.Sqrt(posDistSqr);
if (isLastPingDirectional)
{
if (Vector2.Dot(lastPingDirection, dir) < DirectionalPingDotProduct)
{
blip.FadeTimer = 0.0f;
return false;
}
}
return true;
}
private void DrawBlip(SpriteBatch spriteBatch, SonarBlip blip, Vector2 transducerPos, Vector2 center, float strength)
{
strength = MathHelper.Clamp(strength, 0.0f, 1.0f);
float distort = 1.0f - item.Condition / 100.0f;
Vector2 pos = (blip.Position - transducerPos) * displayScale * zoom;
pos.Y = -pos.Y;
if (Rand.Range(0.5f, 2.0f) < distort) pos.X = -pos.X;
if (Rand.Range(0.5f, 2.0f) < distort) pos.Y = -pos.Y;
float posDistSqr = pos.LengthSquared();
if (posDistSqr > DisplayRadius * DisplayRadius)
{
blip.FadeTimer = 0.0f;
return;
}
if (sonarBlip == null)
{
GUI.DrawRectangle(spriteBatch, center + pos, Vector2.One * 4, Color.Magenta, true);
return;
}
Vector2 dir = pos / (float)Math.Sqrt(posDistSqr);
Vector2 normal = new Vector2(dir.Y, -dir.X);
float scale = (strength + 3.0f) * blip.Scale * zoomSqrt;
Color color = ToolBox.GradientLerp(strength, blipColorGradient);
sonarBlip.Draw(spriteBatch, center + pos, color, sonarBlip.Origin, blip.Rotation ?? MathUtils.VectorToAngle(pos),
blip.Size * scale * 0.04f, SpriteEffects.None, 0);
pos += Rand.Range(0.0f, 1.0f) * dir + Rand.Range(-scale, scale) * normal;
sonarBlip.Draw(spriteBatch, center + pos, color * 0.5f, sonarBlip.Origin, 0, scale * 0.08f, SpriteEffects.None, 0);
}
private void DrawMarker(SpriteBatch spriteBatch, string label, Vector2 position, float scale, Vector2 center, float radius)
{
float dist = position.Length();
position *= zoom;
position *= scale;
position.Y = -position.Y;
float textAlpha = MathHelper.Clamp(1.5f - dist / 50000.0f, 0.5f, 1.0f);
Vector2 dir = Vector2.Normalize(position);
Vector2 markerPos = (dist * zoom * scale > radius) ? dir * radius : position;
markerPos += center;
markerPos.X = (int)markerPos.X;
markerPos.Y = (int)markerPos.Y;
float alpha = 1.0f;
if (dist * scale < radius)
{
float normalizedDist = dist * scale / radius;
alpha = Math.Max(normalizedDist - 0.4f, 0.0f);
float mouseDist = Vector2.Distance(PlayerInput.MousePosition, markerPos);
float hoverThreshold = 150.0f;
if (mouseDist < hoverThreshold)
{
alpha += (hoverThreshold - mouseDist) / hoverThreshold;
}
}
if (!GuiFrame.Children.First().Rect.Contains(markerPos))
{
if (MathUtils.GetLineRectangleIntersection(center, markerPos, GuiFrame.Children.First().Rect, out Vector2 intersection))
{
markerPos = intersection;
}
}
GUI.DrawRectangle(spriteBatch, new Rectangle((int)markerPos.X - 3, (int)markerPos.Y - 3, 6, 6), Color.Red, thickness: 2);
if (alpha <= 0.0f) { return; }
string wrappedLabel = ToolBox.WrapText(label, 150, GUI.SmallFont);
wrappedLabel += "\n" + ((int)(dist * Physics.DisplayToRealWorldRatio) + " m");
Vector2 labelPos = markerPos;
Vector2 textSize = GUI.SmallFont.MeasureString(wrappedLabel);
//flip the text to left side when the marker is on the left side or goes outside the right edge of the interface
if (dir.X < 0.0f || labelPos.X + textSize.X + 10 > GuiFrame.Rect.X) labelPos.X -= textSize.X + 10;
GUI.DrawString(spriteBatch,
new Vector2(labelPos.X + 10, labelPos.Y),
wrappedLabel,
Color.LightBlue * textAlpha * alpha, Color.Black * textAlpha * 0.8f * alpha,
2, GUI.SmallFont);
}
public void ClientWrite(Lidgren.Network.NetBuffer msg, object[] extraData = null)
{
msg.Write(IsActive);
if (IsActive)
{
msg.WriteRangedSingle(zoom, MinZoom, MaxZoom, 8);
msg.Write(useDirectionalPing);
if (useDirectionalPing)
{
msg.WriteRangedSingle(directionalSlider.BarScroll, 0.0f, 1.0f, 8);
}
}
}
public void ClientRead(ServerNetObject type, Lidgren.Network.NetBuffer msg, float sendingTime)
{
long msgStartPos = msg.Position;
bool isActive = msg.ReadBoolean();
float zoomT = 1.0f;
bool directionalPing = useDirectionalPing;
float directionT = 0.0f;
if (isActive)
{
zoomT = msg.ReadRangedSingle(0.0f, 1.0f, 8);
directionalPing = msg.ReadBoolean();
if (directionalPing)
{
directionT = msg.ReadRangedSingle(0.0f, 1.0f, 8);
}
}
if (correctionTimer > 0.0f)
{
int msgLength = (int)(msg.Position - msgStartPos);
msg.Position = msgStartPos;
StartDelayedCorrection(type, msg.ExtractBits(msgLength), sendingTime);
return;
}
IsActive = isActive;
if (isActive)
{
activeTickBox.Selected = true;
zoomSlider.BarScroll = zoomT;
zoom = MathHelper.Lerp(MinZoom, MaxZoom, zoomT);
if (directionalPing)
{
directionalSlider.BarScroll = directionT;
float pingAngle = MathHelper.Lerp(0.0f, MathHelper.TwoPi, directionalSlider.BarScroll);
pingDirection = new Vector2((float)Math.Cos(pingAngle), (float)Math.Sin(pingAngle));
}
useDirectionalPing = directionalTickBox.Selected = directionalPing;
}
else
{
passiveTickBox.Selected = true;
}
}
}
class SonarBlip
{
public float FadeTimer;
public Vector2 Position;
public float Scale;
public Vector2 Velocity;
public float? Rotation;
public Vector2 Size;
public SonarBlip(Vector2 pos, float fadeTimer, float scale)
{
Position = pos;
FadeTimer = Math.Max(fadeTimer, 0.0f);
Scale = scale;
Size = new Vector2(0.5f, 1.0f);
}
}
}