forked from RemoteTechnologiesGroup/RemoteTech
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNetworkFeedback.cs
More file actions
168 lines (143 loc) · 7.68 KB
/
Copy pathNetworkFeedback.cs
File metadata and controls
168 lines (143 loc) · 7.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
using System;
using System.Collections.Generic;
using RemoteTech.RangeModel;
namespace RemoteTech
{
public class NetworkFeedback
{
/// <summary>Returns the position of a target identified only by its Guid</summary>
/// <returns>An absolute world coordinate position.</returns>
/// <param name="target">The item whose position is desired. May be either a satellite
/// or a celestial body</param>
/// Throws System.ArgumentException if target or network does not exist.
public static Vector3d targetPosition(Guid target) {
if (RTCore.Instance != null && RTCore.Instance.Network != null &&
target != Guid.Empty) {
ISatellite targetSat = RTCore.Instance.Network[target];
if (targetSat != null) {
return targetSat.Position;
}
try {
CelestialBody targetPlanet = RTCore.Instance.Network.Planets[target];
return targetPlanet.position;
} catch (KeyNotFoundException) {}
}
throw new System.ArgumentException("No such Guid found", "target");
}
/// <summary>Returns the SoI of a target identified only by its Guid</summary>
/// <returns>If target refers to a celestial body, returns that body. If target refers
/// to an ISatellite, returns the body whose SoI currently contains the ISatellite.</returns>
/// <param name="target">The item whose position is desired. May be either a satellite
/// or a celestial body.</param>
/// Throws System.ArgumentException if target or network does not exist.
public static CelestialBody targetBody(Guid target) {
if (RTCore.Instance != null && RTCore.Instance.Network != null &&
target != Guid.Empty) {
ISatellite targetSat = RTCore.Instance.Network[target];
if (targetSat != null) {
return targetSat.Body;
}
try {
CelestialBody targetPlanet = RTCore.Instance.Network.Planets[target];
return targetPlanet;
} catch (KeyNotFoundException) {}
}
throw new System.ArgumentException("No such Guid found", "target");
}
/// <summary>Counts the number of ISatellites that are in the antenna cone and in range.</summary>
/// <returns>The number of reachable satellites.</returns>
/// <remarks>If antenna does not have a cone, returns 0.</remarks>
/// <param name="antenna">The antenna whose cone must be tested.</param>
/// <param name="target">The object the cone is pointed at.</param>
public static int countInCone(IAntenna antenna, Guid target) {
if (antenna.Dish <= 0.0 || antenna.CosAngle >= 1.0) {
return 0;
}
try {
Vector3d myPos = RTCore.Instance.Network[antenna.Guid].Position;
Vector3d targetDir = (targetPosition(target) - myPos).normalized;
CelestialBody myBody = targetBody(target);
int count = 0;
foreach (ISatellite sat in RTCore.Instance.Satellites) {
Vector3d satDir = (sat.Position - myPos).normalized;
if (Vector3d.Distance(myPos, sat.Position) <= antenna.Dish // in range
&& Vector3d.Dot(targetDir, satDir) >= antenna.CosAngle // in cone
&& sat.Body == myBody) // in target SoI... remove later
count++;
}
return count;
} catch (ArgumentException) {
return 0;
} catch (NullReferenceException) {
return 0;
}
}
/// <summary>Tests whether an antenna can connect to a target</summary>
/// <returns>The range to the target, or a diagnostic error message. Returns the
/// empty string if target is invalid.</returns>
/// <param name="antenna">The antenna attempting to make a connection.</param>
/// <param name="target">The Guid to which it is trying to connect.</param>
public static KeyValuePair<string, UnityEngine.Color> tryConnection(IAntenna antenna, Guid target) {
String status = "ok";
// What kind of target?
if (RTCore.Instance != null && RTCore.Instance.Network != null &&
target != Guid.Empty && target != NetworkManager.ActiveVesselGuid) {
bool warning = false, error = false;
ISatellite mySat = RTCore.Instance.Network[antenna.Guid];
if (mySat == null)
return new KeyValuePair<string, UnityEngine.Color>("", UnityEngine.Color.white);
List<string> conditions = new List<string>();
// Most probably a satellite
ISatellite targetSat = RTCore.Instance.Network[target];
if (targetSat != null) {
if (!RangeModelExtensions.HasLineOfSightWith(mySat, targetSat)) {
status = "No line of sight";
error = true;
}
double dist = RangeModelExtensions.DistanceTo(mySat, targetSat);
// Only standard model supported for now, RangeModel isn't designed for this problem
double maxDist = Math.Max(antenna.Omni, antenna.Dish);
conditions.Add("Current distance:" + RTUtil.FormatSI(dist, "m"));
conditions.Add("Antenna range:" + RTUtil.FormatSI(maxDist, "m"));
if (dist > maxDist) {
status = "Target not in range";
error = true;
}
}
try {
CelestialBody targetPlanet = RTCore.Instance.Network.Planets[target];
double dist = Vector3d.Distance(mySat.Position, targetPlanet.position);
double maxDist = Math.Max(antenna.Omni, antenna.Dish);
double spread = 2.0 * dist * Math.Sqrt(1-antenna.CosAngle*antenna.CosAngle);
int numTargets = countInCone(antenna, target);
if (spread < 2.0 * targetPlanet.Radius) {
// WHAT does this info?
// conditions.Add("Small Cone");
warning = true;
}
conditions.Add("Current distance:"+RTUtil.FormatSI(dist, "m"));
conditions.Add("Antenna range:" + RTUtil.FormatSI(maxDist, "m"));
if (dist <= maxDist) {
conditions.Add(String.Format("Info:{0} beam covers {1} targets)",
RTUtil.FormatSI(spread, "m"),
numTargets
));
} else {
status = "Target not in range";
error = true;
}
if (numTargets <= 0) {
warning = true;
}
} catch (KeyNotFoundException) {}
conditions.Add("Status:" + status);
return new KeyValuePair<string, UnityEngine.Color>(
String.Join("; ", conditions.ToArray()),
error ? UnityEngine.Color.red : (warning ? UnityEngine.Color.yellow : UnityEngine.Color.white)
);
}
// Default behavior
return new KeyValuePair<string, UnityEngine.Color>("", UnityEngine.Color.white);
}
}
}