agrip/esr.mqc

Go to the documentation of this file.
00001 /*  Copyright 2004-2005 Matthew Tylee Atkinson
00002 
00003     This program is free software; you can redistribute it and/or modify
00004     it under the terms of the GNU General Public License as published by
00005     the Free Software Foundation; either version 2 of the License, or
00006     (at your option) any later version.
00007 
00008     This program is distributed in the hope that it will be useful,
00009     but WITHOUT ANY WARRANTY; without even the implied warranty of
00010     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011     GNU General Public License for more details.
00012 
00013     You should have received a copy of the GNU General Public License
00014     along with this program; if not, write to the Free Software
00015     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00016 
00017     See file, 'COPYING', for details.
00018 */
00019 
00020 /* $AGRIP-START */
00021 /* EtherScan Radar Objet */
00022 
00023 
00024 // CONSTANTS
00025 
00026 float SNAP_ESR_LEVEL_LOWER = -1;
00027 float SNAP_ESR_LEVEL_SAME = 0;
00028 float SNAP_ESR_LEVEL_HIGHER = 1;
00029 
00030 float SNAP_ESR_SPECIAL_EXPLOBOX = 10;
00031 float SNAP_ESR_SPECIAL_DROP = 20;
00032 
00033 float SNAP_ESR_BEEPTIME_DIVISOR = 1100;
00034 float SNAP_ESR_BEEPTIME_OFFSET = 100;
00035 
00036 float SNAP_ESR_NAME_RANGE = 500; 
00037 
00038 float SNAP_ESR_GAP_TIME = 0.2;
00039 
00040 
00041 // PROTOTYPES
00042 
00043 void snap_esr_constructor();
00044 void snap_esr_main();
00045 void snap_esr_classic();
00046 float snap_esr_classic_level(float entity_z);
00047 void snap_esr_hazard();
00048 
00049 
00050 // IMPLEMENTATIONS
00051 
00059 void snap_esr_constructor()
00060 {
00061     local entity new_agesr;
00062     local entity s_monster, s_enemy, s_friend;
00063 
00064     new_agesr = spawn();
00065                                                                                            
00066     // Set up new esr object...
00067     new_agesr.movetype = MOVETYPE_NONE;
00068     new_agesr.solid = SOLID_NOT;
00069                                                                                            
00070     /*  Give it the preferences the user specified...
00071         To save memory, we're using existing (and empty for this entity)
00072         fields... */
00073     
00074     // Volume throttle for the sound this object will make...
00075     new_agesr.items = stof(infokey(self, "agv_esr_volume_throttle"));
00076     if( new_agesr.items > 1 || new_agesr.items < 0 )
00077         new_agesr.items = 1;
00078 
00079     // Level detection tolerance...
00080     new_agesr.cnt = stof(infokey(self, "agv_esr_ztolerance"));
00081 
00082     // This property stores a flag to say if we found any hazards at all
00083     // before loosing a lock on one.  It means that we can work out if
00084     // there never were any hazards (in which case the ESR should just turn off)
00085     // or if there was one but it was lost (in which case it should revert back
00086     // to enemy detection)...
00087     new_agesr.frags = -1;
00088     // The property is initially set to -1.  When the hazard ESR is started, it
00089     // looks for hazards.  If it finds one, it sets this to 1.
00090     
00091     // Connect the nav object and player...
00092     new_agesr.owner = self;
00093     self.agrip_esr = new_agesr;
00094 
00095     // Set up the actual sounder entities...
00096     // Monster Sounder...
00097     s_monster = spawn();
00098     s_monster.movetype = MOVETYPE_NONE;
00099     s_monster.solid = SOLID_NOT;
00100     s_monster.frags = self.agrip_esr.items;
00101     s_monster.think = snap_se_stickysound;
00102     s_monster.nextthink = 0;
00103     s_monster.owner = self;
00104     self.agrip_esr.aiment = s_monster;
00105     // Enemy (Player/Bot) Sounder...
00106     s_enemy = spawn();
00107     s_enemy.movetype = MOVETYPE_NONE;
00108     s_enemy.solid = SOLID_NOT;
00109     s_enemy.frags = self.agrip_esr.items;
00110     s_enemy.think = snap_se_stickysound;
00111     s_enemy.nextthink = 0;
00112     s_enemy.owner = self;
00113     self.agrip_esr.enemy = s_enemy;
00114     // friend Sounder...
00115     s_friend = spawn();
00116     s_friend.movetype = MOVETYPE_NONE;
00117     s_friend.solid = SOLID_NOT;
00118     s_friend.frags = self.agrip_esr.items;
00119     s_friend.think = snap_se_stickysound;
00120     s_friend.nextthink = 0;
00121     s_friend.owner = self;
00122     self.agrip_esr.goalentity = s_friend;
00123  
00124     // Set it going...
00125     new_agesr.think = snap_esr_main;
00126     new_agesr.nextthink = time + 0.1;
00127 };
00128 
00132 void snap_esr_main()
00133 {
00134     // What mode are we in?
00135     if( infokey(self.owner, "agv_t_esr") == "1" )
00136     {
00137         snap_esr_classic();
00138     }
00139     else if( infokey(self.owner, "agv_t_esr") == "2" )
00140     {
00141         snap_esr_hazard();
00142     }
00143     else //if( infokey(self.owner, "agv_t_esr") == "0" )
00144     {
00145         // The user pressed the ESR key again when it was in mode 2...
00146         // (i.e. They wanted to kill it.)
00147 
00148         // Kill child objects...
00149         remove(self.aiment);
00150         remove(self.enemy);
00151         remove(self.goalentity);
00152          
00153         // Destruct the ESR...
00154         safe_soundtoclient(self.owner, self.owner, CHAN_AUTO, "toggles/off.wav", 1, ATTN_NORM);
00155         remove(self);
00156     }
00157     /*else
00158     {
00159         local string mode;
00160         mode = infokey(self.owner, "agv_t_esr");
00161         objerror("ESR: ", self.owner.netname, "'s requested ESR mode '", mode, "' is invalid\nPlease report this bug to the developers.  Thank you.\n");
00162     }*/
00163 };
00164 
00180 void snap_esr_classic()
00181 {
00182     local entity potential_hit, nearest_m, nearest_e, nearest_f;
00183     local float mindist, dist, level;
00184     local float tmptime;
00185     local string mt, pht; // for comparing teams
00186     
00187     // Monster level variables...
00188     local float mdist, m_same_dist, m_lower_dist, m_higher_dist, pm_lev;
00189     local entity m_same, m_lower, m_higher;
00190 
00191     // Enemy level variables...
00192     local float edist, e_same_dist, e_lower_dist, e_higher_dist, pe_lev;
00193     local entity e_same, e_lower, e_higher;
00194     
00195     // Friend level variables...
00196     local float fdist, f_same_dist, f_lower_dist, f_higher_dist, pf_lev;
00197     local entity f_same, f_lower, f_higher;
00198 
00199     // Set up variables...
00200     m_lower_dist = m_higher_dist = m_same_dist = 2000;
00201     e_lower_dist = e_higher_dist = e_same_dist = 2000;
00202     f_lower_dist = f_higher_dist = f_same_dist = 2000;
00203  
00204     // Set up entity variables...
00205     nearest_m = world;
00206     m_lower = m_higher = m_same = world;
00207     nearest_e = world;
00208     e_lower = e_higher = e_same = world;
00209     nearest_f = world;
00210     f_lower = f_higher = f_same = world;
00211   
00212 
00213     // DETECTING POTENTIAL THREATS
00214     
00215     // Find nearby entities...
00216     potential_hit = findradius(self.owner.origin, 1000);
00217 
00218     // Work out which (if any) are the closest threats...
00219     // NOTE: Threats on all levels are computed, later the one with the highest
00220     //       priority is chosen.
00221     while( potential_hit )
00222     {
00223         // Don't detect things that shouldn't be detected...
00224         if( snap_misc_ownervisible(potential_hit.origin) )
00225         if( potential_hit.health > 1 )
00226         if( potential_hit != self.owner )
00227         if( potential_hit != world  )
00228         if( potential_hit.classname != "worldspwan" )
00229         if( potential_hit.classname != "door" )
00230         if( potential_hit.classname != "agrip_marker" )
00231         {
00232             // Get distance to the entity...
00233             dist = vlen(self.owner.origin - potential_hit.origin);
00234 
00235             // Work out if it is a monster, enemy or friend...
00236 
00237             // Monster...
00238             if( potential_hit.flags & FL_MONSTER )
00239             {
00240                 //dprint("monster?\n");
00241                 pm_lev = snap_esr_classic_level(potential_hit.origin_z);
00242                 if( pm_lev == SNAP_ESR_LEVEL_SAME && m_same_dist > dist)
00243                 {
00244                     m_same = potential_hit;
00245                     m_same_dist = dist;
00246                 }
00247                 else if( pm_lev == SNAP_ESR_LEVEL_HIGHER && m_higher_dist > dist )
00248                 {
00249                     m_higher = potential_hit;
00250                     m_higher_dist = dist;
00251                 }
00252                 else if( pm_lev == SNAP_ESR_LEVEL_LOWER && m_lower_dist > dist )
00253                 {
00254                     m_lower = potential_hit;
00255                     m_lower_dist = dist;
00256                 }
00257             }
00258             // Potential team-mate...
00259             else if( teamplay )
00260             {
00261                 // On the same team?
00262                 mt = infokey(self.owner, "team");
00263                 pht = infokey(potential_hit, "team");
00264                 if( mt != "" && mt == pht )
00265                 {
00266                     pf_lev = snap_esr_classic_level(potential_hit.origin_z);
00267                     if( pf_lev == SNAP_ESR_LEVEL_SAME && f_same_dist > dist)
00268                     {
00269                         f_same = potential_hit;
00270                         f_same_dist = dist;
00271                     }
00272                     else if( pf_lev == SNAP_ESR_LEVEL_HIGHER && f_higher_dist > dist )
00273                     {
00274                         f_higher = potential_hit;
00275                         f_higher_dist = dist;
00276                     }
00277                     else if( pf_lev == SNAP_ESR_LEVEL_LOWER && f_lower_dist > dist )
00278                     {
00279                         f_lower = potential_hit;
00280                         f_lower_dist = dist;
00281                     }
00282                 }
00283                 // Potential enemy...
00284                 else //if( ! potential_hit.flags & FL_MONSTER )
00285                 {
00286                     //dprint("enemy?\n");
00287                     pe_lev = snap_esr_classic_level(potential_hit.origin_z);
00288                     if( pe_lev == SNAP_ESR_LEVEL_SAME && e_same_dist > dist)
00289                     {
00290                         e_same = potential_hit;
00291                         e_same_dist = dist;
00292                     }
00293                     else if( pe_lev == SNAP_ESR_LEVEL_HIGHER && e_higher_dist > dist )
00294                     {
00295                         e_higher = potential_hit;
00296                         e_higher_dist = dist;
00297                     }
00298                     else if( pe_lev == SNAP_ESR_LEVEL_LOWER && e_lower_dist > dist )
00299                     {
00300                         e_lower = potential_hit;
00301                         e_lower_dist = dist;
00302                     }
00303                 }
00304             }
00305             // No teamplay -- most likely an enemy, then...
00306             else //if( ! potential_hit.flags & FL_MONSTER )
00307             {
00308                 pe_lev = snap_esr_classic_level(potential_hit.origin_z);
00309                 if( pe_lev == SNAP_ESR_LEVEL_SAME && e_same_dist > dist)
00310                 {
00311                     e_same = potential_hit;
00312                     e_same_dist = dist;
00313                 }
00314                 else if( pe_lev == SNAP_ESR_LEVEL_HIGHER && e_higher_dist > dist )
00315                 {
00316                     e_higher = potential_hit;
00317                     e_higher_dist = dist;
00318                 }
00319                 else if( pe_lev == SNAP_ESR_LEVEL_LOWER && e_lower_dist > dist )
00320                 {
00321                     e_lower = potential_hit;
00322                     e_lower_dist = dist;
00323                 }
00324                 }
00325         }
00326 
00327         // Get the next entity...
00328         potential_hit = potential_hit.chain;
00329     }
00330 
00331 
00332     // LEVEL PRIORITIES
00333 
00334     // Here the nearest creature is chosen.  Creatures on the same level always
00335     // take priority over those above or below.  After this, whichever is the
00336     // closest (above or below the player) is chosen.
00337     
00338     // Monster Level Priority...
00339     //dprint("ESR--monster-scan-------\n");
00340     if( m_same != world )
00341     {
00342         // Same level is the highest priority...
00343         nearest_m = m_same;
00344         //dprint("ESR: monster -- same\n");
00345     }
00346     else if( m_higher != world )
00347     {
00348         if( m_lower != world )
00349         {
00350             // Chose based on who's closer...
00351             if( m_lower_dist < m_higher_dist )
00352             {
00353                 nearest_m = m_lower;
00354                 //dprint("ESR: monster -- lower [interp]\n");
00355             }
00356             else
00357             {
00358                 nearest_m = m_higher;
00359                 //dprint("ESR: monster -- higher [interp]\n");
00360             }
00361         }
00362         else
00363         {
00364             // There is no lower monster so the higher one is chosen...
00365             nearest_m = m_higher;
00366             //dprint("ESR: monster -- higher [default]\n");
00367         }
00368     }
00369     else if( m_lower != world )
00370     {
00371         // There is no higher monster so the lower one is chosen...
00372         nearest_m = m_lower;
00373         //dprint("ESR: monster -- lower [default]\n");
00374     }
00375 
00376     // Friend Level Priority...
00377     //dprint("ESR--friend-scan-------\n");
00378     if( f_same != world )
00379     {
00380         // Same level is the highest priority...
00381         nearest_f = f_same;
00382         //dprint("ESR: friend -- same\n");
00383     }
00384     else if( f_higher != world )
00385     {
00386         if( f_lower != world )
00387         {
00388             // Chose based on who's closer...
00389             if( f_lower_dist < f_higher_dist )
00390             {
00391                 nearest_f = f_lower;
00392                 //dprint("ESR: friend -- lower [interp]\n");
00393             }
00394             else
00395             {
00396                 nearest_f = f_higher;
00397                 //dprint("ESR: friend -- higher [interp]\n");
00398             }
00399         }
00400         else
00401         {
00402             // There is no lower friend so the higher one is chosen...
00403             nearest_f = f_higher;
00404             //dprint("ESR: friend -- higher [default]\n");
00405         }
00406     }
00407     else if( f_lower != world )
00408     {
00409         // There is no higher friend so the lower one is chosen...
00410         nearest_f = f_lower;
00411         //dprint("ESR: friend -- lower [default]\n");
00412     }
00413 
00414     // Enemy Level Priority...
00415     //dprint("ESR--enemy-scan-------\n");
00416     if( e_same != world )
00417     {
00418         // Same level is the highest priority...
00419         nearest_e = e_same;
00420         //dprint("ESR: enemy -- same\n");
00421     }
00422     else if( e_higher != world )
00423     {
00424         if( e_lower != world )
00425         {
00426             // Chose based on who's closer...
00427             if( e_lower_dist < e_higher_dist )
00428             {
00429                 nearest_e = e_lower;
00430                 //dprint("ESR: enemy -- lower [interp]\n");
00431             }
00432             else
00433             {
00434                 nearest_e = e_higher;
00435                 //dprint("ESR: enemy -- higher [interp]\n");
00436             }
00437         }
00438         else
00439         {
00440             // There is no lower enemy so the higher one is chosen...
00441             nearest_e = e_higher;
00442             //dprint("ESR: enemy -- higher [default]\n");
00443         }
00444     }
00445     else if( e_lower != world )
00446     {
00447         // There is no higher enemy so the lower one is chosen...
00448         nearest_e = e_lower;
00449         //dprint("ESR: enemy -- lower [default]\n");
00450     }
00451 
00452 
00453     // SOUNDING THE CREATURES OUT
00454     
00455     // Now make sound based on where potential_hit is in relation to player...
00456 
00457     // Do line-of-sight/beep-on-centre test...
00458     makevectors(self.owner.angles);
00459     tracebox(self.owner.origin, VEC_HULL_MIN, VEC_HULL_MAX, self.owner.origin+(v_forward*SNAP_ESR_NAME_RANGE), false, self.owner);
00460     
00461     // Monsters...
00462     if( nearest_m != world )
00463     {
00464         if( infokey(self.owner, "agv_t_esr_monster_warnings") == "1" )
00465         {
00466             //dprint("sounding monster.\n");
00467             if( trace_ent == nearest_m )
00468             {
00469                 // Beep-on-Centre Sounding...
00470                 self.aiment.message = "esr/monster-boc.wav";
00471 
00472                 // L-O-S...
00473                 // only print message if we've got a lock
00474                 if( self.aiment.state == false )
00475                 {
00476                     self.aiment.state = true;
00477                 }
00478             }
00479             else  // not in l-o-s
00480             {
00481                 // Normal Sounding...
00482                 level = snap_esr_classic_level(nearest_m.origin_z);
00483                 mdist = vlen(self.owner.origin - nearest_m.origin);
00484                 if( level == SNAP_ESR_LEVEL_LOWER )
00485                     self.aiment.message = "esr/monster-lower.wav";
00486                 else if( level == SNAP_ESR_LEVEL_SAME )
00487                     self.aiment.message = "esr/monster-same.wav";
00488                 else
00489                     self.aiment.message = "esr/monster-higher.wav";
00490 
00491                 // L-O-S...
00492                 // lost a lock (entity still in FOV) or never had one
00493                 // only play lost lock sound if we did lose a lock...
00494                 if( self.aiment.state == true )
00495                 {
00496                     safe_soundtoclient(self.owner, nearest_m, CHAN_AUTO, "weapons/ric2.wav", 1, ATTN_NORM);
00497                 }
00498                 self.aiment.state = false;
00499             }
00500     
00501             // Prepare to make the sound...
00502             setorigin(self.aiment, nearest_m.origin);
00503             tmptime = (mdist + SNAP_ESR_BEEPTIME_OFFSET) / SNAP_ESR_BEEPTIME_DIVISOR;
00504             if( tmptime < SNAP_ESR_GAP_TIME )
00505                 self.aiment.nextthink = time + SNAP_ESR_GAP_TIME;
00506             else
00507                 self.aiment.nextthink = time + tmptime;
00508         }
00509     }
00510     else  // no nearest_m
00511     {
00512         // L-O-S...
00513         // lost a lock (entity moved out of FOV) or never had one
00514         // only play lost lock sound if we did lose a lock...
00515         if( self.aiment.state == true )
00516         {
00517             safe_soundtoclient(self.owner, self.aiment, CHAN_AUTO, "weapons/ric2.wav", 1, ATTN_NORM);
00518             // Note: have to use ESR sounder as closest approx. of actual
00519             //       position of the entity we were tracking.
00520         }
00521         self.aiment.state = false;
00522     }
00523 
00524     // Friends...
00525     if( nearest_f != world )
00526     {
00527         if( infokey(self.owner, "agv_t_esr_friend_warnings") == "1" )
00528         {
00529             //dprint("sounding friend.\n");
00530             if( trace_ent == nearest_f )
00531             {
00532                 // Beep-on-Centre Sounding...
00533                 self.goalentity.message = "esr/friend-boc.wav";
00534 
00535                 // L-O-S...
00536                 // only print message if we've got a lock
00537                 if( self.goalentity.state == false )
00538                 {
00539                     if( infokey(self.owner, "agv_t_esr_names") == "1" )
00540                     {
00541                         pht = infokey(nearest_f, "team");
00542                         sprint(self.owner, PRINT_HIGH, "!", pht, " ", nearest_f.netname, "\n");
00543                     }
00544                     self.goalentity.state = true;
00545                 }
00546             }
00547             else  // not in l-o-s
00548             {
00549                 // Normal Sounding...
00550                 level = snap_esr_classic_level(nearest_f.origin_z);
00551                 fdist = vlen(self.owner.origin - nearest_f.origin);
00552                 if( level == SNAP_ESR_LEVEL_LOWER )
00553                     self.goalentity.message = "esr/friend-lower.wav";
00554                 else if( level == SNAP_ESR_LEVEL_SAME )
00555                     self.goalentity.message = "esr/friend-same.wav";
00556                 else
00557                     self.goalentity.message = "esr/friend-higher.wav";
00558 
00559                 // L-O-S...
00560                 // lost a lock (entity still in FOV) or never had one
00561                 // only play lost lock sound if we did lose a lock...
00562                 if( self.goalentity.state == true )
00563                 {
00564                     safe_soundtoclient(self.owner, nearest_f, CHAN_AUTO, "weapons/ric2.wav", 1, ATTN_NORM);
00565                 }
00566                 self.goalentity.state = false;
00567             }
00568     
00569             // Prepare to make the sound...
00570             setorigin(self.goalentity, nearest_f.origin);
00571             tmptime = (fdist + SNAP_ESR_BEEPTIME_OFFSET) / SNAP_ESR_BEEPTIME_DIVISOR;
00572             if( tmptime < SNAP_ESR_GAP_TIME )
00573                 self.goalentity.nextthink = time + SNAP_ESR_GAP_TIME;
00574             else
00575                 self.goalentity.nextthink = time + tmptime;
00576         }
00577     }
00578     else  // no nearest_f
00579     {
00580         // L-O-S...
00581         // lost a lock (entity moved out of FOV) or never had one
00582         // only play lost lock sound if we did lose a lock...
00583         if( self.goalentity.state == true )
00584         {
00585             safe_soundtoclient(self.owner, self.goalentity, CHAN_AUTO, "weapons/ric2.wav", 1, ATTN_NORM);
00586             // Note: have to use ESR sounder as closest approx. of actual
00587             //       position of the entity we were tracking.
00588         }
00589         self.goalentity.state = false;
00590     }
00591 
00592     // Enemies...
00593     if( nearest_e != world ) 
00594     {
00595         if( infokey(self.owner, "agv_t_esr_enemy_warnings") == "1" )
00596         {
00597             //dprint("sounding enemy.\n");
00598             if( trace_ent == nearest_e )
00599             {
00600                 // Beep-on-Centre Sounding...
00601                 self.enemy.message = "esr/enemy-boc.wav";
00602 
00603                 // L-O-S...
00604                 // only print message if we've got a lock
00605                 if( self.enemy.state == false )
00606                 {
00607                     if( infokey(self.owner, "agv_t_esr_names") == "1" ) 
00608                     {
00609                         // If in teamplay, print their team too...
00610                         if( teamplay )
00611                         {
00612                             pht = infokey(nearest_f, "team");
00613                             sprint(self.owner, PRINT_HIGH, "!", pht, " ", nearest_e.netname, "\n");
00614                         }
00615                         else
00616                         {
00617                             sprint(self.owner, PRINT_HIGH, "!", nearest_e.netname, "\n");
00618                         }
00619                     }
00620                     self.enemy.state = true;
00621                 }
00622             }
00623             else  // not in l-o-s
00624             {
00625                 // Normal Sounding...
00626                 level = snap_esr_classic_level(nearest_e.origin_z);
00627                 edist = vlen(self.owner.origin - nearest_e.origin);
00628                 if( level == SNAP_ESR_LEVEL_LOWER )
00629                     self.enemy.message = "esr/enemy-lower.wav";
00630                 else if( level == SNAP_ESR_LEVEL_SAME )
00631                     self.enemy.message = "esr/enemy-same.wav";
00632                 else
00633                     self.enemy.message = "esr/enemy-higher.wav";
00634 
00635                 // L-O-S...
00636                 // lost a lock (entity still in FOV) or never had one
00637                 // only play lost lock sound if we did lose a lock...
00638                 if( self.enemy.state == true )
00639                 {
00640                     safe_soundtoclient(self.owner, nearest_e, CHAN_AUTO, "weapons/ric2.wav", 1, ATTN_NORM);
00641                 }
00642                 self.enemy.state = false;
00643             }
00644             
00645             // Prepare to make the sound...
00646             setorigin(self.enemy, nearest_e.origin);
00647             tmptime = (edist + SNAP_ESR_BEEPTIME_OFFSET) / SNAP_ESR_BEEPTIME_DIVISOR;
00648             if( tmptime < SNAP_ESR_GAP_TIME )
00649                 self.enemy.nextthink = time + SNAP_ESR_GAP_TIME;
00650             else
00651                 self.enemy.nextthink = time + tmptime;
00652         }
00653     }
00654     else  // no nearest_e
00655     {
00656         // lost a lock (entity moved out of FOV) or never had one
00657         // only play lost lock sound if we did lose a lock...
00658         if( self.enemy.state == true )
00659         {
00660             safe_soundtoclient(self.owner, self.enemy, CHAN_AUTO, "weapons/ric2.wav", 1, ATTN_NORM);
00661             // Note: have to use ESR sounder as closest approx. of actual
00662             //       position of the entity we were tracking.
00663         }
00664         self.enemy.state = false;
00665     }
00666    
00667     // Finished ESR scan...
00668     self.nextthink = time + SNAP_ESR_GAP_TIME + 0.1;
00669 };
00670 
00677 float snap_esr_classic_level(float entity_z)
00678 {
00679     // potential_hit is higher than player Z + tolerance...
00680     if( entity_z > ( self.owner.origin_z + self.cnt ) )
00681         return SNAP_ESR_LEVEL_HIGHER;
00682     // potential_hit is on a similar level
00683     // (within +/-TOLERANCE of player)...
00684     else if( entity_z > ( self.owner.origin_z - self.cnt ) )
00685         return SNAP_ESR_LEVEL_SAME;
00686     // Must be lower (than player Z - tolerance), then...
00687     else
00688         return SNAP_ESR_LEVEL_LOWER;
00689 };
00690 
00702 void snap_esr_hazard()
00703 {
00704     local float dist_to_hazard; 
00705     local entity local_hazard, find_start_ent;
00706     local float exitflag, foundflag;
00707     
00708     // Find nearby hazard entities...
00709     exitflag = false;
00710     foundflag = false;
00711     find_start_ent = world;
00712 
00713     while( ! exitflag )
00714     {
00715         local_hazard = find(find_start_ent, classname, "agrip_hazard");
00716 
00717         // Check hazard is owned by the right player...
00718         if( local_hazard.owner == self.owner.agrip_nav )
00719         {
00720             foundflag = true;
00721             exitflag = true;
00722         }
00723         else if( local_hazard == world )
00724         {
00725             // Exhausted search...
00726             exitflag = true;
00727         }
00728     
00729         find_start_ent = local_hazard;
00730     }
00731     
00732     // Now work out if we got a lock...
00733     if( foundflag )
00734     {
00735         if( self.frags == -1 ) // Tells us we've never had a lock.
00736         {
00737             snap_misc_m2o("ESR: Set to mode 2.\n");
00738             safe_soundtoclient(self.owner, self.owner, CHAN_AUTO, "toggles/mode.wav", 1, ATTN_NORM);
00739             self.frags = 1;
00740         }
00741         safe_soundtoclient(self.owner, local_hazard, CHAN_AUTO, "esr/haz.wav", self.items, ATTN_NORM);
00742         dist_to_hazard = vlen(local_hazard.origin - self.owner.origin);
00743         self.nextthink = time + ( (dist_to_hazard - 20) / SNAP_ESR_BEEPTIME_DIVISOR );
00744         //dprint(ftos(self.nextthink - time));
00745         //dprint("\n");
00746         if( self.nextthink < time + 0.1 )
00747             self.nextthink = time + 0.1;
00748     }
00749     else
00750     {
00751         // Have we _lost_ a lock or did we never _have_ one?
00752         if( self.frags == -1 )
00753         {
00754             // Never had one...
00755             snap_misc_m2o("ESR: Disabled (no hazard in front).\n");   
00756             stuffcmd(self.owner, "setinfo agv_t_esr 0\n");
00757             self.nextthink = time + 0.1;
00758         }
00759         else
00760         {
00761             // Lost it.
00762             // We must reset self.frags as this hazard deteciton session is over...
00763             self.frags = -1;
00764             snap_misc_m2o("ESR: Lost hazard lock - reverting to mode 1.\n");
00765             safe_soundtoclient(self.owner, self.owner, CHAN_AUTO, "toggles/mode.wav", 1, ATTN_NORM);
00766             stuffcmd(self.owner, "setinfo agv_t_esr 1\n");
00767             self.nextthink = time + 0.1;
00768         }
00769     }
00770 };
00771 
00772 /* $AGRIP-END */

Generated on Tue Jan 1 17:55:54 2008 for AudioQuake QuakeC by  doxygen 1.5.4