Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // cpa_time(): compute the time of CPA for two tracks
- // Input: two tracks Tr1 and Tr2
- // Return: the time at which the two tracks are closest
- public static double cpa_time(Vector3D Tr1_p, Vector3D Tr1_v, Vector3D Tr2_p, Vector3D Tr2_v)
- {
- Vector3D dv = Tr1_v - Tr2_v;
- double dv2 = Vector3D.Dot(dv, dv);
- if (dv2 < 0.00000001) // the tracks are almost parallel
- return 0.0; // any time is ok. Use time 0.
- Vector3D w0 = Tr1_p - Tr2_p;
- double cpatime = -Vector3D.Dot(w0, dv) / dv2;
- return cpatime; // time of CPA
- }
- public class Target
- {
- static public int staleInterval = 5;//the tick limit before we consider a target entry expired. must be larger than our update interval
- public int lastUpd = -1;
- public bool isStale() { return tick - lastUpd > staleInterval; }
- public bool isProjectile = false;
- public List<WeaponFirmware> turretsTargeting = new List<WeaponFirmware>();
- public List<WeaponFirmware> turretsAbleToTarget = new List<WeaponFirmware>();
- public string name;
- public long eid=-1;//torpedoes get a dummy number
- static long torpidx = 1000;
- public Vector3D vel = Vector3D.Zero;
- public Vector3D pos0 = Vector3D.Zero;
- public Vector3D pos1 = Vector3D.Zero;
- public Vector3D pos2 = Vector3D.Zero;
- public BoundingBoxD bbox = BoundingBoxD.CreateInvalid();
- public Target(TorpedoData d) { isProjectile = true; update(d); }
- public Target(MyDetectedEntityInfo i) { isProjectile = false; update(i); }
- public void update(MyDetectedEntityInfo i, WeaponFirmware t =null)
- {
- name = i.Name;
- if (i.Type != MyDetectedEntityType.Missile)
- {
- isProjectile = false;
- eid = i.EntityId;
- bbox = i.BoundingBox;
- pos2 = pos1;
- pos1 = pos0;
- pos0 = i.Position;
- vel = i.Velocity;
- lastUpd = tick;
- if (!i.Name.Equals(name)) name = i.Name;
- //if(t != null && !turretsTargeting.Contains(t)) turretsTargeting.Add(t);
- }
- }
- public void update(TorpedoData d)
- {
- if (eid == -1) eid = torpidx++;
- name = "Torp";
- pos2 = pos1;
- pos1 = pos0;
- pos0 = d.positionApx;
- /*if (pos0 != Vector3D.Zero && pos1 != Vector3D.Zero && pos2 != Vector3D.Zero)
- {
- vel.X = CalculateVelocity(pos2.X, pos1.X, pos0.X);
- vel.Y = CalculateVelocity(pos2.X, pos1.Y, pos0.X);
- vel.Z = CalculateVelocity(pos2.X, pos1.Z, pos0.X);
- vel *= 60;
- }*/
- //dunno if velocity matter. I suppose it could be used to identify torpedo type, but who the fuck uses ramshackles anyway eh
- turretsTargeting = d.turretsTargeting;
- lastUpd = tick;
- }
- public void delock()
- {
- foreach(var tt in turretsTargeting)
- {
- //WeaponFirmware v = null;
- //managedWeapons.TryGetValue(tt, out v);
- if (tt.assignedTarget == this) tt.assignTarget(null);// tt.assignedTarget = null;
- }
- turretsTargeting.Clear();
- //we can also do any postmortem here, like announcing we killed some shit and it was *this* close to fucking our shit up
- }
- public double td0;
- public double td1;
- }
- public class TorpedoData
- {
- public List<WeaponFirmware> turretsTargeting = new List<WeaponFirmware>();
- public Vector3D positionApx;
- public bool updated = false;
- public static double limitsqr = 6*6;
- public bool closeEnough(Vector3D p)
- {
- return (positionApx - p).LengthSquared() < limitsqr;
- }
- }
- List<TorpedoData> calculateTorpedoes(List<WeaponFirmware> missileLockedGuns)
- {
- List<TorpedoData> torpedoes = new List<TorpedoData>();
- List<MyTuple<Vector3D, Vector3D>> scopes = new List<MyTuple<Vector3D, Vector3D>>();
- foreach (var b in missileLockedGuns) scopes.Add(modAPIWeaponCore.GetWeaponScope(b.b, 0));
- for (int x = 0; x < scopes.Count; x++)
- {
- var xg = missileLockedGuns[x];
- var xs = scopes[x];
- for (int y = 0; y < scopes.Count; y++)
- {
- if (y == x) continue;
- var yg = missileLockedGuns[y];
- var ys = scopes[y];
- double cpa_t = cpa_time(xs.Item1, xs.Item2 * xg.settings.AmmoVelocity, ys.Item1, ys.Item2 * yg.settings.AmmoVelocity);
- if(cpa_t > 0 && cpa_t < 1.5)//all PDCs should hit maxtraj in 1s or less
- {
- Vector3D xp = xs.Item1 + (xs.Item2 * xg.settings.AmmoVelocity * cpa_t);
- Vector3D yp = ys.Item1 + (ys.Item2 * yg.settings.AmmoVelocity * cpa_t);
- double dist = (xp - yp).LengthSquared();
- if(dist < TorpedoData.limitsqr)//torp 1500m/s so 25m per tick, oof... lets say <30m from another trajectory. update: live test had it 6m at worst, it seems.
- {
- Vector3D p = (xp + yp) * 0.5;
- TorpedoData t = null;
- foreach(var trp in torpedoes)
- {
- if (trp.closeEnough(p))
- {
- t = trp;
- break;
- }
- }
- if (t == null) t = new TorpedoData();
- t.positionApx = p;
- if (!t.turretsTargeting.Contains(xg)) t.turretsTargeting.Add(xg);
- if (!t.turretsTargeting.Contains(yg)) t.turretsTargeting.Add(yg);
- }
- }
- }
- }
- return torpedoes;
- }
- public void updateTargetingData()
- {
- torpedolocked.Clear();
- foreach (var kvp in targetList) kvp.Value.turretsTargeting.Clear();
- foreach (var kvp in managedWeapons)
- {
- var m = kvp.Value;
- m.update();
- if (m.lockTicks > 0)
- {
- if (m.lastInfo.Type == MyDetectedEntityType.Missile) torpedolocked.Add(m);
- else
- {
- Target v = null;
- targetList.TryGetValue(m.lastInfo.EntityId, out v);
- if (v != null) v.update(m.lastInfo);
- else
- {
- //we aren't gonna add for now - we only want the rapid updates for things that would already be in the global threat list.
- //v = new Target(m.lastInfo);
- //targetList[m.lastInfo.EntityId] = new Target(m.lastInfo);
- }
- //v.turretsTargeting.Add(m);
- }
- }
- /*else if (m.assignedTarget != null)
- {
- m.assignedTarget.turretsTargeting.Add(m);
- }*/
- }
- List<TorpedoData> td = calculateTorpedoes(torpedolocked);
- torpCount = td.Count;
- dbg += "td:"+td.Count + "\n";
- foreach (var kvp in targetList)
- {
- var l = kvp.Value;
- if (l.isProjectile)
- {
- foreach (var t in td)
- {
- if (t.closeEnough(l.pos0))
- {
- t.updated = true;
- l.update(t);
- foreach(var w in t.turretsTargeting)
- {
- w.assignTarget(l);
- }
- break;
- }
- }
- }
- }
- foreach (var t in td)
- {
- if (!t.updated)
- {
- var v = new Target(t);
- targetList[v.eid] = v;
- foreach (var w in t.turretsTargeting)
- {
- w.assignTarget(v);
- }
- }
- }
- List<long> del = new List<long>();
- foreach (var kvp in targetList)
- {
- if (kvp.Value.isStale())
- {
- kvp.Value.delock();
- del.Add(kvp.Key);
- }
- }
- foreach (var d in del)targetList.Remove(d);
- int ntrvl = 4;
- if (lockCount > 0 || torpCount > 0) ntrvl = 1;
- dbg += "ntrvl=" + ntrvl+"\n";
- if (tickcheck(ref threatChk, ntrvl))
- {
- threats.Clear();
- modAPIWeaponCore.GetSortedThreats(gProgram.Me, threats);
- dbg += "tl:" + threats.Count + "\n";
- foreach (var kvp in threats)
- {
- if (kvp.Key.Relationship == MyRelationsBetweenPlayerAndBlock.Enemies)
- {
- Target v = null;
- targetList.TryGetValue(kvp.Key.EntityId, out v);
- if (v != null) v.update(kvp.Key);
- else targetList[kvp.Key.EntityId] = new Target(kvp.Key);
- }
- }
- threatCount = threats.Count;
- }
- //dbg += targetList.Count + "\n";
- }
Add Comment
Please, Sign In to add comment