Auto-Update shared Files

vector is up-to-date (2.0.3) (BUK-M2/Nasal/vector.nas)
vector is up-to-date (2.0.3) (depot/Nasal/vector.nas)
vector is up-to-date (2.0.3) (fleet/Nasal/vector.nas)
vector is up-to-date (2.0.3) (Frigate/Nasal/vector.nas)
vector is up-to-date (2.0.3) (gci-radar/Nasal/vector.nas)
vector is up-to-date (2.0.3) (groundtarget/Nasal/vector.nas)
vector is up-to-date (2.0.3) (MIM-104D/Nasal/vector.nas)
vector is up-to-date (2.0.3) (missile-frigate/Nasal/vector.nas)
vector is up-to-date (2.0.3) (S-200/Nasal/vector.nas)
vector is up-to-date (2.0.3) (S-300/Nasal/vector.nas)
vector is up-to-date (2.0.3) (S-75/Nasal/vector.nas)
Fetched vector None->2.0.3 (SA-3/Nasal/vector.nas)
vector is up-to-date (2.0.3) (SA-6/Nasal/vector.nas)
vector is up-to-date (2.0.3) (ZSU-23/Nasal/vector.nas)
missile-code is up-to-date (1.1.2) (BUK-M2/Nasal/guided-missiles.nas)
missile-code is up-to-date (1.1.2) (MIM-104D/Nasal/guided-missiles.nas)
missile-code is up-to-date (1.1.2) (S-75/Nasal/guided-missiles.nas)
Fetched missile-code None->1.1.2 (SA-3/Nasal/guided-missiles.nas)
missile-code is up-to-date (1.1.2) (SA-6/Nasal/guided-missiles.nas)
damage is up-to-date (1.4.3) (BUK-M2/Nasal/damage.nas)
damage is up-to-date (1.4.3) (depot/Nasal/damage.nas)
damage is up-to-date (1.4.3) (fleet/Nasal/damage.nas)
damage is up-to-date (1.4.3) (Frigate/Nasal/damage.nas)
damage is up-to-date (1.4.3) (gci-radar/Nasal/damage.nas)
damage is up-to-date (1.4.3) (groundtarget/Nasal/damage.nas)
damage is up-to-date (1.4.3) (MIM-104D/Nasal/damage.nas)
damage is up-to-date (1.4.3) (missile-frigate/Nasal/damage.nas)
damage is up-to-date (1.4.3) (S-200/Nasal/damage.nas)
damage is up-to-date (1.4.3) (S-300/Nasal/damage.nas)
damage is up-to-date (1.4.3) (S-75/Nasal/damage.nas)
Fetched damage None->1.4.3 (SA-3/Nasal/damage.nas)
damage is up-to-date (1.4.3) (SA-6/Nasal/damage.nas)
damage is up-to-date (1.4.3) (ZSU-23/Nasal/damage.nas)
datalink is up-to-date (1.1.0) (BUK-M2/Nasal/datalink.nas)
datalink is up-to-date (1.1.0) (fleet/Nasal/datalink.nas)
datalink is up-to-date (1.1.0) (MIM-104D/Nasal/datalink.nas)
datalink is up-to-date (1.1.0) (missile-frigate/Nasal/datalink.nas)
datalink is up-to-date (1.1.0) (S-200/Nasal/datalink.nas)
datalink is up-to-date (1.1.0) (S-300/Nasal/datalink.nas)
datalink is up-to-date (1.1.0) (S-75/Nasal/datalink.nas)
Fetched datalink None->1.1.0 (SA-3/Nasal/datalink.nas)
datalink is up-to-date (1.1.0) (SA-6/Nasal/datalink.nas)
datalink is up-to-date (1.1.0) (ZSU-23/Nasal/datalink.nas)
armament-notification is up-to-date (1.1.0) (BUK-M2/Nasal/ArmamentNotification.nas)
armament-notification is up-to-date (1.1.0) (depot/Nasal/ArmamentNotification.nas)
armament-notification is up-to-date (1.1.0) (fleet/Nasal/ArmamentNotification.nas)
armament-notification is up-to-date (1.1.0) (Frigate/Nasal/ArmamentNotification.nas)
armament-notification is up-to-date (1.1.0) (gci-radar/Nasal/ArmamentNotification.nas)
armament-notification is up-to-date (1.1.0) (groundtarget/Nasal/ArmamentNotification.nas)
armament-notification is up-to-date (1.1.0) (MIM-104D/Nasal/ArmamentNotification.nas)
armament-notification is up-to-date (1.1.0) (missile-frigate/Nasal/ArmamentNotification.nas)
armament-notification is up-to-date (1.1.0) (S-200/Nasal/ArmamentNotification.nas)
armament-notification is up-to-date (1.1.0) (S-300/Nasal/ArmamentNotification.nas)
armament-notification is up-to-date (1.1.0) (S-75/Nasal/ArmamentNotification.nas)
Fetched armament-notification None->1.1.0 (SA-3/Nasal/ArmamentNotification.nas)
armament-notification is up-to-date (1.1.0) (SA-6/Nasal/ArmamentNotification.nas)
armament-notification is up-to-date (1.1.0) (ZSU-23/Nasal/ArmamentNotification.nas)
geo-bridged-transmitter is up-to-date (1.0.1) (BUK-M2/Nasal/GeoBridgedTransmitter.nas)
geo-bridged-transmitter is up-to-date (1.0.1) (depot/Nasal/GeoBridgedTransmitter.nas)
geo-bridged-transmitter is up-to-date (1.0.1) (fleet/Nasal/GeoBridgedTransmitter.nas)
geo-bridged-transmitter is up-to-date (1.0.1) (Frigate/Nasal/GeoBridgedTransmitter.nas)
geo-bridged-transmitter is up-to-date (1.0.1) (gci-radar/Nasal/GeoBridgedTransmitter.nas)
geo-bridged-transmitter is up-to-date (1.0.1) (groundtarget/Nasal/GeoBridgedTransmitter.nas)
geo-bridged-transmitter is up-to-date (1.0.1) (MIM-104D/Nasal/GeoBridgedTransmitter.nas)
geo-bridged-transmitter is up-to-date (1.0.1) (missile-frigate/Nasal/GeoBridgedTransmitter.nas)
geo-bridged-transmitter is up-to-date (1.0.1) (S-200/Nasal/GeoBridgedTransmitter.nas)
geo-bridged-transmitter is up-to-date (1.0.1) (S-300/Nasal/GeoBridgedTransmitter.nas)
geo-bridged-transmitter is up-to-date (1.0.1) (S-75/Nasal/GeoBridgedTransmitter.nas)
Fetched geo-bridged-transmitter None->1.0.1 (SA-3/Nasal/GeoBridgedTransmitter.nas)
geo-bridged-transmitter is up-to-date (1.0.1) (SA-6/Nasal/GeoBridgedTransmitter.nas)
geo-bridged-transmitter is up-to-date (1.0.1) (ZSU-23/Nasal/GeoBridgedTransmitter.nas)
asset-fire-control is up-to-date (1.0.0) (BUK-M2/Nasal/fire-control.nas)
asset-fire-control is up-to-date (1.0.0) (MIM-104D/Nasal/fire-control.nas)
asset-fire-control is up-to-date (1.0.0) (S-75/Nasal/fire-control.nas)
Fetched asset-fire-control None->1.0.0 (SA-3/Nasal/fire-control.nas)
asset-fire-control is up-to-date (1.0.0) (SA-6/Nasal/fire-control.nas)
asset-radar-logic is up-to-date (1.1.0) (BUK-M2/Nasal/radar-logic.nas)
asset-radar-logic is up-to-date (1.1.0) (MIM-104D/Nasal/radar-logic.nas)
asset-radar-logic is up-to-date (1.1.0) (S-75/Nasal/radar-logic.nas)
Fetched asset-radar-logic None->1.1.0 (SA-3/Nasal/radar-logic.nas)
asset-radar-logic is up-to-date (1.1.0) (SA-6/Nasal/radar-logic.nas)
asset-radar-logic is up-to-date (1.1.0) (gci-radar/Nasal/radar-logic.nas)
This commit is contained in:
github-actions[bot] 2023-12-05 00:49:37 +00:00
parent 300cecc219
commit 4917b34ffc
8 changed files with 402 additions and 98 deletions

View File

@ -87,6 +87,48 @@ var ArmamentInFlightNotification =
new_class.Flags = 0; # 8 bits for whatever. new_class.Flags = 0; # 8 bits for whatever.
new_class.UniqueIdentity = _unique; new_class.UniqueIdentity = _unique;
new_class.isValid = func {
var valid = "";
var limitMin = -124;
var limitMax = 123;
# 1 byte integer
if (int(me.Kind) > limitMax or int(me.Kind) < limitMin) {
valid ~= "|ArmamentInFlight.Kind is "~me.Kind;
}
# 1 byte integer
if (int(me.SecondaryKind) > limitMax or int(me.SecondaryKind) < limitMin) {
valid ~= "|ArmamentInFlight.SecondaryKind is "~me.SecondaryKind;
}
# 1 byte float
if (int((me.u_fps-3348)*0.03703) > limitMax or int((me.u_fps-3348)*0.03703) < limitMin) {
valid ~= "|ArmamentInFlight.u_fps is "~me.u_fps;
}
# 1 byte float
if (int(me.Pitch*1.38) > limitMax or int(me.Pitch*1.38) < limitMin) {
valid ~= "|ArmamentInFlight.Pitch is "~me.Pitch;
}
# 1 byte float
if (int(geo.normdeg180(me.Heading)/1.54) > limitMax or int(geo.normdeg180(me.Heading)/1.54) < limitMin) {
valid ~= "|ArmamentInFlight.Heading is "~me.Heading;
}
# 1 byte integer
if (int(me.Flags) > limitMax or int(me.Flags) < limitMin) {
valid ~= "|ArmamentInFlight.Flags is "~me.Flags;
}
# 1 byte integer
if (int(me.UniqueIdentity) > limitMax or int(me.UniqueIdentity) < limitMin) {
valid ~= "|ArmamentInFlight.UniqueIdentity is "~me.UniqueIdentity;
}
# 7 byte string
if (size(me.RemoteCallsign) > 7) {
valid ~= "|ArmamentInFlight.RemoteCallsign is "~me.RemoteCallsign;
}
if (valid != "") {
print("\nEMESARY ENCODING WILL FAIL:");
print(" "~valid);
}
};
new_class.GetBridgeMessageNotificationTypeKey = func { new_class.GetBridgeMessageNotificationTypeKey = func {
return new_class.NotificationType~"."~new_class.Ident~"."~new_class.UniqueIndex; return new_class.NotificationType~"."~new_class.Ident~"."~new_class.UniqueIndex;
}; };

View File

@ -27,18 +27,18 @@
#i.e. change to [notifications.ArmamentInFlightNotification.new(nil), notifications.ArmamentNotification.new(nil)]; #i.e. change to [notifications.ArmamentInFlightNotification.new(nil), notifications.ArmamentNotification.new(nil)];
var geoRoutedNotifications = [notifications.ArmamentInFlightNotification.new()]; var geoRoutedNotifications = [notifications.ArmamentInFlightNotification.new()];
var geoBridgedTransmitter = emesary.Transmitter.new("geoOutgoingBridge"); var geoBridgedTransmitter = emesary.Transmitter.new("geoOutgoingBridge");
var geooutgoingBridge = emesary_mp_bridge.OutgoingMPBridge.new("patriotmp.geo",geoRoutedNotifications, 18, "", geoBridgedTransmitter); var geooutgoingBridge = emesary_mp_bridge.OutgoingMPBridge.new("mp.geo",geoRoutedNotifications, 18, "", geoBridgedTransmitter);
# bridge should be tuned to be around 90% of the packet size full. # bridge should be tuned to be around 90% of the packet size full.
geooutgoingBridge.TransmitFrequencySeconds = 0.75; geooutgoingBridge.TransmitFrequencySeconds = 0.75;
geooutgoingBridge.MPStringMaxLen = 150; geooutgoingBridge.MPStringMaxLen = 175; # each is 34 bytes
emesary_mp_bridge.IncomingMPBridge.startMPBridge(geoRoutedNotifications, 18, emesary.GlobalTransmitter); emesary_mp_bridge.IncomingMPBridge.startMPBridge(geoRoutedNotifications, 18, emesary.GlobalTransmitter);
#----- bridge hit (armament) notifications #----- bridge hit (armament) notifications
var hitRoutedNotifications = [notifications.ArmamentNotification.new(),notifications.StaticNotification.new()]; var hitRoutedNotifications = [notifications.ArmamentNotification.new(),notifications.StaticNotification.new()];
var hitBridgedTransmitter = emesary.Transmitter.new("armamentNotificationBridge"); var hitBridgedTransmitter = emesary.Transmitter.new("armamentNotificationBridge");
var hitoutgoingBridge = emesary_mp_bridge.OutgoingMPBridge.new("patriotmp.hit",hitRoutedNotifications, 19, "", hitBridgedTransmitter); var hitoutgoingBridge = emesary_mp_bridge.OutgoingMPBridge.new("mp.hit",hitRoutedNotifications, 19, "", hitBridgedTransmitter);
hitoutgoingBridge.TransmitFrequencySeconds = 1.5; hitoutgoingBridge.TransmitFrequencySeconds = 1.5;
hitoutgoingBridge.MPStringMaxLen = 120; hitoutgoingBridge.MPStringMaxLen = 120;
emesary_mp_bridge.IncomingMPBridge.startMPBridge(hitRoutedNotifications, 19, emesary.GlobalTransmitter); emesary_mp_bridge.IncomingMPBridge.startMPBridge(hitRoutedNotifications, 19, emesary.GlobalTransmitter);
@ -46,8 +46,38 @@ emesary_mp_bridge.IncomingMPBridge.startMPBridge(hitRoutedNotifications, 19, eme
#----- bridge object notifications #----- bridge object notifications
var objectRoutedNotifications = [notifications.ObjectInFlightNotification.new()]; var objectRoutedNotifications = [notifications.ObjectInFlightNotification.new()];
var objectBridgedTransmitter = emesary.Transmitter.new("objectNotificationBridge"); var objectBridgedTransmitter = emesary.Transmitter.new("objectNotificationBridge");
var objectoutgoingBridge = emesary_mp_bridge.OutgoingMPBridge.new("patriotmp.object",objectRoutedNotifications, 17, "", objectBridgedTransmitter); var objectoutgoingBridge = emesary_mp_bridge.OutgoingMPBridge.new("mp.object",objectRoutedNotifications, 17, "", objectBridgedTransmitter);
objectoutgoingBridge.TransmitFrequencySeconds = 0.2; objectoutgoingBridge.TransmitFrequencySeconds = 0.2;
objectoutgoingBridge.MessageLifeTime = 1; objectoutgoingBridge.MessageLifeTime = 1;
objectoutgoingBridge.MPStringMaxLen = 150; objectoutgoingBridge.MPStringMaxLen = 150;
emesary_mp_bridge.IncomingMPBridge.startMPBridge(objectRoutedNotifications, 17, emesary.GlobalTransmitter); emesary_mp_bridge.IncomingMPBridge.startMPBridge(objectRoutedNotifications, 17, emesary.GlobalTransmitter);
#
# debug all messages - this can be removed when testing isn't required.
var debugRecipient = emesary.Recipient.new("Debug");
debugRecipient.Receive = func(notification)
{
if (notification.NotificationType != "FrameNotification") {
print ("recv(0): type=",notification.NotificationType, " fromIncoming=",notification.FromIncomingBridge);
if (notification.NotificationType == "ArmamentInFlightNotification") {
print("recv(1): ",notification.NotificationType, " ", notification.Ident);
debug.dump(notification);
} else if (notification.NotificationType == "ArmamentNotification") {
if (notification.FromIncomingBridge) {
print("recv(2): ",notification.NotificationType, " ", notification.Ident,
" Kind=",notification.Kind,
" SecondaryKind=",notification.SecondaryKind,
" RelativeAltitude=",notification.RelativeAltitude,
" Distance=",notification.Distance,
" Bearing=",notification.Bearing,
" RemoteCallsign=",notification.RemoteCallsign);
debug.dump(notification);
}
}
}
return emesary.Transmitter.ReceiptStatus_NotProcessed; # we're not processing it, just looking
}
# uncomment next line to activate debug recipient.
#emesary.GlobalTransmitter.Register(debugRecipient);

View File

@ -27,7 +27,7 @@ var mlw_max=getprop("payload/d-config/mlw_max"); #
var auto_flare_caller = getprop("payload/d-config/auto_flare_caller"); # If damage.nas should detect flare releases, or if function is called from somewhere in aircraft var auto_flare_caller = getprop("payload/d-config/auto_flare_caller"); # If damage.nas should detect flare releases, or if function is called from somewhere in aircraft
############################################################################################################################ ############################################################################################################################
srand();
var hp = hp_max; var hp = hp_max;
setprop("sam/damage", math.max(0,100*hp/hp_max));#used in HUD setprop("sam/damage", math.max(0,100*hp/hp_max));#used in HUD
@ -60,6 +60,7 @@ var shells = {
"DEFA 554": [14,0.060], # 30x113mm Mirage, 220g "DEFA 554": [14,0.060], # 30x113mm Mirage, 220g
"20mm APDS": [15,0.030], # CIWS "20mm APDS": [15,0.030], # CIWS
"LAU-10": [16,0.500], # 127mm, ~4-7kg warhead "LAU-10": [16,0.500], # 127mm, ~4-7kg warhead
# Max id is 41
}; };
# lbs of warheads is explosive+fragmentation+fuse, so total warhead mass. # lbs of warheads is explosive+fragmentation+fuse, so total warhead mass.
@ -136,7 +137,7 @@ var warheads = {
"R.530": [67, 55.00,0,0], "R.530": [67, 55.00,0,0],
"MK-82AIR": [68, 192.00,1,0], "MK-82AIR": [68, 192.00,1,0],
"AIM-9M": [69, 20.80,0,0], "AIM-9M": [69, 20.80,0,0],
"R-73 RMD-1": [70, 16.31,0,0],# automat Mig29/su27 "R-73 RVV-MD": [70, 16.31,0,0],# automat su34
"Meteor": [71, 55.00,0,0], "Meteor": [71, 55.00,0,0],
"MICA-EM": [72, 30.00,0,0], "MICA-EM": [72, 30.00,0,0],
"MICA-IR": [73, 30.00,0,0], "MICA-IR": [73, 30.00,0,0],
@ -148,7 +149,7 @@ var warheads = {
"R-55": [79, 20.06,0,0], "R-55": [79, 20.06,0,0],
"R-60": [80, 6.60,0,0], "R-60": [80, 6.60,0,0],
"R-60M": [81, 7.70,0,0], "R-60M": [81, 7.70,0,0],
"R-73E": [82, 16.31,0,0], "R-73": [82, 16.31,0,0],# automat mig23/mig29/su-27
"R-77": [83, 49.60,0,0], "R-77": [83, 49.60,0,0],
"R74": [84, 16.00,0,0], "R74": [84, 16.00,0,0],
"RB-05A": [85, 353.00,1,0], "RB-05A": [85, 353.00,1,0],
@ -165,8 +166,9 @@ var warheads = {
"3M9": [96, 125.00,0,0],# 3M9M3 Missile used with 2K12/SA-6 "3M9": [96, 125.00,0,0],# 3M9M3 Missile used with 2K12/SA-6
"5V28V": [97, 478.00,0,0],# Missile used with S-200D/SA-5 "5V28V": [97, 478.00,0,0],# Missile used with S-200D/SA-5
"AIM-9X": [98, 20.80,0,0], "AIM-9X": [98, 20.80,0,0],
"5V27": [99, 150.00,0,0], "R-23R": [99, 55.00,0,0],# mig23 fox 1
"AGM-65G": [100, 150.00,1,0], "5V27": [100, 150.00,0,0],# Missile used with SA-3/S-125
# Max id is 180
}; };
var AIR_RADAR = "air"; var AIR_RADAR = "air";
@ -184,29 +186,33 @@ var radar_signatures = {
"m2000-5B": AIR_RADAR, "m2000-5B": AIR_RADAR,
"MiG-21bis": AIR_RADAR, "MiG-21bis": AIR_RADAR,
"MiG-21MF-75": AIR_RADAR, "MiG-21MF-75": AIR_RADAR,
"Mig-23MLD": AIR_RADAR,
"MiG-29": AIR_RADAR, "MiG-29": AIR_RADAR,
"SU-27": AIR_RADAR, "SU-27": AIR_RADAR,
"EC-137R": AIR_RADAR, "EC-137R": AIR_RADAR,
"E-3R": AIR_RADAR,
"E-3": AIR_RADAR,
"RC-137R": AIR_RADAR, "RC-137R": AIR_RADAR,
"E-8R": AIR_RADAR, "E-8R": AIR_RADAR,
"EC-137D": AIR_RADAR, "EC-137D": AIR_RADAR,
"Mig-28": AIR_RADAR, "Mig-28": AIR_RADAR,
"SA-6": "gnd-06",#Air radar tone chosen so that there is at least some lock tone until asset-specific is created "SA-6": "gnd-06",
"s-200": "gnd-05", "s-200": "gnd-05",
"ZSU-23-4M": "gnd-23", "ZSU-23-4M": "gnd-23",
"S-75": "gnd-02", "S-75": "gnd-02",
"buk-m2": "gnd-11", "buk-m2": "gnd-17",
"s-300": "gnd-20", "s-300": "gnd-20",
"MIM104D": "gnd-p2", "MIM104D": "gnd-p2",
"missile_frigate": "gnd-nk", "missile_frigate": "gnd-nk",
"fleet": "gnd-nk", "fleet": "gnd-nk",
"SA-3": "gnd-p2",
}; };
var id2warhead = []; var id2warhead = [];
var launched = {};# callsign: elapsed-sec var launched = {};# callsign: elapsed-sec
var approached = {};# callsign: uniqueID var approached = {};# callsign: uniqueID
var heavy_smoke = [61,62,63,65,92,96,97,99]; var heavy_smoke = [61,62,63,65,92,96,97,100];
var k = keys(warheads); var k = keys(warheads);
@ -310,7 +316,7 @@ var DamageRecipient =
var radarOn = bits.test(notification.Flags, 0); var radarOn = bits.test(notification.Flags, 0);
var thrustOn = bits.test(notification.Flags, 1); var thrustOn = bits.test(notification.Flags, 1);
var CWIOn = bits.test(notification.Flags, 2); var CWIOn = bits.test(notification.Flags, 2);
var index = notification.SecondaryKind-21; var index = DamageRecipient.emesaryID2typeID(notification.SecondaryKind);
var typ = id2warhead[index]; var typ = id2warhead[index];
if (notification.Kind == MOVE) { if (notification.Kind == MOVE) {
@ -404,6 +410,7 @@ var DamageRecipient =
setprop("payload/armament/MAW-active", 1);# resets every 1 seconds setprop("payload/armament/MAW-active", 1);# resets every 1 seconds
} elsif (CWIOn) { } elsif (CWIOn) {
setprop("payload/armament/MAW-semiactive", 1);# resets every 1 seconds setprop("payload/armament/MAW-semiactive", 1);# resets every 1 seconds
if (notification.Callsign != nil) setprop("payload/armament/MAW-semiactive-callsign", notification.Callsign);# resets every 1 seconds
} }
MAW_elapsed = elapsed; MAW_elapsed = elapsed;
var appr = approached[notification.Callsign~notification.UniqueIdentity]; var appr = approached[notification.Callsign~notification.UniqueIdentity];
@ -412,8 +419,8 @@ var DamageRecipient =
#printf("Missile Approach Warning from %03d degrees.", bearing); #printf("Missile Approach Warning from %03d degrees.", bearing);
damageLog.push(sprintf("Missile Approach Warning from %03d degrees from %s.", bearing, notification.Callsign)); damageLog.push(sprintf("Missile Approach Warning from %03d degrees from %s.", bearing, notification.Callsign));
if (rwr_to_screen) screen.log.write(sprintf("Missile Approach Warning from %03d degrees.", bearing), 1,0.5,0);# temporary till someone models a RWR in RIO seat if (rwr_to_screen) screen.log.write(sprintf("Missile Approach Warning from %03d degrees.", bearing), 1,0.5,0);# temporary till someone models a RWR in RIO seat
} else { } elsif (CWIOn) {
#printf("Missile Approach Warning"); #printf("Missile Approach Warning (semi-active).");
damageLog.push(sprintf("Missile Approach Warning from %s.", notification.Callsign)); damageLog.push(sprintf("Missile Approach Warning from %s.", notification.Callsign));
if (rwr_to_screen) screen.log.write(sprintf("Missile Approach Warning (semi-active)."), 1,0.5,0);# temporary till someone models a RWR in RIO seat if (rwr_to_screen) screen.log.write(sprintf("Missile Approach Warning (semi-active)."), 1,0.5,0);# temporary till someone models a RWR in RIO seat
} }
@ -437,9 +444,9 @@ var DamageRecipient =
# #
if (tacview_supported and tacview.starttime and (getprop("sim/multiplay/txhost") != "mpserver.opredflag.com" or m28_auto)) { if (tacview_supported and tacview.starttime and (getprop("sim/multiplay/txhost") != "mpserver.opredflag.com" or m28_auto)) {
var node = getCallsign(notification.RemoteCallsign); var node = getCallsign(notification.RemoteCallsign);
if (node != nil and notification.SecondaryKind > 20) { if (node != nil and (notification.SecondaryKind > 20 or notification.SecondaryKind < -40)) {
# its a warhead # its a warhead
var wh = id2warhead[notification.SecondaryKind - 21]; var wh = id2warhead[DamageRecipient.emesaryID2typeID(notification.SecondaryKind)];
var lbs = wh[1]; var lbs = wh[1];
var hitCoord = geo.Coord.new(); var hitCoord = geo.Coord.new();
hitCoord.set_latlon(node.getNode("position/latitude-deg").getValue(), node.getNode("position/longitude-deg").getValue(), node.getNode("position/altitude-ft").getValue()*FT2M+notification.RelativeAltitude); hitCoord.set_latlon(node.getNode("position/latitude-deg").getValue(), node.getNode("position/longitude-deg").getValue(), node.getNode("position/altitude-ft").getValue()*FT2M+notification.RelativeAltitude);
@ -476,11 +483,11 @@ var DamageRecipient =
damageLog.push(sprintf("%s hit you with %d %s.", notification.Callsign, hit_count, typ)); damageLog.push(sprintf("%s hit you with %d %s.", notification.Callsign, hit_count, typ));
nearby_explosion(); nearby_explosion();
} }
} elsif (notification.SecondaryKind > 20) { } elsif (notification.SecondaryKind > 20 or notification.SecondaryKind < -40) {
# its a warhead # its a warhead
if (m28_auto) mig28.engagedBy(notification.Callsign, 1); if (m28_auto) mig28.engagedBy(notification.Callsign, 1);
var dist = notification.Distance; var dist = notification.Distance;
var wh = id2warhead[notification.SecondaryKind - 21]; var wh = id2warhead[DamageRecipient.emesaryID2typeID(notification.SecondaryKind)];
var type = wh[4];#test code var type = wh[4];#test code
if (wh[3] == 1) { if (wh[3] == 1) {
# cluster munition # cluster munition
@ -605,7 +612,29 @@ var DamageRecipient =
return emesary.Transmitter.ReceiptStatus_NotProcessed; return emesary.Transmitter.ReceiptStatus_NotProcessed;
}; };
return new_class; return new_class;
},
typeID2emesaryID: func (typeID) {
if (typeID <= 100) {
return typeID + 21;
} elsif (typeID <= 180) {
return (typeID - 100) * -1 - 40;
} else {
print("Missile TypeID too large value, max is 180");
return 0;
} }
},
emesaryID2typeID: func (emesaryID) {
if (emesaryID > 20) {
return emesaryID - 21;
} elsif (emesaryID < -40) {
return (emesaryID + 40) * -1 + 100;
} else {
print("Missile emesaryID not a warhead");
return 0;
}
},
}; };
damage_recipient = DamageRecipient.new("DamageRecipient"); damage_recipient = DamageRecipient.new("DamageRecipient");
@ -1109,6 +1138,46 @@ var fail_systems = func (probability, factor = 100) {#this factor needs tuning a
} }
} }
} }
if (rand() < probability and rand() < probability and getprop("sim/flight-model") == "yasim") {
setprop("consumables/fuel/tank[0]/level-norm", 0);
setprop("consumables/fuel/tank[1]/level-norm", 0);
setprop("consumables/fuel/tank[2]/level-norm", 0);
setprop("consumables/fuel/tank[3]/level-norm", 0);
setprop("consumables/fuel/tank[4]/level-norm", 0);
setprop("consumables/fuel/tank[5]/level-norm", 0);
setprop("consumables/fuel/tank[6]/level-norm", 0);
setprop("consumables/fuel/tank[7]/level-norm", 0);
setprop("consumables/fuel/tank[8]/level-norm", 0);
setprop("consumables/fuel/tank[9]/level-norm", 0);
setprop("consumables/fuel/tank[10]/level-norm", 0);
setprop("consumables/fuel/tank[11]/level-norm", 0);
# Somtimes these needs to be set too:
setprop("consumables/fuel/tank[0]/level-lbs", 0);
setprop("consumables/fuel/tank[1]/level-lbs", 0);
setprop("consumables/fuel/tank[2]/level-lbs", 0);
setprop("consumables/fuel/tank[3]/level-lbs", 0);
setprop("consumables/fuel/tank[4]/level-lbs", 0);
setprop("consumables/fuel/tank[5]/level-lbs", 0);
setprop("consumables/fuel/tank[6]/level-lbs", 0);
setprop("consumables/fuel/tank[7]/level-lbs", 0);
setprop("consumables/fuel/tank[8]/level-lbs", 0);
setprop("consumables/fuel/tank[9]/level-lbs", 0);
setprop("consumables/fuel/tank[10]/level-lbs", 0);
setprop("consumables/fuel/tank[11]/level-lbs", 0);
# these will make the fraction indicator in fuel dialog not work after relocation, but they are needed:
setprop("consumables/fuel/tank[0]/capacity-m3", 0);
setprop("consumables/fuel/tank[1]/capacity-m3", 0);
setprop("consumables/fuel/tank[2]/capacity-m3", 0);
setprop("consumables/fuel/tank[3]/capacity-m3", 0);
setprop("consumables/fuel/tank[4]/capacity-m3", 0);
setprop("consumables/fuel/tank[5]/capacity-m3", 0);
setprop("consumables/fuel/tank[6]/capacity-m3", 0);
setprop("consumables/fuel/tank[7]/capacity-m3", 0);
setprop("consumables/fuel/tank[8]/capacity-m3", 0);
setprop("consumables/fuel/tank[9]/capacity-m3", 0);
setprop("consumables/fuel/tank[10]/capacity-m3", 0);
setprop("consumables/fuel/tank[11]/capacity-m3", 0);
}
return failed; return failed;
} }
@ -1138,6 +1207,51 @@ var repairYasim = func {
} }
} }
var setupYasimEngines = func {
if (getprop("engines/engine/n1") != nil and !hasMode("engines/engine")) {
var e0 = compat_failure_modes.fail_engine("engine");
FailureMgr.add_failure_mode("engines/engine", "Engine 1", e0);
}
if (getprop("engines/engine[1]/n1") != nil and !hasMode("engines/engine[1]")) {
var e1 = compat_failure_modes.fail_engine("engine[1]");
FailureMgr.add_failure_mode("engines/engine[1]", "Engine 2", e1);
}
if (getprop("engines/engine[2]/n1") != nil and !hasMode("engines/engine[2]")) {
var e2 = compat_failure_modes.fail_engine("engine[2]");
FailureMgr.add_failure_mode("engines/engine[2]", "Engine 3", e2);
}
if (getprop("engines/engine[3]/n1") != nil and !hasMode("engines/engine[3]")) {
var e3 = compat_failure_modes.fail_engine("engine[3]");
FailureMgr.add_failure_mode("engines/engine[3]", "Engine 4", e3);
}
if (getprop("engines/engine[4]/n1") != nil and !hasMode("engines/engine[4]")) {
var e4 = compat_failure_modes.fail_engine("engine[4]");
FailureMgr.add_failure_mode("engines/engine[4]", "Engine 5", e4);
}
if (getprop("engines/engine[5]/n1") != nil and !hasMode("engines/engine[5]")) {
var e5 = compat_failure_modes.fail_engine("engine[5]");
FailureMgr.add_failure_mode("engines/engine[5]", "Engine 6", e5);
}
if (getprop("engines/engine[6]/n1") != nil and !hasMode("engines/engine[6]")) {
var e6 = compat_failure_modes.fail_engine("engine[6]");
FailureMgr.add_failure_mode("engines/engine[6]", "Engine 7", e6);
}
if (getprop("engines/engine[7]/n1") != nil and !hasMode("engines/engine[7]")) {
var e7 = compat_failure_modes.fail_engine("engine[7]");
FailureMgr.add_failure_mode("engines/engine[7]", "Engine 8", e7);
}
}
settimer(setupYasimEngines, 150);
var hasMode = func (test) {
# Tests if a failure mode exist already
var modes = FailureMgr.get_failure_modes();
foreach(mode;modes) {
if (mode["id"]==test) return 1;
}
return 0;
}
setlistener("/sim/signals/reinit", repairYasim); setlistener("/sim/signals/reinit", repairYasim);
hp_f = [hp_max,hp_max,hp_max,hp_max,hp_max,hp_max,hp_max]; hp_f = [hp_max,hp_max,hp_max,hp_max,hp_max,hp_max,hp_max];
@ -1270,6 +1384,7 @@ var processCallsigns = func () {
if (getprop("sim/time/elapsed-sec")-MAW_elapsed > 1.1) { if (getprop("sim/time/elapsed-sec")-MAW_elapsed > 1.1) {
setprop("payload/armament/MAW-active", 0);# resets every 1.1 seconds without warning setprop("payload/armament/MAW-active", 0);# resets every 1.1 seconds without warning
setprop("payload/armament/MAW-semiactive", 0); setprop("payload/armament/MAW-semiactive", 0);
setprop("payload/armament/MAW-semiactive-callsign", "");
} }
# spike handling: # spike handling:
@ -1317,6 +1432,7 @@ var code_ct = func () {
#ANTIC #ANTIC
if (getprop("payload/armament/msg")) { if (getprop("payload/armament/msg")) {
setprop("sim/rendering/redout/enabled", 1); setprop("sim/rendering/redout/enabled", 1);
setprop("sim/rendering/redout/parameters/locked-by-airframe", 1);
#call(func{fgcommand('dialog-close', multiplayer.dialog.dialog.prop())},nil,var err= []);# props.Node.new({"dialog-name": "location-in-air"})); #call(func{fgcommand('dialog-close', multiplayer.dialog.dialog.prop())},nil,var err= []);# props.Node.new({"dialog-name": "location-in-air"}));
if (!m28_auto) call(func{multiplayer.dialog.del();},nil,var err= []); if (!m28_auto) call(func{multiplayer.dialog.del();},nil,var err= []);
if (!getprop("gear/gear[0]/wow")) { if (!getprop("gear/gear[0]/wow")) {
@ -1333,6 +1449,8 @@ var code_ct = func () {
#setprop("/sim/rendering/als-filters/use-filtering", 1); #setprop("/sim/rendering/als-filters/use-filtering", 1);
call(func{var interfaceController = fg1000.GenericInterfaceController.getOrCreateInstance(); call(func{var interfaceController = fg1000.GenericInterfaceController.getOrCreateInstance();
interfaceController.stop();},nil,var err2=[]); interfaceController.stop();},nil,var err2=[]);
} else {
setprop("sim/rendering/redout/parameters/locked-by-airframe", 0);
} }
} }
code_ctTimer = maketimer(1, code_ct); code_ctTimer = maketimer(1, code_ct);
@ -1440,11 +1558,25 @@ var writeDamageLog = func {
io.close(file); io.close(file);
} }
var unitTest = func {
for (var i= 0; i<=180;i+=1) {
var em = DamageRecipient.typeID2emesaryID(i);
var b = DamageRecipient.emesaryID2typeID(em);
if (b != i) {
print("unit test failed for index "~i);
return;
}
}
print("unit test passed");
}
#unitTest();
setlistener("sim/signals/exit", writeDamageLog, 0, 0); setlistener("sim/signals/exit", writeDamageLog, 0, 0);
#screen.property_display.add("payload/armament/MAW-bearing"); #screen.property_display.add("payload/armament/MAW-bearing");
#screen.property_display.add("payload/armament/MAW-active"); #screen.property_display.add("payload/armament/MAW-active");
#screen.property_display.add("payload/armament/MAW-semiactive"); #screen.property_display.add("payload/armament/MAW-semiactive");
#screen.property_display.add("payload/armament/MAW-semiactive-callsign");
#screen.property_display.add("payload/armament/MLW-bearing"); #screen.property_display.add("payload/armament/MLW-bearing");
#screen.property_display.add("payload/armament/MLW-count"); #screen.property_display.add("payload/armament/MLW-count");
#screen.property_display.add("payload/armament/MLW-launcher"); #screen.property_display.add("payload/armament/MLW-launcher");
@ -1454,7 +1586,7 @@ setlistener("sim/signals/exit", writeDamageLog, 0, 0);
#screen.property_display.add("payload/armament/spike-gnd-02"); #screen.property_display.add("payload/armament/spike-gnd-02");
#screen.property_display.add("payload/armament/spike-gnd-05"); #screen.property_display.add("payload/armament/spike-gnd-05");
#screen.property_display.add("payload/armament/spike-gnd-06"); #screen.property_display.add("payload/armament/spike-gnd-06");
#screen.property_display.add("payload/armament/spike-gnd-11"); #screen.property_display.add("payload/armament/spike-gnd-17");
#screen.property_display.add("payload/armament/spike-gnd-23"); #screen.property_display.add("payload/armament/spike-gnd-23");
#screen.property_display.add("payload/armament/spike-gnd-p2"); #screen.property_display.add("payload/armament/spike-gnd-p2");
#screen.property_display.add("payload/armament/spike-gnd-nk"); #screen.property_display.add("payload/armament/spike-gnd-nk");

View File

@ -153,19 +153,11 @@ var slugs_to_lbm = SLUGS2LBM;# since various aircraft use this from outside miss
var first_in_air = 0;# first missile is in the air, other missiles should not write to MP. var first_in_air = 0;# first missile is in the air, other missiles should not write to MP.
var first_in_air_max_sec = 30; var first_in_air_max_sec = 30;
var versionString = getprop("sim/version/flightgear"); #var versionString = getprop("sim/version/flightgear");
var version = split(".", versionString); #var version = split(".", versionString);
var major = num(version[0]); #var major = num(version[0]);
var minor = num(version[1]); #var minor = num(version[1]);
var pica = num(version[2]); #var pica = num(version[2]);
var pickingMethod = 0;
if ((major == 2017 and minor == 2 and pica >= 1) or (major == 2017 and minor > 2) or major > 2017) {
pickingMethod = 1;
}
var offsetMethod = 0;
if ((major == 2017 and minor == 2 and pica >= 1) or (major == 2017 and minor > 2) or major > 2017) {
offsetMethod = 1;
}
var wingedGuideFactor = 0.1; var wingedGuideFactor = 0.1;
@ -193,27 +185,28 @@ var contactPoint = nil;
# get_type() - (AIR, MARINE, SURFACE or ORDNANCE) # get_type() - (AIR, MARINE, SURFACE or ORDNANCE)
# getUnique() - Used when comparing 2 targets to each other and determining if they are the same target. # getUnique() - Used when comparing 2 targets to each other and determining if they are the same target.
# isValid() - If this target is valid # isValid() - If this target is valid
# getElevation() # getElevation() - Pitch to target from launch vehicle
# get_bearing() # get_bearing() - Bearing to target from launch vehicle
# get_Callsign() # get_Callsign()
# get_range() # get_range() - NM
# get_Coord() # get_Coord()
# get_altitude() # get_altitude() - FT
# get_Pitch() # get_Pitch()
# get_Speed() # get_Speed()
# get_heading() # get_heading()
# get_uBody() # get_uBody() - Body velocities in ft/s. Forward component.
# get_vBody() # get_vBody() - Right component
# get_wBody() # get_wBody() - Down component
# getLastGroundTrackBlep() - Used for sample guidance # getLastGroundTrackBlep() - Used for sample guidance
# getFlareNode() - Used for flares. # getFlareNode() - Used for flares.
# getChaffNode() - Used for chaff. # getChaffNode() - Used for chaff.
# isPainted() - Tells if this target is still being radar tracked by the launch platform, only used in semi-radar guided missiles. # isPainted() - Tells if this target is still being radar tracked by the launch platform, only used in semi-radar guided missiles.
# isLaserPainted() - Tells if this target is still being tracked by the launch platform, only used by laser guided ordnance. # isLaserPainted() - Tells if this target is still being tracked by the launch platform, only used by laser guided ordnance.
# isRadiating(coord) - Tell if anti-radiation missile is hit by radiation from target. coord is the weapon position. # isRadiating(coord) - Tell if anti-radiation missile is hit by radiation from target. coord is the weapon position.
# isCommandActive() # isSpikingMe() - Tells if the target is STT locked on launch platform.
# isCommandActive() - If surface based launcher is still tracking (command guidance) or have a search blep (TVM) on target.
# isVirtual() - Tells if the target is just a position, and should not be considered for damage. # isVirtual() - Tells if the target is just a position, and should not be considered for damage.
# get_closure_rate() - closure rate in kt # get_closure_rate() - closure rate in kt to launch platform
var AIM = { var AIM = {
lowestETA: nil, lowestETA: nil,
@ -312,6 +305,8 @@ var AIM = {
m.radarZ = getprop(m.nodeString~"FCS-z"); # In future I will add direction to it also, for now its center gimbal is along -x axis. m.radarZ = getprop(m.nodeString~"FCS-z"); # In future I will add direction to it also, for now its center gimbal is along -x axis.
m.expand_min = getprop(m.nodeString~"expand-min-fire-range"); # Bool. Default false. If min fire range should expand with closing rate. Mainly use this for A/A missiles. m.expand_min = getprop(m.nodeString~"expand-min-fire-range"); # Bool. Default false. If min fire range should expand with closing rate. Mainly use this for A/A missiles.
m.asc = getprop(m.nodeString~"attack-steering-cue-enabled");# Bool. ASC enabled. m.asc = getprop(m.nodeString~"attack-steering-cue-enabled");# Bool. ASC enabled.
m.powerOnRequired = getprop(m.nodeString~"requires-power-on"); # Bool. ASC enabled.
m.powerOnBatteryTime = getprop(m.nodeString~"power-on-battery-time"); # Seconds.
# navigation, guiding and seekerhead # navigation, guiding and seekerhead
m.max_seeker_dev = getprop(m.nodeString~"seeker-field-deg") / 2; # missiles own seekers total FOV diameter. m.max_seeker_dev = getprop(m.nodeString~"seeker-field-deg") / 2; # missiles own seekers total FOV diameter.
m.guidance = getprop(m.nodeString~"guidance"); # heat/radar/semi-radar/tvm/laser/gps/gps-laser/vision/unguided/level/gyro-pitch/radiation/inertial/remote/remote-stable/command/sample m.guidance = getprop(m.nodeString~"guidance"); # heat/radar/semi-radar/tvm/laser/gps/gps-laser/vision/unguided/level/gyro-pitch/radiation/inertial/remote/remote-stable/command/sample
@ -412,6 +407,14 @@ var AIM = {
m.eject_speed = 0; m.eject_speed = 0;
} }
if (m.powerOnRequired == nil) {
m.powerOnRequired = 0;
}
if (m.powerOnBatteryTime == nil) {
m.powerOnBatteryTime = 0;# infinite
}
if (m.rail_forward == 1) { if (m.rail_forward == 1) {
m.rail_pitch_deg = 0; m.rail_pitch_deg = 0;
m.rail_head_deg = 0; m.rail_head_deg = 0;
@ -533,7 +536,7 @@ var AIM = {
m.vector_thrust = 0; m.vector_thrust = 0;
} }
if (m.flareResistance == nil or !m.gnd_launch) { if (m.flareResistance == nil or !m.gnd_launch) {
m.flareResistance = 0.85; m.flareResistance = 0.80;
} }
if (m.chaffResistance == nil or !m.gnd_launch) { if (m.chaffResistance == nil or !m.gnd_launch) {
m.chaffResistance = 0.85; m.chaffResistance = 0.85;
@ -720,6 +723,7 @@ var AIM = {
m.contacts = [];# contacts that should be considered to lock onto. In slave it will only lock to the first. m.contacts = [];# contacts that should be considered to lock onto. In slave it will only lock to the first.
m.warm = 1;# normalized warm/cold m.warm = 1;# normalized warm/cold
m.ready_standby_time = 0;# time when started from standby m.ready_standby_time = 0;# time when started from standby
m.power_on_time = 0;# time when started from standby
m.cooling = 0; m.cooling = 0;
m.slave_to_radar = m.seam_support?1:0; m.slave_to_radar = m.seam_support?1:0;
m.seeker_last_time = 0; m.seeker_last_time = 0;
@ -729,6 +733,11 @@ var AIM = {
m.cooling_last_time = 0; m.cooling_last_time = 0;
m.cool_total_time = 0; m.cool_total_time = 0;
m.powerOn = 0;
m.powerAvailable = m.powerOnBatteryTime;
m.powerOnPassedTime = 0;
m.powerOnLastCheck = 0;
# #
# Emesary damage system # Emesary damage system
# #
@ -1354,6 +1363,10 @@ var AIM = {
me.contacts = vect; me.contacts = vect;
}, },
clearTgt: func {
me.Tgt = nil;
},
commandDir: func (heading_deg, pitch_deg) { commandDir: func (heading_deg, pitch_deg) {
# commands are relative to aircraft bore # commands are relative to aircraft bore
if (me.status == MISSILE_FLYING) return; if (me.status == MISSILE_FLYING) return;
@ -1408,6 +1421,28 @@ var AIM = {
return me.cooling; return me.cooling;
}, },
togglePowerOn: func {
me.powerOn = !me.powerOn;
if (me.powerOn) {
me.power_on_time = getprop("sim/time/elapsed-sec");
}
},
setPowerOn: func (enable) {
me.powerOn = enable;
if (me.powerOn) {
me.power_on_time = getprop("sim/time/elapsed-sec");
}
},
isPowerOn: func {
return me.powerOn;
},
hasPowerEnough: func {
return !me.powerOnRequired or me.powerOnBatteryTime == 0 or me.powerAvailable > me.powerOnBatteryTime * 0.05;
},
start: func { start: func {
if (me.status == MISSILE_STANDBY) { if (me.status == MISSILE_STANDBY) {
me.status = MISSILE_STARTING; me.status = MISSILE_STARTING;
@ -1421,7 +1456,15 @@ var AIM = {
if (me.status != MISSILE_FLYING) { if (me.status != MISSILE_FLYING) {
me.status = MISSILE_STANDBY; me.status = MISSILE_STANDBY;
#printf("stop #%3d %s", me.ID, me.type); #printf("stop #%3d %s", me.ID, me.type);
if (me.guidance == "radiation") {
me.Tgt = nil;
me.contacts = [];
} }
}
},
getStatus: func {
return me.status;
}, },
isCaged: func () { isCaged: func () {
@ -1484,6 +1527,9 @@ var AIM = {
me.elapsed_last = systime(); me.elapsed_last = systime();
me.status = MISSILE_FLYING; me.status = MISSILE_FLYING;
me.powerOnLastCheck = 0;# switch to use me.life_time from elapsed sim time.
me.powerOn = 1;# If pilot releases while power off, we make sure it on now.
if (vect!= nil) { if (vect!= nil) {
# sets a vector of contacts the weapons will try to lock onto # sets a vector of contacts the weapons will try to lock onto
@ -1549,7 +1595,7 @@ var AIM = {
me.railEnd = vector.Math.plus(me.railBegin, vector.Math.product(me.rail_dist_m, me.railvec)); me.railEnd = vector.Math.plus(me.railBegin, vector.Math.product(me.rail_dist_m, me.railvec));
} }
} }
if (offsetMethod and (!me.rail or me.rail_forward)) { if (!me.rail or me.rail_forward) {
var pos = aircraftToCart({x:-me.x, y:me.y, z: -me.z}); var pos = aircraftToCart({x:-me.x, y:me.y, z: -me.z});
init_coord = geo.Coord.new(); init_coord = geo.Coord.new();
init_coord.set_xyz(pos.x, pos.y, pos.z); init_coord.set_xyz(pos.x, pos.y, pos.z);
@ -2094,6 +2140,13 @@ var AIM = {
me.life_time += me.dt; me.life_time += me.dt;
me.consumeBattery(me.life_time);
if (!me.hasPowerEnough()) {
# Smart weapon reduced to dumb weapon
me.free = 1;
me.printStats("Ran out of battery, stopped guiding");
}
me.handleMidFlightFunc(); me.handleMidFlightFunc();
if (me.hasGuided and me.maddog) { if (me.hasGuided and me.maddog) {
@ -2394,12 +2447,8 @@ var AIM = {
# missile on rail, lets move it on the rail # missile on rail, lets move it on the rail
if (me.rail_forward) { if (me.rail_forward) {
var init_coord = nil; var init_coord = nil;
if (offsetMethod) {
me.geodPos = aircraftToCart({x:-me.x, y:me.y, z: -me.z}); me.geodPos = aircraftToCart({x:-me.x, y:me.y, z: -me.z});
me.coord.set_xyz(me.geodPos.x, me.geodPos.y, me.geodPos.z); me.coord.set_xyz(me.geodPos.x, me.geodPos.y, me.geodPos.z);
} else {
me.coord = me.getGPS(me.x, me.y, me.z, OurPitch.getValue());
}
} else { } else {
me.coord = me.getGPS(-me.railPos[0], -me.railPos[1], me.railPos[2], OurPitch.getValue(), OurHdg.getValue()); me.coord = me.getGPS(-me.railPos[0], -me.railPos[1], me.railPos[2], OurPitch.getValue(), OurHdg.getValue());
} }
@ -2723,8 +2772,13 @@ var AIM = {
} else { } else {
me.remote_control_pitch = 0; me.remote_control_pitch = 0;
} }
if (me.settings["abort_midflight_function"] != nil) { if (me.settings["seeker_fov"] != nil) {
me.max_seeker_dev = me.settings.seeker_fov;
me.printStats("Seeker FOV switched to %s",me.max_seeker_dev);
}
if (me.settings["abort_midflight_function"] == 1) {
me.mfFunction = nil; me.mfFunction = nil;
me.printStats("Midflight function finished");
} }
} }
}, },
@ -2872,7 +2926,7 @@ var AIM = {
} }
if (!me.simple_drag) { if (!me.simple_drag) {
if (me.vector_thrust and me.thrust_lbf>0) N=N*0.35; if (me.vector_thrust and me.thrust_lbf>0) N=N*0.15;
if (mach < 1.1) { if (mach < 1.1) {
me.Cdi = (me.Cd_base+me.Cd_delta*me.deploy)*N;# N = normal force in G me.Cdi = (me.Cd_base+me.Cd_delta*me.deploy)*N;# N = normal force in G
} else { } else {
@ -3267,8 +3321,8 @@ var AIM = {
# target has released a new flare, lets check if it fools us # target has released a new flare, lets check if it fools us
me.flareTime = me.life_time; me.flareTime = me.life_time;
me.flareLast = me.flareNumber; me.flareLast = me.flareNumber;
me.aspectDeg = me.aspectToExhaust(me.coord, me.Tgt) / 180; me.aspectDeg = me.aspectToExhaust(me.coord, me.Tgt) / 180;# 0 = viewing engine, 1 = front
me.flareLock = rand() < (1-me.flareResistance + ((1-me.flareResistance) * 0.5 * me.aspectDeg));# 50% extra chance to be fooled if front aspect me.flareLock = rand() < (1-me.flareResistance);
if (me.flareLock) { if (me.flareLock) {
# fooled by the flare # fooled by the flare
me.printStats(me.type~": Missile locked on flare from "~me.callsign); me.printStats(me.type~": Missile locked on flare from "~me.callsign);
@ -3303,7 +3357,7 @@ var AIM = {
me.aspectDeg = me.aspectToExhaust(me.coord, me.Tgt) / 180;# 0 = viewing engine, 1 = front me.aspectDeg = me.aspectToExhaust(me.coord, me.Tgt) / 180;# 0 = viewing engine, 1 = front
me.redux = me.guidance == "semi-radar" or me.guidance == "command" or me.guidance == "tvm"?(me.gnd_launch?0.5:0.75):1; me.redux = me.guidance == "semi-radar" or me.guidance == "command" or me.guidance == "tvm"?(me.gnd_launch?0.5:0.75):1;
me.chaffChance = (1-me.chaffResistance)*me.redux; me.chaffChance = (1-me.chaffResistance)*me.redux;
me.chaffLock = rand() < (me.chaffChance - (me.chaffChance * 0.5 * me.aspectDeg));# 50% less chance to be fooled if front aspect me.chaffLock = rand() < (me.chaffChance - (me.chaffChance * 0.70 * me.aspectDeg));# 70% less chance to be fooled if front aspect
if (me.chaffLock) { if (me.chaffLock) {
me.printStats(me.type~": Missile locked on chaff from "~me.callsign); me.printStats(me.type~": Missile locked on chaff from "~me.callsign);
@ -3337,7 +3391,7 @@ var AIM = {
}, },
checkForLOS: func () { checkForLOS: func () {
if (pickingMethod and me.guidance != "gps" and me.guidance != "gps-laser" and me.guidance != "unguided" and me.guidance != "inertial" and me.guidance != "sample") { if (me.guidance != "gps" and me.guidance != "gps-laser" and me.guidance != "unguided" and me.guidance != "inertial" and me.guidance != "sample") {
me.xyz = {"x":me.coord.x(), "y":me.coord.y(), "z":me.coord.z()}; me.xyz = {"x":me.coord.x(), "y":me.coord.y(), "z":me.coord.z()};
me.directionLOS = {"x":me.t_coord.x()-me.coord.x(), "y":me.t_coord.y()-me.coord.y(), "z":me.t_coord.z()-me.coord.z()}; me.directionLOS = {"x":me.t_coord.x()-me.coord.x(), "y":me.t_coord.y()-me.coord.y(), "z":me.t_coord.z()-me.coord.z()};
@ -3456,7 +3510,11 @@ var AIM = {
me.printStats(me.type~": Passed minimum speed for guiding after %.1f seconds. Target %d%% inside view.", me.life_time, me.normFOV*100); me.printStats(me.type~": Passed minimum speed for guiding after %.1f seconds. Target %d%% inside view.", me.life_time, me.normFOV*100);
} }
} }
if (me.chaffLock and (me.guidance == "command" or me.guidance == "semi-radar" or me.guidance == "tvm") and (me.life_time - me.chaffLockTime) > (me.gnd_launch?4:6)) { if (me.guidance == "gps" or me.guidance == "inertial" or me.guidance == "sample") {
# To make sure deviation_deg is updated in midflight function.
me.FOV_check(me.hdg, me.pitch, me.curr_deviation_h, me.curr_deviation_e, me.max_seeker_dev, me.myMath);
}
if (me.chaffLock and (me.guidance == "command" or me.guidance == "semi-radar" or me.guidance == "tvm") and (me.life_time - me.chaffLockTime) > (me.gnd_launch?4:8)) {
me.chaffLock = 0; me.chaffLock = 0;
me.printStats(me.type~": Chaff dissipated, regained track."); me.printStats(me.type~": Chaff dissipated, regained track.");
} }
@ -4285,7 +4343,7 @@ var AIM = {
notifyInFlight: func (lat,lon,alt,rdar,semiRdr,typeID,typ,unique,thrustOn,callsign, heading, pitch, speed, is_deleted=0) { notifyInFlight: func (lat,lon,alt,rdar,semiRdr,typeID,typ,unique,thrustOn,callsign, heading, pitch, speed, is_deleted=0) {
## thrustON cannot be named 'thrust' as FG for some reason will then think its a function (probably fixed by the way call() now is used) ## thrustON cannot be named 'thrust' as FG for some reason will then think its a function (probably fixed by the way call() now is used)
var msg = notifications.ArmamentInFlightNotification.new("mfly", unique, is_deleted?damage.DESTROY:damage.MOVE, 21+typeID); var msg = notifications.ArmamentInFlightNotification.new("mfly", unique, is_deleted?damage.DESTROY:damage.MOVE, damage.DamageRecipient.typeID2emesaryID(typeID));
if (lat != nil) { if (lat != nil) {
msg.Position.set_latlon(lat,lon,alt); msg.Position.set_latlon(lat,lon,alt);
} else { } else {
@ -4324,7 +4382,7 @@ var AIM = {
}, },
notifyHit: func (RelativeAltitude, Distance, callsign, Bearing, reason, typeID, type, self) { notifyHit: func (RelativeAltitude, Distance, callsign, Bearing, reason, typeID, type, self) {
var msg = notifications.ArmamentNotification.new("mhit", 4, 21+typeID); var msg = notifications.ArmamentNotification.new("mhit", 4, damage.DamageRecipient.typeID2emesaryID(typeID));
msg.RelativeAltitude = RelativeAltitude; msg.RelativeAltitude = RelativeAltitude;
msg.Bearing = Bearing; msg.Bearing = Bearing;
msg.Distance = Distance; msg.Distance = Distance;
@ -4516,11 +4574,27 @@ var AIM = {
} }
}, },
consumeBattery: func (curr_time) {
if (me.powerOnRequired) {
me.powerOnPassedTime = curr_time-me.powerOnLastCheck;
me.powerAvailable += (me.powerOn?-1:1)*me.powerOnPassedTime;
me.powerAvailable = math.clamp(me.powerAvailable, 0, me.powerOnBatteryTime);
me.powerOnLastCheck = curr_time;
}
},
standby: func { standby: func {
# looping in standby mode # looping in standby mode
if (deltaSec.getValue()==0) { if (deltaSec.getValue()==0) {
# paused
settimer(func me.standby(), 0.5); settimer(func me.standby(), 0.5);
return;
} }
me.printCode("In standby(%d)",me.status);
me.curr_time = getprop("sim/time/elapsed-sec");
me.consumeBattery(me.curr_time);
if(me.seam_support and me.uncage_auto) { if(me.seam_support and me.uncage_auto) {
me.caged = 1; me.caged = 1;
} }
@ -4541,8 +4615,11 @@ var AIM = {
# looping in starting mode # looping in starting mode
#print("startup"); #print("startup");
if (deltaSec.getValue()==0) { if (deltaSec.getValue()==0) {
# Paused
settimer(func me.startup(), 0.5); settimer(func me.startup(), 0.5);
return;
} }
me.printCode("In startup()");
if(me.seam_support and me.uncage_auto) { if(me.seam_support and me.uncage_auto) {
me.caged = 1; me.caged = 1;
} }
@ -4550,7 +4627,11 @@ var AIM = {
me.standby(); me.standby();
return; return;
} }
if (me.ready_standby_time != 0 and getprop("sim/time/elapsed-sec") > (me.ready_standby_time+me.ready_time)) {
me.curr_time = getprop("sim/time/elapsed-sec");
me.consumeBattery(me.curr_time);
if (me.ready_standby_time != 0 and me.hasPowerEnough() and ((!me.powerOnRequired and me.curr_time > (me.ready_standby_time+me.ready_time)) or (me.powerOnRequired and (me.powerOn and me.curr_time > me.power_on_time + me.ready_time)))) {
me.status = MISSILE_SEARCH; me.status = MISSILE_SEARCH;
me.search(); me.search();
return; return;
@ -4752,6 +4833,7 @@ var AIM = {
if (deltaSec.getValue()==0) { if (deltaSec.getValue()==0) {
settimer(func me.search(), 0.5); settimer(func me.search(), 0.5);
} }
me.printCode("In search()");
if (me.deleted) { if (me.deleted) {
return; return;
} elsif ( me.status == MISSILE_FLYING ) { } elsif ( me.status == MISSILE_FLYING ) {
@ -4765,13 +4847,21 @@ var AIM = {
#me.trackWeak = 1; #me.trackWeak = 1;
me.standby(); me.standby();
return; return;
} elsif (me.powerOnRequired and (!me.powerOn or (me.powerOnBatteryTime > 0 and me.powerAvailable < me.powerOnBatteryTime * 0.05))) {
me.status = MISSILE_STARTING;
# Stand by.
me.SwSoundVol.setDoubleValue(0);
me.SwSoundOnOff.setBoolValue(0);
#me.trackWeak = 1;
me.standby();
return;
} elsif ( me.status == MISSILE_LOCK) { } elsif ( me.status == MISSILE_LOCK) {
# Locked. # Locked.
me.printSearch("in search loop, but locked!"); me.printSearch("in search loop, but locked!");
me.return_to_search(); me.return_to_search();
return; return;
} }
me.consumeBattery(getprop("sim/time/elapsed-sec"));
me.printSearch("searching"); me.printSearch("searching");
@ -5130,6 +5220,15 @@ var AIM = {
#me.trackWeak = 1; #me.trackWeak = 1;
me.standby(); me.standby();
return; return;
} elsif (me.powerOnRequired and (!me.powerOn or (me.powerOnBatteryTime > 0 and me.powerAvailable < me.powerOnBatteryTime * 0.05))) {
me.status = MISSILE_STARTING;
me.reset_seeker();
# Stand by.
me.SwSoundVol.setDoubleValue(0);
me.SwSoundOnOff.setBoolValue(0);
#me.trackWeak = 1;
me.standby();
return;
} elsif (!me.Tgt.isValid()) { } elsif (!me.Tgt.isValid()) {
# Lost of lock due to target disapearing: # Lost of lock due to target disapearing:
# return to search mode. # return to search mode.
@ -5143,6 +5242,7 @@ var AIM = {
me.return_to_search(); me.return_to_search();
return; return;
} }
me.consumeBattery(getprop("sim/time/elapsed-sec"));
me.printSearch("lock (caged:%d slave:%d point:%s same:%d noCommon:%d)",me.caged,me.slave_to_radar,contactPoint!=nil,me.getContact() == me.Tgt,me.noCommonTarget); me.printSearch("lock (caged:%d slave:%d point:%s same:%d noCommon:%d)",me.caged,me.slave_to_radar,contactPoint!=nil,me.getContact() == me.Tgt,me.noCommonTarget);
# Time interval since lock time or last track loop. # Time interval since lock time or last track loop.
#if (me.status == MISSILE_LOCK) { #if (me.status == MISSILE_LOCK) {
@ -5158,13 +5258,16 @@ var AIM = {
me.coolingSyst(); me.coolingSyst();
me.computeSeekerPos(); me.computeSeekerPos();
if (me.status != MISSILE_STANDBY ) {#TODO: should this also check for starting up? if (me.status != MISSILE_STANDBY ) {#TODO: should this also check for starting up?
me.in_view = me.check_t_in_fov();
if (!me.in_view) { # This code does not seem needed anymore:
me.printSearch("out of view"); #me.in_view = me.check_t_in_fov();
me.return_to_search(); #
return; #if (!me.in_view) {
} # if (me.noCommonTarget and me.guidance == "radiation") me.Tgt = nil;#Hack, todo fix this
# me.printSearch("out of view");
# me.return_to_search();
# return;
#}
if (!me.caged or me.slave_to_radar) { if (!me.caged or me.slave_to_radar) {
me.convertGlobalToSeekerViewDirection(me.Tgt.get_bearing(), me.Tgt.getElevation(), OurHdg.getValue(), OurPitch.getValue(), OurRoll.getValue()); me.convertGlobalToSeekerViewDirection(me.Tgt.get_bearing(), me.Tgt.getElevation(), OurHdg.getValue(), OurPitch.getValue(), OurRoll.getValue());
@ -5184,7 +5287,8 @@ var AIM = {
# Notice: seeker_xxxx_target is used both for denoting where seeker should move towards and where the target is. In this case its the latter: # Notice: seeker_xxxx_target is used both for denoting where seeker should move towards and where the target is. In this case its the latter:
me.convertGlobalToSeekerViewDirection(me.Tgt.get_bearing(), me.Tgt.getElevation(), OurHdg.getValue(), OurPitch.getValue(), OurRoll.getValue()); me.convertGlobalToSeekerViewDirection(me.Tgt.get_bearing(), me.Tgt.getElevation(), OurHdg.getValue(), OurPitch.getValue(), OurRoll.getValue());
me.testSeeker(); me.testSeeker();
if (!me.inBeam or (me.guidance == "semi-radar" and !me.is_painted(me.Tgt))) { me.tagt = me.Tgt;# Used in checkForLock
if (!me.inBeam or !me.checkForLock()) {
me.printSearch("out of beam or no beam for fox 1"); me.printSearch("out of beam or no beam for fox 1");
me.status = MISSILE_SEARCH; me.status = MISSILE_SEARCH;
me.Tgt = nil; me.Tgt = nil;
@ -5298,6 +5402,7 @@ var AIM = {
if (me.seeMe != nil and me.seeMe) { if (me.seeMe != nil and me.seeMe) {
return 1; return 1;
} }
return target.isSpikingMe();
} }
return 0; return 0;
}, },
@ -5319,15 +5424,6 @@ var AIM = {
me.moveSeeker(); me.moveSeeker();
}, },
clamp_min_max: func (v, mm) {
if ( v < -mm ) {
v = -mm;
} elsif ( v > mm ) {
v = mm;
}
return(v);
},
clamp: func(v, min, max) { v < min ? min : v > max ? max : v }, clamp: func(v, min, max) { v < min ? min : v > max ? max : v },
animation_flags_props: func { animation_flags_props: func {

View File

@ -160,7 +160,9 @@ var Contact = {
if(e == nil or e == 0) { if(e == nil or e == 0) {
# AI/MP has no radar properties # AI/MP has no radar properties
var self = geo.aircraft_position(); var self = geo.aircraft_position();
self.set_alt(self.alt()+fire_control.radar_elevation_above_terrain_m); var elev = 0;
call(func {elev = fire_control.radar_elevation_above_terrain_m;},[],nil,nil, var err = []);
self.set_alt(self.alt()+elev);
me.get_Coord(); me.get_Coord();
var angleInv = clamp(self.distance_to(me.coord)/self.direct_distance_to(me.coord), -1, 1); var angleInv = clamp(self.distance_to(me.coord)/self.direct_distance_to(me.coord), -1, 1);
e = (self.alt()>me.coord.alt()?-1:1)*math.acos(angleInv)*R2D; e = (self.alt()>me.coord.alt()?-1:1)*math.acos(angleInv)*R2D;
@ -391,7 +393,9 @@ var isNotBehindTerrain = func( mp ) {
var myPos = geo.aircraft_position(); var myPos = geo.aircraft_position();
myPos.set_alt(myPos.alt()+fire_control.radar_elevation_above_terrain_m); var elev = 0;
call(func {elev = fire_control.radar_elevation_above_terrain_m;},[],nil,nil, var err = []);
myPos.set_alt(myPos.alt()+elev);
var target_distance = myPos.direct_distance_to(aircraftPos); var target_distance = myPos.direct_distance_to(aircraftPos);

View File

@ -2,7 +2,7 @@ var Math = {
# #
# Authors: Nikolai V. Chr, Axel Paccalin. # Authors: Nikolai V. Chr, Axel Paccalin.
# #
# Version 2.01 # Version 2.02
# #
# When doing euler coords. to cartesian: +x = forw, +y = left, +z = up. # When doing euler coords. to cartesian: +x = forw, +y = left, +z = up.
# FG struct. coords: +x = back, +y = right, +z = up. # FG struct. coords: +x = back, +y = right, +z = up.
@ -287,13 +287,13 @@ var Math = {
} }
if (coord1.alt() != coord2.alt()) { if (coord1.alt() != coord2.alt()) {
me.d12 = coord1.direct_distance_to(coord2); me.d12 = coord1.direct_distance_to(coord2);
me.coord3 = geo.Coord.new(coord1);
me.coord3.set_alt(coord1.alt()-me.d12*0.5);# this will increase the area of the triangle so that rounding errors dont get in the way.
me.d13 = coord1.alt()-me.coord3.alt();
if (me.d12 == 0) { if (me.d12 == 0) {
# on top of each other, maybe rounding error.. # on top of each other, maybe rounding error..
return 0; return 0;
} }
me.coord3 = geo.Coord.new(coord1);
me.coord3.set_alt(coord1.alt()-me.d12*5);# this will increase the area of the triangle so that rounding errors dont get in the way. Changed to 5 May 2023, which gives more presision than 0.5 when c1 and c2 are very close.
me.d13 = coord1.alt()-me.coord3.alt();
me.d32 = me.coord3.direct_distance_to(coord2); me.d32 = me.coord3.direct_distance_to(coord2);
if (math.abs(me.d13)+me.d32 < me.d12) { if (math.abs(me.d13)+me.d32 < me.d12) {
# rounding errors somewhere..one triangle side is longer than other 2 sides combined. # rounding errors somewhere..one triangle side is longer than other 2 sides combined.

View File

@ -45,7 +45,7 @@
"path": "S-75/Nasal/vector.nas" "path": "S-75/Nasal/vector.nas"
}, },
{ {
"version": null, "version": "2.0.3",
"path": "SA-3/Nasal/vector.nas" "path": "SA-3/Nasal/vector.nas"
}, },
{ {
@ -71,7 +71,7 @@
"path": "S-75/Nasal/guided-missiles.nas" "path": "S-75/Nasal/guided-missiles.nas"
}, },
{ {
"version": null, "version": "1.1.2",
"path": "SA-3/Nasal/guided-missiles.nas" "path": "SA-3/Nasal/guided-missiles.nas"
}, },
{ {
@ -125,7 +125,7 @@
"path": "S-75/Nasal/damage.nas" "path": "S-75/Nasal/damage.nas"
}, },
{ {
"version": null, "version": "1.4.3",
"path": "SA-3/Nasal/damage.nas" "path": "SA-3/Nasal/damage.nas"
}, },
{ {
@ -167,7 +167,7 @@
"path": "S-75/Nasal/datalink.nas" "path": "S-75/Nasal/datalink.nas"
}, },
{ {
"version": null, "version": "1.1.0",
"path": "SA-3/Nasal/datalink.nas" "path": "SA-3/Nasal/datalink.nas"
}, },
{ {
@ -225,7 +225,7 @@
"path": "S-75/Nasal/ArmamentNotification.nas" "path": "S-75/Nasal/ArmamentNotification.nas"
}, },
{ {
"version": null, "version": "1.1.0",
"path": "SA-3/Nasal/ArmamentNotification.nas" "path": "SA-3/Nasal/ArmamentNotification.nas"
}, },
{ {
@ -283,7 +283,7 @@
"path": "S-75/Nasal/GeoBridgedTransmitter.nas" "path": "S-75/Nasal/GeoBridgedTransmitter.nas"
}, },
{ {
"version": null, "version": "1.0.1",
"path": "SA-3/Nasal/GeoBridgedTransmitter.nas" "path": "SA-3/Nasal/GeoBridgedTransmitter.nas"
}, },
{ {
@ -309,7 +309,7 @@
"path": "S-75/Nasal/fire-control.nas" "path": "S-75/Nasal/fire-control.nas"
}, },
{ {
"version": null, "version": "1.0.0",
"path": "SA-3/Nasal/fire-control.nas" "path": "SA-3/Nasal/fire-control.nas"
}, },
{ {
@ -331,7 +331,7 @@
"path": "S-75/Nasal/radar-logic.nas" "path": "S-75/Nasal/radar-logic.nas"
}, },
{ {
"version": null, "version": "1.1.0",
"path": "SA-3/Nasal/radar-logic.nas" "path": "SA-3/Nasal/radar-logic.nas"
}, },
{ {