diff --git a/BUK-M2/Nasal/damage.nas b/BUK-M2/Nasal/damage.nas index 2c7f0e3..617c99f 100644 --- a/BUK-M2/Nasal/damage.nas +++ b/BUK-M2/Nasal/damage.nas @@ -1206,40 +1206,49 @@ var repairYasim = func { } var setupYasimEngines = func { - if (getprop("engines/engine/n1") != nil and !contains(FailureMgr.get_failure_modes(), "engines/engine")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[1]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[2]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[3]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[4]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[5]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[6]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[7]")) { + 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, 300); +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); diff --git a/Frigate/Nasal/damage.nas b/Frigate/Nasal/damage.nas index 2c7f0e3..617c99f 100644 --- a/Frigate/Nasal/damage.nas +++ b/Frigate/Nasal/damage.nas @@ -1206,40 +1206,49 @@ var repairYasim = func { } var setupYasimEngines = func { - if (getprop("engines/engine/n1") != nil and !contains(FailureMgr.get_failure_modes(), "engines/engine")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[1]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[2]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[3]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[4]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[5]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[6]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[7]")) { + 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, 300); +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); diff --git a/MIM-104D/Nasal/damage.nas b/MIM-104D/Nasal/damage.nas index 2c7f0e3..617c99f 100644 --- a/MIM-104D/Nasal/damage.nas +++ b/MIM-104D/Nasal/damage.nas @@ -1206,40 +1206,49 @@ var repairYasim = func { } var setupYasimEngines = func { - if (getprop("engines/engine/n1") != nil and !contains(FailureMgr.get_failure_modes(), "engines/engine")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[1]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[2]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[3]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[4]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[5]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[6]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[7]")) { + 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, 300); +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); diff --git a/S-200/Nasal/damage.nas b/S-200/Nasal/damage.nas index 44b753a..617c99f 100644 --- a/S-200/Nasal/damage.nas +++ b/S-200/Nasal/damage.nas @@ -27,9 +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 TRUE = 1; -var FALSE = 0; - +srand(); var hp = hp_max; setprop("sam/damage", math.max(0,100*hp/hp_max));#used in HUD @@ -62,6 +60,7 @@ var shells = { "DEFA 554": [14,0.060], # 30x113mm Mirage, 220g "20mm APDS": [15,0.030], # CIWS "LAU-10": [16,0.500], # 127mm, ~4-7kg warhead + # Max id is 41 }; # lbs of warheads is explosive+fragmentation+fuse, so total warhead mass. @@ -164,7 +163,11 @@ var warheads = { "pilot": [93, 0.00,1,0],# ejected pilot "BETAB-500ShP": [94, 1160.00,1,0], "Flare": [95, 0.00,0,0], - "3M9": [96, 125.00,0,0],# 3M9 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 + "AIM-9X": [98, 20.80,0,0], + "R-23R": [99, 55.00,0,0],# mig23 fox 1 + # Max id is 180 }; var AIR_RADAR = "air"; @@ -182,17 +185,21 @@ var radar_signatures = { "m2000-5B": AIR_RADAR, "MiG-21bis": AIR_RADAR, "MiG-21MF-75": AIR_RADAR, + "Mig-23MLD": AIR_RADAR, "MiG-29": AIR_RADAR, "SU-27": AIR_RADAR, "EC-137R": AIR_RADAR, + "E-3R": AIR_RADAR, + "E-3": AIR_RADAR, "RC-137R": AIR_RADAR, "E-8R": AIR_RADAR, "EC-137D": AIR_RADAR, "Mig-28": AIR_RADAR, - "SA-6": AIR_RADAR,#Air radar tone chosen so that there is at least some lock tone until asset-specific is created + "SA-6": "gnd-06",#Air radar tone chosen so that there is at least some lock tone until asset-specific is created + "s-200": "gnd-05", "ZSU-23-4M": "gnd-23", "S-75": "gnd-02", - "buk-m2": "gnd-11", + "buk-m2": "gnd-17", "s-300": "gnd-20", "MIM104D": "gnd-p2", "missile_frigate": "gnd-nk", @@ -203,7 +210,7 @@ var radar_signatures = { var id2warhead = []; var launched = {};# callsign: elapsed-sec var approached = {};# callsign: uniqueID -var heavy_smoke = [61,62,63,65,92,96]; +var heavy_smoke = [61,62,63,65,92,96,97]; var k = keys(warheads); @@ -241,6 +248,10 @@ for(var myid = 0;myid 450) { - printf("Missile Approach Warning from %03d degrees.", bearing); - 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,1,0);# temporary till someone models a RWR in RIO seat + if (radarOn) { + #printf("Missile Approach Warning from %03d degrees.", bearing); + 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 + } else { + #printf("Missile Approach Warning"); + 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 + } approached[notification.Callsign~notification.UniqueIdentity] = elapsed; - if (m28_auto) mig28.engagedBy(notification.Callsign); + if (m28_auto) mig28.engagedBy(notification.Callsign, 1); } return emesary.Transmitter.ReceiptStatus_OK; } @@ -415,11 +440,11 @@ var DamageRecipient = # debug.dump(notification); # # - if (tacview_supported and tacview.starttime and getprop("sim/multiplay/txhost") != "mpserver.opredflag.com") { + if (tacview_supported and tacview.starttime and (getprop("sim/multiplay/txhost") != "mpserver.opredflag.com" or m28_auto)) { 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 - var wh = id2warhead[notification.SecondaryKind - 21]; + var wh = id2warhead[DamageRecipient.emesaryID2typeID(notification.SecondaryKind)]; var lbs = wh[1]; 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); @@ -439,9 +464,10 @@ var DamageRecipient = var callsign = processCallsign(getprop("sim/multiplay/callsign")); if (notification.RemoteCallsign == callsign and getprop("payload/armament/msg") == 1) { #damage enabled and were getting hit - if (m28_auto) mig28.engagedBy(notification.Callsign); + if (notification.SecondaryKind < 0 and hitable_by_cannon) { # cannon hit + if (m28_auto) mig28.engagedBy(notification.Callsign, 0); var probability = id2shell[-1*notification.SecondaryKind-1][1]; var typ = id2shell[-1*notification.SecondaryKind-1][2]; var hit_count = notification.Distance; @@ -455,10 +481,11 @@ var DamageRecipient = damageLog.push(sprintf("%s hit you with %d %s.", notification.Callsign, hit_count, typ)); nearby_explosion(); } - } elsif (notification.SecondaryKind > 20) { + } elsif (notification.SecondaryKind > 20 or notification.SecondaryKind < -40) { # its a warhead + if (m28_auto) mig28.engagedBy(notification.Callsign, 1); var dist = notification.Distance; - var wh = id2warhead[notification.SecondaryKind - 21]; + var wh = id2warhead[DamageRecipient.emesaryID2typeID(notification.SecondaryKind)]; var type = wh[4];#test code if (wh[3] == 1) { # cluster munition @@ -549,21 +576,18 @@ var DamageRecipient = } if (notification.Kind == CREATE and getprop("payload/armament/enable-craters") == 1 and statics["obj_"~notification.UniqueIdentity] == nil) { if (notification.SecondaryKind == 0) {# TODO: make a hash with all the models - var crater_model = getprop("payload/armament/models") ~ "crater_small.xml"; - var static = geo.put_model(crater_model, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); + var static = geo.put_model(crater_model0, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); if (static != nil) { statics["obj_"~notification.UniqueIdentity] = [static, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading, notification.SecondaryKind]; #static is a PropertyNode inside /models } } elsif (notification.SecondaryKind == 1) { - var crater_model = getprop("payload/armament/models") ~ "crater_big.xml"; - var static = geo.put_model(crater_model, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); + var static = geo.put_model(crater_model1, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); if (static != nil) { statics["obj_"~notification.UniqueIdentity] = [static, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading, notification.SecondaryKind]; } } elsif (notification.SecondaryKind == 2) { - var crater_model = getprop("payload/armament/models") ~ "bomb_hit_smoke.xml"; - var static = geo.put_model(crater_model, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); + var static = geo.put_model(crater_model2, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); if (static != nil) { statics["obj_"~notification.UniqueIdentity] = [static, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading, notification.SecondaryKind]; } @@ -586,7 +610,29 @@ var DamageRecipient = return emesary.Transmitter.ReceiptStatus_NotProcessed; }; 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"); @@ -863,6 +909,7 @@ var flare_update_time = 0.4; var flare_duration = 8; var flare_terminal_speed = 50;#m/s var flares_max_process_per_loop = 4; +var flare_sequencer = -120; var flare_sorter = func(a, b) { if(a[0] < b[0]){ @@ -945,7 +992,9 @@ var flare_released = func { getprop("orientation/heading-deg"), FT2M*getprop("velocities/speed-down-fps"), FT2M*math.sqrt(getprop("velocities/speed-north-fps")*getprop("velocities/speed-north-fps")+getprop("velocities/speed-east-fps")*getprop("velocities/speed-east-fps")), - int(rand()*240)-120]; + flare_sequencer]; + flare_sequencer += 1; + if (flare_sequencer > 120) flare_sequencer = -120; append(flare_list, flare); var msg = notifications.ObjectInFlightNotification.new("ffly", flare[6], MOVE, 21+95); msg.Flags = 0; @@ -1087,6 +1136,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; } @@ -1116,6 +1205,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); hp_f = [hp_max,hp_max,hp_max,hp_max,hp_max,hp_max,hp_max]; @@ -1233,7 +1367,7 @@ var processCallsigns = func () { var painted = 0; var paint_list = []; foreach (var player; players) { - if(player.getChild("valid") != nil and player.getChild("valid").getValue() == TRUE and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { + 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(); callsign_struct[callsign] = player; var str6 = player.getNode("sim/multiplay/generic/string[6]"); @@ -1247,6 +1381,8 @@ var processCallsigns = func () { } 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-semiactive", 0); + setprop("payload/armament/MAW-semiactive-callsign", ""); } # spike handling: @@ -1293,16 +1429,16 @@ processCallsignsTimer.start(); var code_ct = func () { #ANTIC if (getprop("payload/armament/msg")) { - setprop("sim/rendering/redout/enabled", TRUE); + setprop("sim/rendering/redout/enabled", 1); #call(func{fgcommand('dialog-close', multiplayer.dialog.dialog.prop())},nil,var err= []);# props.Node.new({"dialog-name": "location-in-air"})); - 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")) { call(func{fgcommand('dialog-close', props.Node.new({"dialog-name": "WeightAndFuel"}))},nil,var err2 = []); call(func{fgcommand('dialog-close', props.Node.new({"dialog-name": "system-failures"}))},nil,var err2 = []); call(func{fgcommand('dialog-close', props.Node.new({"dialog-name": "instrument-failures"}))},nil,var err2 = []); } setprop("sim/freeze/fuel",0); - setprop("/sim/speed-up", 1); + if (!m28_auto) setprop("/sim/speed-up", 1); setprop("/gui/map/draw-traffic", 0); setprop("/sim/marker-pins/traffic", 0); setprop("/sim/gui/dialogs/map-canvas/draw-TFC", 0); @@ -1317,7 +1453,7 @@ code_ctTimer.simulatedTime = 1; -setprop("/sim/failure-manager/display-on-screen", FALSE); +setprop("/sim/failure-manager/display-on-screen", 0); code_ctTimer.start(); @@ -1337,6 +1473,22 @@ var re_init = func (node) { } stopLaunch(); damageLog.push("Aircraft was repaired due to re-init."); + + # Remove all 3D craters and re-place them. Due to re-init can remove some of them. + + foreach (var thekey ; keys(statics)) { + var sta = statics[thekey]; + if (sta[0] != nil) { + sta[0].remove(); + if (sta[5] == 0) {# TODO: make a hash with all the models + sta[0] = geo.put_model(crater_model0, sta[1], sta[2], sta[3], sta[4]); + } elsif (sta[5] == 1) { + sta[0] = geo.put_model(crater_model1, sta[1], sta[2], sta[3], sta[4]); + } elsif (sta[5] == 2) { + sta[0] = geo.put_model(crater_model2, sta[1], sta[2], sta[3], sta[4]); + } + } + } } #================================================================== @@ -1401,10 +1553,25 @@ var writeDamageLog = func { 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); #screen.property_display.add("payload/armament/MAW-bearing"); #screen.property_display.add("payload/armament/MAW-active"); +#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-count"); #screen.property_display.add("payload/armament/MLW-launcher"); @@ -1412,7 +1579,9 @@ setlistener("sim/signals/exit", writeDamageLog, 0, 0); #screen.property_display.add("payload/armament/spike-air"); #screen.property_display.add("payload/armament/spike-gnd-20"); #screen.property_display.add("payload/armament/spike-gnd-02"); -#screen.property_display.add("payload/armament/spike-gnd-11"); +#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-17"); #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-nk"); \ No newline at end of file diff --git a/S-200/Nasal/vector.nas b/S-200/Nasal/vector.nas index 621b0cb..ebc5347 100644 --- a/S-200/Nasal/vector.nas +++ b/S-200/Nasal/vector.nas @@ -2,7 +2,7 @@ var Math = { # # Authors: Nikolai V. Chr, Axel Paccalin. # - # Version 2.01 + # Version 2.02 # # When doing euler coords. to cartesian: +x = forw, +y = left, +z = up. # FG struct. coords: +x = back, +y = right, +z = up. @@ -287,13 +287,13 @@ var Math = { } if (coord1.alt() != coord2.alt()) { 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) { # on top of each other, maybe rounding error.. 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); if (math.abs(me.d13)+me.d32 < me.d12) { # rounding errors somewhere..one triangle side is longer than other 2 sides combined. @@ -479,4 +479,4 @@ var unitTest = { printf("These two should be the same %s = %s",Math.format(aircraft),Math.format(aircraft2)); }, }; -#unitTest.start(); \ No newline at end of file +#unitTest.start(); diff --git a/S-300/Nasal/damage.nas b/S-300/Nasal/damage.nas index 44b753a..617c99f 100644 --- a/S-300/Nasal/damage.nas +++ b/S-300/Nasal/damage.nas @@ -27,9 +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 TRUE = 1; -var FALSE = 0; - +srand(); var hp = hp_max; setprop("sam/damage", math.max(0,100*hp/hp_max));#used in HUD @@ -62,6 +60,7 @@ var shells = { "DEFA 554": [14,0.060], # 30x113mm Mirage, 220g "20mm APDS": [15,0.030], # CIWS "LAU-10": [16,0.500], # 127mm, ~4-7kg warhead + # Max id is 41 }; # lbs of warheads is explosive+fragmentation+fuse, so total warhead mass. @@ -164,7 +163,11 @@ var warheads = { "pilot": [93, 0.00,1,0],# ejected pilot "BETAB-500ShP": [94, 1160.00,1,0], "Flare": [95, 0.00,0,0], - "3M9": [96, 125.00,0,0],# 3M9 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 + "AIM-9X": [98, 20.80,0,0], + "R-23R": [99, 55.00,0,0],# mig23 fox 1 + # Max id is 180 }; var AIR_RADAR = "air"; @@ -182,17 +185,21 @@ var radar_signatures = { "m2000-5B": AIR_RADAR, "MiG-21bis": AIR_RADAR, "MiG-21MF-75": AIR_RADAR, + "Mig-23MLD": AIR_RADAR, "MiG-29": AIR_RADAR, "SU-27": AIR_RADAR, "EC-137R": AIR_RADAR, + "E-3R": AIR_RADAR, + "E-3": AIR_RADAR, "RC-137R": AIR_RADAR, "E-8R": AIR_RADAR, "EC-137D": AIR_RADAR, "Mig-28": AIR_RADAR, - "SA-6": AIR_RADAR,#Air radar tone chosen so that there is at least some lock tone until asset-specific is created + "SA-6": "gnd-06",#Air radar tone chosen so that there is at least some lock tone until asset-specific is created + "s-200": "gnd-05", "ZSU-23-4M": "gnd-23", "S-75": "gnd-02", - "buk-m2": "gnd-11", + "buk-m2": "gnd-17", "s-300": "gnd-20", "MIM104D": "gnd-p2", "missile_frigate": "gnd-nk", @@ -203,7 +210,7 @@ var radar_signatures = { var id2warhead = []; var launched = {};# callsign: elapsed-sec var approached = {};# callsign: uniqueID -var heavy_smoke = [61,62,63,65,92,96]; +var heavy_smoke = [61,62,63,65,92,96,97]; var k = keys(warheads); @@ -241,6 +248,10 @@ for(var myid = 0;myid 450) { - printf("Missile Approach Warning from %03d degrees.", bearing); - 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,1,0);# temporary till someone models a RWR in RIO seat + if (radarOn) { + #printf("Missile Approach Warning from %03d degrees.", bearing); + 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 + } else { + #printf("Missile Approach Warning"); + 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 + } approached[notification.Callsign~notification.UniqueIdentity] = elapsed; - if (m28_auto) mig28.engagedBy(notification.Callsign); + if (m28_auto) mig28.engagedBy(notification.Callsign, 1); } return emesary.Transmitter.ReceiptStatus_OK; } @@ -415,11 +440,11 @@ var DamageRecipient = # debug.dump(notification); # # - if (tacview_supported and tacview.starttime and getprop("sim/multiplay/txhost") != "mpserver.opredflag.com") { + if (tacview_supported and tacview.starttime and (getprop("sim/multiplay/txhost") != "mpserver.opredflag.com" or m28_auto)) { 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 - var wh = id2warhead[notification.SecondaryKind - 21]; + var wh = id2warhead[DamageRecipient.emesaryID2typeID(notification.SecondaryKind)]; var lbs = wh[1]; 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); @@ -439,9 +464,10 @@ var DamageRecipient = var callsign = processCallsign(getprop("sim/multiplay/callsign")); if (notification.RemoteCallsign == callsign and getprop("payload/armament/msg") == 1) { #damage enabled and were getting hit - if (m28_auto) mig28.engagedBy(notification.Callsign); + if (notification.SecondaryKind < 0 and hitable_by_cannon) { # cannon hit + if (m28_auto) mig28.engagedBy(notification.Callsign, 0); var probability = id2shell[-1*notification.SecondaryKind-1][1]; var typ = id2shell[-1*notification.SecondaryKind-1][2]; var hit_count = notification.Distance; @@ -455,10 +481,11 @@ var DamageRecipient = damageLog.push(sprintf("%s hit you with %d %s.", notification.Callsign, hit_count, typ)); nearby_explosion(); } - } elsif (notification.SecondaryKind > 20) { + } elsif (notification.SecondaryKind > 20 or notification.SecondaryKind < -40) { # its a warhead + if (m28_auto) mig28.engagedBy(notification.Callsign, 1); var dist = notification.Distance; - var wh = id2warhead[notification.SecondaryKind - 21]; + var wh = id2warhead[DamageRecipient.emesaryID2typeID(notification.SecondaryKind)]; var type = wh[4];#test code if (wh[3] == 1) { # cluster munition @@ -549,21 +576,18 @@ var DamageRecipient = } if (notification.Kind == CREATE and getprop("payload/armament/enable-craters") == 1 and statics["obj_"~notification.UniqueIdentity] == nil) { if (notification.SecondaryKind == 0) {# TODO: make a hash with all the models - var crater_model = getprop("payload/armament/models") ~ "crater_small.xml"; - var static = geo.put_model(crater_model, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); + var static = geo.put_model(crater_model0, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); if (static != nil) { statics["obj_"~notification.UniqueIdentity] = [static, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading, notification.SecondaryKind]; #static is a PropertyNode inside /models } } elsif (notification.SecondaryKind == 1) { - var crater_model = getprop("payload/armament/models") ~ "crater_big.xml"; - var static = geo.put_model(crater_model, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); + var static = geo.put_model(crater_model1, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); if (static != nil) { statics["obj_"~notification.UniqueIdentity] = [static, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading, notification.SecondaryKind]; } } elsif (notification.SecondaryKind == 2) { - var crater_model = getprop("payload/armament/models") ~ "bomb_hit_smoke.xml"; - var static = geo.put_model(crater_model, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); + var static = geo.put_model(crater_model2, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); if (static != nil) { statics["obj_"~notification.UniqueIdentity] = [static, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading, notification.SecondaryKind]; } @@ -586,7 +610,29 @@ var DamageRecipient = return emesary.Transmitter.ReceiptStatus_NotProcessed; }; 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"); @@ -863,6 +909,7 @@ var flare_update_time = 0.4; var flare_duration = 8; var flare_terminal_speed = 50;#m/s var flares_max_process_per_loop = 4; +var flare_sequencer = -120; var flare_sorter = func(a, b) { if(a[0] < b[0]){ @@ -945,7 +992,9 @@ var flare_released = func { getprop("orientation/heading-deg"), FT2M*getprop("velocities/speed-down-fps"), FT2M*math.sqrt(getprop("velocities/speed-north-fps")*getprop("velocities/speed-north-fps")+getprop("velocities/speed-east-fps")*getprop("velocities/speed-east-fps")), - int(rand()*240)-120]; + flare_sequencer]; + flare_sequencer += 1; + if (flare_sequencer > 120) flare_sequencer = -120; append(flare_list, flare); var msg = notifications.ObjectInFlightNotification.new("ffly", flare[6], MOVE, 21+95); msg.Flags = 0; @@ -1087,6 +1136,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; } @@ -1116,6 +1205,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); hp_f = [hp_max,hp_max,hp_max,hp_max,hp_max,hp_max,hp_max]; @@ -1233,7 +1367,7 @@ var processCallsigns = func () { var painted = 0; var paint_list = []; foreach (var player; players) { - if(player.getChild("valid") != nil and player.getChild("valid").getValue() == TRUE and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { + 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(); callsign_struct[callsign] = player; var str6 = player.getNode("sim/multiplay/generic/string[6]"); @@ -1247,6 +1381,8 @@ var processCallsigns = func () { } 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-semiactive", 0); + setprop("payload/armament/MAW-semiactive-callsign", ""); } # spike handling: @@ -1293,16 +1429,16 @@ processCallsignsTimer.start(); var code_ct = func () { #ANTIC if (getprop("payload/armament/msg")) { - setprop("sim/rendering/redout/enabled", TRUE); + setprop("sim/rendering/redout/enabled", 1); #call(func{fgcommand('dialog-close', multiplayer.dialog.dialog.prop())},nil,var err= []);# props.Node.new({"dialog-name": "location-in-air"})); - 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")) { call(func{fgcommand('dialog-close', props.Node.new({"dialog-name": "WeightAndFuel"}))},nil,var err2 = []); call(func{fgcommand('dialog-close', props.Node.new({"dialog-name": "system-failures"}))},nil,var err2 = []); call(func{fgcommand('dialog-close', props.Node.new({"dialog-name": "instrument-failures"}))},nil,var err2 = []); } setprop("sim/freeze/fuel",0); - setprop("/sim/speed-up", 1); + if (!m28_auto) setprop("/sim/speed-up", 1); setprop("/gui/map/draw-traffic", 0); setprop("/sim/marker-pins/traffic", 0); setprop("/sim/gui/dialogs/map-canvas/draw-TFC", 0); @@ -1317,7 +1453,7 @@ code_ctTimer.simulatedTime = 1; -setprop("/sim/failure-manager/display-on-screen", FALSE); +setprop("/sim/failure-manager/display-on-screen", 0); code_ctTimer.start(); @@ -1337,6 +1473,22 @@ var re_init = func (node) { } stopLaunch(); damageLog.push("Aircraft was repaired due to re-init."); + + # Remove all 3D craters and re-place them. Due to re-init can remove some of them. + + foreach (var thekey ; keys(statics)) { + var sta = statics[thekey]; + if (sta[0] != nil) { + sta[0].remove(); + if (sta[5] == 0) {# TODO: make a hash with all the models + sta[0] = geo.put_model(crater_model0, sta[1], sta[2], sta[3], sta[4]); + } elsif (sta[5] == 1) { + sta[0] = geo.put_model(crater_model1, sta[1], sta[2], sta[3], sta[4]); + } elsif (sta[5] == 2) { + sta[0] = geo.put_model(crater_model2, sta[1], sta[2], sta[3], sta[4]); + } + } + } } #================================================================== @@ -1401,10 +1553,25 @@ var writeDamageLog = func { 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); #screen.property_display.add("payload/armament/MAW-bearing"); #screen.property_display.add("payload/armament/MAW-active"); +#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-count"); #screen.property_display.add("payload/armament/MLW-launcher"); @@ -1412,7 +1579,9 @@ setlistener("sim/signals/exit", writeDamageLog, 0, 0); #screen.property_display.add("payload/armament/spike-air"); #screen.property_display.add("payload/armament/spike-gnd-20"); #screen.property_display.add("payload/armament/spike-gnd-02"); -#screen.property_display.add("payload/armament/spike-gnd-11"); +#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-17"); #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-nk"); \ No newline at end of file diff --git a/S-300/Nasal/vector.nas b/S-300/Nasal/vector.nas index 621b0cb..ebc5347 100644 --- a/S-300/Nasal/vector.nas +++ b/S-300/Nasal/vector.nas @@ -2,7 +2,7 @@ var Math = { # # Authors: Nikolai V. Chr, Axel Paccalin. # - # Version 2.01 + # Version 2.02 # # When doing euler coords. to cartesian: +x = forw, +y = left, +z = up. # FG struct. coords: +x = back, +y = right, +z = up. @@ -287,13 +287,13 @@ var Math = { } if (coord1.alt() != coord2.alt()) { 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) { # on top of each other, maybe rounding error.. 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); if (math.abs(me.d13)+me.d32 < me.d12) { # rounding errors somewhere..one triangle side is longer than other 2 sides combined. @@ -479,4 +479,4 @@ var unitTest = { printf("These two should be the same %s = %s",Math.format(aircraft),Math.format(aircraft2)); }, }; -#unitTest.start(); \ No newline at end of file +#unitTest.start(); diff --git a/S-75/Nasal/damage.nas b/S-75/Nasal/damage.nas index 2c7f0e3..617c99f 100644 --- a/S-75/Nasal/damage.nas +++ b/S-75/Nasal/damage.nas @@ -1206,40 +1206,49 @@ var repairYasim = func { } var setupYasimEngines = func { - if (getprop("engines/engine/n1") != nil and !contains(FailureMgr.get_failure_modes(), "engines/engine")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[1]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[2]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[3]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[4]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[5]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[6]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[7]")) { + 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, 300); +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); diff --git a/SA-6/Nasal/damage.nas b/SA-6/Nasal/damage.nas index 2c7f0e3..617c99f 100644 --- a/SA-6/Nasal/damage.nas +++ b/SA-6/Nasal/damage.nas @@ -1206,40 +1206,49 @@ var repairYasim = func { } var setupYasimEngines = func { - if (getprop("engines/engine/n1") != nil and !contains(FailureMgr.get_failure_modes(), "engines/engine")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[1]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[2]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[3]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[4]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[5]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[6]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[7]")) { + 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, 300); +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); diff --git a/ZSU-23/Nasal/damage.nas b/ZSU-23/Nasal/damage.nas index 44b753a..617c99f 100644 --- a/ZSU-23/Nasal/damage.nas +++ b/ZSU-23/Nasal/damage.nas @@ -27,9 +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 TRUE = 1; -var FALSE = 0; - +srand(); var hp = hp_max; setprop("sam/damage", math.max(0,100*hp/hp_max));#used in HUD @@ -62,6 +60,7 @@ var shells = { "DEFA 554": [14,0.060], # 30x113mm Mirage, 220g "20mm APDS": [15,0.030], # CIWS "LAU-10": [16,0.500], # 127mm, ~4-7kg warhead + # Max id is 41 }; # lbs of warheads is explosive+fragmentation+fuse, so total warhead mass. @@ -164,7 +163,11 @@ var warheads = { "pilot": [93, 0.00,1,0],# ejected pilot "BETAB-500ShP": [94, 1160.00,1,0], "Flare": [95, 0.00,0,0], - "3M9": [96, 125.00,0,0],# 3M9 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 + "AIM-9X": [98, 20.80,0,0], + "R-23R": [99, 55.00,0,0],# mig23 fox 1 + # Max id is 180 }; var AIR_RADAR = "air"; @@ -182,17 +185,21 @@ var radar_signatures = { "m2000-5B": AIR_RADAR, "MiG-21bis": AIR_RADAR, "MiG-21MF-75": AIR_RADAR, + "Mig-23MLD": AIR_RADAR, "MiG-29": AIR_RADAR, "SU-27": AIR_RADAR, "EC-137R": AIR_RADAR, + "E-3R": AIR_RADAR, + "E-3": AIR_RADAR, "RC-137R": AIR_RADAR, "E-8R": AIR_RADAR, "EC-137D": AIR_RADAR, "Mig-28": AIR_RADAR, - "SA-6": AIR_RADAR,#Air radar tone chosen so that there is at least some lock tone until asset-specific is created + "SA-6": "gnd-06",#Air radar tone chosen so that there is at least some lock tone until asset-specific is created + "s-200": "gnd-05", "ZSU-23-4M": "gnd-23", "S-75": "gnd-02", - "buk-m2": "gnd-11", + "buk-m2": "gnd-17", "s-300": "gnd-20", "MIM104D": "gnd-p2", "missile_frigate": "gnd-nk", @@ -203,7 +210,7 @@ var radar_signatures = { var id2warhead = []; var launched = {};# callsign: elapsed-sec var approached = {};# callsign: uniqueID -var heavy_smoke = [61,62,63,65,92,96]; +var heavy_smoke = [61,62,63,65,92,96,97]; var k = keys(warheads); @@ -241,6 +248,10 @@ for(var myid = 0;myid 450) { - printf("Missile Approach Warning from %03d degrees.", bearing); - 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,1,0);# temporary till someone models a RWR in RIO seat + if (radarOn) { + #printf("Missile Approach Warning from %03d degrees.", bearing); + 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 + } else { + #printf("Missile Approach Warning"); + 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 + } approached[notification.Callsign~notification.UniqueIdentity] = elapsed; - if (m28_auto) mig28.engagedBy(notification.Callsign); + if (m28_auto) mig28.engagedBy(notification.Callsign, 1); } return emesary.Transmitter.ReceiptStatus_OK; } @@ -415,11 +440,11 @@ var DamageRecipient = # debug.dump(notification); # # - if (tacview_supported and tacview.starttime and getprop("sim/multiplay/txhost") != "mpserver.opredflag.com") { + if (tacview_supported and tacview.starttime and (getprop("sim/multiplay/txhost") != "mpserver.opredflag.com" or m28_auto)) { 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 - var wh = id2warhead[notification.SecondaryKind - 21]; + var wh = id2warhead[DamageRecipient.emesaryID2typeID(notification.SecondaryKind)]; var lbs = wh[1]; 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); @@ -439,9 +464,10 @@ var DamageRecipient = var callsign = processCallsign(getprop("sim/multiplay/callsign")); if (notification.RemoteCallsign == callsign and getprop("payload/armament/msg") == 1) { #damage enabled and were getting hit - if (m28_auto) mig28.engagedBy(notification.Callsign); + if (notification.SecondaryKind < 0 and hitable_by_cannon) { # cannon hit + if (m28_auto) mig28.engagedBy(notification.Callsign, 0); var probability = id2shell[-1*notification.SecondaryKind-1][1]; var typ = id2shell[-1*notification.SecondaryKind-1][2]; var hit_count = notification.Distance; @@ -455,10 +481,11 @@ var DamageRecipient = damageLog.push(sprintf("%s hit you with %d %s.", notification.Callsign, hit_count, typ)); nearby_explosion(); } - } elsif (notification.SecondaryKind > 20) { + } elsif (notification.SecondaryKind > 20 or notification.SecondaryKind < -40) { # its a warhead + if (m28_auto) mig28.engagedBy(notification.Callsign, 1); var dist = notification.Distance; - var wh = id2warhead[notification.SecondaryKind - 21]; + var wh = id2warhead[DamageRecipient.emesaryID2typeID(notification.SecondaryKind)]; var type = wh[4];#test code if (wh[3] == 1) { # cluster munition @@ -549,21 +576,18 @@ var DamageRecipient = } if (notification.Kind == CREATE and getprop("payload/armament/enable-craters") == 1 and statics["obj_"~notification.UniqueIdentity] == nil) { if (notification.SecondaryKind == 0) {# TODO: make a hash with all the models - var crater_model = getprop("payload/armament/models") ~ "crater_small.xml"; - var static = geo.put_model(crater_model, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); + var static = geo.put_model(crater_model0, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); if (static != nil) { statics["obj_"~notification.UniqueIdentity] = [static, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading, notification.SecondaryKind]; #static is a PropertyNode inside /models } } elsif (notification.SecondaryKind == 1) { - var crater_model = getprop("payload/armament/models") ~ "crater_big.xml"; - var static = geo.put_model(crater_model, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); + var static = geo.put_model(crater_model1, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); if (static != nil) { statics["obj_"~notification.UniqueIdentity] = [static, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading, notification.SecondaryKind]; } } elsif (notification.SecondaryKind == 2) { - var crater_model = getprop("payload/armament/models") ~ "bomb_hit_smoke.xml"; - var static = geo.put_model(crater_model, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); + var static = geo.put_model(crater_model2, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); if (static != nil) { statics["obj_"~notification.UniqueIdentity] = [static, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading, notification.SecondaryKind]; } @@ -586,7 +610,29 @@ var DamageRecipient = return emesary.Transmitter.ReceiptStatus_NotProcessed; }; 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"); @@ -863,6 +909,7 @@ var flare_update_time = 0.4; var flare_duration = 8; var flare_terminal_speed = 50;#m/s var flares_max_process_per_loop = 4; +var flare_sequencer = -120; var flare_sorter = func(a, b) { if(a[0] < b[0]){ @@ -945,7 +992,9 @@ var flare_released = func { getprop("orientation/heading-deg"), FT2M*getprop("velocities/speed-down-fps"), FT2M*math.sqrt(getprop("velocities/speed-north-fps")*getprop("velocities/speed-north-fps")+getprop("velocities/speed-east-fps")*getprop("velocities/speed-east-fps")), - int(rand()*240)-120]; + flare_sequencer]; + flare_sequencer += 1; + if (flare_sequencer > 120) flare_sequencer = -120; append(flare_list, flare); var msg = notifications.ObjectInFlightNotification.new("ffly", flare[6], MOVE, 21+95); msg.Flags = 0; @@ -1087,6 +1136,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; } @@ -1116,6 +1205,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); hp_f = [hp_max,hp_max,hp_max,hp_max,hp_max,hp_max,hp_max]; @@ -1233,7 +1367,7 @@ var processCallsigns = func () { var painted = 0; var paint_list = []; foreach (var player; players) { - if(player.getChild("valid") != nil and player.getChild("valid").getValue() == TRUE and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { + 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(); callsign_struct[callsign] = player; var str6 = player.getNode("sim/multiplay/generic/string[6]"); @@ -1247,6 +1381,8 @@ var processCallsigns = func () { } 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-semiactive", 0); + setprop("payload/armament/MAW-semiactive-callsign", ""); } # spike handling: @@ -1293,16 +1429,16 @@ processCallsignsTimer.start(); var code_ct = func () { #ANTIC if (getprop("payload/armament/msg")) { - setprop("sim/rendering/redout/enabled", TRUE); + setprop("sim/rendering/redout/enabled", 1); #call(func{fgcommand('dialog-close', multiplayer.dialog.dialog.prop())},nil,var err= []);# props.Node.new({"dialog-name": "location-in-air"})); - 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")) { call(func{fgcommand('dialog-close', props.Node.new({"dialog-name": "WeightAndFuel"}))},nil,var err2 = []); call(func{fgcommand('dialog-close', props.Node.new({"dialog-name": "system-failures"}))},nil,var err2 = []); call(func{fgcommand('dialog-close', props.Node.new({"dialog-name": "instrument-failures"}))},nil,var err2 = []); } setprop("sim/freeze/fuel",0); - setprop("/sim/speed-up", 1); + if (!m28_auto) setprop("/sim/speed-up", 1); setprop("/gui/map/draw-traffic", 0); setprop("/sim/marker-pins/traffic", 0); setprop("/sim/gui/dialogs/map-canvas/draw-TFC", 0); @@ -1317,7 +1453,7 @@ code_ctTimer.simulatedTime = 1; -setprop("/sim/failure-manager/display-on-screen", FALSE); +setprop("/sim/failure-manager/display-on-screen", 0); code_ctTimer.start(); @@ -1337,6 +1473,22 @@ var re_init = func (node) { } stopLaunch(); damageLog.push("Aircraft was repaired due to re-init."); + + # Remove all 3D craters and re-place them. Due to re-init can remove some of them. + + foreach (var thekey ; keys(statics)) { + var sta = statics[thekey]; + if (sta[0] != nil) { + sta[0].remove(); + if (sta[5] == 0) {# TODO: make a hash with all the models + sta[0] = geo.put_model(crater_model0, sta[1], sta[2], sta[3], sta[4]); + } elsif (sta[5] == 1) { + sta[0] = geo.put_model(crater_model1, sta[1], sta[2], sta[3], sta[4]); + } elsif (sta[5] == 2) { + sta[0] = geo.put_model(crater_model2, sta[1], sta[2], sta[3], sta[4]); + } + } + } } #================================================================== @@ -1401,10 +1553,25 @@ var writeDamageLog = func { 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); #screen.property_display.add("payload/armament/MAW-bearing"); #screen.property_display.add("payload/armament/MAW-active"); +#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-count"); #screen.property_display.add("payload/armament/MLW-launcher"); @@ -1412,7 +1579,9 @@ setlistener("sim/signals/exit", writeDamageLog, 0, 0); #screen.property_display.add("payload/armament/spike-air"); #screen.property_display.add("payload/armament/spike-gnd-20"); #screen.property_display.add("payload/armament/spike-gnd-02"); -#screen.property_display.add("payload/armament/spike-gnd-11"); +#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-17"); #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-nk"); \ No newline at end of file diff --git a/ZSU-23/Nasal/vector.nas b/ZSU-23/Nasal/vector.nas index 621b0cb..ebc5347 100644 --- a/ZSU-23/Nasal/vector.nas +++ b/ZSU-23/Nasal/vector.nas @@ -2,7 +2,7 @@ var Math = { # # Authors: Nikolai V. Chr, Axel Paccalin. # - # Version 2.01 + # Version 2.02 # # When doing euler coords. to cartesian: +x = forw, +y = left, +z = up. # FG struct. coords: +x = back, +y = right, +z = up. @@ -287,13 +287,13 @@ var Math = { } if (coord1.alt() != coord2.alt()) { 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) { # on top of each other, maybe rounding error.. 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); if (math.abs(me.d13)+me.d32 < me.d12) { # rounding errors somewhere..one triangle side is longer than other 2 sides combined. @@ -479,4 +479,4 @@ var unitTest = { printf("These two should be the same %s = %s",Math.format(aircraft),Math.format(aircraft2)); }, }; -#unitTest.start(); \ No newline at end of file +#unitTest.start(); diff --git a/depot/Nasal/damage.nas b/depot/Nasal/damage.nas index 2c7f0e3..617c99f 100644 --- a/depot/Nasal/damage.nas +++ b/depot/Nasal/damage.nas @@ -1206,40 +1206,49 @@ var repairYasim = func { } var setupYasimEngines = func { - if (getprop("engines/engine/n1") != nil and !contains(FailureMgr.get_failure_modes(), "engines/engine")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[1]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[2]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[3]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[4]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[5]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[6]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[7]")) { + 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, 300); +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); diff --git a/fleet/Nasal/damage.nas b/fleet/Nasal/damage.nas index 44b753a..617c99f 100644 --- a/fleet/Nasal/damage.nas +++ b/fleet/Nasal/damage.nas @@ -27,9 +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 TRUE = 1; -var FALSE = 0; - +srand(); var hp = hp_max; setprop("sam/damage", math.max(0,100*hp/hp_max));#used in HUD @@ -62,6 +60,7 @@ var shells = { "DEFA 554": [14,0.060], # 30x113mm Mirage, 220g "20mm APDS": [15,0.030], # CIWS "LAU-10": [16,0.500], # 127mm, ~4-7kg warhead + # Max id is 41 }; # lbs of warheads is explosive+fragmentation+fuse, so total warhead mass. @@ -164,7 +163,11 @@ var warheads = { "pilot": [93, 0.00,1,0],# ejected pilot "BETAB-500ShP": [94, 1160.00,1,0], "Flare": [95, 0.00,0,0], - "3M9": [96, 125.00,0,0],# 3M9 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 + "AIM-9X": [98, 20.80,0,0], + "R-23R": [99, 55.00,0,0],# mig23 fox 1 + # Max id is 180 }; var AIR_RADAR = "air"; @@ -182,17 +185,21 @@ var radar_signatures = { "m2000-5B": AIR_RADAR, "MiG-21bis": AIR_RADAR, "MiG-21MF-75": AIR_RADAR, + "Mig-23MLD": AIR_RADAR, "MiG-29": AIR_RADAR, "SU-27": AIR_RADAR, "EC-137R": AIR_RADAR, + "E-3R": AIR_RADAR, + "E-3": AIR_RADAR, "RC-137R": AIR_RADAR, "E-8R": AIR_RADAR, "EC-137D": AIR_RADAR, "Mig-28": AIR_RADAR, - "SA-6": AIR_RADAR,#Air radar tone chosen so that there is at least some lock tone until asset-specific is created + "SA-6": "gnd-06",#Air radar tone chosen so that there is at least some lock tone until asset-specific is created + "s-200": "gnd-05", "ZSU-23-4M": "gnd-23", "S-75": "gnd-02", - "buk-m2": "gnd-11", + "buk-m2": "gnd-17", "s-300": "gnd-20", "MIM104D": "gnd-p2", "missile_frigate": "gnd-nk", @@ -203,7 +210,7 @@ var radar_signatures = { var id2warhead = []; var launched = {};# callsign: elapsed-sec var approached = {};# callsign: uniqueID -var heavy_smoke = [61,62,63,65,92,96]; +var heavy_smoke = [61,62,63,65,92,96,97]; var k = keys(warheads); @@ -241,6 +248,10 @@ for(var myid = 0;myid 450) { - printf("Missile Approach Warning from %03d degrees.", bearing); - 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,1,0);# temporary till someone models a RWR in RIO seat + if (radarOn) { + #printf("Missile Approach Warning from %03d degrees.", bearing); + 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 + } else { + #printf("Missile Approach Warning"); + 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 + } approached[notification.Callsign~notification.UniqueIdentity] = elapsed; - if (m28_auto) mig28.engagedBy(notification.Callsign); + if (m28_auto) mig28.engagedBy(notification.Callsign, 1); } return emesary.Transmitter.ReceiptStatus_OK; } @@ -415,11 +440,11 @@ var DamageRecipient = # debug.dump(notification); # # - if (tacview_supported and tacview.starttime and getprop("sim/multiplay/txhost") != "mpserver.opredflag.com") { + if (tacview_supported and tacview.starttime and (getprop("sim/multiplay/txhost") != "mpserver.opredflag.com" or m28_auto)) { 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 - var wh = id2warhead[notification.SecondaryKind - 21]; + var wh = id2warhead[DamageRecipient.emesaryID2typeID(notification.SecondaryKind)]; var lbs = wh[1]; 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); @@ -439,9 +464,10 @@ var DamageRecipient = var callsign = processCallsign(getprop("sim/multiplay/callsign")); if (notification.RemoteCallsign == callsign and getprop("payload/armament/msg") == 1) { #damage enabled and were getting hit - if (m28_auto) mig28.engagedBy(notification.Callsign); + if (notification.SecondaryKind < 0 and hitable_by_cannon) { # cannon hit + if (m28_auto) mig28.engagedBy(notification.Callsign, 0); var probability = id2shell[-1*notification.SecondaryKind-1][1]; var typ = id2shell[-1*notification.SecondaryKind-1][2]; var hit_count = notification.Distance; @@ -455,10 +481,11 @@ var DamageRecipient = damageLog.push(sprintf("%s hit you with %d %s.", notification.Callsign, hit_count, typ)); nearby_explosion(); } - } elsif (notification.SecondaryKind > 20) { + } elsif (notification.SecondaryKind > 20 or notification.SecondaryKind < -40) { # its a warhead + if (m28_auto) mig28.engagedBy(notification.Callsign, 1); var dist = notification.Distance; - var wh = id2warhead[notification.SecondaryKind - 21]; + var wh = id2warhead[DamageRecipient.emesaryID2typeID(notification.SecondaryKind)]; var type = wh[4];#test code if (wh[3] == 1) { # cluster munition @@ -549,21 +576,18 @@ var DamageRecipient = } if (notification.Kind == CREATE and getprop("payload/armament/enable-craters") == 1 and statics["obj_"~notification.UniqueIdentity] == nil) { if (notification.SecondaryKind == 0) {# TODO: make a hash with all the models - var crater_model = getprop("payload/armament/models") ~ "crater_small.xml"; - var static = geo.put_model(crater_model, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); + var static = geo.put_model(crater_model0, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); if (static != nil) { statics["obj_"~notification.UniqueIdentity] = [static, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading, notification.SecondaryKind]; #static is a PropertyNode inside /models } } elsif (notification.SecondaryKind == 1) { - var crater_model = getprop("payload/armament/models") ~ "crater_big.xml"; - var static = geo.put_model(crater_model, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); + var static = geo.put_model(crater_model1, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); if (static != nil) { statics["obj_"~notification.UniqueIdentity] = [static, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading, notification.SecondaryKind]; } } elsif (notification.SecondaryKind == 2) { - var crater_model = getprop("payload/armament/models") ~ "bomb_hit_smoke.xml"; - var static = geo.put_model(crater_model, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); + var static = geo.put_model(crater_model2, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); if (static != nil) { statics["obj_"~notification.UniqueIdentity] = [static, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading, notification.SecondaryKind]; } @@ -586,7 +610,29 @@ var DamageRecipient = return emesary.Transmitter.ReceiptStatus_NotProcessed; }; 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"); @@ -863,6 +909,7 @@ var flare_update_time = 0.4; var flare_duration = 8; var flare_terminal_speed = 50;#m/s var flares_max_process_per_loop = 4; +var flare_sequencer = -120; var flare_sorter = func(a, b) { if(a[0] < b[0]){ @@ -945,7 +992,9 @@ var flare_released = func { getprop("orientation/heading-deg"), FT2M*getprop("velocities/speed-down-fps"), FT2M*math.sqrt(getprop("velocities/speed-north-fps")*getprop("velocities/speed-north-fps")+getprop("velocities/speed-east-fps")*getprop("velocities/speed-east-fps")), - int(rand()*240)-120]; + flare_sequencer]; + flare_sequencer += 1; + if (flare_sequencer > 120) flare_sequencer = -120; append(flare_list, flare); var msg = notifications.ObjectInFlightNotification.new("ffly", flare[6], MOVE, 21+95); msg.Flags = 0; @@ -1087,6 +1136,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; } @@ -1116,6 +1205,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); hp_f = [hp_max,hp_max,hp_max,hp_max,hp_max,hp_max,hp_max]; @@ -1233,7 +1367,7 @@ var processCallsigns = func () { var painted = 0; var paint_list = []; foreach (var player; players) { - if(player.getChild("valid") != nil and player.getChild("valid").getValue() == TRUE and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { + 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(); callsign_struct[callsign] = player; var str6 = player.getNode("sim/multiplay/generic/string[6]"); @@ -1247,6 +1381,8 @@ var processCallsigns = func () { } 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-semiactive", 0); + setprop("payload/armament/MAW-semiactive-callsign", ""); } # spike handling: @@ -1293,16 +1429,16 @@ processCallsignsTimer.start(); var code_ct = func () { #ANTIC if (getprop("payload/armament/msg")) { - setprop("sim/rendering/redout/enabled", TRUE); + setprop("sim/rendering/redout/enabled", 1); #call(func{fgcommand('dialog-close', multiplayer.dialog.dialog.prop())},nil,var err= []);# props.Node.new({"dialog-name": "location-in-air"})); - 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")) { call(func{fgcommand('dialog-close', props.Node.new({"dialog-name": "WeightAndFuel"}))},nil,var err2 = []); call(func{fgcommand('dialog-close', props.Node.new({"dialog-name": "system-failures"}))},nil,var err2 = []); call(func{fgcommand('dialog-close', props.Node.new({"dialog-name": "instrument-failures"}))},nil,var err2 = []); } setprop("sim/freeze/fuel",0); - setprop("/sim/speed-up", 1); + if (!m28_auto) setprop("/sim/speed-up", 1); setprop("/gui/map/draw-traffic", 0); setprop("/sim/marker-pins/traffic", 0); setprop("/sim/gui/dialogs/map-canvas/draw-TFC", 0); @@ -1317,7 +1453,7 @@ code_ctTimer.simulatedTime = 1; -setprop("/sim/failure-manager/display-on-screen", FALSE); +setprop("/sim/failure-manager/display-on-screen", 0); code_ctTimer.start(); @@ -1337,6 +1473,22 @@ var re_init = func (node) { } stopLaunch(); damageLog.push("Aircraft was repaired due to re-init."); + + # Remove all 3D craters and re-place them. Due to re-init can remove some of them. + + foreach (var thekey ; keys(statics)) { + var sta = statics[thekey]; + if (sta[0] != nil) { + sta[0].remove(); + if (sta[5] == 0) {# TODO: make a hash with all the models + sta[0] = geo.put_model(crater_model0, sta[1], sta[2], sta[3], sta[4]); + } elsif (sta[5] == 1) { + sta[0] = geo.put_model(crater_model1, sta[1], sta[2], sta[3], sta[4]); + } elsif (sta[5] == 2) { + sta[0] = geo.put_model(crater_model2, sta[1], sta[2], sta[3], sta[4]); + } + } + } } #================================================================== @@ -1401,10 +1553,25 @@ var writeDamageLog = func { 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); #screen.property_display.add("payload/armament/MAW-bearing"); #screen.property_display.add("payload/armament/MAW-active"); +#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-count"); #screen.property_display.add("payload/armament/MLW-launcher"); @@ -1412,7 +1579,9 @@ setlistener("sim/signals/exit", writeDamageLog, 0, 0); #screen.property_display.add("payload/armament/spike-air"); #screen.property_display.add("payload/armament/spike-gnd-20"); #screen.property_display.add("payload/armament/spike-gnd-02"); -#screen.property_display.add("payload/armament/spike-gnd-11"); +#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-17"); #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-nk"); \ No newline at end of file diff --git a/fleet/Nasal/vector.nas b/fleet/Nasal/vector.nas index 621b0cb..ebc5347 100644 --- a/fleet/Nasal/vector.nas +++ b/fleet/Nasal/vector.nas @@ -2,7 +2,7 @@ var Math = { # # Authors: Nikolai V. Chr, Axel Paccalin. # - # Version 2.01 + # Version 2.02 # # When doing euler coords. to cartesian: +x = forw, +y = left, +z = up. # FG struct. coords: +x = back, +y = right, +z = up. @@ -287,13 +287,13 @@ var Math = { } if (coord1.alt() != coord2.alt()) { 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) { # on top of each other, maybe rounding error.. 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); if (math.abs(me.d13)+me.d32 < me.d12) { # rounding errors somewhere..one triangle side is longer than other 2 sides combined. @@ -479,4 +479,4 @@ var unitTest = { printf("These two should be the same %s = %s",Math.format(aircraft),Math.format(aircraft2)); }, }; -#unitTest.start(); \ No newline at end of file +#unitTest.start(); diff --git a/gci-radar/Nasal/damage.nas b/gci-radar/Nasal/damage.nas index 2c7f0e3..617c99f 100644 --- a/gci-radar/Nasal/damage.nas +++ b/gci-radar/Nasal/damage.nas @@ -1206,40 +1206,49 @@ var repairYasim = func { } var setupYasimEngines = func { - if (getprop("engines/engine/n1") != nil and !contains(FailureMgr.get_failure_modes(), "engines/engine")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[1]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[2]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[3]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[4]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[5]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[6]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[7]")) { + 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, 300); +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); diff --git a/groundtarget/Nasal/damage.nas b/groundtarget/Nasal/damage.nas index 2c7f0e3..617c99f 100644 --- a/groundtarget/Nasal/damage.nas +++ b/groundtarget/Nasal/damage.nas @@ -1206,40 +1206,49 @@ var repairYasim = func { } var setupYasimEngines = func { - if (getprop("engines/engine/n1") != nil and !contains(FailureMgr.get_failure_modes(), "engines/engine")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[1]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[2]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[3]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[4]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[5]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[6]")) { + 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 !contains(FailureMgr.get_failure_modes(), "engines/engine[7]")) { + 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, 300); +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); diff --git a/missile-frigate/Nasal/damage.nas b/missile-frigate/Nasal/damage.nas index 44b753a..617c99f 100644 --- a/missile-frigate/Nasal/damage.nas +++ b/missile-frigate/Nasal/damage.nas @@ -27,9 +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 TRUE = 1; -var FALSE = 0; - +srand(); var hp = hp_max; setprop("sam/damage", math.max(0,100*hp/hp_max));#used in HUD @@ -62,6 +60,7 @@ var shells = { "DEFA 554": [14,0.060], # 30x113mm Mirage, 220g "20mm APDS": [15,0.030], # CIWS "LAU-10": [16,0.500], # 127mm, ~4-7kg warhead + # Max id is 41 }; # lbs of warheads is explosive+fragmentation+fuse, so total warhead mass. @@ -164,7 +163,11 @@ var warheads = { "pilot": [93, 0.00,1,0],# ejected pilot "BETAB-500ShP": [94, 1160.00,1,0], "Flare": [95, 0.00,0,0], - "3M9": [96, 125.00,0,0],# 3M9 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 + "AIM-9X": [98, 20.80,0,0], + "R-23R": [99, 55.00,0,0],# mig23 fox 1 + # Max id is 180 }; var AIR_RADAR = "air"; @@ -182,17 +185,21 @@ var radar_signatures = { "m2000-5B": AIR_RADAR, "MiG-21bis": AIR_RADAR, "MiG-21MF-75": AIR_RADAR, + "Mig-23MLD": AIR_RADAR, "MiG-29": AIR_RADAR, "SU-27": AIR_RADAR, "EC-137R": AIR_RADAR, + "E-3R": AIR_RADAR, + "E-3": AIR_RADAR, "RC-137R": AIR_RADAR, "E-8R": AIR_RADAR, "EC-137D": AIR_RADAR, "Mig-28": AIR_RADAR, - "SA-6": AIR_RADAR,#Air radar tone chosen so that there is at least some lock tone until asset-specific is created + "SA-6": "gnd-06",#Air radar tone chosen so that there is at least some lock tone until asset-specific is created + "s-200": "gnd-05", "ZSU-23-4M": "gnd-23", "S-75": "gnd-02", - "buk-m2": "gnd-11", + "buk-m2": "gnd-17", "s-300": "gnd-20", "MIM104D": "gnd-p2", "missile_frigate": "gnd-nk", @@ -203,7 +210,7 @@ var radar_signatures = { var id2warhead = []; var launched = {};# callsign: elapsed-sec var approached = {};# callsign: uniqueID -var heavy_smoke = [61,62,63,65,92,96]; +var heavy_smoke = [61,62,63,65,92,96,97]; var k = keys(warheads); @@ -241,6 +248,10 @@ for(var myid = 0;myid 450) { - printf("Missile Approach Warning from %03d degrees.", bearing); - 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,1,0);# temporary till someone models a RWR in RIO seat + if (radarOn) { + #printf("Missile Approach Warning from %03d degrees.", bearing); + 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 + } else { + #printf("Missile Approach Warning"); + 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 + } approached[notification.Callsign~notification.UniqueIdentity] = elapsed; - if (m28_auto) mig28.engagedBy(notification.Callsign); + if (m28_auto) mig28.engagedBy(notification.Callsign, 1); } return emesary.Transmitter.ReceiptStatus_OK; } @@ -415,11 +440,11 @@ var DamageRecipient = # debug.dump(notification); # # - if (tacview_supported and tacview.starttime and getprop("sim/multiplay/txhost") != "mpserver.opredflag.com") { + if (tacview_supported and tacview.starttime and (getprop("sim/multiplay/txhost") != "mpserver.opredflag.com" or m28_auto)) { 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 - var wh = id2warhead[notification.SecondaryKind - 21]; + var wh = id2warhead[DamageRecipient.emesaryID2typeID(notification.SecondaryKind)]; var lbs = wh[1]; 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); @@ -439,9 +464,10 @@ var DamageRecipient = var callsign = processCallsign(getprop("sim/multiplay/callsign")); if (notification.RemoteCallsign == callsign and getprop("payload/armament/msg") == 1) { #damage enabled and were getting hit - if (m28_auto) mig28.engagedBy(notification.Callsign); + if (notification.SecondaryKind < 0 and hitable_by_cannon) { # cannon hit + if (m28_auto) mig28.engagedBy(notification.Callsign, 0); var probability = id2shell[-1*notification.SecondaryKind-1][1]; var typ = id2shell[-1*notification.SecondaryKind-1][2]; var hit_count = notification.Distance; @@ -455,10 +481,11 @@ var DamageRecipient = damageLog.push(sprintf("%s hit you with %d %s.", notification.Callsign, hit_count, typ)); nearby_explosion(); } - } elsif (notification.SecondaryKind > 20) { + } elsif (notification.SecondaryKind > 20 or notification.SecondaryKind < -40) { # its a warhead + if (m28_auto) mig28.engagedBy(notification.Callsign, 1); var dist = notification.Distance; - var wh = id2warhead[notification.SecondaryKind - 21]; + var wh = id2warhead[DamageRecipient.emesaryID2typeID(notification.SecondaryKind)]; var type = wh[4];#test code if (wh[3] == 1) { # cluster munition @@ -549,21 +576,18 @@ var DamageRecipient = } if (notification.Kind == CREATE and getprop("payload/armament/enable-craters") == 1 and statics["obj_"~notification.UniqueIdentity] == nil) { if (notification.SecondaryKind == 0) {# TODO: make a hash with all the models - var crater_model = getprop("payload/armament/models") ~ "crater_small.xml"; - var static = geo.put_model(crater_model, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); + var static = geo.put_model(crater_model0, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); if (static != nil) { statics["obj_"~notification.UniqueIdentity] = [static, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading, notification.SecondaryKind]; #static is a PropertyNode inside /models } } elsif (notification.SecondaryKind == 1) { - var crater_model = getprop("payload/armament/models") ~ "crater_big.xml"; - var static = geo.put_model(crater_model, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); + var static = geo.put_model(crater_model1, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); if (static != nil) { statics["obj_"~notification.UniqueIdentity] = [static, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading, notification.SecondaryKind]; } } elsif (notification.SecondaryKind == 2) { - var crater_model = getprop("payload/armament/models") ~ "bomb_hit_smoke.xml"; - var static = geo.put_model(crater_model, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); + var static = geo.put_model(crater_model2, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading); if (static != nil) { statics["obj_"~notification.UniqueIdentity] = [static, notification.Position.lat(), notification.Position.lon(), notification.Position.alt(), notification.Heading, notification.SecondaryKind]; } @@ -586,7 +610,29 @@ var DamageRecipient = return emesary.Transmitter.ReceiptStatus_NotProcessed; }; 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"); @@ -863,6 +909,7 @@ var flare_update_time = 0.4; var flare_duration = 8; var flare_terminal_speed = 50;#m/s var flares_max_process_per_loop = 4; +var flare_sequencer = -120; var flare_sorter = func(a, b) { if(a[0] < b[0]){ @@ -945,7 +992,9 @@ var flare_released = func { getprop("orientation/heading-deg"), FT2M*getprop("velocities/speed-down-fps"), FT2M*math.sqrt(getprop("velocities/speed-north-fps")*getprop("velocities/speed-north-fps")+getprop("velocities/speed-east-fps")*getprop("velocities/speed-east-fps")), - int(rand()*240)-120]; + flare_sequencer]; + flare_sequencer += 1; + if (flare_sequencer > 120) flare_sequencer = -120; append(flare_list, flare); var msg = notifications.ObjectInFlightNotification.new("ffly", flare[6], MOVE, 21+95); msg.Flags = 0; @@ -1087,6 +1136,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; } @@ -1116,6 +1205,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); hp_f = [hp_max,hp_max,hp_max,hp_max,hp_max,hp_max,hp_max]; @@ -1233,7 +1367,7 @@ var processCallsigns = func () { var painted = 0; var paint_list = []; foreach (var player; players) { - if(player.getChild("valid") != nil and player.getChild("valid").getValue() == TRUE and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { + 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(); callsign_struct[callsign] = player; var str6 = player.getNode("sim/multiplay/generic/string[6]"); @@ -1247,6 +1381,8 @@ var processCallsigns = func () { } 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-semiactive", 0); + setprop("payload/armament/MAW-semiactive-callsign", ""); } # spike handling: @@ -1293,16 +1429,16 @@ processCallsignsTimer.start(); var code_ct = func () { #ANTIC if (getprop("payload/armament/msg")) { - setprop("sim/rendering/redout/enabled", TRUE); + setprop("sim/rendering/redout/enabled", 1); #call(func{fgcommand('dialog-close', multiplayer.dialog.dialog.prop())},nil,var err= []);# props.Node.new({"dialog-name": "location-in-air"})); - 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")) { call(func{fgcommand('dialog-close', props.Node.new({"dialog-name": "WeightAndFuel"}))},nil,var err2 = []); call(func{fgcommand('dialog-close', props.Node.new({"dialog-name": "system-failures"}))},nil,var err2 = []); call(func{fgcommand('dialog-close', props.Node.new({"dialog-name": "instrument-failures"}))},nil,var err2 = []); } setprop("sim/freeze/fuel",0); - setprop("/sim/speed-up", 1); + if (!m28_auto) setprop("/sim/speed-up", 1); setprop("/gui/map/draw-traffic", 0); setprop("/sim/marker-pins/traffic", 0); setprop("/sim/gui/dialogs/map-canvas/draw-TFC", 0); @@ -1317,7 +1453,7 @@ code_ctTimer.simulatedTime = 1; -setprop("/sim/failure-manager/display-on-screen", FALSE); +setprop("/sim/failure-manager/display-on-screen", 0); code_ctTimer.start(); @@ -1337,6 +1473,22 @@ var re_init = func (node) { } stopLaunch(); damageLog.push("Aircraft was repaired due to re-init."); + + # Remove all 3D craters and re-place them. Due to re-init can remove some of them. + + foreach (var thekey ; keys(statics)) { + var sta = statics[thekey]; + if (sta[0] != nil) { + sta[0].remove(); + if (sta[5] == 0) {# TODO: make a hash with all the models + sta[0] = geo.put_model(crater_model0, sta[1], sta[2], sta[3], sta[4]); + } elsif (sta[5] == 1) { + sta[0] = geo.put_model(crater_model1, sta[1], sta[2], sta[3], sta[4]); + } elsif (sta[5] == 2) { + sta[0] = geo.put_model(crater_model2, sta[1], sta[2], sta[3], sta[4]); + } + } + } } #================================================================== @@ -1401,10 +1553,25 @@ var writeDamageLog = func { 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); #screen.property_display.add("payload/armament/MAW-bearing"); #screen.property_display.add("payload/armament/MAW-active"); +#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-count"); #screen.property_display.add("payload/armament/MLW-launcher"); @@ -1412,7 +1579,9 @@ setlistener("sim/signals/exit", writeDamageLog, 0, 0); #screen.property_display.add("payload/armament/spike-air"); #screen.property_display.add("payload/armament/spike-gnd-20"); #screen.property_display.add("payload/armament/spike-gnd-02"); -#screen.property_display.add("payload/armament/spike-gnd-11"); +#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-17"); #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-nk"); \ No newline at end of file diff --git a/missile-frigate/Nasal/vector.nas b/missile-frigate/Nasal/vector.nas index 621b0cb..ebc5347 100644 --- a/missile-frigate/Nasal/vector.nas +++ b/missile-frigate/Nasal/vector.nas @@ -2,7 +2,7 @@ var Math = { # # Authors: Nikolai V. Chr, Axel Paccalin. # - # Version 2.01 + # Version 2.02 # # When doing euler coords. to cartesian: +x = forw, +y = left, +z = up. # FG struct. coords: +x = back, +y = right, +z = up. @@ -287,13 +287,13 @@ var Math = { } if (coord1.alt() != coord2.alt()) { 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) { # on top of each other, maybe rounding error.. 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); if (math.abs(me.d13)+me.d32 < me.d12) { # rounding errors somewhere..one triangle side is longer than other 2 sides combined. @@ -479,4 +479,4 @@ var unitTest = { printf("These two should be the same %s = %s",Math.format(aircraft),Math.format(aircraft2)); }, }; -#unitTest.start(); \ No newline at end of file +#unitTest.start();