diff --git a/Mirage-2000/Nasal/fire-control.nas b/Mirage-2000/Nasal/fire-control.nas index 491ba09e..4ae9be56 100644 --- a/Mirage-2000/Nasal/fire-control.nas +++ b/Mirage-2000/Nasal/fire-control.nas @@ -654,6 +654,20 @@ var FireControl = { me.selectedType = nil; printDebug("FC: nothing selected"); }, + + setPoint: func (c) { + me.ag = me.getSelectedWeapon(); + if (me.ag != nil and me.ag["target_pnt"] == 1) { + if (c == nil) { + print("agm65 nil"); + me.ag.setContacts([]); + } else { + print("agm65 xfer"); + me.tgp_point = ContactTGP.new("TGP-Spot",c); + me.ag.setContacts([me.tgp_point]); + } + } + }, }; var debug = 0; @@ -661,8 +675,134 @@ var printDebug = func (msg) {if (debug == 1) print(msg);}; var printfDebug = func {if (debug == 1) call(printf,arg);}; -# This is non-generic method, please edit it to fit your radar setup: + +# This is non-generic methods, please edit it to fit your radar setup: var getCompleteRadarTargetsList = func { # A list of all MP/AI aircraft/ships/surface-targets around the aircraft. return radar.completeList; } + +var ContactTGP = { + new: func(callsign, coord) { + var obj = { parents : [ContactTGP]};# in real OO class this should inherit from Contact, but in nasal it does not need to + obj.coord = geo.Coord.new(coord); + obj.coord.set_alt(coord.alt()+1);#avoid z fighting + obj.callsign = callsign; + obj.unique = rand(); + return obj; + }, + + isValid: func () { + return 1; + }, + + isVirtual: func () { + return 1; + }, + + isPainted: func () { + return 0; + }, + + isLaserPainted: func{ + getprop("controls/armament/laser-arm-dmd"); + }, + + isRadiating: func (c) { + return 0; + }, + + getUnique: func () { + return me.unique; + }, + + getElevation: func() { + #var e = 0; + var self = geo.aircraft_position(); + #var angleInv = ja37.clamp(self.distance_to(me.coord)/self.direct_distance_to(me.coord), -1, 1); + #e = (self.alt()>me.coord.alt()?-1:1)*math.acos(angleInv)*R2D; + return vector.Math.getPitch(self, me.coord); + }, + + getFlareNode: func () { + return nil; + }, + + getChaffNode: func () { + return nil; + }, + + get_Coord: func(){ + return me.coord; + }, + + getETA: func { + return nil; + }, + + getHitChance: func { + return nil; + }, + + get_Callsign: func(){ + return me.callsign; + }, + + get_model: func(){ + return "TGP spot"; + }, + + get_Speed: func(){ + # return true airspeed + return 0; + }, + + get_Longitude: func(){ + var n = me.coord.lon(); + return n; + }, + + get_Latitude: func(){ + var n = me.coord.lat(); + return n; + }, + + get_Pitch: func(){ + return 0; + }, + + get_Roll: func(){ + return 0; + }, + + get_heading : func(){ + return 0; + }, + + get_bearing: func(){ + var n = me.get_bearing_from_Coord(geo.aircraft_position()); + return n; + }, + + get_altitude: func(){ + #Return Alt in feet + return me.coord.alt()*M2FT; + }, + + get_range: func() { + var r = me.coord.direct_distance_to(geo.aircraft_position()) * M2NM; + return r; + }, + + get_type: func () { + return armament.POINT; + }, + + get_bearing_from_Coord: func(MyAircraftCoord){ + var myBearing = 0; + if(me.coord.is_defined()) { + myBearing = MyAircraftCoord.course_to(me.coord); + } + return myBearing; + }, +}; diff --git a/Mirage-2000/Nasal/missile-code.nas b/Mirage-2000/Nasal/missile-code.nas index 88ac96b1..2ea0d0ba 100644 --- a/Mirage-2000/Nasal/missile-code.nas +++ b/Mirage-2000/Nasal/missile-code.nas @@ -132,15 +132,16 @@ var AIR = 0; var MARINE = 1; var SURFACE = 2; var ORDNANCE = 3; +var POINT = 4; # set these to print stuff to console: -var DEBUG_STATS = 1;#most basic stuff +var DEBUG_STATS = 0;#most basic stuff var DEBUG_FLIGHT = 0;#for creating missiles sometimes good to have this on to see how it flies. # set these to debug the code: -var DEBUG_STATS_DETAILS = FALSE; -var DEBUG_GUIDANCE = FALSE; -var DEBUG_GUIDANCE_DETAILS = FALSE; +var DEBUG_STATS_DETAILS = 0; +var DEBUG_GUIDANCE = 0; +var DEBUG_GUIDANCE_DETAILS = 0; var DEBUG_FLIGHT_DETAILS = 0; var DEBUG_SEARCH = 0; var DEBUG_CODE = FALSE; @@ -269,7 +270,7 @@ var AIM = { m.max_fire_range_nm = getprop(m.nodeString~"max-fire-range-nm"); # max range that the FCS allows firing m.min_fire_range_nm = getprop(m.nodeString~"min-fire-range-nm"); # it wont get solid lock before the target has this range m.fcs_fov = getprop(m.nodeString~"FCS-field-deg") / 2; # fire control system total field of view diameter for when searching and getting lock before launch. - m.class = getprop(m.nodeString~"class"); # put in letters here that represent the types the missile can fire at. A=air, M=marine, G=ground + m.class = getprop(m.nodeString~"class"); # put in letters here that represent the types the missile can fire at. A=air, M=marine, G=ground, P=point m.brevity = getprop(m.nodeString~"fire-msg"); # what the pilot will call out over the comm when he fires this weapon m.coolable = getprop(m.nodeString~"coolable"); # If the seeker supports being cooled. (AIM-9L or later supports) m.cool_time = getprop(m.nodeString~"cool-time"); # Time to cold the seeker from fully warm. @@ -341,7 +342,11 @@ var AIM = { m.dlz_enabled = getprop(m.nodeString~"DLZ"); # Supports dynamic launch zone info. For now only works with A/A. [optional] m.dlz_opt_alt = getprop(m.nodeString~"DLZ-optimal-alt-feet"); # Minimum altitude required to hit the target at max range. m.dlz_opt_mach = getprop(m.nodeString~"DLZ-optimal-closing-mach"); # Closing speed required to hit the target at max range at minimum altitude. - + # advanced settings + m.advanced = getprop(m.nodeString~"advanced"); # bool. Use advanced drag and guidance-laws. + m.a_ratio = getprop(m.nodeString~"wing-aspect-ratio"); # 1.5 + m.wing_eff = getprop(m.nodeString~"wing-efficiency-relative-to-an-elliptical-planform"); # 1 + m.Cd_plume = getprop(m.nodeString~"exhaust-plume-paracitic-drag-factor"); # 15/25 m.mode_slave = TRUE;# if slaved to command seeker directions from radar/helmet/cursor @@ -437,8 +442,15 @@ var AIM = { if (m.chaffResistance == nil) { m.chaffResistance = 0.95; } + if (m.guidanceLaw == nil) { + m.guidanceLaw = "APN"; + } if (m.pro_constant == nil) { - m.pro_constant = 3; + if (find("APN", m.guidanceLaw)!=-1) { + m.pro_constant = 5; + } else { + m.pro_constant = 3; + } } if (m.force_lbf_1 == nil or m.force_lbf_1 == 0) { m.force_lbf_1 = 0; @@ -448,9 +460,6 @@ var AIM = { m.force_lbf_2 = 0; m.stage_2_duration = 0; } - if (m.guidanceLaw == nil) { - m.guidanceLaw = "APN"; - } if (m.destruct_when_free == nil) { m.destruct_when_free = FALSE; } @@ -497,6 +506,9 @@ var AIM = { if (m.no_pitch == nil) { m.no_pitch = 0; } + if(m.advanced == nil) { + m.advanced = FALSE; + } m.useModelCase = getprop("payload/armament/modelsUseCase"); m.useModelUpperCase = getprop("payload/armament/modelsUpperCase"); @@ -529,6 +541,7 @@ var AIM = { m.target_air = find("A", m.class)==-1?FALSE:TRUE; m.target_sea = find("M", m.class)==-1?FALSE:TRUE;#use M for marine, since S can be confused with surface. m.target_gnd = find("G", m.class)==-1?FALSE:TRUE; + m.target_pnt = find("P", m.class)==-1?FALSE:TRUE; # Find the next index for "models/model" and create property node. # Find the next index for "ai/models/aim-9" and create property node. @@ -563,7 +576,6 @@ var AIM = { if (m.useSingleFile == FALSE) { var id_model = m.weapon_model ~ m.ID ~ ".xml"; m.model.getNode("path", 1).setValue(id_model); - print("Attempting to load "~id_model); } else { var id_model = m.weapon_model2~".xml"; m.model.getNode("path", 1).setValue(id_model); @@ -1248,6 +1260,10 @@ var AIM = { } if (me.target_sea) { classes = classes~classesSep~"Ship"; + classesSep = ", "; + } + if (me.target_pnt) { + classes = classes~classesSep~"TGP point"; } var cooling = me.coolable?"YES":"NO"; var rea = me.reaquire?"YES":"NO"; @@ -1467,6 +1483,19 @@ var AIM = { } me.printStats("****************************************************"); }, + + setNewTargetInFlight: func (tagt) { + me.Tgt = tagt; + me.callsign = me.Tgt.get_Callsign(); + me.newTargetAssigned = TRUE; + me.t_coord = me.Tgt.get_Coord(); + me.fovLost = FALSE; + me.lostLOS = FALSE; + me.radLostLock = FALSE; + me.semiLostLock = FALSE; + me.heatLostLock = FALSE; + me.hasGuided = FALSE; + }, flight: func { @@ -1513,11 +1542,12 @@ var AIM = { me.printStats("Guidance law switched to %s", me.guidanceLaw); } if (me.settings["target"] != nil) { - me.Tgt = me.settings.target; - me.callsign = me.Tgt.get_Callsign(); - me.newTargetAssigned = TRUE; - me.t_coord = nil; - me.printStats("Target switched to %s",me.callsign); + if (me.newLock(me.settings.target)) { + me.setNewTargetInFlight(me.settings.target); + me.printStats("Target switched to %s",me.callsign); + } else { + me.printStats("Target switch ignored, could not lock on %s",me.settings.target.get_Callsign()); + } } } @@ -1537,21 +1567,14 @@ var AIM = { me.switchIndex = 0; me.nextFovCheck = me.nextFovCheck+me.switchTime; } - me.Tgt = me.contacts[me.switchIndex]; - me.callsign = me.Tgt.get_Callsign(); - me.newTargetAssigned = TRUE; - me.t_coord = nil; - me.fovLost = FALSE; - me.lostLOS = FALSE; - me.radLostLock = FALSE; - me.semiLostLock = FALSE; - me.heatLostLock = FALSE; - me.hasGuided = FALSE; - if (!me.checkForClassInFlight(me.Tgt)) { + me.newTgt = me.contacts[me.switchIndex]; + if (!me.newLock(me.newTgt)) { me.Tgt = nil; me.callsign = "Unknown"; me.newTargetAssigned = FALSE; - } + } else { + me.setNewTargetInFlight(me.newTgt); + } } } @@ -1559,14 +1582,15 @@ var AIM = { me.keepPitch = me.pitch; } if (me.Tgt != nil and me.Tgt.isValid() == FALSE) {#TODO: verify that the following threaded code can handle invalid contact. As its read from property-tree, not mutex protected. - if (me.newTargetAssigned) { - me.Tgt=nil; - me.t_coord=nil; - } else { + if (!(me.canSwitch and me.reaquire)) { me.printStats(me.type~": Target went away, deleting missile."); me.sendMessage(me.type~" missed "~me.callsign~": Target logged off."); settimer(func me.del(),0); return; + } else { + me.Tgt = nil; + me.callsign = "Unknown"; + me.newTargetAssigned = FALSE; } } me.dt = deltaSec.getValue();#TODO: time since last time nasal timers were called @@ -1656,7 +1680,7 @@ var AIM = { me.maxMach3 = me.speed_m; } - me.Cd = me.drag(me.speed_m); + me.Cd = me.drag(me.speed_m,me["myG"]); me.speed_change_fps = me.speedChange(me.thrust_lbf, me.rho, me.Cd); @@ -1822,9 +1846,10 @@ var AIM = { # Get target position. if (me.Tgt != nil and me.t_coord != nil) { if (me.flareLock == FALSE and me.chaffLock == FALSE) { - me.t_coord = me.Tgt.get_Coord(); - if (me.t_coord == nil) { + me.t_coord = geo.Coord.new(me.Tgt.get_Coord());#in case multiple missiles use same Tgt we cannot rely on coords being different, so we extra create new. + if (me.t_coord == nil or !me.t_coord.is_defined()) { # just to protect the multithreaded code for invalid pos. + print("Missile target has undefined coord!"); me.Tgt = nil; } } else { @@ -1916,7 +1941,7 @@ var AIM = { # check stats while flying: # me.printFlight("Mach %04.2f , time %05.1f s , thrust %05.1f lbf , G-force %05.2f", me.speed_m, me.life_time, me.thrust_lbf, me.g); - me.printFlight("Alt %07.1f ft , direct distance to target %04.1f NM", me.alt_ft, me.Tgt!=nil?me.direct_dist_m*M2NM:-1); + me.printFlight("Alt %07.1f ft , direct distance to target %04.1f NM", me.alt_ft, (me.Tgt!=nil and me.direct_dist_m!=nil)?me.direct_dist_m*M2NM:-1); if (me.exploded == TRUE) { me.printStats("%s max absolute %.2f Mach. Max relative %.2f Mach. Max alt %6d ft. Terminal %.2f mach.", me.type, me.maxMach, me.maxMach-me.startMach, me.maxAlt, me.speed_m); @@ -1983,7 +2008,7 @@ var AIM = { # telemetry if (me.data == TRUE) { - me.eta = me.free == TRUE or me.horz_closing_rate_fps == -1?-1:(me.dist_curr*M2FT)/me.horz_closing_rate_fps; + me.eta = me.free == TRUE or me.horz_closing_rate_fps == -1?-1:(me["t_go"]!=nil?me.t_go:(me.dist_curr*M2FT)/me.horz_closing_rate_fps); me.hit = 50;# in percent if (me.life_time > me.drop_time+me.stage_1_duration) { # little less optimistic after reaching topspeed @@ -2025,7 +2050,7 @@ var AIM = { me.ai.getNode("valid").setBoolValue(1); } #thread.unlock(frameToggle); - } + } }, getGPS: func(x, y, z, pitch, head=nil, roll=nil) { @@ -2094,21 +2119,35 @@ var AIM = { return me.c; }, - drag: func (mach) { + drag: func (mach, N=nil) { # Nikolai V. Chr.: Made the drag calc more in line with big missiles as opposed to small bullets. # # The old equations were based on curves for a conventional shell/bullet (no boat-tail), # and derived from Davic Culps code in AIBallistic. - me.Cd = 0; + me.Cd0 = 0; if (mach < 0.7) { - me.Cd = (0.0125 * mach + 0.20) * 5 * (me.Cd_base+me.Cd_delta*me.deploy); + me.Cd0 = (0.0125 * mach + 0.20) * 5 * (me.Cd_base+me.Cd_delta*me.deploy); } elsif (mach < 1.2 ) { - me.Cd = (0.3742 * math.pow(mach, 2) - 0.252 * mach + 0.0021 + 0.2 ) * 5 * (me.Cd_base+me.Cd_delta*me.deploy); + me.Cd0 = (0.3742 * math.pow(mach, 2) - 0.252 * mach + 0.0021 + 0.2 ) * 5 * (me.Cd_base+me.Cd_delta*me.deploy); + } else { + me.Cd0 = (0.2965 * math.pow(mach, -1.1506) + 0.2) * 5 * (me.Cd_base+me.Cd_delta*me.deploy); + } + if (me.advanced) { + if (N==nil) N=1; + else N=N+1; + if (mach < 1.0) { + me.Cdi = me.Cd0*N;# N = normal force in G + } else { + N = N * me.mass * g_fps;# N = normal force in LBF (me.mass is in slugs) + me.CN = 2*N/(me.rho*me.old_speed_fps*me.old_speed_fps*me.ref_area_sqft); + me.Cdi = (me.CN*me.CN)/(math.pi*me.wing_eff*me.a_ratio); + } + me.Cd0 = me["thrust_lbf"] != nil and me.thrust_lbf>0?me.Cd0*me.Cd_plume:me.Cd0; } else { - me.Cd = (0.2965 * math.pow(mach, -1.1506) + 0.2) * 5 * (me.Cd_base+me.Cd_delta*me.deploy); + me.Cdi = 0; } - return me.Cd; + return me.Cd0+me.Cdi; }, maxG: func (rho, max_g_sealevel) { @@ -2175,6 +2214,7 @@ var AIM = { }, energyBleed: func (gForce, altitude) { + if (me.advanced) return 0; # Bleed of energy from pulling Gs. # This is very inaccurate, but better than nothing. # @@ -2933,7 +2973,7 @@ var AIM = { me.raw_steer_signal_elev += me.gravComp; } return; - } elsif (find("APN", me.guidanceLaw)) { + } elsif (find("APN", me.guidanceLaw)!=-1) { me.apn = 1; } else { me.apn = 0; @@ -2955,7 +2995,9 @@ var AIM = { me.horz_closing_rate_fps = me.clamp(((me.dist_last - me.dist_curr)*M2FT)/me.dt, 0, 1000000);#clamped due to cruise missiles that can fly slower than target. me.printGuideDetails("Horz closing rate: %05d ft/sec", me.horz_closing_rate_fps); - + me.vert_closing_rate_fps = me.clamp(((me.dist_direct_last - me.dist_curr_direct)*M2FT)/me.dt, 0.0, 1000000); + me.printGuideDetails("Vert closing rate: %05d ft/sec", me.vert_closing_rate_fps); + me.c_dv = geo.normdeg180(me.t_course-me.last_t_course); me.line_of_sight_rate_rps = (D2R*me.c_dv)/me.dt;#positive clockwise @@ -3017,17 +3059,54 @@ var AIM = { me.last_t_norm_speed = me.t_LOS_norm_speed_fps; - # acceleration perpendicular to instantaneous line of sight in feet/sec^2 - me.acc_lateral_fps2 = me.pro_constant*me.line_of_sight_rate_rps*me.horz_closing_rate_fps+me.apn*me.pro_constant*me.t_LOS_norm_acc_fps2/2; + # time to go calc + me.t_away_norm_speed_fps = math.cos((me.t_course - me.t_heading)*D2R)*me.t_horz_speed_fps; + me.t_speed_vert_fps = math.sin(me.t_pitch*D2R)*me.t_speed_fps; + me.m_speed_vert_fps = math.sin(me.pitch*D2R)*me.old_speed_horz_fps; + me.t_pos_z = (me.t_coord.alt()-me.coord.alt())*M2FT; + me.Vt = [me.t_away_norm_speed_fps,me.t_LOS_norm_speed_fps,me.t_speed_vert_fps]; + me.Vm = [me.old_speed_horz_fps,0,me.m_speed_vert_fps]; + me.Pm = [0,0,0]; + me.Pt = [me.dist_curr*M2FT,0,me.t_pos_z]; + me.V_tm = vector.Math.minus(me.Vt,me.Vm); + me.R_tm = vector.Math.minus(me.Pm,me.Pt); + me.t_go = vector.Math.dotProduct(me.R_tm,me.R_tm)/vector.Math.dotProduct(me.R_tm, me.V_tm); + #me.t_go = M2FT*me.dist_curr_direct/me.vert_closing_rate_fps;#time to go (too simple) + #printf("time_to_go %.1f, closing %d",me.t_go,me.vert_closing_rate_fps); + + if (me.apn) { + # APN (constant best at 5, but the higher value the more sensitive to noise) + # Augmented proportional navigation. Takes target acc. into account. + me.toBody = math.cos(me.curr_deviation_h*D2R);#convert perpendicular LOS acc. to perpendicular body acc. + if (me.toBody==0) me.toBody=0.00001; + # acceleration perpendicular to instantaneous line of sight in feet/sec^2: + me.acc_lateral_fps2 = me.pro_constant*me.line_of_sight_rate_rps*me.horz_closing_rate_fps/me.toBody+me.pro_constant*me.t_LOS_norm_acc_fps2*0.5;# in some litterature the second pro_constant is replaced by t_go, but that will make the missile overcompensate. + #printf("vert acc = %.2f + %.2f G", me.pro_constant*me.line_of_sight_rate_up_rps*me.vert_closing_rate_fps/g_fps, (me.apn*me.pro_constant*me.t_LOS_elev_norm_acc/2)/g_fps); + me.velocity_vector_length_fps = me.clamp(me.old_speed_horz_fps, 0.0001, 1000000); + me.commanded_lateral_vector_length_fps = me.acc_lateral_fps2*me.dt; + me.raw_steer_signal_head = R2D*me.commanded_lateral_vector_length_fps/me.velocity_vector_length_fps; + } elsif (!me.apn) { + # PN (constant best at 3) + # Generalized Proportional navigation. + me.toBody = math.cos(me.curr_deviation_h*D2R);#convert perpendicular LOS acc. to perpendicular body acc. + if (me.toBody==0) me.toBody=0.00001; + me.acc_lateral_fps2 = me.pro_constant*me.line_of_sight_rate_rps*me.horz_closing_rate_fps/me.toBody; + me.velocity_vector_length_fps = me.clamp(me.old_speed_horz_fps, 0.0001, 1000000); + me.commanded_lateral_vector_length_fps = me.acc_lateral_fps2*me.dt; + me.raw_steer_signal_head = R2D*me.commanded_lateral_vector_length_fps/me.velocity_vector_length_fps; + } else { + # PN [invented during WWII by Luke Chia‐Liu Yuan] + # Original Proportional navigation. + # Rearranging the equations gives Pure proportional navigation, which show that this law + # does not take missile alpha into account, and is therefore not very good in real life. + me.radians_lateral_per_sec = me.pro_constant*me.line_of_sight_rate_rps; + me.raw_steer_signal_head = me.dt*me.radians_lateral_per_sec*R2D; + } #printf("horz acc = %.1f + %.1f", proportionality_constant*line_of_sight_rate_rps*horz_closing_rate_fps, proportionality_constant*t_LOS_norm_acc/2); # now translate that sideways acc to an angle: - me.velocity_vector_length_fps = me.clamp(me.old_speed_horz_fps, 0.0001, 1000000); - me.commanded_lateral_vector_length_fps = me.acc_lateral_fps2*me.dt; - - #isosceles triangle: - me.raw_steer_signal_head = math.asin(me.clamp((me.commanded_lateral_vector_length_fps*0.5)/me.velocity_vector_length_fps,-1,1))*R2D*2; - #me.raw_steer_signal_head = math.atan2(me.commanded_lateral_vector_length_fps, me.velocity_vector_length_fps)*R2D; # flawed, its not a right triangle + + #printf("Proportional lead: %0.1f deg horz", -(me.curr_deviation_h-me.raw_steer_signal_head)); @@ -3035,7 +3114,7 @@ var AIM = { #me.print(sprintf("commanded-perpendicular-acceleration=%.1f ft/s^2", acc_lateral_fps2)); #printf("horz leading by %.1f deg, commanding %.1f deg", me.curr_deviation_h, me.raw_steer_signal_head); - if (me.cruise_or_loft == FALSE) {# and me.last_cruise_or_loft == FALSE + if (me.cruise_or_loft == FALSE) { me.fixed_aim = nil; me.fixed_aim_time = nil; if (find("PN",me.guidanceLaw) != -1 and size(me.guidanceLaw) > 3) { @@ -3053,8 +3132,7 @@ var AIM = { # augmented proportional navigation for elevation # ################################################### #me.print(me.guidanceLaw~" in fully control"); - me.vert_closing_rate_fps = me.clamp(((me.dist_direct_last - me.dist_curr_direct)*M2FT)/me.dt, 0.0, 1000000); - me.printGuideDetails("Vert closing rate: %05d ft/sec", me.vert_closing_rate_fps); + me.line_of_sight_rate_up_rps = (D2R*(me.t_elev_deg-me.last_t_elev_deg))/me.dt; # calculate target acc as normal to LOS line: (up acc is positive) @@ -3071,14 +3149,33 @@ var AIM = { me.t_LOS_elev_norm_acc = (me.t_LOS_elev_norm_speed - me.last_t_elev_norm_speed)/me.dt; me.last_t_elev_norm_speed = me.t_LOS_elev_norm_speed; #printf("Target acc. perpendicular to LOS (positive up): %.1f G.", me.t_LOS_elev_norm_acc/g_fps); - - me.acc_upwards_fps2 = me.pro_constant*me.line_of_sight_rate_up_rps*me.vert_closing_rate_fps+me.apn*me.pro_constant*me.t_LOS_elev_norm_acc/2; - #printf("vert acc = %.2f + %.2f G", me.pro_constant*me.line_of_sight_rate_up_rps*me.vert_closing_rate_fps/g_fps, (me.apn*me.pro_constant*me.t_LOS_elev_norm_acc/2)/g_fps); - me.velocity_vector_length_fps = me.clamp(me.old_speed_fps, 0.0001, 1000000); - me.commanded_upwards_vector_length_fps = me.acc_upwards_fps2*me.dt; - - me.raw_steer_signal_elev = math.asin(me.clamp((me.commanded_upwards_vector_length_fps*0.5)/me.velocity_vector_length_fps,-1,1))*R2D*2; - #me.raw_steer_signal_elev = math.atan2(me.commanded_upwards_vector_length_fps, me.velocity_vector_length_fps)*R2D; + if (me.apn) { + # APN (constant best at 5, but the higher value the more sensitive to noise) + # Augmented proportional navigation. Takes target acc. into account. + me.toBody = math.cos(me.curr_deviation_e*D2R);#convert perpendicular LOS acc. to perpendicular body acc. + if (me.toBody==0) me.toBody=0.00001; + me.acc_upwards_fps2 = me.pro_constant*me.line_of_sight_rate_up_rps*me.vert_closing_rate_fps/me.toBody+me.pro_constant*me.t_LOS_elev_norm_acc/2; + #printf("vert acc = %.2f + %.2f G", me.pro_constant*me.line_of_sight_rate_up_rps*me.vert_closing_rate_fps/g_fps, (me.apn*me.pro_constant*me.t_LOS_elev_norm_acc/2)/g_fps); + me.velocity_vector_length_fps = me.clamp(me.old_speed_fps, 0.0001, 1000000); + me.commanded_upwards_vector_length_fps = me.acc_upwards_fps2*me.dt; + me.raw_steer_signal_elev = R2D*me.commanded_upwards_vector_length_fps/me.velocity_vector_length_fps; + } elsif (!me.apn) { + # PN (constant best at 3) + # Proportional navigation. Takes target acc. into account. + me.toBody = math.cos(me.curr_deviation_e*D2R);#convert perpendicular LOS acc. to perpendicular body acc. + if (me.toBody==0) me.toBody=0.00001; + me.acc_upwards_fps2 = me.pro_constant*me.line_of_sight_rate_up_rps*me.vert_closing_rate_fps/me.toBody; + me.velocity_vector_length_fps = me.clamp(me.old_speed_fps, 0.0001, 1000000); + me.commanded_upwards_vector_length_fps = me.acc_upwards_fps2*me.dt; + me.raw_steer_signal_elev = R2D*me.commanded_upwards_vector_length_fps/me.velocity_vector_length_fps; + } else { + # PN [invented during WWII by Luke Chia‐Liu Yuan] + # Original Proportional navigation. + # Rearranging the equations gives Pure proportional navigation, which show that this law + # does not take missile alpha into account, and is therefore not very good in real life. + me.radians_up_per_sec = me.pro_constant*me.line_of_sight_rate_up_rps; + me.raw_steer_signal_elev = me.dt*me.radians_up_per_sec*R2D; + } # now compensate for the predicted gravity drop of attitude: me.attitudePN = math.atan2(-(me.speed_down_fps+g_fps * me.dt), me.speed_horizontal_fps ) * R2D; @@ -3131,13 +3228,17 @@ var AIM = { ####Ground interaction me.ground = geo.elevation(me.coord.lat(), me.coord.lon()); - if(me.ground != nil) - { + if(me.ground != nil) { if(me.ground > me.coord.alt()) { me.event = "exploded"; if(me.life_time < me.arming_time) { me.event = "landed disarmed"; } + if (me.Tgt != nil and me.direct_dist_m == nil) { + # maddog might go here + me.Tgt = nil; + #me.direct_dist_m = me.coord.direct_distance_to(me.Tgt.get_Coord()); + } if ((me.Tgt != nil and me.direct_dist_m != nil) or me.Tgt == nil) { me.explode("Hit terrain.", me.event); return TRUE; @@ -3145,7 +3246,7 @@ var AIM = { } } - if (me.Tgt != nil and me.guidance != "inertial") { + if (me.Tgt != nil and me.t_coord != nil and me.guidance != "inertial") { # Get current direct distance. me.cur_dir_dist_m = me.coord.direct_distance_to(me.t_coord); if (me.useHitInterpolation == TRUE) { # use Nikolai V. Chr. interpolation @@ -3246,11 +3347,11 @@ var AIM = { } var explosion_coord = me.last_coord; - if (me.Tgt != nil) { + if (me.Tgt != nil and me.last_t_coord != nil and me.t_coord != nil) {#the two latter checks is for maddog/canSwitch, shouldn't really be needed but is. var min_distance = me.direct_dist_m; for (var i = 0.00; i <= 1; i += 0.025) { - var t_coord = me.interpolate(me.last_t_coord, me.t_coord, i); + var t_coord = me.interpolate(me.last_t_coord, me.t_coord, i);#todo: nil in numric inside this var coord = me.interpolate(me.last_coord, me.coord, i); var dist = coord.direct_distance_to(t_coord); if (dist < min_distance) { @@ -3361,7 +3462,7 @@ var AIM = { continue; } var min_distance = me.testMe.get_Coord().direct_distance_to(explode_coord); - if (min_distance < me.reportDist and me.testMe.getUnique() != me.Tgt.getUnique()) { + if (min_distance < me.reportDist and (me.Tgt == nil or me.testMe.getUnique() != me.Tgt.getUnique())) { var phrase = sprintf("%s %s: %.1f meters from: %s", me.type,event, min_distance, me.testMe.get_Callsign()); me.printStats(phrase); me.sendMessage(phrase); @@ -3380,7 +3481,10 @@ var AIM = { }, interpolate: func (start, end, fraction) { - me.xx = (start.x()*(1-fraction)+end.x()*fraction); + #if (!start.is_defined()) print("start undefined:"); found the bug so these prints not needed anymore + #if (!end.is_defined()) print("end undefined:"); + me.xx = (start.x()*(1-fraction) + +end.x()*fraction); me.yy = (start.y()*(1-fraction)+end.y()*fraction); me.zz = (start.z()*(1-fraction)+end.z()*fraction); @@ -3474,32 +3578,130 @@ var AIM = { checkForLock: func { # call this only before firing - if ((me.class!="A" or me.tagt.get_Speed()>15) and ((me.guidance != "semi-radar" or me.is_painted(me.tagt) == TRUE) and (me.guidance !="laser" or me.is_laser_painted(me.tagt) == TRUE)) + if (!(me.tagt.get_type() == AIR and me.tagt.get_Speed()<15) and ((me.guidance != "semi-radar" or me.is_painted(me.tagt) == TRUE) and (me.guidance !="laser" or me.is_laser_painted(me.tagt) == TRUE)) and (me.guidance != "radiation" or me.is_radiating_aircraft(me.tagt) == TRUE) and me.rng < me.max_fire_range_nm and me.rng > me.min_fire_range_nm and me.FOV_check(me.total_horiz, me.total_elev, me.fcs_fov) and (me.rng < me.detect_range_curr_nm or (me.guidance != "radar" and me.guidance != "semi-radar" and me.guidance != "heat" and me.guidance != "vision" and me.guidance != "heat" and me.guidance != "radiation")) - and (me.guidance != "heat" or (me.all_aspect == TRUE or me.rear_aspect(geo.aircraft_position(), me.tagt) == TRUE))) { + and (me.guidance != "heat" or (me.all_aspect == TRUE or me.rear_aspect(geo.aircraft_position(), me.tagt) == TRUE)) + and me.checkForView()) { return TRUE; } + #printf("Lock failed %d %d %d %d %d %d",me.tagt.get_Speed()>15,me.rng < me.max_fire_range_nm,me.rng > me.min_fire_range_nm,me.FOV_check(me.total_horiz, me.total_elev, me.fcs_fov),me.rng < me.detect_range_curr_nm,me.checkForView()); return FALSE; }, + checkForView: func { + if (me.guidance != "gps" and me.guidance != "inertial") { + me.launchCoord = geo.aircraft_position(); + me.potentialCoord = me.tagt.get_Coord(); + me.xyz = {"x":me.launchCoord.x(), "y":me.launchCoord.y(), "z":me.launchCoord.z()}; + me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; + + # Check for terrain between own weapon and target: + me.terrainGeod = get_cart_ground_intersection(me.xyz, me.directionLOS); + if (me.terrainGeod == nil) { + return TRUE; + } else { + me.terrain = geo.Coord.new(); + me.terrain.set_latlon(me.terrainGeod.lat, me.terrainGeod.lon, me.terrainGeod.elevation); + me.maxDist = me.launchCoord.direct_distance_to(me.potentialCoord)-1;#-1 is to avoid z-fighting distance + me.terrainDist = me.launchCoord.direct_distance_to(me.terrain); + if (me.terrainDist >= me.maxDist) { + return TRUE; + } + } + return FALSE; + } + return TRUE; + }, + + checkForViewInFlight: func (tagt) { + if (me.guidance != "gps" and me.guidance != "inertial") { + me.launchCoord = me.coord; + me.potentialCoord = tagt.get_Coord(); + me.xyz = {"x":me.launchCoord.x(), "y":me.launchCoord.y(), "z":me.launchCoord.z()}; + me.directionLOS = {"x":me.potentialCoord.x()-me.launchCoord.x(), "y":me.potentialCoord.y()-me.launchCoord.y(), "z":me.potentialCoord.z()-me.launchCoord.z()}; + + # Check for terrain between own weapon and target: + me.terrainGeod = get_cart_ground_intersection(me.xyz, me.directionLOS); + if (me.terrainGeod == nil) { + return TRUE; + } else { + me.terrain = geo.Coord.new(); + me.terrain.set_latlon(me.terrainGeod.lat, me.terrainGeod.lon, me.terrainGeod.elevation); + me.maxDist = me.launchCoord.direct_distance_to(me.potentialCoord)-1;#-1 is to avoid z-fighting distance + me.terrainDist = me.launchCoord.direct_distance_to(me.terrain); + if (me.terrainDist >= me.maxDist) { + return TRUE; + } + } + return FALSE; + } + return TRUE; + }, + checkForClass: func { # call this only before firing if(me.slaveContact != nil and me.slaveContact.isValid() == TRUE and ( (me.slaveContact.get_type() == SURFACE and me.target_gnd == TRUE) or (me.slaveContact.get_type() == AIR and me.target_air == TRUE) + or (me.slaveContact.get_type() == POINT and me.target_pnt == TRUE) or (me.slaveContact.get_type() == MARINE and me.target_sea == TRUE))) { return TRUE; } + #if(me.slaveContact != nil) printf("class failed %d %d %d",me.slaveContact.isValid() == TRUE,me.slaveContact.get_type() == AIR,me.target_air == TRUE); return FALSE; }, + + newLock: func (tagt) { + # for switching to new lock during flight. + #reorder to gain performance + me.newlockgained = 0; + if (!tagt.isValid()) { + me.printStatsDetails("Test: invalid contact. Rejected."); + return 0; + } + me.printStatsDetails("Test starting on %s:",tagt.get_Callsign()); + me.newCoord = tagt.get_Coord(); + if (me.coord.direct_distance_to(me.newCoord)*M2NM > me.detect_range_curr_nm) { + me.printStatsDetails("Test: contact out of range. Rejected."); + return 0; + } + me.newlockgained = me.checkForClassInFlight(tagt); + if (!me.newlockgained) {me.printStatsDetails("Test: invalid type: %d. Rejected.",tagt.get_type());return 0;} + if (me.guidance == "laser") { + me.newlockgained = me.is_laser_painted(tagt); + if (!me.newlockgained){me.printStatsDetails("Test: no laser lock. Rejected.");return 0;} + } elsif (me.guidance == "semi-radar") { + me.newlockgained = me.is_painted(tagt); + if (!me.newlockgained) {me.printStatsDetails("Test: no radar paint. Rejected.");return 0;} + } elsif (me.guidance == "radiation") { + me.newlockgained = me.is_radiating_me(tagt); + if (!me.newlockgained) {me.printStatsDetails("Test: not radiating me. Rejected.");return 0;} + } elsif (me.guidance == "heat") { + me.newlockgained = me.all_aspect == TRUE or me.rear_aspect(me.coord, tagt); + if (!me.newlockgained) {me.printStatsDetails("Test: no view of heat source. Rejected.");return 0;} + } + if (me.guidance != "gps" and me.guidance != "inertial") { + me.new_elev_deg = me.getPitch(me.coord, me.newCoord); + me.new_course = me.coord.course_to(me.newCoord); + me.new_deviation_e = me.new_elev_deg - me.pitch; + me.new_deviation_h = me.new_course - me.hdg; + me.newlockgained = me.FOV_check(me.new_deviation_h, me.new_deviation_e, me.max_seeker_dev); + if (!me.newlockgained) {me.printStatsDetails("Test: not in FoV. Rejected.");return 0;} + } + me.newlockgained = me.checkForViewInFlight(tagt); + if (!me.newlockgained) {me.printStatsDetails("Test: terrain obscurre contact. Rejected.");return 0;} + else me.printStatsDetails("Test: contact approved."); + return me.newlockgained; + }, checkForClassInFlight: func (tact) { # call this only after firing if(tact != nil and tact.isValid() == TRUE and ( (tact.get_type() == SURFACE and me.target_gnd == TRUE) or (tact.get_type() == AIR and me.target_air == TRUE) + or (tact.get_type() == POINT and me.target_pnt == TRUE) or (tact.get_type() == MARINE and me.target_sea == TRUE))) { return TRUE; } @@ -4379,4 +4581,4 @@ var spamLoop = func { settimer(spamLoop, 1.20); } -spamLoop(); +spamLoop(); \ No newline at end of file diff --git a/Mirage-2000/TODO EN b/Mirage-2000/TODO EN new file mode 100644 index 00000000..bd64d398 --- /dev/null +++ b/Mirage-2000/TODO EN @@ -0,0 +1,284 @@ +This need to be translated. +At the creation of this file only the TODO stuff will be tranlated (then we will translate one by one the other stuff) + +------------------------------------------------------------------------------- + REMERCIMENTS +------------------------------------------------------------------------------- + +Merci à tout ceux qui ont contribué à ce grand projet : +- Helijah +- Buckaroo +- Koubi +- FG-TUX +- Ray, +- Anusil +- XIII +- la f16 team +- la CitationX team +- tout ceux qui ont developpé en libre les missiles que j'ai pu récupérer +- Nico +- Thomas +- Hardball +- Itouchpods +- Richard +- Leto +- Rudolf +- Legoboydlp +- FB +- Swamp +- HB-VANO + +Merci à tous ceux qui m'ont aidé -et qui m'aideront peut-être encore :-) +Merci à tous les autres que j'ai peut être oublié. + +Tous ensemble on a fait (et on fera j'espère) un super boulot. +Ce mirage 2000-5, il est énorme !! + +------------------------------------------------------------------------------- + FAIT +------------------------------------------------------------------------------- + +- Rajout de tout un tas de load. (Matra MICA, AIM120, Matra R550 Magic 2, + aim-9, GBU16, GBU12, AGM65, SCALP, Sea Eagle, AIM-54, MATRA-R530, R74) +- Voir la possibilité de lancer des missiles, de mettre le code en générique + pour que cela soit facilement adaptable sur d'autre appareils ou d’autres + missiles. Cela se fera en relation avec les load. +- possibilité de larguer les réservoirs. +- Rajouter des boutons pour "load rapide" comme les boutons "FAD" du f14 +- Amélioration du son. +- Amélioration de la texture old (plus de décalage des aérofrein du dessous) +- Amélioration du tir au canon (que j'ai du réduire de moitié de vitesse pour + conserver les fps) +- Amélioration du HUD, (agrandissement et suppression des décalages des ronds + "radar" avec plusieurs modes sélectionnables, des indications supplémentaires + qui s'affichent de façon conditionnelles (mach, Agl, frein, Gear) ... +- Possibilité d'avoir pour l'appareil le plus proche, le callsign, altitude, + cap de l'appareil, position par rapport au 2000, vitesse au sol (parce que je + ne trouve pas la fonction X^X nécessaire au calcul de la vitesse KEAS à un + altitude donnée...) +- Possibilité de démarrer le réacteur... Script de Ryan Miller (basé sur celui + de Syd Adams) +- Revoir le radar, et les ronds hud qui restent en parasites quand on diminue + la portée du radar etc (Ca a été changé sur le code source du HUD de base, + donc pas moi qui l'ai fait mais merci au bonhomme qui l'a fait) +- Changer l'affichage du radar central, avec des traits moins gros...(mais vu + que j'arrive à rien avec blender....) et corriger le code d'affichage (ça je + peux faire) +- Autopilot + suivi d'avion en mode auto +- Regarder comment faire "apparaître" le model sans fumée et l'explosion (de + façon graphique... J'ai les modèles mais il faut que je code) +- Amelioration du contrail (temps, -40, humidité >65% et augmentation du volume + du contrail) +- Ajout d'un bruit de turbine au démarrage +- See changelog + + +- réduire la font-size des mfd +- valeurs settées pour l'AP en magenta (comme sur le MFD des liners) +- modifier certaines couleurs de l'EHSI +- activer la météo au démarrage sur le mfd EHSI +- ajouter l'information dewpoint (météo mfd EHSI) +- modifier les font-size des MFD +- corriger l'efficacite du train avant +- améliorer le hud : changer la disposition des infos (cible la plus proche) +- améliorer le hud : ajouter un Turn Indicator +- améliorer le hud : afficher les g, aoa +- améliorer le hud : mode plus compact pour gears et breaks +- améliorer le hud : STALL, PULL UP, WARNING blink +- ouvrir la verrière au démarrage +- sur l'EHSI ajouter la possibilité de suivre un wp gps (DTO, nav slave) +- harmoniser les unités : NM, ft, inHg, hPa, kt, FL, OAT, aoa +- lire les sons exterieurs si le cockpit est ouvert +- ajouter des commentaires. refaire certaines indentations +- ajouter en haut à droite un mini hud visible lorsque le panel est hors champ + données minimales : alt-cap-speed-assiette +- réindenter les fichiers xml et les scripts nas, corriger les erreurs, + ajout de commentaires, supprimer les "trailing spaces" +- pouvoir entre-ouvrir la verrière +- désactiver les sons (train et moteur) au lancement du jeu +- modifier le fichier textures.xcf.gz pour faire plus facilement de nouvelles + livrées (4 layers : radar, intrados, extrados couleur1, extrados couleur2) +- créer une livrée "désert" +- créer une livrée "emirats arabes unis" +- supprimer les fichiers xml inutilisés (renommés pour l'instant en *.TO_CHECK et *.TO_DELETE) +- modifier les xml suite à l'utilisation de tidy pour qu'ils soient plus lisibles +- refondre des camouflages dans textures.xcf.gz (camouflages différents 2000-5/2000 C) +- améliorer la livrée "texture.png" +- améliorer la livrée "sky_HQ.png" +- améliorer la livrée "desert_HQ.png" +- améliorer la livrée "UAEAF_HQ.png" +- supprimer les logos + numéros + marquages dans textures.xcf.gz +- ajouter une doc de création des livrées dans Mirage2000/Docs/ +- ajouter des calques dans le fichier logos.xcf.gz et créer des groupes : langue, pays, escadron +- corriger des bugs +- avoir un camouflage plus conforme à la réalité + * les côtés gauche et droit ne sont normalement pas identiques + * le camouflage du 2000C et du 2000N ne sont pas totalement identiques (la + tache de l'aile droite sur le 2000N remonte sur le fuselage + * le 2000N a une troisième couleur pour l'intrados le camouflage diffère de + celui du 2000C près du radome + +- Rendre visibles les load en multijoueur +- Essayer de moins charger d'objet 3D (dans les load, car cela peut ralentir + les fps) +- Peut être limiter les chargements aux armes Matra +- Rajouter le missile Exocet et ASMP +- améliorer la stabilisation en mode Auto-pilote (essayer en time * 8 pour voir + le problème) => Done with Itouchpods +- rendre plus joli le cône transsonique +- améliorer encore la PC ? (voir le f35 du hangar FGUK) +- 2000C -> 2000-5 + * ajouter les antennes de queue + * supprimer le tube pitot [DONE] + * ajouter les lance leurres sur les Karman de voilure [DONE] +- créer une version biplace [DONE] +- créer des livrées pour les bidons externes +- pouvoir éteindre le radar +- améliorer les sons de démarrage du moteur : voir su27 dans le hangar FGUK +- Mettre des boutons pour les lights...(ou sur le MFD ou en recupérer + d'ailleurs ....ce serait bien d'avoir 3 ou 4 option de light) [DONE] +- Les phares principaux ne font pas de lumière...(parking) +- ajouter les lumières de vol en formation (gris éteint, vert pastel allumé) [DONE] +- Siège éjectable (+bloquer la vue sur le siège éjecté+bloquer les commandes de + l'avion) +- améliorer l'EHSI : cas où nav1 est slave d'un wp gps +- Gérer les missiles semi actifs +- Comprendre le problème avec la "ground detection" des missiles A/G +- Faire déplier les ailes du Apache/scalp (et faire une livrée SCALP) +- Faire réagir les missiles au contre mesures... (type flare....) +- Pod de designation laser -> vue plus possibilité de "créer" une cible en + sniper vu et de cliquer pour la sélectionner + +------------------------------------------------------------------------------- + To Do list +------------------------------------------------------------------------------- + +Pour moi et pour ceux qui veulent bien : + +LOAD : +- Make loads visible when they are dropped/shooted (emesary) +- Make them in MP, with emesary + +FDM : +FDM is now working like that : FDM -> FCS -> FBW -> autopilot +see if other fdm are possible, more accurate, with keeping the actual FBW/autopilot + +MODEL : +- Re do the turbine [DONE] +- Re do the exhaust +- Add flare dispenser +- Do reaslitic texture, with detailed upper part/top (actually the UV map was not enough accurate) +- Re do the UV map ? +- Rain issu in the cockpit + + + +SUBMODELS : +- with the new fire control the dropped tanks are no longer visible + + +INSTRUMENTS : + +- Add the Mirage 2000D cockpit +- move 30 cm forward the console/panel of the front seat (too close from the pilot)(need a 3D person for that) +- add masterarm in the cockpit +- make the tacan working [DONE] (thanks to Rudolf) +- make the vor/ils working +- add the internial central/navigation computer +- make the blue button work (need to figure out how they work) +- make a canvas radar diplay, better and closer to reality +- make a canvas in the right mfd, in order to add an RWR +- Add an RWR +- make the hud accurate, with all different mod : + *Weapons mode : GUN, A/A IR, A/A radar etc + *nav mode, landing mode, checkpoint etc + +- make the mini hud selectable (give the abilty to disable it for screenshot or 1-auto-0) +- make the part at the right of the radar screen more accurate, with real instruments and their real place. +- Improve the ground targeting mode : make it look like the f16 + + + +SON : +- corriger dans le xml la balise ofset -> offset +- Étudier les sons, et les cônes de dispersion rendu possible par le xml. Cela + permettrai d'avoir le son seulement "après" l'appareil quand la vitesse du + son est dépassée ...(voir même de diminuer le cône de dispersion quand mach 2 + est atteint.) + + +TANKER : +- Make the tanker visible through MP (emesary) + +LIGHT : + + +MISSILE : +- be up to date with the f16 (fire control and missile.nas) + + +COMMUNICATION : +- ? + +TUTORIAUX +- add a tutorial on how to use the autopilot. +- ass a tutorial on how to do radio navigation + + + + + + + + +DÉVELOPPEMENT : +(in french, need to be translated) +- http://wiki.flightgear.org/Standard_aircraft_structure +- faire une documentation pour permettre à plus de monde de participer au + développement +- définir des normes de codages sur les fichiers xml et les scripts nasal + (indentation, commentaires, position des accolades, des propriétés des + balises, des alignements, comment aider au debug) +- faire du ménage dans les fichiers et ajouter des commentaires +- extraire les scripts nasal des xml +- supprimer les fichiers qui ne sont pas utilisés/chargés +- augmenter les FPS : + * identifier les pertes + * réduire certaines facettes des modèles 3D + * fusionner certains fichiers pour accélerer le chargement lors du lancement + du jeu + * revoir l'accès aux propriétés : + http://wiki.flightgear.org/Nasal_Variables#Nasal_variables_vs._the_property_tree + * consulter : + http://wiki.flightgear.org/User:Philosopher/Optimization_findings +- améliorer les nasal + * harmoniser les noms des scripts nasal (les prefixer de m2000-5- ?) + * if(a == nil) et non pas if(a == "nil") + * éviter : + if(a == 1){...} + if(a == 2){...} + if(a == 3){...} + préférer : + if(a == 1){...} + elsif(a == 2){...} + elsif(a == 3){...} + * éviter : + if(k == 'cle1') { v == 'valeur1'; } + if(k == 'cle2') { v == 'valeur2'; } + if(k == 'cle3') { v == 'valeur3'; } + préférer : + hash = { 'cle1': 'valeur1', 'cle2': 'valeur2', 'cle3': 'valeur3',}; + v = hash['cle1']; + * éviter : + count_1 += 1; + if(count_1 > 3) { count_1 = 0; } + if(count_1 == 0) { setprop(NAVprop, "NAV1"); } + if(count_1 == 1) { setprop(NAVprop, "NAV2"); } + if(count_1 == 2) { setprop(NAVprop, "TACAN");} + if(count_1 == 3) { setprop(NAVprop, "FMS"); } + préférer : + cycle = ["NAV1", "NAV2", "TACAN", "FMS"]; + choice += 1; + setprop(my_property, cycle[math.mod(choice, 4)]); + +------------------------------------------------------------------------------- diff --git a/Mirage-2000/TODO b/Mirage-2000/TODO FR similarity index 99% rename from Mirage-2000/TODO rename to Mirage-2000/TODO FR index d56e9d3a..599bf6a2 100644 --- a/Mirage-2000/TODO +++ b/Mirage-2000/TODO FR @@ -107,24 +107,13 @@ Ce mirage 2000-5, il est énorme !! * le 2000N a une troisième couleur pour l'intrados le camouflage diffère de celui du 2000C près du radome -------------------------------------------------------------------------------- - To Do list -------------------------------------------------------------------------------- - -Pour moi et pour ceux qui veulent bien : - -LOAD : - Rendre visibles les load en multijoueur - Essayer de moins charger d'objet 3D (dans les load, car cela peut ralentir les fps) -- Peut être limiter les chargements aux armes Matra ... ? ... +- Peut être limiter les chargements aux armes Matra - Rajouter le missile Exocet et ASMP - -FDM : - améliorer la stabilisation en mode Auto-pilote (essayer en time * 8 pour voir - le problème) - -MODEL : + le problème) => Done with Itouchpods - rendre plus joli le cône transsonique - améliorer encore la PC ? (voir le f35 du hangar FGUK) - 2000C -> 2000-5 @@ -132,23 +121,50 @@ MODEL : * supprimer le tube pitot [DONE] * ajouter les lance leurres sur les Karman de voilure [DONE] - créer une version biplace [DONE] +- créer des livrées pour les bidons externes +- pouvoir éteindre le radar +- améliorer les sons de démarrage du moteur : voir su27 dans le hangar FGUK +- Mettre des boutons pour les lights...(ou sur le MFD ou en recupérer + d'ailleurs ....ce serait bien d'avoir 3 ou 4 option de light) [DONE] +- Les phares principaux ne font pas de lumière...(parking) +- ajouter les lumières de vol en formation (gris éteint, vert pastel allumé) [DONE] +- Siège éjectable (+bloquer la vue sur le siège éjecté+bloquer les commandes de + l'avion) +- améliorer l'EHSI : cas où nav1 est slave d'un wp gps +- Gérer les missiles semi actifs +- Comprendre le problème avec la "ground detection" des missiles A/G +- Faire déplier les ailes du Apache/scalp (et faire une livrée SCALP) +- Faire réagir les missiles au contre mesures... (type flare....) +- Pod de designation laser -> vue plus possibilité de "créer" une cible en + sniper vu et de cliquer pour la sélectionner + +------------------------------------------------------------------------------- + To Do list +------------------------------------------------------------------------------- + +Pour moi et pour ceux qui veulent bien : + +LOAD : + + +FDM : + +MODEL : + SUBMODELS : - Voir si en multijoueur, un missile lancé par un avion tiers peut être visible... -- créer des livrées pour les bidons externes + INSTRUMENTS : -- pouvoir éteindre le radar + - Faire marcher les différents mode hud, par exemple le rond pour le tir Canon, le rond du lock mode, rajouter un mode de virtualisation des pistes d'atterrissage (existe dans les hud) ou encore gestion de waypoint (existe aussi) - Finir de rajouter les instruments qui manquent : manche, manette de gaz, ECM APU etc ... [WORK IN PROGRESS] -- Siège éjectable (+bloquer la vue sur le siège éjecté+bloquer les commandes de - l'avion) -- améliorer l'EHSI : cas où nav1 est slave d'un wp gps - ajouter sur le hud ou sur un MFD le taux de virage (1min, 2min) SON : @@ -157,24 +173,16 @@ SON : permettrai d'avoir le son seulement "après" l'appareil quand la vitesse du son est dépassée ...(voir même de diminuer le cône de dispersion quand mach 2 est atteint.) -- améliorer les sons de démarrage du moteur : voir su27 dans le hangar FGUK + TANKER : - Quand on commande un tanker, il n'est pas visible en multijoueur... LIGHT : -- Mettre des boutons pour les lights...(ou sur le MFD ou en recupérer - d'ailleurs ....ce serait bien d'avoir 3 ou 4 option de light) [DONE] -- Les phares principaux ne font pas de lumière...(parking) -- ajouter les lumières de vol en formation (gris éteint, vert pastel allumé) [DONE] + MISSILE : -- Gérer les missiles semi actifs -- Comprendre le problème avec la "ground detection" des missiles A/G -- Faire déplier les ailes du Apache/scalp (et faire une livrée SCALP) -- Faire réagir les missiles au contre mesures... (type flare....) -- Pod de designation laser -> vue plus possibilité de "créer" une cible en - sniper vu et de cliquer pour la sélectionner + COMMUNICATION : - ?