00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
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
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
00067 new_agesr.movetype = MOVETYPE_NONE;
00068 new_agesr.solid = SOLID_NOT;
00069
00070
00071
00072
00073
00074
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
00080 new_agesr.cnt = stof(infokey(self, "agv_esr_ztolerance"));
00081
00082
00083
00084
00085
00086
00087 new_agesr.frags = -1;
00088
00089
00090
00091
00092 new_agesr.owner = self;
00093 self.agrip_esr = new_agesr;
00094
00095
00096
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
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
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
00125 new_agesr.think = snap_esr_main;
00126 new_agesr.nextthink = time + 0.1;
00127 };
00128
00132 void snap_esr_main()
00133 {
00134
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
00144 {
00145
00146
00147
00148
00149 remove(self.aiment);
00150 remove(self.enemy);
00151 remove(self.goalentity);
00152
00153
00154 safe_soundtoclient(self.owner, self.owner, CHAN_AUTO, "toggles/off.wav", 1, ATTN_NORM);
00155 remove(self);
00156 }
00157
00158
00159
00160
00161
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;
00186
00187
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
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
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
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
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
00214
00215
00216 potential_hit = findradius(self.owner.origin, 1000);
00217
00218
00219
00220
00221 while( potential_hit )
00222 {
00223
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
00233 dist = vlen(self.owner.origin - potential_hit.origin);
00234
00235
00236
00237
00238 if( potential_hit.flags & FL_MONSTER )
00239 {
00240
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
00259 else if( teamplay )
00260 {
00261
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
00284 else
00285 {
00286
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
00306 else
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
00328 potential_hit = potential_hit.chain;
00329 }
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 if( m_same != world )
00341 {
00342
00343 nearest_m = m_same;
00344
00345 }
00346 else if( m_higher != world )
00347 {
00348 if( m_lower != world )
00349 {
00350
00351 if( m_lower_dist < m_higher_dist )
00352 {
00353 nearest_m = m_lower;
00354
00355 }
00356 else
00357 {
00358 nearest_m = m_higher;
00359
00360 }
00361 }
00362 else
00363 {
00364
00365 nearest_m = m_higher;
00366
00367 }
00368 }
00369 else if( m_lower != world )
00370 {
00371
00372 nearest_m = m_lower;
00373
00374 }
00375
00376
00377
00378 if( f_same != world )
00379 {
00380
00381 nearest_f = f_same;
00382
00383 }
00384 else if( f_higher != world )
00385 {
00386 if( f_lower != world )
00387 {
00388
00389 if( f_lower_dist < f_higher_dist )
00390 {
00391 nearest_f = f_lower;
00392
00393 }
00394 else
00395 {
00396 nearest_f = f_higher;
00397
00398 }
00399 }
00400 else
00401 {
00402
00403 nearest_f = f_higher;
00404
00405 }
00406 }
00407 else if( f_lower != world )
00408 {
00409
00410 nearest_f = f_lower;
00411
00412 }
00413
00414
00415
00416 if( e_same != world )
00417 {
00418
00419 nearest_e = e_same;
00420
00421 }
00422 else if( e_higher != world )
00423 {
00424 if( e_lower != world )
00425 {
00426
00427 if( e_lower_dist < e_higher_dist )
00428 {
00429 nearest_e = e_lower;
00430
00431 }
00432 else
00433 {
00434 nearest_e = e_higher;
00435
00436 }
00437 }
00438 else
00439 {
00440
00441 nearest_e = e_higher;
00442
00443 }
00444 }
00445 else if( e_lower != world )
00446 {
00447
00448 nearest_e = e_lower;
00449
00450 }
00451
00452
00453
00454
00455
00456
00457
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
00462 if( nearest_m != world )
00463 {
00464 if( infokey(self.owner, "agv_t_esr_monster_warnings") == "1" )
00465 {
00466
00467 if( trace_ent == nearest_m )
00468 {
00469
00470 self.aiment.message = "esr/monster-boc.wav";
00471
00472
00473
00474 if( self.aiment.state == false )
00475 {
00476 self.aiment.state = true;
00477 }
00478 }
00479 else
00480 {
00481
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
00492
00493
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
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
00511 {
00512
00513
00514
00515 if( self.aiment.state == true )
00516 {
00517 safe_soundtoclient(self.owner, self.aiment, CHAN_AUTO, "weapons/ric2.wav", 1, ATTN_NORM);
00518
00519
00520 }
00521 self.aiment.state = false;
00522 }
00523
00524
00525 if( nearest_f != world )
00526 {
00527 if( infokey(self.owner, "agv_t_esr_friend_warnings") == "1" )
00528 {
00529
00530 if( trace_ent == nearest_f )
00531 {
00532
00533 self.goalentity.message = "esr/friend-boc.wav";
00534
00535
00536
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
00548 {
00549
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
00560
00561
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
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
00579 {
00580
00581
00582
00583 if( self.goalentity.state == true )
00584 {
00585 safe_soundtoclient(self.owner, self.goalentity, CHAN_AUTO, "weapons/ric2.wav", 1, ATTN_NORM);
00586
00587
00588 }
00589 self.goalentity.state = false;
00590 }
00591
00592
00593 if( nearest_e != world )
00594 {
00595 if( infokey(self.owner, "agv_t_esr_enemy_warnings") == "1" )
00596 {
00597
00598 if( trace_ent == nearest_e )
00599 {
00600
00601 self.enemy.message = "esr/enemy-boc.wav";
00602
00603
00604
00605 if( self.enemy.state == false )
00606 {
00607 if( infokey(self.owner, "agv_t_esr_names") == "1" )
00608 {
00609
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
00624 {
00625
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
00636
00637
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
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
00655 {
00656
00657
00658 if( self.enemy.state == true )
00659 {
00660 safe_soundtoclient(self.owner, self.enemy, CHAN_AUTO, "weapons/ric2.wav", 1, ATTN_NORM);
00661
00662
00663 }
00664 self.enemy.state = false;
00665 }
00666
00667
00668 self.nextthink = time + SNAP_ESR_GAP_TIME + 0.1;
00669 };
00670
00677 float snap_esr_classic_level(float entity_z)
00678 {
00679
00680 if( entity_z > ( self.owner.origin_z + self.cnt ) )
00681 return SNAP_ESR_LEVEL_HIGHER;
00682
00683
00684 else if( entity_z > ( self.owner.origin_z - self.cnt ) )
00685 return SNAP_ESR_LEVEL_SAME;
00686
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
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
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
00726 exitflag = true;
00727 }
00728
00729 find_start_ent = local_hazard;
00730 }
00731
00732
00733 if( foundflag )
00734 {
00735 if( self.frags == -1 )
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
00745
00746 if( self.nextthink < time + 0.1 )
00747 self.nextthink = time + 0.1;
00748 }
00749 else
00750 {
00751
00752 if( self.frags == -1 )
00753 {
00754
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
00762
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