library mwfunc; const #include_ "mwconst.abi" type #include_ "mwtype.abi" var static ObjectID last_sound_played; static Boolean any_sounds_played; //------------------------------------------------------------------------------------ function init; code any_sounds_played = FALSE; endfunction; function getRelativeAlignment (ObjectID p1,ObjectID p2) : integer; var integer align1; integer align2; code align1 = getAlignment (p1); align2 = getAlignment (p2); if align2 == NEUTRAL_ALIGNMENT then return (NEUTRAL); endif; if align1 <> align2 then return (ENEMY); endif; return (FRIENDLY); endfunction; function SnapToGround(ObjectID obj); var LocPoint l; code getLocation(obj,l); l[1] = -1; teleport(obj,l); endfunction; function ProtectAGroup(integer group_num) : integer; // This one may or may not work. Needs testing. var code if (isShot (GroupObjectId(group_num))) then if (getRelativeAlignment(me,WhoShot(GroupObjectId(group_num))) == ENEMY) then setTarget(me,WhoShot(GroupObjectId(group_num))); return (1); endif; endif; return (0); endfunction; function GeneralPlayChatter(ObjectId sound, integer which_timer, integer what_delay, integer what_chance); // if Timer which_timer is over what_delay, there is a chance what_chance // that the sound sound is played. After this, the timer is reset. // use this function for easy handling of radio chatter. // what_chance is a number from 0 to 1000. The percentage chance of the sound playing is // what_chance / 10 var code if (any_sounds_played == TRUE) then if (last_sound_played == sound) then what_chance = -1; endif; endif; if (TimeGreater(which_timer,what_delay)) then if (Rand(0,1000) <= what_chance) then PlaySound(sound); last_sound_played = sound; any_sounds_played = TRUE; ResetTimer(which_timer); endif; endif; endfunction; function SetMyTarget(integer searchrange) : boolean; var integer foe; code foe = FindObject(ME,FA_ENEMY,FT_DEFAULT,FC_BEST_TARGET,FF_WHO_SHOT + FF_SEEPLAYER,searchrange); if (foe <> no_unit) then SetTarget (me,foe); return (true); endif; return (false); endfunction; function FindEnemy(integer searchrange, integer flags) : boolean; var integer foe; code foe = FindObject(ME,FA_ENEMY,flags,FC_BEST_TARGET,FF_WHO_SHOT + FF_SEEPLAYER,searchrange); if (foe <> no_unit) then SetTarget (me,foe); return (true); endif; return (false); endfunction; function Bot_FindEnemy(integer searchrange) : boolean; var integer foe; code foe = FindObject(ME,FA_ENEMY,FT_DEFAULT,FC_BEST_TARGET,FF_WHO_SHOT + FF_SEEPLAYER + FF_LOOK_EVERYWHERE,searchrange); if (foe <> no_unit) then SetTarget (me,foe); return (true); endif; return (false); endfunction; function LeaveAttackState(integer withdrawrange) : boolean; var integer target; code target = gettarget(me); //1. I somehow got here without a legitimate target if (target < 0) then return(true); else //2. My target is dead if (isDead (target) == TRUE) then return(true); else //3. My target has gotten too far from me if ((isWithin(target,me,withdrawrange)) == FALSE) then if (WhoShot(me) <> target) then return(true); endif; endif; endif; endif; return (false); endfunction; function PlayChatter(ObjectID who_speaks, ObjectId sound, integer which_timer, integer what_delay, integer what_chance, Boolean check_combat); // if Timer which_timer is over what_delay and unit who_speaks is // alive, there is a chance what_chance // that the sound sound is played. After this, the timer is reset. // If check_combat is TRUE, the sound is only played if who_speaks is involved in a fight. // use this function for easy handling of radio chatter. // what_chance is a number from 0 to 1000. The percentage chance of the sound playing is // what_chance / 10 var code if (any_sounds_played == TRUE) then if (last_sound_played == sound) then what_chance = -1; endif; endif; if ((IsDead(who_speaks) == FALSE) and (TimeGreater(which_timer,what_delay))) then if (Rand(0,1000) <= what_chance) then if ((check_combat == FALSE) or ((check_combat == TRUE) and (IsShot(who_speaks)))) then PlaySound(sound); last_sound_played = sound; any_sounds_played = TRUE; ResetTimer(which_timer); endif; endif; endif; endfunction; function GroupPlayChatter(integer group_who_speaks, ObjectId sound, integer which_timer, integer what_delay, integer what_chance, Boolean check_combat); // if Timer which_timer is over what_delay and group group_who_speaks is // alive, there is a chance what_chance // that the sound sound is played. After this, the timer is reset. // If check_combat is TRUE, the sound is only played if the group is involved in a fight. // use this function for easy handling of radio chatter. // what_chance is a number from 0 to 1000. The percentage chance of the sound playing is // what_chance / 10 var code if (any_sounds_played == TRUE) then if (last_sound_played == sound) then what_chance = -1; endif; endif; if ((GroupAllDead(GroupObjectId(group_who_speaks)) == FALSE) and (TimeGreater(which_timer,what_delay)) and (Rand(0,1000) <= what_chance)) then if ((check_combat == FALSE) or ((check_combat == TRUE) and (IsShot(GroupObjectId(group_who_speaks))))) then PlaySound(sound); last_sound_played = sound; any_sounds_played = TRUE; ResetTimer(which_timer); endif; endif; endfunction; // Cinema_ZoomOut(): // Does a generic zoom-out camera animation suitable for mission victory or failure cut scenes. // "who" is the unit to zoom out from; it must be a single unit (typically the player's 'Mech). // "unique_timer_id" is the ID of a timer that the function can use that's not used for anything // else in any of the ABL scripts related to this mission. // "duration" is how long the zoom-out sequence will last. 10 to 20 seconds is generally // recommended, though this may be anything above 0. Since the distance to zoom out // is fixed, a longer duration will mean a slower zoom-out. function Cinema_ZoomOut(ObjectID who, integer unique_timer_id, real duration) : Boolean; var real time_remaining; code if (Not TimeGreater(unique_timer_id,0)) then StartTimer(unique_timer_id); Targetfollowobject(who); camerafollowobject(who); SetCameraFootShake(who,100); TargetOffset(0.0,5.0,0.0,0.0,true); CameraOffset(0.0,5.0,30.0,0.0,true); return (false); endif; if (TimeGreater(unique_timer_id,duration)) then return (true); endif; if (duration > 2.0) then if (TimeGreater(unique_timer_id,2.0)) then time_remaining = duration - 2.0; TargetOffset(0.0,9.0,-20.0,time_remaining,true); CameraOffset(0.0,40.0,150.0,time_remaining,true); endif; endif; return (false); endfunction; // IsShotOrDead(): // Returns true if the unit was shot recently or is destroyed. function IsShotOrDead(ObjectID who) : Boolean; var code if (IsDead(who)) then return (true); endif; return (IsShot(who)); endfunction; // WhoShotOrKilled(): // Indicates who shot or destroyed a given unit function WhoShotOrKilled(ObjectID who) : ObjectID; var code if (IsDead(who)) then return (WhoDestroyed(who)); endif; if (IsShot(who) == false) then return (WhoShot(who)); endif; return (NO_UNIT); endfunction; // ReachedNav(): // Indicates whether a unit (or group or team) IsWithin() a nav point function ReachedNav(ObjectID who, ObjectID nav) : Boolean; var code return (IsWithin(who,nav,150)); endfunction; function AddStandardBuckets; var code TrackBucket(Bucket_KILLS,0,true); TrackBucket(Bucket_DEATHS,0,true); TrackBucket(Bucket_CUSTOM,0,true); endfunction; function SetupScoring_Attrition; var code SetFlagsEnabled(FLAGS_HIDE); SetCustomBucketNameIndex(843); AddStandardBuckets; AddCustomBucketParameter(Bucket_ENEMY_DAMAGE_INFLICT,1); AddCustomBucketParameter(Bucket_FRIENDLY_DAMAGE_INFLICT,-1); AddCustomBucketParameter(Bucket_ENEMY_KILLS,500); AddCustomBucketParameter(Bucket_FRIENDLY_KILLS,-500); AddCustomBucketParameter(Bucket_SUICIDES,-500); AddCustomBucketParameter(Bucket_ENEMY_KILLS_BY_TONNAGE,5); AddCustomBucketParameter(Bucket_ENEMY_COMPONENT_KILLS,50); AddCustomBucketParameter(Bucket_FRIENDLY_COMPONENT_KILLS,-50); endfunction; function SetupScoring_Cthulu; var code SetFlagsEnabled(FLAGS_HIDE); SetCustomBucketNameIndex(843); AddStandardBuckets; AddCustomBucketParameter(Bucket_ENEMY_DAMAGE_INFLICT,1); AddCustomBucketParameter(Bucket_FRIENDLY_DAMAGE_INFLICT,-1); AddCustomBucketParameter(Bucket_SUICIDES,-500); AddCustomBucketParameter(Bucket_ENEMY_KILLS_BY_TONNAGE,5); AddCustomBucketParameter(Bucket_ENEMY_COMPONENT_KILLS,50); AddCustomBucketParameter(Bucket_FRIENDLY_COMPONENT_KILLS,-50); endfunction; function SetupScoring_TeamAttrition; var code SetFlagsEnabled(FLAGS_HIDE); SetCustomBucketNameIndex(844); AddStandardBuckets; AddCustomBucketParameter(Bucket_ENEMY_DAMAGE_INFLICT,1); AddCustomBucketParameter(Bucket_FRIENDLY_DAMAGE_INFLICT,-1); AddCustomBucketParameter(Bucket_ENEMY_KILLS,500); AddCustomBucketParameter(Bucket_FRIENDLY_KILLS,-500); AddCustomBucketParameter(Bucket_SUICIDES,-500); AddCustomBucketParameter(Bucket_ENEMY_KILLS_BY_TONNAGE,5); AddCustomBucketParameter(Bucket_ENEMY_COMPONENT_KILLS,50); AddCustomBucketParameter(Bucket_FRIENDLY_COMPONENT_KILLS,-50); endfunction; function SetupScoring_Destruction; var code SetFlagsEnabled(FLAGS_HIDE); SetCustomBucketNameIndex(845); AddStandardBuckets; AddCustomBucketParameter(Bucket_ENEMY_KILLS,1); AddCustomBucketParameter(Bucket_SUICIDES,-1); endfunction; function SetupScoring_TeamDestruction; var code SetFlagsEnabled(FLAGS_HIDE); SetCustomBucketNameIndex(846); AddStandardBuckets; AddCustomBucketParameter(Bucket_ENEMY_KILLS,1); AddCustomBucketParameter(Bucket_FRIENDLY_KILLS,-1); AddCustomBucketParameter(Bucket_SUICIDES,-1); endfunction; function SetupScoring_STB; var code SetFlagsEnabled(FLAGS_UNIVERSAL_ONLY); SetFlagCaptureEnabled(false); ShowFlagsAsNavPoints(TRUE); SetCustomBucketNameIndex(850); AddStandardBuckets; AddCustomBucketParameter(Bucket_FLAG_HOLD_TIME,1); endfunction; function SetupScoring_KOTH(ObjectID hill, integer radius); var code SetFlagsEnabled(FLAGS_HIDE); if (hill <> -1) then TrackObjectBucket(Bucket_OBJECTIVE_CONTESTED,hill,radius,false); TrackObjectBucket(Bucket_OBJECTIVE_UNCONTESTED,hill,radius,false); endif; SetCustomBucketNameIndex(848); AddStandardBuckets; AddCustomBucketParameter(Bucket_OBJECTIVE_CONTESTED,1); AddCustomBucketParameter(Bucket_OBJECTIVE_UNCONTESTED,5); endfunction; function SetupScoring_TKOTH(ObjectID hill, integer radius); var code SetFlagsEnabled(FLAGS_HIDE); if (hill <> -1) then TrackObjectBucket(Bucket_OBJECTIVE_CONTESTED,hill,radius,false); TrackObjectBucket(Bucket_OBJECTIVE_UNCONTESTED,hill,radius,false); endif; SetCustomBucketNameIndex(849); AddStandardBuckets; AddCustomBucketParameter(Bucket_OBJECTIVE_CONTESTED,1); AddCustomBucketParameter(Bucket_OBJECTIVE_UNCONTESTED,5); endfunction; function SetupScoring_CTF; var code SetFlagsEnabled(FLAGS_TEAM_ONLY); ShowFlagsAsNavPoints(TRUE); SetCustomBucketNameIndex(847); AddStandardBuckets; AddCustomBucketParameter(Bucket_FLAGS_CAPTURED,1000); AddCustomBucketParameter(Bucket_ENEMY_KILLS,250); AddCustomBucketParameter(Bucket_FRIENDLY_KILLS,-25); AddCustomBucketParameter(Bucket_SUICIDES,-25); endfunction; function SetupScoring_Territories(ObjectID hill, integer radius); var code SetFlagsEnabled(FLAGS_HIDE); if (hill <> -1) then TrackObjectBucket(Bucket_OBJECTIVE_UNCONTESTED,hill,radius,false); endif; SetCustomBucketNameIndex(852); AddStandardBuckets; AddCustomBucketParameter(Bucket_OBJECTIVE_UNCONTESTED,1); endfunction; function SetupScoring_CaptureBase; var code SetFlagsEnabled(FLAGS_HIDE); SetCustomBucketNameIndex(853); AddStandardBuckets; AddCustomBucketParameter(Bucket_ENEMY_KILLS,25); AddCustomBucketParameter(Bucket_FRIENDLY_KILLS,-25); AddCustomBucketParameter(Bucket_SUICIDES,-25); endfunction; function SetupScoring_DestroyObjective; var code SetFlagsEnabled(FLAGS_HIDE); SetCustomBucketNameIndex(854); AddStandardBuckets; // TODO: add scoring for objective destruction AddCustomBucketParameter(Bucket_ENEMY_KILLS,25); AddCustomBucketParameter(Bucket_FRIENDLY_KILLS,-25); AddCustomBucketParameter(Bucket_SUICIDES,-25); endfunction; function SetupScoring_Escort; var code SetFlagsEnabled(FLAGS_HIDE); SetCustomBucketNameIndex(851); AddStandardBuckets; AddCustomBucketParameter(Bucket_ENEMY_KILLS,500); AddCustomBucketParameter(Bucket_FRIENDLY_KILLS,-500); AddCustomBucketParameter(Bucket_SUICIDES,-500); endfunction; function SetupScoring_SiegeAssault; var code SetFlagsEnabled (FLAGS_HIDE); SetCustomBucketNameIndex (862); AddStandardBuckets; AddCustomBucketParameter(Bucket_ENEMY_KILLS,25); AddCustomBucketParameter(Bucket_FRIENDLY_KILLS,-25); AddCustomBucketParameter(Bucket_SUICIDES,-25); AddCustomBucketParameter(Bucket_ENEMY_BUILDING_KILLS,350); AddCustomBucketParameter(Bucket_FRIENDLY_BUILDING_KILLS,-350); AddCustomBucketParameter(Bucket_ENEMY_TURRET_KILLS,25); AddCustomBucketParameter(Bucket_FRIENDLY_TURRET_KILLS,-25); endfunction; function SetupScoring_MasterTrial; var code SetFlagsEnabled(FLAGS_HIDE); SetCustomBucketNameIndex(861); AddStandardBuckets; AddCustomBucketParameter(Bucket_ENEMY_DAMAGE_INFLICT,1); AddCustomBucketParameter(Bucket_FRIENDLY_DAMAGE_INFLICT,-1); AddCustomBucketParameter(Bucket_ENEMY_KILLS,500); AddCustomBucketParameter(Bucket_FRIENDLY_KILLS,-500); AddCustomBucketParameter(Bucket_SUICIDES,-500); endfunction; code print("mwfunc"); endlibrary.