From 350595a49df0aeaab8d681e23f7b8cb40f349359 Mon Sep 17 00:00:00 2001 From: l0k1 <1434407+l0k1@users.noreply.github.com> Date: Fri, 21 Aug 2026 22:32:59 +0000 Subject: [PATCH] Auto-Update shared Files asset-fire-control 1.0.3->1.0.4 (BUK-M2/Nasal/fire-control.nas) asset-fire-control 1.0.3->1.0.4 (MIM-104D/Nasal/fire-control.nas) asset-fire-control 1.0.3->1.0.4 (S-75/Nasal/fire-control.nas) asset-fire-control 1.0.3->1.0.4 (SA-3/Nasal/fire-control.nas) asset-fire-control 1.0.3->1.0.4 (SA-6/Nasal/fire-control.nas) datalink 1.1.1->1.1.2 (BUK-M2/Nasal/datalink.nas) datalink 1.1.1->1.1.2 (fleet/Nasal/datalink.nas) datalink 1.1.1->1.1.2 (MIM-104D/Nasal/datalink.nas) datalink 1.1.1->1.1.2 (missile-frigate/Nasal/datalink.nas) datalink 1.1.1->1.1.2 (S-200/Nasal/datalink.nas) datalink 1.1.1->1.1.2 (S-300/Nasal/datalink.nas) datalink 1.1.1->1.1.2 (S-75/Nasal/datalink.nas) datalink 1.1.1->1.1.2 (SA-3/Nasal/datalink.nas) datalink 1.1.1->1.1.2 (SA-6/Nasal/datalink.nas) datalink 1.1.1->1.1.2 (ZSU-23/Nasal/datalink.nas) damage 1.4.13->1.4.14 (BUK-M2/Nasal/damage.nas) damage 1.4.13->1.4.14 (depot/Nasal/damage.nas) damage 1.4.13->1.4.14 (fleet/Nasal/damage.nas) damage 1.4.13->1.4.14 (Frigate/Nasal/damage.nas) damage 1.4.13->1.4.14 (gci-radar/Nasal/damage.nas) damage 1.4.13->1.4.14 (groundtarget/Nasal/damage.nas) damage 1.4.13->1.4.14 (MIM-104D/Nasal/damage.nas) damage 1.4.13->1.4.14 (missile-frigate/Nasal/damage.nas) damage 1.4.13->1.4.14 (S-200/Nasal/damage.nas) damage 1.4.13->1.4.14 (S-300/Nasal/damage.nas) damage 1.4.13->1.4.14 (S-75/Nasal/damage.nas) damage 1.4.13->1.4.14 (SA-3/Nasal/damage.nas) damage 1.4.13->1.4.14 (SA-6/Nasal/damage.nas) damage 1.4.13->1.4.14 (ZSU-23/Nasal/damage.nas) missile-code 1.2.0->1.2.4 (BUK-M2/Nasal/guided-missiles.nas) missile-code 1.2.0->1.2.4 (MIM-104D/Nasal/guided-missiles.nas) missile-code 1.2.0->1.2.4 (S-75/Nasal/guided-missiles.nas) missile-code 1.2.0->1.2.4 (SA-3/Nasal/guided-missiles.nas) missile-code 1.2.0->1.2.4 (SA-6/Nasal/guided-missiles.nas) --- BUK-M2/Nasal/damage.nas | 32 +- BUK-M2/Nasal/datalink.nas | 5 +- BUK-M2/Nasal/fire-control.nas | 2 +- BUK-M2/Nasal/guided-missiles.nas | 39 +- Frigate/Nasal/damage.nas | 32 +- MIM-104D/Nasal/damage.nas | 32 +- MIM-104D/Nasal/datalink.nas | 5 +- MIM-104D/Nasal/fire-control.nas | 2 +- MIM-104D/Nasal/guided-missiles.nas | 39 +- S-200/Nasal/damage.nas | 32 +- S-200/Nasal/datalink.nas | 5 +- S-300/Nasal/damage.nas | 32 +- S-300/Nasal/datalink.nas | 5 +- S-75/Nasal/damage.nas | 32 +- S-75/Nasal/datalink.nas | 5 +- S-75/Nasal/fire-control.nas | 2 +- S-75/Nasal/guided-missiles.nas | 39 +- SA-3/Nasal/damage.nas | 32 +- SA-3/Nasal/datalink.nas | 5 +- SA-3/Nasal/fire-control.nas | 2 +- SA-3/Nasal/guided-missiles.nas | 39 +- SA-6/Nasal/damage.nas | 32 +- SA-6/Nasal/datalink.nas | 5 +- SA-6/Nasal/fire-control.nas | 2 +- SA-6/Nasal/guided-missiles.nas | 39 +- ZSU-23/Nasal/damage.nas | 32 +- ZSU-23/Nasal/datalink.nas | 5 +- depot/Nasal/damage.nas | 32 +- fleet/Nasal/damage.nas | 32 +- fleet/Nasal/datalink.nas | 5 +- gci-radar/Nasal/damage.nas | 32 +- groundtarget/Nasal/damage.nas | 32 +- missile-frigate/Nasal/damage.nas | 32 +- missile-frigate/Nasal/datalink.nas | 5 +- oprf-versions.json | 692 +++++++++++++++-------------- 35 files changed, 899 insertions(+), 496 deletions(-) diff --git a/BUK-M2/Nasal/damage.nas b/BUK-M2/Nasal/damage.nas index b0b9c45..31317dc 100644 --- a/BUK-M2/Nasal/damage.nas +++ b/BUK-M2/Nasal/damage.nas @@ -312,7 +312,7 @@ var DamageRecipient = if(getprop("payload/armament/msg") == 0 and getprop("payload/armament/spectator") != 1 and notification.RemoteCallsign != notification.Callsign) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -474,7 +474,7 @@ var DamageRecipient = # debug.dump(notification); # # - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { damageLog.push("Ignored hit by "~notification.Callsign); return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -1387,6 +1387,30 @@ var getCallsign = func (callsign) { return node; } +# 'ignored' player test +# In FG 2024, multiplayer.ignore hash was removed in favour of property controls/invisible. +# These methods test both for compatibility. + +var ignored_struct = {}; + +var isIgnoredNode = func(node) { + if (contains(multiplayer, "ignore")) { + var callsign = node.getValue("callsign"); + return callsign != nil and multiplayer.ignore[callsign]; + } else { + node = node.getNode("controls/invisible"); + return node != nil and node.getBoolValue(); + } +} + +var isIgnoredCallsign = func(callsign) { + if (contains(multiplayer, "ignore")) { + return multiplayer.ignore[callsign]; + } else { + return contains(ignored_struct, preAlphaKey ~ callsign); + } +} + var MAW_elapsed = 0; var radarSpikes = {}; @@ -1397,6 +1421,7 @@ foreach (key ; keys(radar_signatures)) { var processCallsigns = func () { callsign_struct = {}; + ignored_struct = {}; var players = props.globals.getNode("ai/models").getChildren(); var myCallsign = getprop("sim/multiplay/callsign"); myCallsign = size(myCallsign) < 8 ? myCallsign : left(myCallsign,7); @@ -1405,7 +1430,8 @@ var processCallsigns = func () { foreach (var player; players) { if(player.getChild("valid") != nil and player.getChild("valid").getValue() == 1 and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { var callsign = player.getChild("callsign").getValue(); - if(multiplayer.ignore[callsign] == 1) { + if(isIgnoredNode(player)) { + ignored_struct[preAlphaKey ~ callsign] = player; continue; } callsign_struct[preAlphaKey ~ callsign] = player; diff --git a/BUK-M2/Nasal/datalink.nas b/BUK-M2/Nasal/datalink.nas index c93ab48..ef4226c 100644 --- a/BUK-M2/Nasal/datalink.nas +++ b/BUK-M2/Nasal/datalink.nas @@ -452,9 +452,8 @@ var receive_loop = func { if (!mp.getValue("valid")) continue; var callsign = mp.getValue("callsign"); if (callsign == nil) continue; - if(multiplayer.ignore[callsign] == 1) { - continue; - } + if (damage.isIgnoredNode(mp)) continue; + callsign_to_index[callsign] = idx; var data = mp.getValue(mp_path); diff --git a/BUK-M2/Nasal/fire-control.nas b/BUK-M2/Nasal/fire-control.nas index 5301734..129f7b8 100644 --- a/BUK-M2/Nasal/fire-control.nas +++ b/BUK-M2/Nasal/fire-control.nas @@ -172,7 +172,7 @@ var scan = func() { foreach(var mp; mvec){ if (mp.getNode("valid") == nil or mp.getNode("valid").getValue() != 1) continue; if (mp.getNode("callsign") == nil or mp.getNode("callsign").getValue() == nil - or multiplayer.ignore[mp.getNode("callsign").getValue()] == 1) continue; + or damage.isIgnoredNode(mp)) continue; var prio = fire_control(mp, my_pos); append(prio_vector, prio); if (prio[3] == 1) { diff --git a/BUK-M2/Nasal/guided-missiles.nas b/BUK-M2/Nasal/guided-missiles.nas index e2a508e..05bf5be 100644 --- a/BUK-M2/Nasal/guided-missiles.nas +++ b/BUK-M2/Nasal/guided-missiles.nas @@ -190,7 +190,7 @@ var contactPoint = nil; # isValid() - If this target is valid # getElevation() - Pitch to target from launch vehicle # get_bearing() - Bearing to target from launch vehicle -# get_Callsign() +# get_Callsign() # get_range() - NM # get_Coord() # get_altitude() - FT @@ -1362,7 +1362,7 @@ var AIM = { # do NOT call this after launch # see also release(vect) if (me.status == MISSILE_FLYING) return; - me.contacts = vect; + me.contacts = vect; }, clearTgt: func { @@ -1630,7 +1630,7 @@ var AIM = { me.model.getNode("heading-deg-prop", 1).setValue(me.hdgN.getPath()); me.model.getNode("pitch-deg-prop", 1).setValue(me.pitchN.getPath()); me.model.getNode("roll-deg-prop", 1).setValue(me.rollN.getPath()); - + # Get initial velocity vector (aircraft): me.speed_down_fps = getprop("velocities/speed-down-fps"); @@ -1763,7 +1763,7 @@ var AIM = { me.lock_on_sun = 0; - + if(!sep_thread) { me.flightTimer = maketimer(0, me, me.flight); @@ -2241,7 +2241,7 @@ var AIM = { me.deploy_prop.setDoubleValue(me.deploy); me.thrust_lbf = me.thrust();# pounds force (lbf) - + # Jmav remove the # from the line below for cruise missile adjustment: #me.printAlways("guiding=%d time=%d: mach=%.3f alt=%d %s",me.guiding, me.life_time, me.speed_m, me.alt_ft, me.observing); @@ -2751,7 +2751,7 @@ var AIM = { me.loft_alt = me.settings.altitude; } if (me.settings["altitude_at"] != nil) { - # Altitude above target + # Altitude above target me.settings.altitude_at+=me.Tgt.get_altitude(); if (me.loft_alt != me.settings.altitude_at) me.printStats("Loft altitude switched to %d", me.settings.altitude_at); me.loft_alt = me.settings.altitude_at; @@ -3221,7 +3221,7 @@ var AIM = { me.blep = me.Tgt.getLastGroundTrackBlep(); if (me.blep == nil and me.newTargetAssigned) { # TODO: Do not remember what this is for - me.t_coord_sampled = me.t_coord; + me.t_coord_sampled = me.t_coord; } elsif (me.blep == nil) { me.free = 1; me.guiding = 0; @@ -4007,11 +4007,11 @@ var AIM = { me.t_go = me.myMath.dotProduct(me.R_tm,me.R_tm)/me.myMath.dotProduct(me.R_tm, me.V_tm); #printf("time_to_go %.1f, closing %d",me.t_go,me.vert_closing_rate_fps); - + # Horizontal homing: if (me.guidanceLaw == "LOS") { - + me.K1 = 2.5; me.K2 = 10.0; @@ -4720,10 +4720,14 @@ var AIM = { me.geodPos = aircraftToCart({x:-me.radarX, y:me.radarY, z: -me.radarZ}); me.launchCoord.set_xyz(me.geodPos.x, me.geodPos.y, me.geodPos.z); } - - me.potentialCoord = me.tagt.get_Coord(); + me.potentialCoord = nil; + if (contains(me.tagt, "get_coord_for_view")) { + me.potentialCoord = me.tagt.get_coord_for_view(me.guidance == "radiation"); + } else { + me.potentialCoord = me.tagt.get_Coord(); + } me.xyz = {"x":me.launchCoord.x(), "y":me.launchCoord.y(), "z":me.launchCoord.z()}; - me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; + me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; # Check for terrain between own weapon and target: me.terrainGeod = get_cart_ground_intersection(me.xyz, me.directionLOS); @@ -4746,9 +4750,14 @@ var AIM = { checkForViewInFlight: func (tagt) { if (me.guidance != "gps-laser" and me.guidance != "gps" and me.guidance != "inertial" and me.guidance != "sample") { me.launchCoord = me.coord; - me.potentialCoord = tagt.get_Coord(); + me.potentialCoord = nil; + if (contains(me.tagt, "get_coord_for_view")) { + me.potentialCoord = me.tagt.get_coord_for_view(me.guidance == "radiation"); + } else { + me.potentialCoord = me.tagt.get_Coord(); + } me.xyz = {"x":me.launchCoord.x(), "y":me.launchCoord.y(), "z":me.launchCoord.z()}; - me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; + me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; # Check for terrain between own weapon and target: me.terrainGeod = get_cart_ground_intersection(me.xyz, me.directionLOS); @@ -5043,7 +5052,7 @@ var AIM = { goToLock: func { me.callsign = damage.processCallsign(me.tagt.get_Callsign()); - if (multiplayer.ignore[me.callsign] == 1) { + if (damage.isIgnoredCallsign(me.callsign)) { me.callsign = "Unknown"; if (me.tagt == contact) contact = nil; makesettimer(func me.search(), 0.1); diff --git a/Frigate/Nasal/damage.nas b/Frigate/Nasal/damage.nas index b0b9c45..31317dc 100644 --- a/Frigate/Nasal/damage.nas +++ b/Frigate/Nasal/damage.nas @@ -312,7 +312,7 @@ var DamageRecipient = if(getprop("payload/armament/msg") == 0 and getprop("payload/armament/spectator") != 1 and notification.RemoteCallsign != notification.Callsign) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -474,7 +474,7 @@ var DamageRecipient = # debug.dump(notification); # # - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { damageLog.push("Ignored hit by "~notification.Callsign); return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -1387,6 +1387,30 @@ var getCallsign = func (callsign) { return node; } +# 'ignored' player test +# In FG 2024, multiplayer.ignore hash was removed in favour of property controls/invisible. +# These methods test both for compatibility. + +var ignored_struct = {}; + +var isIgnoredNode = func(node) { + if (contains(multiplayer, "ignore")) { + var callsign = node.getValue("callsign"); + return callsign != nil and multiplayer.ignore[callsign]; + } else { + node = node.getNode("controls/invisible"); + return node != nil and node.getBoolValue(); + } +} + +var isIgnoredCallsign = func(callsign) { + if (contains(multiplayer, "ignore")) { + return multiplayer.ignore[callsign]; + } else { + return contains(ignored_struct, preAlphaKey ~ callsign); + } +} + var MAW_elapsed = 0; var radarSpikes = {}; @@ -1397,6 +1421,7 @@ foreach (key ; keys(radar_signatures)) { var processCallsigns = func () { callsign_struct = {}; + ignored_struct = {}; var players = props.globals.getNode("ai/models").getChildren(); var myCallsign = getprop("sim/multiplay/callsign"); myCallsign = size(myCallsign) < 8 ? myCallsign : left(myCallsign,7); @@ -1405,7 +1430,8 @@ var processCallsigns = func () { foreach (var player; players) { if(player.getChild("valid") != nil and player.getChild("valid").getValue() == 1 and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { var callsign = player.getChild("callsign").getValue(); - if(multiplayer.ignore[callsign] == 1) { + if(isIgnoredNode(player)) { + ignored_struct[preAlphaKey ~ callsign] = player; continue; } callsign_struct[preAlphaKey ~ callsign] = player; diff --git a/MIM-104D/Nasal/damage.nas b/MIM-104D/Nasal/damage.nas index b0b9c45..31317dc 100644 --- a/MIM-104D/Nasal/damage.nas +++ b/MIM-104D/Nasal/damage.nas @@ -312,7 +312,7 @@ var DamageRecipient = if(getprop("payload/armament/msg") == 0 and getprop("payload/armament/spectator") != 1 and notification.RemoteCallsign != notification.Callsign) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -474,7 +474,7 @@ var DamageRecipient = # debug.dump(notification); # # - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { damageLog.push("Ignored hit by "~notification.Callsign); return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -1387,6 +1387,30 @@ var getCallsign = func (callsign) { return node; } +# 'ignored' player test +# In FG 2024, multiplayer.ignore hash was removed in favour of property controls/invisible. +# These methods test both for compatibility. + +var ignored_struct = {}; + +var isIgnoredNode = func(node) { + if (contains(multiplayer, "ignore")) { + var callsign = node.getValue("callsign"); + return callsign != nil and multiplayer.ignore[callsign]; + } else { + node = node.getNode("controls/invisible"); + return node != nil and node.getBoolValue(); + } +} + +var isIgnoredCallsign = func(callsign) { + if (contains(multiplayer, "ignore")) { + return multiplayer.ignore[callsign]; + } else { + return contains(ignored_struct, preAlphaKey ~ callsign); + } +} + var MAW_elapsed = 0; var radarSpikes = {}; @@ -1397,6 +1421,7 @@ foreach (key ; keys(radar_signatures)) { var processCallsigns = func () { callsign_struct = {}; + ignored_struct = {}; var players = props.globals.getNode("ai/models").getChildren(); var myCallsign = getprop("sim/multiplay/callsign"); myCallsign = size(myCallsign) < 8 ? myCallsign : left(myCallsign,7); @@ -1405,7 +1430,8 @@ var processCallsigns = func () { foreach (var player; players) { if(player.getChild("valid") != nil and player.getChild("valid").getValue() == 1 and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { var callsign = player.getChild("callsign").getValue(); - if(multiplayer.ignore[callsign] == 1) { + if(isIgnoredNode(player)) { + ignored_struct[preAlphaKey ~ callsign] = player; continue; } callsign_struct[preAlphaKey ~ callsign] = player; diff --git a/MIM-104D/Nasal/datalink.nas b/MIM-104D/Nasal/datalink.nas index c93ab48..ef4226c 100644 --- a/MIM-104D/Nasal/datalink.nas +++ b/MIM-104D/Nasal/datalink.nas @@ -452,9 +452,8 @@ var receive_loop = func { if (!mp.getValue("valid")) continue; var callsign = mp.getValue("callsign"); if (callsign == nil) continue; - if(multiplayer.ignore[callsign] == 1) { - continue; - } + if (damage.isIgnoredNode(mp)) continue; + callsign_to_index[callsign] = idx; var data = mp.getValue(mp_path); diff --git a/MIM-104D/Nasal/fire-control.nas b/MIM-104D/Nasal/fire-control.nas index 5301734..129f7b8 100644 --- a/MIM-104D/Nasal/fire-control.nas +++ b/MIM-104D/Nasal/fire-control.nas @@ -172,7 +172,7 @@ var scan = func() { foreach(var mp; mvec){ if (mp.getNode("valid") == nil or mp.getNode("valid").getValue() != 1) continue; if (mp.getNode("callsign") == nil or mp.getNode("callsign").getValue() == nil - or multiplayer.ignore[mp.getNode("callsign").getValue()] == 1) continue; + or damage.isIgnoredNode(mp)) continue; var prio = fire_control(mp, my_pos); append(prio_vector, prio); if (prio[3] == 1) { diff --git a/MIM-104D/Nasal/guided-missiles.nas b/MIM-104D/Nasal/guided-missiles.nas index e2a508e..05bf5be 100644 --- a/MIM-104D/Nasal/guided-missiles.nas +++ b/MIM-104D/Nasal/guided-missiles.nas @@ -190,7 +190,7 @@ var contactPoint = nil; # isValid() - If this target is valid # getElevation() - Pitch to target from launch vehicle # get_bearing() - Bearing to target from launch vehicle -# get_Callsign() +# get_Callsign() # get_range() - NM # get_Coord() # get_altitude() - FT @@ -1362,7 +1362,7 @@ var AIM = { # do NOT call this after launch # see also release(vect) if (me.status == MISSILE_FLYING) return; - me.contacts = vect; + me.contacts = vect; }, clearTgt: func { @@ -1630,7 +1630,7 @@ var AIM = { me.model.getNode("heading-deg-prop", 1).setValue(me.hdgN.getPath()); me.model.getNode("pitch-deg-prop", 1).setValue(me.pitchN.getPath()); me.model.getNode("roll-deg-prop", 1).setValue(me.rollN.getPath()); - + # Get initial velocity vector (aircraft): me.speed_down_fps = getprop("velocities/speed-down-fps"); @@ -1763,7 +1763,7 @@ var AIM = { me.lock_on_sun = 0; - + if(!sep_thread) { me.flightTimer = maketimer(0, me, me.flight); @@ -2241,7 +2241,7 @@ var AIM = { me.deploy_prop.setDoubleValue(me.deploy); me.thrust_lbf = me.thrust();# pounds force (lbf) - + # Jmav remove the # from the line below for cruise missile adjustment: #me.printAlways("guiding=%d time=%d: mach=%.3f alt=%d %s",me.guiding, me.life_time, me.speed_m, me.alt_ft, me.observing); @@ -2751,7 +2751,7 @@ var AIM = { me.loft_alt = me.settings.altitude; } if (me.settings["altitude_at"] != nil) { - # Altitude above target + # Altitude above target me.settings.altitude_at+=me.Tgt.get_altitude(); if (me.loft_alt != me.settings.altitude_at) me.printStats("Loft altitude switched to %d", me.settings.altitude_at); me.loft_alt = me.settings.altitude_at; @@ -3221,7 +3221,7 @@ var AIM = { me.blep = me.Tgt.getLastGroundTrackBlep(); if (me.blep == nil and me.newTargetAssigned) { # TODO: Do not remember what this is for - me.t_coord_sampled = me.t_coord; + me.t_coord_sampled = me.t_coord; } elsif (me.blep == nil) { me.free = 1; me.guiding = 0; @@ -4007,11 +4007,11 @@ var AIM = { me.t_go = me.myMath.dotProduct(me.R_tm,me.R_tm)/me.myMath.dotProduct(me.R_tm, me.V_tm); #printf("time_to_go %.1f, closing %d",me.t_go,me.vert_closing_rate_fps); - + # Horizontal homing: if (me.guidanceLaw == "LOS") { - + me.K1 = 2.5; me.K2 = 10.0; @@ -4720,10 +4720,14 @@ var AIM = { me.geodPos = aircraftToCart({x:-me.radarX, y:me.radarY, z: -me.radarZ}); me.launchCoord.set_xyz(me.geodPos.x, me.geodPos.y, me.geodPos.z); } - - me.potentialCoord = me.tagt.get_Coord(); + me.potentialCoord = nil; + if (contains(me.tagt, "get_coord_for_view")) { + me.potentialCoord = me.tagt.get_coord_for_view(me.guidance == "radiation"); + } else { + me.potentialCoord = me.tagt.get_Coord(); + } me.xyz = {"x":me.launchCoord.x(), "y":me.launchCoord.y(), "z":me.launchCoord.z()}; - me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; + me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; # Check for terrain between own weapon and target: me.terrainGeod = get_cart_ground_intersection(me.xyz, me.directionLOS); @@ -4746,9 +4750,14 @@ var AIM = { checkForViewInFlight: func (tagt) { if (me.guidance != "gps-laser" and me.guidance != "gps" and me.guidance != "inertial" and me.guidance != "sample") { me.launchCoord = me.coord; - me.potentialCoord = tagt.get_Coord(); + me.potentialCoord = nil; + if (contains(me.tagt, "get_coord_for_view")) { + me.potentialCoord = me.tagt.get_coord_for_view(me.guidance == "radiation"); + } else { + me.potentialCoord = me.tagt.get_Coord(); + } me.xyz = {"x":me.launchCoord.x(), "y":me.launchCoord.y(), "z":me.launchCoord.z()}; - me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; + me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; # Check for terrain between own weapon and target: me.terrainGeod = get_cart_ground_intersection(me.xyz, me.directionLOS); @@ -5043,7 +5052,7 @@ var AIM = { goToLock: func { me.callsign = damage.processCallsign(me.tagt.get_Callsign()); - if (multiplayer.ignore[me.callsign] == 1) { + if (damage.isIgnoredCallsign(me.callsign)) { me.callsign = "Unknown"; if (me.tagt == contact) contact = nil; makesettimer(func me.search(), 0.1); diff --git a/S-200/Nasal/damage.nas b/S-200/Nasal/damage.nas index b0b9c45..31317dc 100644 --- a/S-200/Nasal/damage.nas +++ b/S-200/Nasal/damage.nas @@ -312,7 +312,7 @@ var DamageRecipient = if(getprop("payload/armament/msg") == 0 and getprop("payload/armament/spectator") != 1 and notification.RemoteCallsign != notification.Callsign) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -474,7 +474,7 @@ var DamageRecipient = # debug.dump(notification); # # - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { damageLog.push("Ignored hit by "~notification.Callsign); return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -1387,6 +1387,30 @@ var getCallsign = func (callsign) { return node; } +# 'ignored' player test +# In FG 2024, multiplayer.ignore hash was removed in favour of property controls/invisible. +# These methods test both for compatibility. + +var ignored_struct = {}; + +var isIgnoredNode = func(node) { + if (contains(multiplayer, "ignore")) { + var callsign = node.getValue("callsign"); + return callsign != nil and multiplayer.ignore[callsign]; + } else { + node = node.getNode("controls/invisible"); + return node != nil and node.getBoolValue(); + } +} + +var isIgnoredCallsign = func(callsign) { + if (contains(multiplayer, "ignore")) { + return multiplayer.ignore[callsign]; + } else { + return contains(ignored_struct, preAlphaKey ~ callsign); + } +} + var MAW_elapsed = 0; var radarSpikes = {}; @@ -1397,6 +1421,7 @@ foreach (key ; keys(radar_signatures)) { var processCallsigns = func () { callsign_struct = {}; + ignored_struct = {}; var players = props.globals.getNode("ai/models").getChildren(); var myCallsign = getprop("sim/multiplay/callsign"); myCallsign = size(myCallsign) < 8 ? myCallsign : left(myCallsign,7); @@ -1405,7 +1430,8 @@ var processCallsigns = func () { foreach (var player; players) { if(player.getChild("valid") != nil and player.getChild("valid").getValue() == 1 and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { var callsign = player.getChild("callsign").getValue(); - if(multiplayer.ignore[callsign] == 1) { + if(isIgnoredNode(player)) { + ignored_struct[preAlphaKey ~ callsign] = player; continue; } callsign_struct[preAlphaKey ~ callsign] = player; diff --git a/S-200/Nasal/datalink.nas b/S-200/Nasal/datalink.nas index c93ab48..ef4226c 100644 --- a/S-200/Nasal/datalink.nas +++ b/S-200/Nasal/datalink.nas @@ -452,9 +452,8 @@ var receive_loop = func { if (!mp.getValue("valid")) continue; var callsign = mp.getValue("callsign"); if (callsign == nil) continue; - if(multiplayer.ignore[callsign] == 1) { - continue; - } + if (damage.isIgnoredNode(mp)) continue; + callsign_to_index[callsign] = idx; var data = mp.getValue(mp_path); diff --git a/S-300/Nasal/damage.nas b/S-300/Nasal/damage.nas index b0b9c45..31317dc 100644 --- a/S-300/Nasal/damage.nas +++ b/S-300/Nasal/damage.nas @@ -312,7 +312,7 @@ var DamageRecipient = if(getprop("payload/armament/msg") == 0 and getprop("payload/armament/spectator") != 1 and notification.RemoteCallsign != notification.Callsign) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -474,7 +474,7 @@ var DamageRecipient = # debug.dump(notification); # # - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { damageLog.push("Ignored hit by "~notification.Callsign); return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -1387,6 +1387,30 @@ var getCallsign = func (callsign) { return node; } +# 'ignored' player test +# In FG 2024, multiplayer.ignore hash was removed in favour of property controls/invisible. +# These methods test both for compatibility. + +var ignored_struct = {}; + +var isIgnoredNode = func(node) { + if (contains(multiplayer, "ignore")) { + var callsign = node.getValue("callsign"); + return callsign != nil and multiplayer.ignore[callsign]; + } else { + node = node.getNode("controls/invisible"); + return node != nil and node.getBoolValue(); + } +} + +var isIgnoredCallsign = func(callsign) { + if (contains(multiplayer, "ignore")) { + return multiplayer.ignore[callsign]; + } else { + return contains(ignored_struct, preAlphaKey ~ callsign); + } +} + var MAW_elapsed = 0; var radarSpikes = {}; @@ -1397,6 +1421,7 @@ foreach (key ; keys(radar_signatures)) { var processCallsigns = func () { callsign_struct = {}; + ignored_struct = {}; var players = props.globals.getNode("ai/models").getChildren(); var myCallsign = getprop("sim/multiplay/callsign"); myCallsign = size(myCallsign) < 8 ? myCallsign : left(myCallsign,7); @@ -1405,7 +1430,8 @@ var processCallsigns = func () { foreach (var player; players) { if(player.getChild("valid") != nil and player.getChild("valid").getValue() == 1 and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { var callsign = player.getChild("callsign").getValue(); - if(multiplayer.ignore[callsign] == 1) { + if(isIgnoredNode(player)) { + ignored_struct[preAlphaKey ~ callsign] = player; continue; } callsign_struct[preAlphaKey ~ callsign] = player; diff --git a/S-300/Nasal/datalink.nas b/S-300/Nasal/datalink.nas index c93ab48..ef4226c 100644 --- a/S-300/Nasal/datalink.nas +++ b/S-300/Nasal/datalink.nas @@ -452,9 +452,8 @@ var receive_loop = func { if (!mp.getValue("valid")) continue; var callsign = mp.getValue("callsign"); if (callsign == nil) continue; - if(multiplayer.ignore[callsign] == 1) { - continue; - } + if (damage.isIgnoredNode(mp)) continue; + callsign_to_index[callsign] = idx; var data = mp.getValue(mp_path); diff --git a/S-75/Nasal/damage.nas b/S-75/Nasal/damage.nas index b0b9c45..31317dc 100644 --- a/S-75/Nasal/damage.nas +++ b/S-75/Nasal/damage.nas @@ -312,7 +312,7 @@ var DamageRecipient = if(getprop("payload/armament/msg") == 0 and getprop("payload/armament/spectator") != 1 and notification.RemoteCallsign != notification.Callsign) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -474,7 +474,7 @@ var DamageRecipient = # debug.dump(notification); # # - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { damageLog.push("Ignored hit by "~notification.Callsign); return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -1387,6 +1387,30 @@ var getCallsign = func (callsign) { return node; } +# 'ignored' player test +# In FG 2024, multiplayer.ignore hash was removed in favour of property controls/invisible. +# These methods test both for compatibility. + +var ignored_struct = {}; + +var isIgnoredNode = func(node) { + if (contains(multiplayer, "ignore")) { + var callsign = node.getValue("callsign"); + return callsign != nil and multiplayer.ignore[callsign]; + } else { + node = node.getNode("controls/invisible"); + return node != nil and node.getBoolValue(); + } +} + +var isIgnoredCallsign = func(callsign) { + if (contains(multiplayer, "ignore")) { + return multiplayer.ignore[callsign]; + } else { + return contains(ignored_struct, preAlphaKey ~ callsign); + } +} + var MAW_elapsed = 0; var radarSpikes = {}; @@ -1397,6 +1421,7 @@ foreach (key ; keys(radar_signatures)) { var processCallsigns = func () { callsign_struct = {}; + ignored_struct = {}; var players = props.globals.getNode("ai/models").getChildren(); var myCallsign = getprop("sim/multiplay/callsign"); myCallsign = size(myCallsign) < 8 ? myCallsign : left(myCallsign,7); @@ -1405,7 +1430,8 @@ var processCallsigns = func () { foreach (var player; players) { if(player.getChild("valid") != nil and player.getChild("valid").getValue() == 1 and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { var callsign = player.getChild("callsign").getValue(); - if(multiplayer.ignore[callsign] == 1) { + if(isIgnoredNode(player)) { + ignored_struct[preAlphaKey ~ callsign] = player; continue; } callsign_struct[preAlphaKey ~ callsign] = player; diff --git a/S-75/Nasal/datalink.nas b/S-75/Nasal/datalink.nas index c93ab48..ef4226c 100644 --- a/S-75/Nasal/datalink.nas +++ b/S-75/Nasal/datalink.nas @@ -452,9 +452,8 @@ var receive_loop = func { if (!mp.getValue("valid")) continue; var callsign = mp.getValue("callsign"); if (callsign == nil) continue; - if(multiplayer.ignore[callsign] == 1) { - continue; - } + if (damage.isIgnoredNode(mp)) continue; + callsign_to_index[callsign] = idx; var data = mp.getValue(mp_path); diff --git a/S-75/Nasal/fire-control.nas b/S-75/Nasal/fire-control.nas index 5301734..129f7b8 100644 --- a/S-75/Nasal/fire-control.nas +++ b/S-75/Nasal/fire-control.nas @@ -172,7 +172,7 @@ var scan = func() { foreach(var mp; mvec){ if (mp.getNode("valid") == nil or mp.getNode("valid").getValue() != 1) continue; if (mp.getNode("callsign") == nil or mp.getNode("callsign").getValue() == nil - or multiplayer.ignore[mp.getNode("callsign").getValue()] == 1) continue; + or damage.isIgnoredNode(mp)) continue; var prio = fire_control(mp, my_pos); append(prio_vector, prio); if (prio[3] == 1) { diff --git a/S-75/Nasal/guided-missiles.nas b/S-75/Nasal/guided-missiles.nas index e2a508e..05bf5be 100644 --- a/S-75/Nasal/guided-missiles.nas +++ b/S-75/Nasal/guided-missiles.nas @@ -190,7 +190,7 @@ var contactPoint = nil; # isValid() - If this target is valid # getElevation() - Pitch to target from launch vehicle # get_bearing() - Bearing to target from launch vehicle -# get_Callsign() +# get_Callsign() # get_range() - NM # get_Coord() # get_altitude() - FT @@ -1362,7 +1362,7 @@ var AIM = { # do NOT call this after launch # see also release(vect) if (me.status == MISSILE_FLYING) return; - me.contacts = vect; + me.contacts = vect; }, clearTgt: func { @@ -1630,7 +1630,7 @@ var AIM = { me.model.getNode("heading-deg-prop", 1).setValue(me.hdgN.getPath()); me.model.getNode("pitch-deg-prop", 1).setValue(me.pitchN.getPath()); me.model.getNode("roll-deg-prop", 1).setValue(me.rollN.getPath()); - + # Get initial velocity vector (aircraft): me.speed_down_fps = getprop("velocities/speed-down-fps"); @@ -1763,7 +1763,7 @@ var AIM = { me.lock_on_sun = 0; - + if(!sep_thread) { me.flightTimer = maketimer(0, me, me.flight); @@ -2241,7 +2241,7 @@ var AIM = { me.deploy_prop.setDoubleValue(me.deploy); me.thrust_lbf = me.thrust();# pounds force (lbf) - + # Jmav remove the # from the line below for cruise missile adjustment: #me.printAlways("guiding=%d time=%d: mach=%.3f alt=%d %s",me.guiding, me.life_time, me.speed_m, me.alt_ft, me.observing); @@ -2751,7 +2751,7 @@ var AIM = { me.loft_alt = me.settings.altitude; } if (me.settings["altitude_at"] != nil) { - # Altitude above target + # Altitude above target me.settings.altitude_at+=me.Tgt.get_altitude(); if (me.loft_alt != me.settings.altitude_at) me.printStats("Loft altitude switched to %d", me.settings.altitude_at); me.loft_alt = me.settings.altitude_at; @@ -3221,7 +3221,7 @@ var AIM = { me.blep = me.Tgt.getLastGroundTrackBlep(); if (me.blep == nil and me.newTargetAssigned) { # TODO: Do not remember what this is for - me.t_coord_sampled = me.t_coord; + me.t_coord_sampled = me.t_coord; } elsif (me.blep == nil) { me.free = 1; me.guiding = 0; @@ -4007,11 +4007,11 @@ var AIM = { me.t_go = me.myMath.dotProduct(me.R_tm,me.R_tm)/me.myMath.dotProduct(me.R_tm, me.V_tm); #printf("time_to_go %.1f, closing %d",me.t_go,me.vert_closing_rate_fps); - + # Horizontal homing: if (me.guidanceLaw == "LOS") { - + me.K1 = 2.5; me.K2 = 10.0; @@ -4720,10 +4720,14 @@ var AIM = { me.geodPos = aircraftToCart({x:-me.radarX, y:me.radarY, z: -me.radarZ}); me.launchCoord.set_xyz(me.geodPos.x, me.geodPos.y, me.geodPos.z); } - - me.potentialCoord = me.tagt.get_Coord(); + me.potentialCoord = nil; + if (contains(me.tagt, "get_coord_for_view")) { + me.potentialCoord = me.tagt.get_coord_for_view(me.guidance == "radiation"); + } else { + me.potentialCoord = me.tagt.get_Coord(); + } me.xyz = {"x":me.launchCoord.x(), "y":me.launchCoord.y(), "z":me.launchCoord.z()}; - me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; + me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; # Check for terrain between own weapon and target: me.terrainGeod = get_cart_ground_intersection(me.xyz, me.directionLOS); @@ -4746,9 +4750,14 @@ var AIM = { checkForViewInFlight: func (tagt) { if (me.guidance != "gps-laser" and me.guidance != "gps" and me.guidance != "inertial" and me.guidance != "sample") { me.launchCoord = me.coord; - me.potentialCoord = tagt.get_Coord(); + me.potentialCoord = nil; + if (contains(me.tagt, "get_coord_for_view")) { + me.potentialCoord = me.tagt.get_coord_for_view(me.guidance == "radiation"); + } else { + me.potentialCoord = me.tagt.get_Coord(); + } me.xyz = {"x":me.launchCoord.x(), "y":me.launchCoord.y(), "z":me.launchCoord.z()}; - me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; + me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; # Check for terrain between own weapon and target: me.terrainGeod = get_cart_ground_intersection(me.xyz, me.directionLOS); @@ -5043,7 +5052,7 @@ var AIM = { goToLock: func { me.callsign = damage.processCallsign(me.tagt.get_Callsign()); - if (multiplayer.ignore[me.callsign] == 1) { + if (damage.isIgnoredCallsign(me.callsign)) { me.callsign = "Unknown"; if (me.tagt == contact) contact = nil; makesettimer(func me.search(), 0.1); diff --git a/SA-3/Nasal/damage.nas b/SA-3/Nasal/damage.nas index b0b9c45..31317dc 100644 --- a/SA-3/Nasal/damage.nas +++ b/SA-3/Nasal/damage.nas @@ -312,7 +312,7 @@ var DamageRecipient = if(getprop("payload/armament/msg") == 0 and getprop("payload/armament/spectator") != 1 and notification.RemoteCallsign != notification.Callsign) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -474,7 +474,7 @@ var DamageRecipient = # debug.dump(notification); # # - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { damageLog.push("Ignored hit by "~notification.Callsign); return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -1387,6 +1387,30 @@ var getCallsign = func (callsign) { return node; } +# 'ignored' player test +# In FG 2024, multiplayer.ignore hash was removed in favour of property controls/invisible. +# These methods test both for compatibility. + +var ignored_struct = {}; + +var isIgnoredNode = func(node) { + if (contains(multiplayer, "ignore")) { + var callsign = node.getValue("callsign"); + return callsign != nil and multiplayer.ignore[callsign]; + } else { + node = node.getNode("controls/invisible"); + return node != nil and node.getBoolValue(); + } +} + +var isIgnoredCallsign = func(callsign) { + if (contains(multiplayer, "ignore")) { + return multiplayer.ignore[callsign]; + } else { + return contains(ignored_struct, preAlphaKey ~ callsign); + } +} + var MAW_elapsed = 0; var radarSpikes = {}; @@ -1397,6 +1421,7 @@ foreach (key ; keys(radar_signatures)) { var processCallsigns = func () { callsign_struct = {}; + ignored_struct = {}; var players = props.globals.getNode("ai/models").getChildren(); var myCallsign = getprop("sim/multiplay/callsign"); myCallsign = size(myCallsign) < 8 ? myCallsign : left(myCallsign,7); @@ -1405,7 +1430,8 @@ var processCallsigns = func () { foreach (var player; players) { if(player.getChild("valid") != nil and player.getChild("valid").getValue() == 1 and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { var callsign = player.getChild("callsign").getValue(); - if(multiplayer.ignore[callsign] == 1) { + if(isIgnoredNode(player)) { + ignored_struct[preAlphaKey ~ callsign] = player; continue; } callsign_struct[preAlphaKey ~ callsign] = player; diff --git a/SA-3/Nasal/datalink.nas b/SA-3/Nasal/datalink.nas index c93ab48..ef4226c 100644 --- a/SA-3/Nasal/datalink.nas +++ b/SA-3/Nasal/datalink.nas @@ -452,9 +452,8 @@ var receive_loop = func { if (!mp.getValue("valid")) continue; var callsign = mp.getValue("callsign"); if (callsign == nil) continue; - if(multiplayer.ignore[callsign] == 1) { - continue; - } + if (damage.isIgnoredNode(mp)) continue; + callsign_to_index[callsign] = idx; var data = mp.getValue(mp_path); diff --git a/SA-3/Nasal/fire-control.nas b/SA-3/Nasal/fire-control.nas index 5301734..129f7b8 100644 --- a/SA-3/Nasal/fire-control.nas +++ b/SA-3/Nasal/fire-control.nas @@ -172,7 +172,7 @@ var scan = func() { foreach(var mp; mvec){ if (mp.getNode("valid") == nil or mp.getNode("valid").getValue() != 1) continue; if (mp.getNode("callsign") == nil or mp.getNode("callsign").getValue() == nil - or multiplayer.ignore[mp.getNode("callsign").getValue()] == 1) continue; + or damage.isIgnoredNode(mp)) continue; var prio = fire_control(mp, my_pos); append(prio_vector, prio); if (prio[3] == 1) { diff --git a/SA-3/Nasal/guided-missiles.nas b/SA-3/Nasal/guided-missiles.nas index e2a508e..05bf5be 100644 --- a/SA-3/Nasal/guided-missiles.nas +++ b/SA-3/Nasal/guided-missiles.nas @@ -190,7 +190,7 @@ var contactPoint = nil; # isValid() - If this target is valid # getElevation() - Pitch to target from launch vehicle # get_bearing() - Bearing to target from launch vehicle -# get_Callsign() +# get_Callsign() # get_range() - NM # get_Coord() # get_altitude() - FT @@ -1362,7 +1362,7 @@ var AIM = { # do NOT call this after launch # see also release(vect) if (me.status == MISSILE_FLYING) return; - me.contacts = vect; + me.contacts = vect; }, clearTgt: func { @@ -1630,7 +1630,7 @@ var AIM = { me.model.getNode("heading-deg-prop", 1).setValue(me.hdgN.getPath()); me.model.getNode("pitch-deg-prop", 1).setValue(me.pitchN.getPath()); me.model.getNode("roll-deg-prop", 1).setValue(me.rollN.getPath()); - + # Get initial velocity vector (aircraft): me.speed_down_fps = getprop("velocities/speed-down-fps"); @@ -1763,7 +1763,7 @@ var AIM = { me.lock_on_sun = 0; - + if(!sep_thread) { me.flightTimer = maketimer(0, me, me.flight); @@ -2241,7 +2241,7 @@ var AIM = { me.deploy_prop.setDoubleValue(me.deploy); me.thrust_lbf = me.thrust();# pounds force (lbf) - + # Jmav remove the # from the line below for cruise missile adjustment: #me.printAlways("guiding=%d time=%d: mach=%.3f alt=%d %s",me.guiding, me.life_time, me.speed_m, me.alt_ft, me.observing); @@ -2751,7 +2751,7 @@ var AIM = { me.loft_alt = me.settings.altitude; } if (me.settings["altitude_at"] != nil) { - # Altitude above target + # Altitude above target me.settings.altitude_at+=me.Tgt.get_altitude(); if (me.loft_alt != me.settings.altitude_at) me.printStats("Loft altitude switched to %d", me.settings.altitude_at); me.loft_alt = me.settings.altitude_at; @@ -3221,7 +3221,7 @@ var AIM = { me.blep = me.Tgt.getLastGroundTrackBlep(); if (me.blep == nil and me.newTargetAssigned) { # TODO: Do not remember what this is for - me.t_coord_sampled = me.t_coord; + me.t_coord_sampled = me.t_coord; } elsif (me.blep == nil) { me.free = 1; me.guiding = 0; @@ -4007,11 +4007,11 @@ var AIM = { me.t_go = me.myMath.dotProduct(me.R_tm,me.R_tm)/me.myMath.dotProduct(me.R_tm, me.V_tm); #printf("time_to_go %.1f, closing %d",me.t_go,me.vert_closing_rate_fps); - + # Horizontal homing: if (me.guidanceLaw == "LOS") { - + me.K1 = 2.5; me.K2 = 10.0; @@ -4720,10 +4720,14 @@ var AIM = { me.geodPos = aircraftToCart({x:-me.radarX, y:me.radarY, z: -me.radarZ}); me.launchCoord.set_xyz(me.geodPos.x, me.geodPos.y, me.geodPos.z); } - - me.potentialCoord = me.tagt.get_Coord(); + me.potentialCoord = nil; + if (contains(me.tagt, "get_coord_for_view")) { + me.potentialCoord = me.tagt.get_coord_for_view(me.guidance == "radiation"); + } else { + me.potentialCoord = me.tagt.get_Coord(); + } me.xyz = {"x":me.launchCoord.x(), "y":me.launchCoord.y(), "z":me.launchCoord.z()}; - me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; + me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; # Check for terrain between own weapon and target: me.terrainGeod = get_cart_ground_intersection(me.xyz, me.directionLOS); @@ -4746,9 +4750,14 @@ var AIM = { checkForViewInFlight: func (tagt) { if (me.guidance != "gps-laser" and me.guidance != "gps" and me.guidance != "inertial" and me.guidance != "sample") { me.launchCoord = me.coord; - me.potentialCoord = tagt.get_Coord(); + me.potentialCoord = nil; + if (contains(me.tagt, "get_coord_for_view")) { + me.potentialCoord = me.tagt.get_coord_for_view(me.guidance == "radiation"); + } else { + me.potentialCoord = me.tagt.get_Coord(); + } me.xyz = {"x":me.launchCoord.x(), "y":me.launchCoord.y(), "z":me.launchCoord.z()}; - me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; + me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; # Check for terrain between own weapon and target: me.terrainGeod = get_cart_ground_intersection(me.xyz, me.directionLOS); @@ -5043,7 +5052,7 @@ var AIM = { goToLock: func { me.callsign = damage.processCallsign(me.tagt.get_Callsign()); - if (multiplayer.ignore[me.callsign] == 1) { + if (damage.isIgnoredCallsign(me.callsign)) { me.callsign = "Unknown"; if (me.tagt == contact) contact = nil; makesettimer(func me.search(), 0.1); diff --git a/SA-6/Nasal/damage.nas b/SA-6/Nasal/damage.nas index b0b9c45..31317dc 100644 --- a/SA-6/Nasal/damage.nas +++ b/SA-6/Nasal/damage.nas @@ -312,7 +312,7 @@ var DamageRecipient = if(getprop("payload/armament/msg") == 0 and getprop("payload/armament/spectator") != 1 and notification.RemoteCallsign != notification.Callsign) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -474,7 +474,7 @@ var DamageRecipient = # debug.dump(notification); # # - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { damageLog.push("Ignored hit by "~notification.Callsign); return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -1387,6 +1387,30 @@ var getCallsign = func (callsign) { return node; } +# 'ignored' player test +# In FG 2024, multiplayer.ignore hash was removed in favour of property controls/invisible. +# These methods test both for compatibility. + +var ignored_struct = {}; + +var isIgnoredNode = func(node) { + if (contains(multiplayer, "ignore")) { + var callsign = node.getValue("callsign"); + return callsign != nil and multiplayer.ignore[callsign]; + } else { + node = node.getNode("controls/invisible"); + return node != nil and node.getBoolValue(); + } +} + +var isIgnoredCallsign = func(callsign) { + if (contains(multiplayer, "ignore")) { + return multiplayer.ignore[callsign]; + } else { + return contains(ignored_struct, preAlphaKey ~ callsign); + } +} + var MAW_elapsed = 0; var radarSpikes = {}; @@ -1397,6 +1421,7 @@ foreach (key ; keys(radar_signatures)) { var processCallsigns = func () { callsign_struct = {}; + ignored_struct = {}; var players = props.globals.getNode("ai/models").getChildren(); var myCallsign = getprop("sim/multiplay/callsign"); myCallsign = size(myCallsign) < 8 ? myCallsign : left(myCallsign,7); @@ -1405,7 +1430,8 @@ var processCallsigns = func () { foreach (var player; players) { if(player.getChild("valid") != nil and player.getChild("valid").getValue() == 1 and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { var callsign = player.getChild("callsign").getValue(); - if(multiplayer.ignore[callsign] == 1) { + if(isIgnoredNode(player)) { + ignored_struct[preAlphaKey ~ callsign] = player; continue; } callsign_struct[preAlphaKey ~ callsign] = player; diff --git a/SA-6/Nasal/datalink.nas b/SA-6/Nasal/datalink.nas index c93ab48..ef4226c 100644 --- a/SA-6/Nasal/datalink.nas +++ b/SA-6/Nasal/datalink.nas @@ -452,9 +452,8 @@ var receive_loop = func { if (!mp.getValue("valid")) continue; var callsign = mp.getValue("callsign"); if (callsign == nil) continue; - if(multiplayer.ignore[callsign] == 1) { - continue; - } + if (damage.isIgnoredNode(mp)) continue; + callsign_to_index[callsign] = idx; var data = mp.getValue(mp_path); diff --git a/SA-6/Nasal/fire-control.nas b/SA-6/Nasal/fire-control.nas index 5301734..129f7b8 100644 --- a/SA-6/Nasal/fire-control.nas +++ b/SA-6/Nasal/fire-control.nas @@ -172,7 +172,7 @@ var scan = func() { foreach(var mp; mvec){ if (mp.getNode("valid") == nil or mp.getNode("valid").getValue() != 1) continue; if (mp.getNode("callsign") == nil or mp.getNode("callsign").getValue() == nil - or multiplayer.ignore[mp.getNode("callsign").getValue()] == 1) continue; + or damage.isIgnoredNode(mp)) continue; var prio = fire_control(mp, my_pos); append(prio_vector, prio); if (prio[3] == 1) { diff --git a/SA-6/Nasal/guided-missiles.nas b/SA-6/Nasal/guided-missiles.nas index e2a508e..05bf5be 100644 --- a/SA-6/Nasal/guided-missiles.nas +++ b/SA-6/Nasal/guided-missiles.nas @@ -190,7 +190,7 @@ var contactPoint = nil; # isValid() - If this target is valid # getElevation() - Pitch to target from launch vehicle # get_bearing() - Bearing to target from launch vehicle -# get_Callsign() +# get_Callsign() # get_range() - NM # get_Coord() # get_altitude() - FT @@ -1362,7 +1362,7 @@ var AIM = { # do NOT call this after launch # see also release(vect) if (me.status == MISSILE_FLYING) return; - me.contacts = vect; + me.contacts = vect; }, clearTgt: func { @@ -1630,7 +1630,7 @@ var AIM = { me.model.getNode("heading-deg-prop", 1).setValue(me.hdgN.getPath()); me.model.getNode("pitch-deg-prop", 1).setValue(me.pitchN.getPath()); me.model.getNode("roll-deg-prop", 1).setValue(me.rollN.getPath()); - + # Get initial velocity vector (aircraft): me.speed_down_fps = getprop("velocities/speed-down-fps"); @@ -1763,7 +1763,7 @@ var AIM = { me.lock_on_sun = 0; - + if(!sep_thread) { me.flightTimer = maketimer(0, me, me.flight); @@ -2241,7 +2241,7 @@ var AIM = { me.deploy_prop.setDoubleValue(me.deploy); me.thrust_lbf = me.thrust();# pounds force (lbf) - + # Jmav remove the # from the line below for cruise missile adjustment: #me.printAlways("guiding=%d time=%d: mach=%.3f alt=%d %s",me.guiding, me.life_time, me.speed_m, me.alt_ft, me.observing); @@ -2751,7 +2751,7 @@ var AIM = { me.loft_alt = me.settings.altitude; } if (me.settings["altitude_at"] != nil) { - # Altitude above target + # Altitude above target me.settings.altitude_at+=me.Tgt.get_altitude(); if (me.loft_alt != me.settings.altitude_at) me.printStats("Loft altitude switched to %d", me.settings.altitude_at); me.loft_alt = me.settings.altitude_at; @@ -3221,7 +3221,7 @@ var AIM = { me.blep = me.Tgt.getLastGroundTrackBlep(); if (me.blep == nil and me.newTargetAssigned) { # TODO: Do not remember what this is for - me.t_coord_sampled = me.t_coord; + me.t_coord_sampled = me.t_coord; } elsif (me.blep == nil) { me.free = 1; me.guiding = 0; @@ -4007,11 +4007,11 @@ var AIM = { me.t_go = me.myMath.dotProduct(me.R_tm,me.R_tm)/me.myMath.dotProduct(me.R_tm, me.V_tm); #printf("time_to_go %.1f, closing %d",me.t_go,me.vert_closing_rate_fps); - + # Horizontal homing: if (me.guidanceLaw == "LOS") { - + me.K1 = 2.5; me.K2 = 10.0; @@ -4720,10 +4720,14 @@ var AIM = { me.geodPos = aircraftToCart({x:-me.radarX, y:me.radarY, z: -me.radarZ}); me.launchCoord.set_xyz(me.geodPos.x, me.geodPos.y, me.geodPos.z); } - - me.potentialCoord = me.tagt.get_Coord(); + me.potentialCoord = nil; + if (contains(me.tagt, "get_coord_for_view")) { + me.potentialCoord = me.tagt.get_coord_for_view(me.guidance == "radiation"); + } else { + me.potentialCoord = me.tagt.get_Coord(); + } me.xyz = {"x":me.launchCoord.x(), "y":me.launchCoord.y(), "z":me.launchCoord.z()}; - me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; + me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; # Check for terrain between own weapon and target: me.terrainGeod = get_cart_ground_intersection(me.xyz, me.directionLOS); @@ -4746,9 +4750,14 @@ var AIM = { checkForViewInFlight: func (tagt) { if (me.guidance != "gps-laser" and me.guidance != "gps" and me.guidance != "inertial" and me.guidance != "sample") { me.launchCoord = me.coord; - me.potentialCoord = tagt.get_Coord(); + me.potentialCoord = nil; + if (contains(me.tagt, "get_coord_for_view")) { + me.potentialCoord = me.tagt.get_coord_for_view(me.guidance == "radiation"); + } else { + me.potentialCoord = me.tagt.get_Coord(); + } me.xyz = {"x":me.launchCoord.x(), "y":me.launchCoord.y(), "z":me.launchCoord.z()}; - me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; + me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; # Check for terrain between own weapon and target: me.terrainGeod = get_cart_ground_intersection(me.xyz, me.directionLOS); @@ -5043,7 +5052,7 @@ var AIM = { goToLock: func { me.callsign = damage.processCallsign(me.tagt.get_Callsign()); - if (multiplayer.ignore[me.callsign] == 1) { + if (damage.isIgnoredCallsign(me.callsign)) { me.callsign = "Unknown"; if (me.tagt == contact) contact = nil; makesettimer(func me.search(), 0.1); diff --git a/ZSU-23/Nasal/damage.nas b/ZSU-23/Nasal/damage.nas index b0b9c45..31317dc 100644 --- a/ZSU-23/Nasal/damage.nas +++ b/ZSU-23/Nasal/damage.nas @@ -312,7 +312,7 @@ var DamageRecipient = if(getprop("payload/armament/msg") == 0 and getprop("payload/armament/spectator") != 1 and notification.RemoteCallsign != notification.Callsign) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -474,7 +474,7 @@ var DamageRecipient = # debug.dump(notification); # # - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { damageLog.push("Ignored hit by "~notification.Callsign); return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -1387,6 +1387,30 @@ var getCallsign = func (callsign) { return node; } +# 'ignored' player test +# In FG 2024, multiplayer.ignore hash was removed in favour of property controls/invisible. +# These methods test both for compatibility. + +var ignored_struct = {}; + +var isIgnoredNode = func(node) { + if (contains(multiplayer, "ignore")) { + var callsign = node.getValue("callsign"); + return callsign != nil and multiplayer.ignore[callsign]; + } else { + node = node.getNode("controls/invisible"); + return node != nil and node.getBoolValue(); + } +} + +var isIgnoredCallsign = func(callsign) { + if (contains(multiplayer, "ignore")) { + return multiplayer.ignore[callsign]; + } else { + return contains(ignored_struct, preAlphaKey ~ callsign); + } +} + var MAW_elapsed = 0; var radarSpikes = {}; @@ -1397,6 +1421,7 @@ foreach (key ; keys(radar_signatures)) { var processCallsigns = func () { callsign_struct = {}; + ignored_struct = {}; var players = props.globals.getNode("ai/models").getChildren(); var myCallsign = getprop("sim/multiplay/callsign"); myCallsign = size(myCallsign) < 8 ? myCallsign : left(myCallsign,7); @@ -1405,7 +1430,8 @@ var processCallsigns = func () { foreach (var player; players) { if(player.getChild("valid") != nil and player.getChild("valid").getValue() == 1 and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { var callsign = player.getChild("callsign").getValue(); - if(multiplayer.ignore[callsign] == 1) { + if(isIgnoredNode(player)) { + ignored_struct[preAlphaKey ~ callsign] = player; continue; } callsign_struct[preAlphaKey ~ callsign] = player; diff --git a/ZSU-23/Nasal/datalink.nas b/ZSU-23/Nasal/datalink.nas index c93ab48..ef4226c 100644 --- a/ZSU-23/Nasal/datalink.nas +++ b/ZSU-23/Nasal/datalink.nas @@ -452,9 +452,8 @@ var receive_loop = func { if (!mp.getValue("valid")) continue; var callsign = mp.getValue("callsign"); if (callsign == nil) continue; - if(multiplayer.ignore[callsign] == 1) { - continue; - } + if (damage.isIgnoredNode(mp)) continue; + callsign_to_index[callsign] = idx; var data = mp.getValue(mp_path); diff --git a/depot/Nasal/damage.nas b/depot/Nasal/damage.nas index b0b9c45..31317dc 100644 --- a/depot/Nasal/damage.nas +++ b/depot/Nasal/damage.nas @@ -312,7 +312,7 @@ var DamageRecipient = if(getprop("payload/armament/msg") == 0 and getprop("payload/armament/spectator") != 1 and notification.RemoteCallsign != notification.Callsign) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -474,7 +474,7 @@ var DamageRecipient = # debug.dump(notification); # # - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { damageLog.push("Ignored hit by "~notification.Callsign); return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -1387,6 +1387,30 @@ var getCallsign = func (callsign) { return node; } +# 'ignored' player test +# In FG 2024, multiplayer.ignore hash was removed in favour of property controls/invisible. +# These methods test both for compatibility. + +var ignored_struct = {}; + +var isIgnoredNode = func(node) { + if (contains(multiplayer, "ignore")) { + var callsign = node.getValue("callsign"); + return callsign != nil and multiplayer.ignore[callsign]; + } else { + node = node.getNode("controls/invisible"); + return node != nil and node.getBoolValue(); + } +} + +var isIgnoredCallsign = func(callsign) { + if (contains(multiplayer, "ignore")) { + return multiplayer.ignore[callsign]; + } else { + return contains(ignored_struct, preAlphaKey ~ callsign); + } +} + var MAW_elapsed = 0; var radarSpikes = {}; @@ -1397,6 +1421,7 @@ foreach (key ; keys(radar_signatures)) { var processCallsigns = func () { callsign_struct = {}; + ignored_struct = {}; var players = props.globals.getNode("ai/models").getChildren(); var myCallsign = getprop("sim/multiplay/callsign"); myCallsign = size(myCallsign) < 8 ? myCallsign : left(myCallsign,7); @@ -1405,7 +1430,8 @@ var processCallsigns = func () { foreach (var player; players) { if(player.getChild("valid") != nil and player.getChild("valid").getValue() == 1 and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { var callsign = player.getChild("callsign").getValue(); - if(multiplayer.ignore[callsign] == 1) { + if(isIgnoredNode(player)) { + ignored_struct[preAlphaKey ~ callsign] = player; continue; } callsign_struct[preAlphaKey ~ callsign] = player; diff --git a/fleet/Nasal/damage.nas b/fleet/Nasal/damage.nas index b0b9c45..31317dc 100644 --- a/fleet/Nasal/damage.nas +++ b/fleet/Nasal/damage.nas @@ -312,7 +312,7 @@ var DamageRecipient = if(getprop("payload/armament/msg") == 0 and getprop("payload/armament/spectator") != 1 and notification.RemoteCallsign != notification.Callsign) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -474,7 +474,7 @@ var DamageRecipient = # debug.dump(notification); # # - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { damageLog.push("Ignored hit by "~notification.Callsign); return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -1387,6 +1387,30 @@ var getCallsign = func (callsign) { return node; } +# 'ignored' player test +# In FG 2024, multiplayer.ignore hash was removed in favour of property controls/invisible. +# These methods test both for compatibility. + +var ignored_struct = {}; + +var isIgnoredNode = func(node) { + if (contains(multiplayer, "ignore")) { + var callsign = node.getValue("callsign"); + return callsign != nil and multiplayer.ignore[callsign]; + } else { + node = node.getNode("controls/invisible"); + return node != nil and node.getBoolValue(); + } +} + +var isIgnoredCallsign = func(callsign) { + if (contains(multiplayer, "ignore")) { + return multiplayer.ignore[callsign]; + } else { + return contains(ignored_struct, preAlphaKey ~ callsign); + } +} + var MAW_elapsed = 0; var radarSpikes = {}; @@ -1397,6 +1421,7 @@ foreach (key ; keys(radar_signatures)) { var processCallsigns = func () { callsign_struct = {}; + ignored_struct = {}; var players = props.globals.getNode("ai/models").getChildren(); var myCallsign = getprop("sim/multiplay/callsign"); myCallsign = size(myCallsign) < 8 ? myCallsign : left(myCallsign,7); @@ -1405,7 +1430,8 @@ var processCallsigns = func () { foreach (var player; players) { if(player.getChild("valid") != nil and player.getChild("valid").getValue() == 1 and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { var callsign = player.getChild("callsign").getValue(); - if(multiplayer.ignore[callsign] == 1) { + if(isIgnoredNode(player)) { + ignored_struct[preAlphaKey ~ callsign] = player; continue; } callsign_struct[preAlphaKey ~ callsign] = player; diff --git a/fleet/Nasal/datalink.nas b/fleet/Nasal/datalink.nas index c93ab48..ef4226c 100644 --- a/fleet/Nasal/datalink.nas +++ b/fleet/Nasal/datalink.nas @@ -452,9 +452,8 @@ var receive_loop = func { if (!mp.getValue("valid")) continue; var callsign = mp.getValue("callsign"); if (callsign == nil) continue; - if(multiplayer.ignore[callsign] == 1) { - continue; - } + if (damage.isIgnoredNode(mp)) continue; + callsign_to_index[callsign] = idx; var data = mp.getValue(mp_path); diff --git a/gci-radar/Nasal/damage.nas b/gci-radar/Nasal/damage.nas index b0b9c45..31317dc 100644 --- a/gci-radar/Nasal/damage.nas +++ b/gci-radar/Nasal/damage.nas @@ -312,7 +312,7 @@ var DamageRecipient = if(getprop("payload/armament/msg") == 0 and getprop("payload/armament/spectator") != 1 and notification.RemoteCallsign != notification.Callsign) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -474,7 +474,7 @@ var DamageRecipient = # debug.dump(notification); # # - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { damageLog.push("Ignored hit by "~notification.Callsign); return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -1387,6 +1387,30 @@ var getCallsign = func (callsign) { return node; } +# 'ignored' player test +# In FG 2024, multiplayer.ignore hash was removed in favour of property controls/invisible. +# These methods test both for compatibility. + +var ignored_struct = {}; + +var isIgnoredNode = func(node) { + if (contains(multiplayer, "ignore")) { + var callsign = node.getValue("callsign"); + return callsign != nil and multiplayer.ignore[callsign]; + } else { + node = node.getNode("controls/invisible"); + return node != nil and node.getBoolValue(); + } +} + +var isIgnoredCallsign = func(callsign) { + if (contains(multiplayer, "ignore")) { + return multiplayer.ignore[callsign]; + } else { + return contains(ignored_struct, preAlphaKey ~ callsign); + } +} + var MAW_elapsed = 0; var radarSpikes = {}; @@ -1397,6 +1421,7 @@ foreach (key ; keys(radar_signatures)) { var processCallsigns = func () { callsign_struct = {}; + ignored_struct = {}; var players = props.globals.getNode("ai/models").getChildren(); var myCallsign = getprop("sim/multiplay/callsign"); myCallsign = size(myCallsign) < 8 ? myCallsign : left(myCallsign,7); @@ -1405,7 +1430,8 @@ var processCallsigns = func () { foreach (var player; players) { if(player.getChild("valid") != nil and player.getChild("valid").getValue() == 1 and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { var callsign = player.getChild("callsign").getValue(); - if(multiplayer.ignore[callsign] == 1) { + if(isIgnoredNode(player)) { + ignored_struct[preAlphaKey ~ callsign] = player; continue; } callsign_struct[preAlphaKey ~ callsign] = player; diff --git a/groundtarget/Nasal/damage.nas b/groundtarget/Nasal/damage.nas index b0b9c45..31317dc 100644 --- a/groundtarget/Nasal/damage.nas +++ b/groundtarget/Nasal/damage.nas @@ -312,7 +312,7 @@ var DamageRecipient = if(getprop("payload/armament/msg") == 0 and getprop("payload/armament/spectator") != 1 and notification.RemoteCallsign != notification.Callsign) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -474,7 +474,7 @@ var DamageRecipient = # debug.dump(notification); # # - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { damageLog.push("Ignored hit by "~notification.Callsign); return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -1387,6 +1387,30 @@ var getCallsign = func (callsign) { return node; } +# 'ignored' player test +# In FG 2024, multiplayer.ignore hash was removed in favour of property controls/invisible. +# These methods test both for compatibility. + +var ignored_struct = {}; + +var isIgnoredNode = func(node) { + if (contains(multiplayer, "ignore")) { + var callsign = node.getValue("callsign"); + return callsign != nil and multiplayer.ignore[callsign]; + } else { + node = node.getNode("controls/invisible"); + return node != nil and node.getBoolValue(); + } +} + +var isIgnoredCallsign = func(callsign) { + if (contains(multiplayer, "ignore")) { + return multiplayer.ignore[callsign]; + } else { + return contains(ignored_struct, preAlphaKey ~ callsign); + } +} + var MAW_elapsed = 0; var radarSpikes = {}; @@ -1397,6 +1421,7 @@ foreach (key ; keys(radar_signatures)) { var processCallsigns = func () { callsign_struct = {}; + ignored_struct = {}; var players = props.globals.getNode("ai/models").getChildren(); var myCallsign = getprop("sim/multiplay/callsign"); myCallsign = size(myCallsign) < 8 ? myCallsign : left(myCallsign,7); @@ -1405,7 +1430,8 @@ var processCallsigns = func () { foreach (var player; players) { if(player.getChild("valid") != nil and player.getChild("valid").getValue() == 1 and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { var callsign = player.getChild("callsign").getValue(); - if(multiplayer.ignore[callsign] == 1) { + if(isIgnoredNode(player)) { + ignored_struct[preAlphaKey ~ callsign] = player; continue; } callsign_struct[preAlphaKey ~ callsign] = player; diff --git a/missile-frigate/Nasal/damage.nas b/missile-frigate/Nasal/damage.nas index b0b9c45..31317dc 100644 --- a/missile-frigate/Nasal/damage.nas +++ b/missile-frigate/Nasal/damage.nas @@ -312,7 +312,7 @@ var DamageRecipient = if(getprop("payload/armament/msg") == 0 and getprop("payload/armament/spectator") != 1 and notification.RemoteCallsign != notification.Callsign) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -474,7 +474,7 @@ var DamageRecipient = # debug.dump(notification); # # - if(multiplayer.ignore[notification.Callsign] == 1) { + if(isIgnoredCallsign(notification.Callsign)) { damageLog.push("Ignored hit by "~notification.Callsign); return emesary.Transmitter.ReceiptStatus_NotProcessed; } @@ -1387,6 +1387,30 @@ var getCallsign = func (callsign) { return node; } +# 'ignored' player test +# In FG 2024, multiplayer.ignore hash was removed in favour of property controls/invisible. +# These methods test both for compatibility. + +var ignored_struct = {}; + +var isIgnoredNode = func(node) { + if (contains(multiplayer, "ignore")) { + var callsign = node.getValue("callsign"); + return callsign != nil and multiplayer.ignore[callsign]; + } else { + node = node.getNode("controls/invisible"); + return node != nil and node.getBoolValue(); + } +} + +var isIgnoredCallsign = func(callsign) { + if (contains(multiplayer, "ignore")) { + return multiplayer.ignore[callsign]; + } else { + return contains(ignored_struct, preAlphaKey ~ callsign); + } +} + var MAW_elapsed = 0; var radarSpikes = {}; @@ -1397,6 +1421,7 @@ foreach (key ; keys(radar_signatures)) { var processCallsigns = func () { callsign_struct = {}; + ignored_struct = {}; var players = props.globals.getNode("ai/models").getChildren(); var myCallsign = getprop("sim/multiplay/callsign"); myCallsign = size(myCallsign) < 8 ? myCallsign : left(myCallsign,7); @@ -1405,7 +1430,8 @@ var processCallsigns = func () { foreach (var player; players) { if(player.getChild("valid") != nil and player.getChild("valid").getValue() == 1 and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { var callsign = player.getChild("callsign").getValue(); - if(multiplayer.ignore[callsign] == 1) { + if(isIgnoredNode(player)) { + ignored_struct[preAlphaKey ~ callsign] = player; continue; } callsign_struct[preAlphaKey ~ callsign] = player; diff --git a/missile-frigate/Nasal/datalink.nas b/missile-frigate/Nasal/datalink.nas index c93ab48..ef4226c 100644 --- a/missile-frigate/Nasal/datalink.nas +++ b/missile-frigate/Nasal/datalink.nas @@ -452,9 +452,8 @@ var receive_loop = func { if (!mp.getValue("valid")) continue; var callsign = mp.getValue("callsign"); if (callsign == nil) continue; - if(multiplayer.ignore[callsign] == 1) { - continue; - } + if (damage.isIgnoredNode(mp)) continue; + callsign_to_index[callsign] = idx; var data = mp.getValue(mp_path); diff --git a/oprf-versions.json b/oprf-versions.json index ab84d14..9ad5571 100644 --- a/oprf-versions.json +++ b/oprf-versions.json @@ -1,346 +1,350 @@ { - "vector": [ - { - "version": "2.0.3", - "path": "BUK-M2/Nasal/vector.nas" - }, - { - "version": "2.0.3", - "path": "depot/Nasal/vector.nas" - }, - { - "version": "2.0.3", - "path": "fleet/Nasal/vector.nas" - }, - { - "version": "2.0.3", - "path": "Frigate/Nasal/vector.nas" - }, - { - "version": "2.0.3", - "path": "gci-radar/Nasal/vector.nas" - }, - { - "version": "2.0.3", - "path": "groundtarget/Nasal/vector.nas" - }, - { - "version": "2.0.3", - "path": "MIM-104D/Nasal/vector.nas" - }, - { - "version": "2.0.3", - "path": "missile-frigate/Nasal/vector.nas" - }, - { - "version": "2.0.3", - "path": "S-200/Nasal/vector.nas" - }, - { - "version": "2.0.3", - "path": "S-300/Nasal/vector.nas" - }, - { - "version": "2.0.3", - "path": "S-75/Nasal/vector.nas" - }, - { - "version": "2.0.3", - "path": "SA-3/Nasal/vector.nas" - }, - { - "version": "2.0.3", - "path": "SA-6/Nasal/vector.nas" - }, - { - "version": "2.0.3", - "path": "ZSU-23/Nasal/vector.nas" - } - ], - "missile-code": [ - { - "version": "1.2.0", - "path": "BUK-M2/Nasal/guided-missiles.nas" - }, - { - "version": "1.2.0", - "path": "MIM-104D/Nasal/guided-missiles.nas" - }, - { - "version": "1.2.0", - "path": "S-75/Nasal/guided-missiles.nas" - }, - { - "version": "1.2.0", - "path": "SA-3/Nasal/guided-missiles.nas" - }, - { - "version": "1.2.0", - "path": "SA-6/Nasal/guided-missiles.nas" - } - ], - "damage": [ - { - "version": "1.4.13", - "path": "BUK-M2/Nasal/damage.nas" - }, - { - "version": "1.4.13", - "path": "depot/Nasal/damage.nas" - }, - { - "version": "1.4.13", - "path": "fleet/Nasal/damage.nas" - }, - { - "version": "1.4.13", - "path": "Frigate/Nasal/damage.nas" - }, - { - "version": "1.4.13", - "path": "gci-radar/Nasal/damage.nas" - }, - { - "version": "1.4.13", - "path": "groundtarget/Nasal/damage.nas" - }, - { - "version": "1.4.13", - "path": "MIM-104D/Nasal/damage.nas" - }, - { - "version": "1.4.13", - "path": "missile-frigate/Nasal/damage.nas" - }, - { - "version": "1.4.13", - "path": "S-200/Nasal/damage.nas" - }, - { - "version": "1.4.13", - "path": "S-300/Nasal/damage.nas" - }, - { - "version": "1.4.13", - "path": "S-75/Nasal/damage.nas" - }, - { - "version": "1.4.13", - "path": "SA-3/Nasal/damage.nas" - }, - { - "version": "1.4.13", - "path": "SA-6/Nasal/damage.nas" - }, - { - "version": "1.4.13", - "path": "ZSU-23/Nasal/damage.nas" - } - ], - "datalink": [ - { - "version": "1.1.1", - "path": "BUK-M2/Nasal/datalink.nas" - }, - { - "version": "1.1.1", - "path": "fleet/Nasal/datalink.nas" - }, - { - "version": "1.1.1", - "path": "MIM-104D/Nasal/datalink.nas" - }, - { - "version": "1.1.1", - "path": "missile-frigate/Nasal/datalink.nas" - }, - { - "version": "1.1.1", - "path": "S-200/Nasal/datalink.nas" - }, - { - "version": "1.1.1", - "path": "S-300/Nasal/datalink.nas" - }, - { - "version": "1.1.1", - "path": "S-75/Nasal/datalink.nas" - }, - { - "version": "1.1.1", - "path": "SA-3/Nasal/datalink.nas" - }, - { - "version": "1.1.1", - "path": "SA-6/Nasal/datalink.nas" - }, - { - "version": "1.1.1", - "path": "ZSU-23/Nasal/datalink.nas" - } - ], - "armament-notification": [ - { - "version": "1.1.0", - "path": "BUK-M2/Nasal/ArmamentNotification.nas" - }, - { - "version": "1.1.0", - "path": "depot/Nasal/ArmamentNotification.nas" - }, - { - "version": "1.1.0", - "path": "fleet/Nasal/ArmamentNotification.nas" - }, - { - "version": "1.1.0", - "path": "Frigate/Nasal/ArmamentNotification.nas" - }, - { - "version": "1.1.0", - "path": "gci-radar/Nasal/ArmamentNotification.nas" - }, - { - "version": "1.1.0", - "path": "groundtarget/Nasal/ArmamentNotification.nas" - }, - { - "version": "1.1.0", - "path": "MIM-104D/Nasal/ArmamentNotification.nas" - }, - { - "version": "1.1.0", - "path": "missile-frigate/Nasal/ArmamentNotification.nas" - }, - { - "version": "1.1.0", - "path": "S-200/Nasal/ArmamentNotification.nas" - }, - { - "version": "1.1.0", - "path": "S-300/Nasal/ArmamentNotification.nas" - }, - { - "version": "1.1.0", - "path": "S-75/Nasal/ArmamentNotification.nas" - }, - { - "version": "1.1.0", - "path": "SA-3/Nasal/ArmamentNotification.nas" - }, - { - "version": "1.1.0", - "path": "SA-6/Nasal/ArmamentNotification.nas" - }, - { - "version": "1.1.0", - "path": "ZSU-23/Nasal/ArmamentNotification.nas" - } - ], - "geo-bridged-transmitter": [ - { - "version": "1.0.1", - "path": "BUK-M2/Nasal/GeoBridgedTransmitter.nas" - }, - { - "version": "1.0.1", - "path": "depot/Nasal/GeoBridgedTransmitter.nas" - }, - { - "version": "1.0.1", - "path": "fleet/Nasal/GeoBridgedTransmitter.nas" - }, - { - "version": "1.0.1", - "path": "Frigate/Nasal/GeoBridgedTransmitter.nas" - }, - { - "version": "1.0.1", - "path": "gci-radar/Nasal/GeoBridgedTransmitter.nas" - }, - { - "version": "1.0.1", - "path": "groundtarget/Nasal/GeoBridgedTransmitter.nas" - }, - { - "version": "1.0.1", - "path": "MIM-104D/Nasal/GeoBridgedTransmitter.nas" - }, - { - "version": "1.0.1", - "path": "missile-frigate/Nasal/GeoBridgedTransmitter.nas" - }, - { - "version": "1.0.1", - "path": "S-200/Nasal/GeoBridgedTransmitter.nas" - }, - { - "version": "1.0.1", - "path": "S-300/Nasal/GeoBridgedTransmitter.nas" - }, - { - "version": "1.0.1", - "path": "S-75/Nasal/GeoBridgedTransmitter.nas" - }, - { - "version": "1.0.1", - "path": "SA-3/Nasal/GeoBridgedTransmitter.nas" - }, - { - "version": "1.0.1", - "path": "SA-6/Nasal/GeoBridgedTransmitter.nas" - }, - { - "version": "1.0.1", - "path": "ZSU-23/Nasal/GeoBridgedTransmitter.nas" - } - ], - "asset-fire-control": [ - { - "version": "1.0.3", - "path": "BUK-M2/Nasal/fire-control.nas" - }, - { - "version": "1.0.3", - "path": "MIM-104D/Nasal/fire-control.nas" - }, - { - "version": "1.0.3", - "path": "S-75/Nasal/fire-control.nas" - }, - { - "version": "1.0.3", - "path": "SA-3/Nasal/fire-control.nas" - }, - { - "version": "1.0.3", - "path": "SA-6/Nasal/fire-control.nas" - } - ], - "asset-radar-logic": [ - { - "version": "1.1.0", - "path": "BUK-M2/Nasal/radar-logic.nas" - }, - { - "version": "1.1.0", - "path": "MIM-104D/Nasal/radar-logic.nas" - }, - { - "version": "1.1.0", - "path": "S-75/Nasal/radar-logic.nas" - }, - { - "version": "1.1.0", - "path": "SA-3/Nasal/radar-logic.nas" - }, - { - "version": "1.1.0", - "path": "SA-6/Nasal/radar-logic.nas" - }, - { - "version": "1.1.0", - "path": "gci-radar/Nasal/radar-logic.nas" - } - ] + "version": 1, + "last_updated": "2026-08-21T22:32:58.833925+00:00", + "data": { + "vector": [ + { + "version": "2.0.3", + "path": "BUK-M2/Nasal/vector.nas" + }, + { + "version": "2.0.3", + "path": "depot/Nasal/vector.nas" + }, + { + "version": "2.0.3", + "path": "fleet/Nasal/vector.nas" + }, + { + "version": "2.0.3", + "path": "Frigate/Nasal/vector.nas" + }, + { + "version": "2.0.3", + "path": "gci-radar/Nasal/vector.nas" + }, + { + "version": "2.0.3", + "path": "groundtarget/Nasal/vector.nas" + }, + { + "version": "2.0.3", + "path": "MIM-104D/Nasal/vector.nas" + }, + { + "version": "2.0.3", + "path": "missile-frigate/Nasal/vector.nas" + }, + { + "version": "2.0.3", + "path": "S-200/Nasal/vector.nas" + }, + { + "version": "2.0.3", + "path": "S-300/Nasal/vector.nas" + }, + { + "version": "2.0.3", + "path": "S-75/Nasal/vector.nas" + }, + { + "version": "2.0.3", + "path": "SA-3/Nasal/vector.nas" + }, + { + "version": "2.0.3", + "path": "SA-6/Nasal/vector.nas" + }, + { + "version": "2.0.3", + "path": "ZSU-23/Nasal/vector.nas" + } + ], + "missile-code": [ + { + "version": "1.2.4", + "path": "BUK-M2/Nasal/guided-missiles.nas" + }, + { + "version": "1.2.4", + "path": "MIM-104D/Nasal/guided-missiles.nas" + }, + { + "version": "1.2.4", + "path": "S-75/Nasal/guided-missiles.nas" + }, + { + "version": "1.2.4", + "path": "SA-3/Nasal/guided-missiles.nas" + }, + { + "version": "1.2.4", + "path": "SA-6/Nasal/guided-missiles.nas" + } + ], + "damage": [ + { + "version": "1.4.14", + "path": "BUK-M2/Nasal/damage.nas" + }, + { + "version": "1.4.14", + "path": "depot/Nasal/damage.nas" + }, + { + "version": "1.4.14", + "path": "fleet/Nasal/damage.nas" + }, + { + "version": "1.4.14", + "path": "Frigate/Nasal/damage.nas" + }, + { + "version": "1.4.14", + "path": "gci-radar/Nasal/damage.nas" + }, + { + "version": "1.4.14", + "path": "groundtarget/Nasal/damage.nas" + }, + { + "version": "1.4.14", + "path": "MIM-104D/Nasal/damage.nas" + }, + { + "version": "1.4.14", + "path": "missile-frigate/Nasal/damage.nas" + }, + { + "version": "1.4.14", + "path": "S-200/Nasal/damage.nas" + }, + { + "version": "1.4.14", + "path": "S-300/Nasal/damage.nas" + }, + { + "version": "1.4.14", + "path": "S-75/Nasal/damage.nas" + }, + { + "version": "1.4.14", + "path": "SA-3/Nasal/damage.nas" + }, + { + "version": "1.4.14", + "path": "SA-6/Nasal/damage.nas" + }, + { + "version": "1.4.14", + "path": "ZSU-23/Nasal/damage.nas" + } + ], + "datalink": [ + { + "version": "1.1.2", + "path": "BUK-M2/Nasal/datalink.nas" + }, + { + "version": "1.1.2", + "path": "fleet/Nasal/datalink.nas" + }, + { + "version": "1.1.2", + "path": "MIM-104D/Nasal/datalink.nas" + }, + { + "version": "1.1.2", + "path": "missile-frigate/Nasal/datalink.nas" + }, + { + "version": "1.1.2", + "path": "S-200/Nasal/datalink.nas" + }, + { + "version": "1.1.2", + "path": "S-300/Nasal/datalink.nas" + }, + { + "version": "1.1.2", + "path": "S-75/Nasal/datalink.nas" + }, + { + "version": "1.1.2", + "path": "SA-3/Nasal/datalink.nas" + }, + { + "version": "1.1.2", + "path": "SA-6/Nasal/datalink.nas" + }, + { + "version": "1.1.2", + "path": "ZSU-23/Nasal/datalink.nas" + } + ], + "armament-notification": [ + { + "version": "1.1.0", + "path": "BUK-M2/Nasal/ArmamentNotification.nas" + }, + { + "version": "1.1.0", + "path": "depot/Nasal/ArmamentNotification.nas" + }, + { + "version": "1.1.0", + "path": "fleet/Nasal/ArmamentNotification.nas" + }, + { + "version": "1.1.0", + "path": "Frigate/Nasal/ArmamentNotification.nas" + }, + { + "version": "1.1.0", + "path": "gci-radar/Nasal/ArmamentNotification.nas" + }, + { + "version": "1.1.0", + "path": "groundtarget/Nasal/ArmamentNotification.nas" + }, + { + "version": "1.1.0", + "path": "MIM-104D/Nasal/ArmamentNotification.nas" + }, + { + "version": "1.1.0", + "path": "missile-frigate/Nasal/ArmamentNotification.nas" + }, + { + "version": "1.1.0", + "path": "S-200/Nasal/ArmamentNotification.nas" + }, + { + "version": "1.1.0", + "path": "S-300/Nasal/ArmamentNotification.nas" + }, + { + "version": "1.1.0", + "path": "S-75/Nasal/ArmamentNotification.nas" + }, + { + "version": "1.1.0", + "path": "SA-3/Nasal/ArmamentNotification.nas" + }, + { + "version": "1.1.0", + "path": "SA-6/Nasal/ArmamentNotification.nas" + }, + { + "version": "1.1.0", + "path": "ZSU-23/Nasal/ArmamentNotification.nas" + } + ], + "geo-bridged-transmitter": [ + { + "version": "1.0.1", + "path": "BUK-M2/Nasal/GeoBridgedTransmitter.nas" + }, + { + "version": "1.0.1", + "path": "depot/Nasal/GeoBridgedTransmitter.nas" + }, + { + "version": "1.0.1", + "path": "fleet/Nasal/GeoBridgedTransmitter.nas" + }, + { + "version": "1.0.1", + "path": "Frigate/Nasal/GeoBridgedTransmitter.nas" + }, + { + "version": "1.0.1", + "path": "gci-radar/Nasal/GeoBridgedTransmitter.nas" + }, + { + "version": "1.0.1", + "path": "groundtarget/Nasal/GeoBridgedTransmitter.nas" + }, + { + "version": "1.0.1", + "path": "MIM-104D/Nasal/GeoBridgedTransmitter.nas" + }, + { + "version": "1.0.1", + "path": "missile-frigate/Nasal/GeoBridgedTransmitter.nas" + }, + { + "version": "1.0.1", + "path": "S-200/Nasal/GeoBridgedTransmitter.nas" + }, + { + "version": "1.0.1", + "path": "S-300/Nasal/GeoBridgedTransmitter.nas" + }, + { + "version": "1.0.1", + "path": "S-75/Nasal/GeoBridgedTransmitter.nas" + }, + { + "version": "1.0.1", + "path": "SA-3/Nasal/GeoBridgedTransmitter.nas" + }, + { + "version": "1.0.1", + "path": "SA-6/Nasal/GeoBridgedTransmitter.nas" + }, + { + "version": "1.0.1", + "path": "ZSU-23/Nasal/GeoBridgedTransmitter.nas" + } + ], + "asset-fire-control": [ + { + "version": "1.0.4", + "path": "BUK-M2/Nasal/fire-control.nas" + }, + { + "version": "1.0.4", + "path": "MIM-104D/Nasal/fire-control.nas" + }, + { + "version": "1.0.4", + "path": "S-75/Nasal/fire-control.nas" + }, + { + "version": "1.0.4", + "path": "SA-3/Nasal/fire-control.nas" + }, + { + "version": "1.0.4", + "path": "SA-6/Nasal/fire-control.nas" + } + ], + "asset-radar-logic": [ + { + "version": "1.1.0", + "path": "BUK-M2/Nasal/radar-logic.nas" + }, + { + "version": "1.1.0", + "path": "MIM-104D/Nasal/radar-logic.nas" + }, + { + "version": "1.1.0", + "path": "S-75/Nasal/radar-logic.nas" + }, + { + "version": "1.1.0", + "path": "SA-3/Nasal/radar-logic.nas" + }, + { + "version": "1.1.0", + "path": "SA-6/Nasal/radar-logic.nas" + }, + { + "version": "1.1.0", + "path": "gci-radar/Nasal/radar-logic.nas" + } + ] + } } \ No newline at end of file