This commit is contained in:
2025-09-12 15:20:28 +08:00
commit 3257a14c32
449 changed files with 388780 additions and 0 deletions

View File

@@ -0,0 +1,329 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 aslct7.f and akshn7.f
// Replicates the gun fire 7,3,7,x alternative behavior
include_once BrawlerScriptUtil.txt
behavior weapon_decision_gun
script_debug_writes off
script_variables
double RNGWPN = 3000.0; #feet (from MIND file)
WsfQuantumTaskerProcessor processor;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawGuns = true;
WsfDraw mDraw = WsfDraw();
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
// Takes the place of production rules
bool mAlternative7371Enabled = true;
// Alternative ID
int ilevel = 7;
int kalt = 3;
int icall = 7; // Always 7 for gun
int lcall = 1;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
// Needed?
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
// Replicates the checks done in canfirg.f
// Return true if the gun can be fired ("hard" checks)
// Sets the string to the fail reason
script bool canfirg(string failMsg)
/*
cnfire = .false.
C --NOTE THAT WE ARE RECALCULATING PILOT POSTURE VARIABLES HERE
C --ppmrmx WILL BE NEEDED IN shldfrg, SO PERFORM THIS CALCULATION
C --UNCONDITIONALLY.
call gunenv(xp(1,me),vp(1,me),xp(1,ppmiac),vp(1,ppmiac),
1 ppmptr,ppmrmn,ppmrmx,ppmapt,ppmse,ppmaof,ppmenv,ppmtrk,ppmohr,
2 rbep )
C --If temp midway in a 0.5 second burst exceeds maximum (1.0 by
C --definition) then you can't shoot. Rate of temperature rise
C --is 1.0/t_to_heat, so that firing for t_to_heat seconds reaches
C --the limit.
overheat = (gun_temp+0.25/t_to_heat .gt. 1.0)
if (overheat) then
rsfail = 'GUN OVERHEAT'
return
endif
C
C --CHECK IF TARGET IS IN ENVELOPE
if (.not.ppmenv) then
rsfail = 'NOT IN ENVELOPE '
return
endif
C
C --CHECK ON PROBABILITY IN RANGE
pinrng = prmax2(ppmiac,ppmrmx,1.0,0.2)
pbinrg = pinrng.ge.pr2lim
if (.not.pbinrg) then
rsfail = 'LOW PROB IN RANGE'
return
endif
C
visacq = inform(ppmiac).eq.1 .and. time.le.seet(ppmiac)+0.5
C --If pilot has not had a recent visual (or does not have a
C --radar lock if rdrgun is set), then gun can't be fired.
if(.not.rdrgun) then
C --DO I HAVE A RECENT VISUAL?
if(.not.visacq) then
rsfail = 'NO RECENT VISUAL'
return
endif
else
C --AN ESTABLISHED RADAR TRACK MAY SUBSTITUTE FOR A VISUAL
C --IF RDRGUN=.TRUE.
call lockid(iacid,ppmjid,locked)
gunacq = visacq .or. locked.eq.2
if(.not.gunacq) then
rsfail = 'NO RECENT VISUAL OR LOCK'
return
endif
endif
C
cnfire = .true.
*/
#bool canFire = false;
bool canFire = true; #LBM - temporary
return canFire;
end_script
// Replicates the checks done in shldfrg.f
// Return true if the should should be fired ("soft" checks)
// Sets the string to the fail reason if any
script bool shldfrg(string failMsg)
/*
C --If target is inside Rmax2, don't need the following
C --tests(target is inside no-escape range).
C --CHECK THAT PILOT BELIEVES RANGE IS OK FOR TARGETING
pinrng = prmax2(ppmiac,ppmrmx,ppm_rpeak,0.2)
pbinrg = pinrng.ge.pr2lim
call pdset('PROB_IN_RANGE',pbinrg)
C
C --CALCULATE CURRENT ENVELOPE LEVEL; ppmrmx WAS RECALCULATED IN canfirg
elevnow = envlvg(rngnow(me,ppmiac),rdotme(ppmiac),ppmse,ppmrmx,
1 'SHOOT')
C --CALCULATE PROJECTED ENVELOPE, CONSTANT VELOCITY PROJECTION FOR
C --ME AND CURRENT ACCELERATION PROJECTION FOR TARGET.
C --call vecinc(xp(1,me),tproj3,vp(1,me),xme)
C --Full projection for target, fixed velocity projection
C --for attacker.
C --call gunenv(xme,vp(1,me),xeut(1,ppmiac),veut(1,ppmiac),
call gunenv(xeuan,veuan,xeut(1,ppmiac),veut(1,ppmiac),
1 ppmptr,rmin,rmax,aimp,se,aof,inenvp,trkbl,ovrhoz,rbep)
elevprj = envlvg(rngun(ppmiac),rngrun(ppmiac),se,rmax,'SHOOT')
if(lprnt) write(ioutp,2000) rmin,rmax,rng(ppmiac),aimp,se,aof,
1 elevprj
C
C --CHECK PROJECTION -- IS LEVEL DECREASING?
worse = (elevnow.ge.elevprj)
call pdset('SHOT_WORSENING',worse)
C
needid = (irel(ppmiac).eq.0) .and. (id_mode.ne.bvr_id_md)
call pdset('SURE_BAD_GUY',.not.needid)
C
if (needid)then
lfire = .false.
rsfail = 'NEED ID'
elseif(.not.(pbinrg.or.worse))then
rsfail = '!(IN RPEAK OR WORSE)'
lfire = .false.
else
lfire = .true.
endif
*/
# bool lfire = false;
bool lfire = true; #LBM - temporary
return lfire;
end_script
precondition
#writeln_d(PLATFORM.Name(), " precondition weapon_decision_gun, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
// aslct7.f line 123 - 132
# --CHECK IF TARGET SELECTED
# if (ppmiac .eq. 0 .and. .not.dewvmsl)then
# rsfail = 'NO TARGET SELECTED'
# goto 800
# endif
# --CHECK IF WEAPON SELECTED
# if (ppmptr .eq. 0)then
# rsfail = 'NO WEAPON SELECTED'
# goto 800
# endif
WsfTaskList tasks = processor.TasksReceivedOfType("WEAPON");
if(tasks.Count() <= 0)
{
return Failure("no target selected");
}
WsfTrack targetTrack = PLATFORM.MasterTrackList().FindTrack(tasks.Entry(0).LocalTrackId());
if (!targetTrack.IsValid())
{
return Failure("no valid target track");
}
#LBM - temporary
# // Weapon selection done in selwpn.f (called from aslct2.f)
# // checks weapon inventory. Use a similar check here as a replacement
# if (!HaveWeapon(PLATFORM))
# {
# // TODO Account for weapon type gun/missile
# return Failure("no weapon selected");
# }
if (!PLATFORM.Weapon("gun").IsValid() || PLATFORM.Weapon("gun").QuantityRemaining() <= 0)
{
writeln_d(" ", PLATFORM.Name(), " no weapon selected at time: ", TIME_NOW);
return Failure("no weapon selected");
}
# // aslct7() calls canfir().
# // canfir.f checks production rules and GCI inhibit
# // just doing a simple flag for now
# if (!mAlternative7371Enabled)
# {
# writeln_d("behavior not enabled!");
# return Failure("behavior alternative not enabled");
# }
#
# //canfir.f calls canfirg()
# string msg = "";
# if (!canfirg(msg))
# {
# return Failure(msg);
# }
#
# // aslct7 line 199 - 205
# // if undamaged calls shldfr().
# // if we are damaged skip checks and fire now
# if (PLATFORM.DamageFactor() <= 0.0)
# {
# // shldfr.f just calls the specific weapon type
# if (!shldfrg(msg))
# {
# return Failure(msg);
# }
# }
#
# // aslct7 creates and alternative to evaluate.
# // The alternative has no projection and always
# // evaluates to 1, so skip that processing
WsfWeapon gun = PLATFORM.Weapon("gun");
if (gun.LaunchComputer().CanIntercept(targetTrack, 0.1)) #see "firing_delay" for BULLET weapon
{
WsfGeoPoint pt = gun.LaunchComputer().InterceptPoint();
#TODO - move slant range check to gun's launch computer???
if (PLATFORM.SlantRangeTo(pt) <= (RNGWPN * MATH.M_PER_FT()))
{
# #draw line to intercept point
# if (mDrawGuns)
# {
# double delta = ((WsfBrawlerPlatform)PLATFORM).ProjectedTimeDelta();
# mDraw.SetLayer("behavior_weapon_decision_gun");
# mDraw.SetDuration(delta);
# mDraw.SetColor(0.5, 0.5, 0.5); #gray
# mDraw.SetLineSize(1);
# mDraw.SetLineStyle("solid");
# mDraw.BeginLines();
# mDraw.Vertex(PLATFORM.Location());
# mDraw.Vertex(pt);
# mDraw.End();
# }
return true;
}
else
{
writeln_d("no gun fire, too far away");
return Failure("no gun fire, too far away");
}
}
else
{
writeln_d("gun cannot intercept target yet");
return Failure("gun cannot intercept target yet");
}
// All conditions pass, weapon can fire
return true;
end_precondition
execute
// Replicates akshn7.f
// We don't need to do all the bookeeping that BRAWLER
// does. Just launch the weapon.
// TODO Fill in gun fire
#LBM - temporary
WsfTrack targetTrack = PLATFORM.MasterTrackList().FindTrack(processor.TasksReceivedOfType("WEAPON").Entry(0).LocalTrackId());
WsfWeapon weapon = PLATFORM.Weapon("gun");
bool launched = weapon.FireSalvo(targetTrack, 1); // Always firing one for now
if (!launched)
{
writeln_d(" ", PLATFORM.Name(), " could NOT fire at track: ", targetTrack.TargetName(), " at time: ", TIME_NOW);
}
else if (mDrawGuns)
{
double delta = ((WsfBrawlerPlatform)PLATFORM).ProjectedTimeDelta();
mDraw.SetLayer("behavior_weapon_decision_gun");
mDraw.SetDuration(delta);
mDraw.SetColor(1.0, 1.0, 1.0); #white
mDraw.SetLineSize(2);
mDraw.SetLineStyle("dotted2");
mDraw.BeginLines();
mDraw.Vertex(PLATFORM.Location());
mDraw.Vertex(targetTrack.CurrentLocation());
mDraw.End();
}
end_execute
end_behavior