home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 2003 June / macformat-130.iso / mac / Reviewed⁄Demos / Spearhead Demo / demota / pak1.pk3 / global / alarm_system.scr < prev    next >
Encoding:
Text File  |  2002-10-21  |  38.6 KB  |  1,050 lines

  1. ////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. //  MoH: Allied Assault Script File  
  4. //  Global function: Alarm ringing and reinforcement system for disguise levels
  5. //  Script Written By: Benson 'elmagoo' Russell
  6. //
  7. ////////////////////////////////////////////////////////////////////////////////////////
  8.  
  9. //**************************************************************************
  10. //*** Will setup and run the alarm system for a disguise level
  11. //*** syntax --------------------------------
  12. //*** alarm_system_setup
  13. //**************************************************************************
  14. alarm_system_setup:
  15.  
  16. //*********************************************
  17. //*** CHECK EXISTENCE OF CRITICAL COMPONENTS
  18.  
  19. //*** check for zone_triggers
  20. if ($zone_trigger == NULL)
  21. {
  22.     println "^~^~^ ALARM SYSTEM ERROR:  There are no zone_trigger's in the level, aborting alarm system"
  23.     goto alarm_system_setup_end
  24. }
  25.  
  26. /*
  27. //*** check for backup spawners
  28. if ($ai_backup_spawner == NULL)
  29. {
  30.     println "^~^~^ ALARM SYSTEM ERROR:  There are no $ai_backup_spawner's in the level, aborting alarm system"
  31.     goto alarm_system_setup_end    
  32. }
  33.  
  34. //*** check for alarm switches
  35. if ($alarm_switch == NULL)
  36. {
  37.     println "^~^~^ ALARM SYSTEM ERROR:  There are no $alarm_switch's in the level, aborting alarm system"
  38.     goto alarm_system_setup_end    
  39. }
  40. */
  41.  
  42. //*** check for alarm switch triggers
  43. if ($alarm_switch_trigger == NULL)
  44. {
  45.     println "^~^~^ ALARM SYSTEM ERROR:  There are no $alarm_switch_trigger's in the level, aborting alarm system"
  46.     goto alarm_system_setup_end    
  47. }
  48.  
  49. //*** check for ai alarm pullers
  50. if ($ai_alarm == NULL)
  51. {
  52.     println "^~^~^ ALARM SYSTEM ERROR:  There are no $ai_alarm guys in the level, aborting alarm system!!!"
  53.     goto alarm_system_setup_end
  54. }
  55.  
  56. //*** check for ai sounding alarm waittrigger
  57. if ($waittrigger_gofor_alarm == NULL)
  58. {
  59.     println "^~^~^ ALARM SYSTEM ERROR:  There is no $waittrigger_gofor_alarm in the level, aborting alarm system!!!"
  60.     goto alarm_system_setup_end
  61. }
  62.  
  63. //*** check for ai sounding alarm waittrigger
  64. if ($waittrigger_alarm_master == NULL)
  65. {
  66.     println "^~^~^ ALARM SYSTEM ERROR:  There is no $waittrigger_alarm_master in the level, aborting alarm system!!!"
  67.     goto alarm_system_setup_end
  68. }
  69.  
  70. //*** check for ai sounding alarm waittrigger
  71. if ($waittrigger_alarm_backup_spawning == NULL)
  72. {
  73.     println "^~^~^ ALARM SYSTEM ERROR:  There is no $waittrigger_alarm_backup_spawning in the level, aborting alarm system!!!"
  74.     goto alarm_system_setup_end
  75. }
  76.  
  77. //*** check for ai sounding alarm waittrigger
  78. if ($waittrigger_alarm_sound == NULL)
  79. {
  80.     println "^~^~^ ALARM SYSTEM ERROR:  There is no $waittrigger_alarm_sound in the level, aborting alarm system!!!"
  81.     goto alarm_system_setup_end
  82. }
  83.  
  84.  
  85. //*********************************************
  86. //*** INIT VARIABLES
  87.  
  88. //*** for backup spawning guys
  89. level.ai_alarm_backup[1] = 0
  90. level.ai_alarm_backup_total = 0
  91.  
  92. //*** holds all the zone string names
  93. level.zone[1] = NULL
  94.  
  95. //*** used for alerted AI stack
  96. level.ai_alerted_stack[1] = NULL
  97. level.ai_alerted_index = 0
  98. level.ai_alerted_isprocessing = 0
  99.  
  100. /*
  101. //*** check for a default backup up reinforcement model
  102. if (level.ai_alarm_backup_model == NIL)
  103. {
  104.     println "^~^~^ ALARM SYSTEM:  level.ai_alarm_backup_model was not set, some reinforcement AI may not spawn!!!"
  105. }
  106.  
  107. //*** check for if a backup default model was set, but no default gun was set
  108. if (level.ai_alarm_backup_model != NIL && level.ai_alarm_backup_model_gun == NIL)
  109. {
  110.     println "^~^~^ ALARM SYSTEM:  level.ai_alarm_backup_model_gun was not set, some reinforcement AI may not have the proper weapons!!!"
  111. }
  112. */
  113.  
  114. //*** check the maximum allowed number of spawned guys, default it to 5 if nothing was set
  115. if (level.ai_alarm_backup_max == NIL)
  116. {
  117.     println "^~^~^ ALARM SYSTEM:  level.ai_alarm_backup_max was not set, defaulting to a maximum of 4 backup guys!!!"
  118.     level.ai_alarm_backup_max = 4
  119. }
  120.  
  121. //*** check the cycle time for spawning backup guys
  122. if (level.ai_alarm_backup_time == NIL)
  123. {
  124.     println "^~^~^ ALARM SYSTEM:  level.ai_alarm_backup_time was not set, defaulting to 15 seconds!!!"
  125.     level.ai_alarm_backup_time = 15
  126. }
  127.  
  128. //*** check for a default sound
  129. if (level.alarm_sound == NIL)
  130. {
  131.     println "^~^~^ ALARM SYSTEM:  level.alarm_sound was not set, there is no default sound!  Some sounds may not play!!!"
  132. }
  133.  
  134. //*** check for a default removal distance for backup guys
  135. if (level.backup_remove_distance == NIL)
  136. {
  137.     println "^~^~^ ALARM SYSTEM:  level.backup_remove_distance was not set, defaulting it to 2048!!!"
  138.     level.backup_remove_distance = 2048
  139. }
  140.  
  141.  
  142. //*********************************************
  143. //*** PRE-PROCESSING
  144.  
  145. local.zone_index = 1
  146.  
  147. //*** zone triggers and backup spawners
  148. for (local.i = 1; local.i <= $zone_trigger.size ; local.i ++)
  149. {
  150.     //*** check to see if the zone has a name, if not abort the alarm system
  151.     if ($zone_trigger[local.i].zone == NIL)
  152.         {
  153.             println "^~^~^ ALARM SYSTEM ERROR:  $zone_trigger without a .zone property at coordinates:  " $zone_trigger[local.i].origin "  :Aborting alarm system!!!"
  154.         goto alarm_system_setup_end
  155.         }
  156.     
  157.     //println "DEBUG ALARM: processing zone trigger: " local.i
  158.     
  159.     //*** check the existing zone against the zones stored to assign it a number, and count the zones
  160.     for (local.j = 1; local.j < local.zone_index ; local.j ++)
  161.         {
  162.         //println "DEBUG ALARM: cycling through zone array for a match: " $zone_trigger[local.i].zone " :on zone arry index: " local.j
  163.         
  164.         //*** check to see if this zone is already assigned a number, if so, skip to next zone
  165.             if ($zone_trigger[local.i].zone == level.zone[local.j])
  166.                 {
  167.                     //println "DEBUG ALARM: zone array match found on index: " local.j " :matching: " level.zone[local.j]
  168.             goto alarm_system_setup_zone_trigger_skipto_spawners
  169.                 }
  170.         }
  171.     
  172.     //println "DEBUG ALARM: zone match not found.  Assigning to index: " local.zone_index
  173.     
  174.     level.zone[local.zone_index] = $zone_trigger[local.i].zone
  175.     local.zone_index ++
  176.  
  177. alarm_system_setup_zone_trigger_skipto_spawners:
  178.     //*** assign the zone number into the trigger
  179.     $zone_trigger[local.i].zone_number = local.j
  180.  
  181.     //println "DEBUG ALARM: assigning zone number: " local.j " :to zone: " $zone_trigger[local.i].zone
  182.         
  183.     //*** set the index in the trigger
  184.     $zone_trigger[local.i].zone_index = local.i
  185.     
  186.     local.index = 1
  187.     
  188.     //*** convert the targeted AI into spawners with their values saved
  189.     if ($($zone_trigger[local.i].target) != NULL)
  190.         {
  191.             local.check = $($zone_trigger[local.i].target)
  192.         
  193. //        println "DEBUG ALARM: master target for zone trigger: " $zone_trigger[local.i].target
  194. //        println "DEBUG ALARM: master target after assigning to variable: " local.check
  195.         
  196. //        println "DEBUG ALARM: processing spawners for zone_trigger: " $zone_trigger[local.i].zone 
  197.         
  198.         if (local.check.isprocessed != 1)
  199.                 {
  200. //            println "DEBUG ALARM: spanwers currently not processed for zone: " $zone_trigger[local.i].zone
  201.             
  202.             //*** mark it as processed and grab the current trigger zone's index for further processing info
  203.             local.check.isprocessed = 1
  204.             local.check.zone_index = local.i
  205.             
  206.             //*** assign the zone and zone_number into the zone center
  207.             local.check.zone = $zone_trigger[local.i].zone
  208.             local.check.zone_number = $zone_trigger[local.i].zone_number
  209.             
  210.             //*** loop while there's still targets in the chain and process them
  211.             local.check = $(local.check.target)
  212.             while (local.check != NULL)
  213.                         {
  214.                 /*
  215.                     //*** grab all of the AI's properties
  216.                             local.temp_type_attack = local.check.type_attack
  217.                     local.temp_weapon = local.check.weapon
  218.                 
  219.                 //println "ALARM SYSTEM SETUP:  Grabbing spawner AI's weapon: " local.check.weapon
  220.                 
  221.                     local.temp_hearing = local.check.hearing
  222.                     local.temp_sight = local.check.sight
  223.                     local.temp_fov = local.check.fov
  224.                     local.temp_leash = local.check.leash
  225.                     local.temp_mindist = local.check.mindist
  226.                     local.temp_maxdist = local.check.maxdist
  227.                     local.temp_health = local.check.health
  228.                     local.temp_soundawareness = local.check.soundawareness
  229.                     local.temp_noticescale = local.check.noticescale
  230.                     local.temp_fixedleash = local.check.fixedleash
  231.                     local.temp_enemysharerange = local.check.enemysharerange
  232.                     local.temp_voicetype = local.check.voicetype
  233.                     local.temp_accuracy = local.check.accuracy
  234.                     local.temp_ammo_grenade = local.check.ammo_grenade
  235.                     local.temp_gren_awareness = local.check.gren_awareness
  236.                 local.temp_alarmnode = local.check.alarmnode
  237.                     local.temp_targetname = local.check.targetname
  238.                     local.temp_target = local.check.target
  239.                 local.temp_model = local.check.model
  240.                     local.temp_origin = local.check.origin
  241.                     
  242.                     //*** remove the AI
  243.                     local.check remove
  244.                     
  245.                     //*** generate a targetname for the spawner
  246.                     local.script_origin_targetname = ($zone_trigger[local.i].zone + "_spawner" + local.index)
  247.                     
  248.                     //*** spawn a script origin in it's place
  249.                     spawn script_origin targetname local.script_origin_targetname
  250.                     
  251.                     //*** place the script origin and assign all the values into it
  252.                     local.script_origin = $(local.script_origin_targetname)
  253.         
  254.                             local.script_origin.type_attack = local.temp_type_attack
  255.                     local.script_origin.hearing = local.temp_hearing
  256.                     local.script_origin.sight = local.temp_sight
  257.                     local.script_origin.fov = local.temp_fov
  258.                     local.script_origin.leash = local.temp_leash
  259.                     local.script_origin.mindist = local.temp_mindist
  260.                     local.script_origin.maxdist = local.temp_maxdist
  261.                     local.script_origin.health = local.temp_health
  262.                     local.script_origin.soundawareness = local.temp_soundawareness
  263.                     local.script_origin.noticescale = local.temp_noticescale
  264.                     local.script_origin.fixedleash = local.temp_fixedleash
  265.                     local.script_origin.enemysharerange = local.temp_enemysharerange
  266.                     local.script_origin.voicetype = local.temp_voicetype
  267.                     local.script_origin.accuracy = local.temp_accuracy
  268.                     local.script_origin.ammo_grenade = local.temp_ammo_grenade
  269.                     local.script_origin.gren_awareness = local.temp_gren_awareness
  270.                 local.script_origin.alarmnode = local.temp_alarmnode
  271.                     local.script_origin.target = local.temp_target
  272.                     local.script_origin.spawn_targetname = local.temp_targetname
  273.                 local.script_origin.spawn_model = local.temp_model
  274.                 local.script_origin.spawn_weapon = local.temp_weapon
  275.                     local.script_origin.origin = local.temp_origin
  276.                     */
  277.                 
  278.                 //*** convert the guy into a spawner
  279.                 local.spawner = waitthread global/spawner.scr::spawner_create_targetname local.check
  280.                 
  281.                     //*** if a match is found, store it's targetname into the trigger
  282.                             $zone_trigger[local.i].backup_spawner[local.index] = local.spawner
  283.                     
  284. //                    println "DEBUG ALARM: storing spawner into zone trigger with index: " local.i
  285. //                    println "DEBUG ALARM: storing spawner into .backup_spawners count: " local.index
  286. //                    println "DEBUG ALARM: storing spawner: " $zone_trigger[local.i].backup_spawner[local.index]
  287.                     
  288.                     local.index ++
  289.                     
  290.                     //*** reasign the check variable and proceed to the next entity
  291.                     local.check = $(local.spawner.spawn_target)
  292.                 
  293. //                println "DEBUG ALARM: " local.spawner " has a target of: " local.spawner.spawn_target
  294.                         }
  295.                 }
  296.         else  //*** grab all the values that have already been stuffed
  297.         {
  298. //            println "DEBUG ALARM: spanwers are processed for zone: " $zone_trigger[local.i].zone
  299.             for (local.k = 1; local.k <= $zone_trigger[local.check.zone_index].backup_spawner.size ; local.k ++)
  300.                         {
  301.                             $zone_trigger[local.i].backup_spawner[local.k] = $zone_trigger[local.check.zone_index].backup_spawner[local.k]
  302.                 
  303. //                    println "DEBUG ALARM: storing spawner targetname: " $zone_trigger[local.i].backup_spawner[local.k] " :in spawner index: " local.k
  304.                         }
  305.         }        
  306.         }
  307.  
  308.         //*** cycle through and find associated alarm switches per zone
  309.         if ($zone_trigger[local.i].alarm_switch != NIL)
  310.         {
  311.         //println "DEBUG ALARM: looking for alarm switch on zone_trigger with index: " local.i
  312.         
  313.             for (local.l = 1; local.l <= $alarm_switch_trigger.size ; local.l ++)
  314.                 {
  315.                     if ($alarm_switch_trigger[local.l].alarm_switch == NIL)
  316.                         {
  317.                             println "^~^~^ ALARM SYSTEM ERROR:  $alarm_switch_trigger with no .alarm_switch value set at coordinates: " $alarm_switch_trigger[local.l].origin " :Aborting alarm system!!!"
  318.                 goto alarm_system_setup_end
  319.                         }
  320.             
  321.             if ($alarm_switch_trigger[local.l].alarm_switch == $zone_trigger[local.i].alarm_switch)
  322.                         {
  323.                 //*** set the index in the switch
  324.                 $alarm_switch_trigger[local.l].alarm_switch_index = local.l
  325.                 
  326.                 //*** grab the switches settings and put them into the zone trigger
  327.                 $zone_trigger[local.i].alarm_switch_index = local.l
  328.                 $zone_trigger[local.i].alarm_switch_model = $($alarm_switch_trigger[local.l].target)
  329.                 $zone_trigger[local.i].alarm_switch_node = $($zone_trigger[local.i].alarm_switch_model.target)
  330.                 
  331.                 //println "DEBUG ALARM: alarm switch found!  Index of switch: " $zone_trigger[local.i].alarm_switch_index
  332.                 //println "DEBUG ALARM: alarm switch found!  targetname of model: " $zone_trigger[local.i].alarm_switch_model
  333.                 //println "DEBUG ALARM: alarm switch found!  targetname of node: " $zone_trigger[local.i].alarm_switch_node
  334.                 goto alarm_system_setup_zone_trigger_skipto_launchthread
  335.                         }
  336.                 }
  337.         
  338.         println "^~^~^ ALARM SYSTEM ERROR:  $zone_trigger with no associated alarm switch for zone: " $zone_trigger[local.i].zone " : at coordinates: " $zone_trigger[local.i]origin " :Aborting alarm system!!!"
  339.         goto alarm_system_setup_end
  340.         }
  341.     else
  342.     {
  343.         println "^~^~^ ALARM SYSTEM ERROR:  $zone_trigger with no associated alarm switch for zone: " $zone_trigger[local.i].zone " : at coordinates: " $zone_trigger[local.i]origin " :Aborting alarm system!!!"
  344.         goto alarm_system_setup_end
  345.     }
  346.  
  347. alarm_system_setup_zone_trigger_skipto_launchthread:    
  348.     //*** launch the zone trigger thread
  349.     $zone_trigger[local.i] thread zone_trigger_thread local.i
  350. }
  351.  
  352. //*** search through the alarm sounds and see if sound alias' are set, else set it to the default
  353. for (local.i = 1; local.i <= $alarm_sound.size ; local.i ++)
  354. {
  355.     if ($alarm_sound[local.i].sound_alias == NIL && level.alarm_sound != NIL)
  356.         {
  357.             $alarm_sound[local.i].sound_alias = level.alarm_sound
  358.         }
  359.     else if ($alarm_sound[local.i].sound_alias == NIL && level.alarm_sound == NIL)
  360.     {
  361.         println "^~^~^ ALARM SYSTEM: $alarm_sound at coordinates: " $alarm_sound[local.i].origin " :with no alias, no default is set!  Sound will NOT play from here!!!"
  362.     }
  363. }
  364.  
  365. //*********************************************
  366. //*** LAUNCH THREADS
  367.  
  368. //*** setup all the alarm AI
  369. for (local.i = 1; local.i <= $ai_alarm.size ; local.i ++)
  370. {
  371.     $ai_alarm[local.i] thread ai_alarm_setup
  372. }
  373.  
  374. //*** launch a thread for all the alarm switches
  375. for (local.i = 1; local.i <= $alarm_switch_trigger.size ; local.i ++)
  376. {
  377.     $alarm_switch_trigger[local.i] thread alarm_switch_thread
  378. }
  379.  
  380. thread ai_gofor_alarm  //determines who should run for the alarm
  381. thread alarm_system_master  //master cycle for turning the alarms on and off
  382. thread alarm_system_sound  //thread for alarm sounds to play
  383. thread alarm_system_backup_spawn  //thread for spawning backup guys
  384.  
  385. alarm_system_setup_end:
  386. end
  387.  
  388.  
  389. //*************************************************************************************
  390. //*************************************************************************************
  391. //
  392. // INIT THREADS
  393. //
  394. //*************************************************************************************
  395. //*************************************************************************************
  396.  
  397.  
  398. //**************************************************************************
  399. //*** alarm system zone trigger thread
  400. //**************************************************************************
  401. zone_trigger_thread local.index:
  402.  
  403. zone_trigger_loop:
  404. local.self waittill trigger
  405.  
  406. local.dude = parm.other
  407.  
  408. //println "ALARM SYSTEM ZONE TRIGGER: " local.dude " just passed through zone: " local.self.zone " : zone number : " local.self.zone_number " : zone index : " local.self.zone_index
  409.  
  410. local.dude.zone = local.self.zone
  411. local.dude.zone_number = local.self.zone_number
  412. local.dude.zone_index = local.self.zone_index
  413.  
  414. goto zone_trigger_loop
  415.  
  416. end
  417.  
  418.  
  419. //**************************************************************************
  420. //*** alarm system $ai_alarm setup thread
  421. //**************************************************************************
  422. ai_alarm_setup:
  423.  
  424. //*** check to make sure the AI is targeting the zone center, if not, remove him from the world
  425. if (local.self.target == NIL || local.self.target == "")
  426. {
  427.     println "^~^~^ ALARM SYSTEM ERROR:  $ai_alarm guy at coordinates: " local.self.origin " :has no target!  Removing him from the alarm system!!!"
  428.     local.self remove    
  429.     goto ai_alarm_setup_end
  430. }
  431.  
  432. //*** stuff the zone and zone_number into the AI
  433. local.self.zone = local.self.target.zone
  434. local.self.zone_number = local.self.target.zone_number
  435. local.self.zone_index = local.self.target.zone_index
  436.  
  437. //*** set his type_attack to alarm, and his alarmthread to run
  438. local.self.type_attack = "alarm"
  439. local.self.alarmthread = global/alarm_system.scr::ai_alarm_alerted
  440.  
  441. ai_alarm_setup_end:
  442. end
  443.  
  444.  
  445. //**************************************************************************
  446. //*** alarm system backup guy death thread
  447. //**************************************************************************
  448. ai_backup_death:
  449.  
  450. local.self waittill death
  451.  
  452. level.ai_alarm_backup_total --
  453.  
  454. local.self.targetname = ""
  455.  
  456. end
  457.  
  458.  
  459. //*************************************************************************************
  460. //*************************************************************************************
  461. //
  462. // MAIN SYSTEM THREADS
  463. //
  464. //*************************************************************************************
  465. //*************************************************************************************
  466.  
  467.  
  468. //**************************************************************************
  469. //*** alarm system ai alerted stack - adding to
  470. //**************************************************************************
  471. ai_alarm_alerted:
  472.  
  473. /*
  474. if (level.ai_alerted_isprocessing == 1)
  475. {
  476.     println "^~^~^ ALARM SYSTEM ALERT STACK ADD ERROR: An AI tried to update the stack while an instance was running!!  Aborting for that A!!"
  477.     goto ai_alerted_stack_add_end
  478. }
  479. */
  480.  
  481. //println "AI ALARM THREAD: ai has been alerted!!!"
  482.  
  483. //*** if the stack is busy, wait till it's free
  484. while (level.ai_alerted_isprocessing == 1)
  485. {
  486.     //println "AI ALARM THREAD: alerted stack is processing, holding"
  487.     wait .5
  488. }
  489.  
  490. //*** claim the stack
  491. level.ai_alerted_isprocessing = 1
  492.  
  493. level.ai_alerted_index ++
  494. level.ai_alerted_stack[level.ai_alerted_index] = local.self
  495.  
  496. //println "AI ALARM THREAD: added ai to stack index: " level.ai_alerted_index
  497.  
  498. //*** trigger the gofor thread to find someone to go ring the alarm
  499. trigger $waittrigger_gofor_alarm
  500.  
  501. //*** relinquish the stack
  502. level.ai_alerted_isprocessing = 0
  503.  
  504. ai_alerted_stack_add_end:
  505. end
  506.  
  507.  
  508. //**************************************************************************
  509. //*** alarm system ai alerted stack - bumping the stack
  510. //**************************************************************************
  511. ai_alarm_alerted_bumpstack:
  512.  
  513. //println "AI ALARM STACK BUMP: bumping AI off of the alerted stack!" 
  514.  
  515. //*** if the stack is already processing, wait till it's ready
  516. while (level.ai_alerted_isprocessing == 1)
  517. {
  518.     //println "AI ALARM STACK BUMP: stack is processing, holding!"
  519.     wait .1
  520. }
  521.  
  522. //*** claim the stack
  523. level.ai_alerted_isprocessing = 1
  524.  
  525. //*** cycle all the existing stack entries down one index
  526. for (local.i = 1; local.i < level.ai_alerted_index ; local.i ++)
  527. {
  528.     //println "AI ALARM STACK BUMP: cycling stack down: " (local.i + 1) " : moving into index: " local.i
  529.     level.ai_alerted_stack[local.i] = level.ai_alerted_stack[(local.i + 1)]
  530. }
  531.  
  532. level.ai_alerted_stack[level.ai_alerted_index] = NULL
  533. level.ai_alerted_index --
  534.  
  535. //println "AI ALARM STACK BUMP: new alerted index number: " level.ai_alerted_index 
  536.  
  537. //*** relinquish the stack
  538. level.ai_alerted_isprocessing = 0
  539.  
  540. end
  541.  
  542.  
  543. //**************************************************************************
  544. //*** alarm system ai gofor alarm switch master thread
  545. //**************************************************************************
  546. ai_gofor_alarm:
  547.  
  548. ai_gofor_alarm_reset:
  549.  
  550. local.stack_processing_index = 1
  551.  
  552. $waittrigger_gofor_alarm waittill trigger
  553.  
  554. //println "GOFOR ALARM: the player has been spotted!!"
  555.  
  556. ai_gofor_alarm_processnext:
  557.  
  558. //*** check if the alarm is ringing, if it is, go to the wait area for the alarm to finish
  559. if (level.alarm == 1)
  560. {
  561.     //println "GOFOR ALARM: the alarm is currently on, wait for it to finish"
  562.     goto ai_gofor_alarm_waitforalarm
  563. }
  564.  
  565. //*** if the alerted stack is empty, abort out completely
  566. if (level.ai_alerted_index == 0)
  567. {
  568.     //println "GOFOR ALARM: the alerted stack is empty, resetting the gofor thread!"
  569.     goto ai_gofor_alarm_reset
  570. }
  571.  
  572. //*** if the processing index exceeded the stack, reset it to one to start going through the stack again
  573. if (local.stack_processing_index > level.ai_alerted_index)
  574. {
  575.     //println "GOFOR ALARM: the processing index is greater than the stack index, resetting to 1"
  576.     local.stack_processing_index = 1
  577.     wait 3
  578. }
  579.  
  580. //*** grab the first guy on the stack
  581. local.ai_alerted = level.ai_alerted_stack[local.stack_processing_index]
  582.  
  583. //println "GOFOR ALARM: processing alerted stack index: " local.stack_processing_index " : in zone: " local.ai_alerted.zone 
  584.  
  585. //*** check if the guy is still alive, else goto the next guy
  586. if !(isalive local.ai_alerted)
  587. {
  588.     //println "GOFOR ALARM: " local.ai_alerted " is dead, bumping stack and finding the next guy"
  589.     waitthread ai_alarm_alerted_bumpstack
  590.     goto ai_gofor_alarm_processnext
  591. }
  592.  
  593. //*** unholster the guys weapon
  594. local.ai_alerted unholster
  595.  
  596. //*** check if the guy is still alerted, else goto the next guy
  597. if (local.ai_alerted.thinkstate != "attack")
  598. {
  599.     //println "GOFOR ALARM: " local.ai_alerted " is no longer alert, bumping stack and finding the next guy"
  600.     waitthread ai_alarm_alerted_bumpstack
  601.         local.ai_alerted.type_attack = "alarm"
  602.         local.ai_alerted.alarmthread = global/alarm_system.scr::ai_alarm_alerted    
  603.     goto ai_gofor_alarm_processnext
  604. }
  605.  
  606. //*** if the ai can't see the player pick a different alerted guy
  607. if (!(local.ai_alerted canseenoents $player))
  608. {
  609.     //println "GOFOR ALARM: " local.ai_alerted " can't see the player, trying a different alerted guy!"
  610.         local.stack_processing_index ++
  611.         local.ai_alerted exec global/enable_ai.scr
  612.         goto ai_gofor_alarm_processnext    
  613. }
  614.  
  615. //println "GOFOR ALARM: beginning check to make the found guy run to the alarm"
  616. local.ai_runto_switch = 1
  617.  
  618. //*** start looping to make the guy run to the alarm node
  619. while (local.ai_runto_switch != 0)
  620. {
  621.     //println "GOFOR ALARM: in running loop, level.alarm: " level.alarm
  622.     //*** check if the alarm is on
  623.     if (level.alarm == 1)
  624.         {
  625.             local.ai_runto_switch = 0
  626.         local.alarm_reached = 0  //0 means the alarm was rung while going for it
  627.         goto ai_gofor_alarm_breakrunning
  628.         }
  629.     
  630.     if !(isalive local.ai_alerted)
  631.         {
  632.             local.ai_runto_switch = 0
  633.         local.alarm_reached = 1  //1 means the ai was killed
  634.         goto ai_gofor_alarm_breakrunning
  635.         }
  636.     //*** grab the desired alarm switch
  637.     local.choosen_alarm = $alarm_switch_trigger[$zone_trigger[local.ai_alerted.zone_index].alarm_switch_index]
  638.     local.choosen_alarm_node = $zone_trigger[local.ai_alerted.zone_index].alarm_switch_node
  639.  
  640.         //*** check for the alarmswitch he's supposed to pull and if he's closer to it than the player is
  641.         local.distance_ai = local.ai_alerted.origin - local.choosen_alarm.origin
  642.         local.distance_player = $player.origin - local.choosen_alarm.origin
  643.         
  644.     //println "GOFOR ALARM LOOP: distance_ai: " local.distance_ai " : distance player: " local.distance_player 
  645.     
  646.         if ((local.distance_ai * local.distance_ai) < (local.distance_player * local.distance_player))
  647.         {
  648.             //*** the AI is closer to the switch
  649.             local.ai_runto_switch = 1
  650.         }
  651.         else
  652.         {
  653.             //*** the player is closer to the switch, goto the next guy in the stack
  654.         local.ai_runto_switch = 0
  655.         local.alarm_reached = 2  //2 means the ai is alive, but couldn't reach the alarm, process the next guy in the stack
  656.         goto ai_gofor_alarm_breakrunning
  657.         }
  658.     
  659.     //*** check to see if the AI has reached the alarm, if so, mark it reached and break the loop
  660.     if (vector_length(local.ai_alerted.origin - local.choosen_alarm_node.origin) <= 24)
  661.         {
  662.             local.alarm_reached = 3  //3 means the switch was reached successfully
  663.         local.ai_runto_switch = 0
  664.         goto ai_gofor_alarm_breakrunning
  665.         }
  666.     
  667.     //println "GOFOR ALARM: the alerted guy hasn't reached the alarm yet, make him keep running!" 
  668.     //*** disable his AI so he can be manipulated
  669.     local.ai_alerted exec global/disable_ai.scr
  670.  
  671.     //*** if all the checks are cool, tell him to run to the node
  672.     local.ai_alerted exec global/runto.scr local.choosen_alarm_node
  673.  
  674. ai_gofor_alarm_breakrunning:        
  675.     wait .5
  676. }
  677.  
  678. //println "GOFOR ALARM: finished trying to make: " local.ai_alerted " run to the alarm"
  679.  
  680. //*** check the status of how he broke out of the loop
  681. if (local.alarm_reached == 0)
  682. {
  683.     //*** the ai is alive and the alarm was rung enroute
  684.     //println "GOFOR ALARM: " local.ai_alerted " had the alarm rung in route to the alarm"
  685.         goto ai_gofor_alarm_waitforalarm
  686. }
  687. else if (local.alarm_reached == 1)
  688. {
  689.     //*** the ai was killed
  690.     //println "GOFOR ALARM: " local.ai_alerted " was killed enroute to the alarm, bumping stack and restarting"
  691.     waitthread ai_alarm_alerted_bumpstack
  692.     goto ai_gofor_alarm_processnext
  693. }
  694. else if (local.alarm_reached == 2)
  695. {
  696.     //*** the ai and was prevented from ringing the alarm
  697.     //println "GOFOR ALARM: " local.ai_alerted " was prevented from reaching the alarm"
  698.         local.stack_processing_index ++
  699.         local.ai_alerted exec global/enable_ai.scr
  700.         goto ai_gofor_alarm_processnext    
  701. }
  702.  
  703.  
  704. //println "GOFOR ALARM: " local.ai_alerted " has reached the alarm, making him turn to face it"
  705. local.ai_alerted exec global/turnto.scr local.choosen_alarm
  706. local.ai_alerted waittill turndone
  707.  
  708. local.ai_alerted exec global/turnto.scr NULL
  709.  
  710. wait 1
  711. //*** check if the guy is still dead, or if the alarm was rung.  If so goto the next guy on the stack
  712. if !(isalive local.ai_alerted)
  713. {
  714.     //println "GOFOR ALARM: " local.ai_alerted " was killed at the alarm, bumping stack and restarting"
  715.     waitthread ai_alarm_alerted_bumpstack
  716.     goto ai_gofor_alarm_processnext
  717. }
  718. else if (level.alarm == 1)
  719. {
  720.     //println "GOFOR ALARM: " local.ai_alerted " reached the alarm, but it was activated before he could trigger it"
  721.         local.stack_processing_index ++
  722.         local.ai_alerted exec global/enable_ai.scr
  723.         goto ai_gofor_alarm_waitforalarm    
  724. }
  725.  
  726.  
  727. //*** trigger the alarm and reenable the guy
  728. //trigger $alarm_switch_trigger[$zone_trigger[local.ai_alerted.zone_index].alarm_switch_index]
  729. //println "SWITCH USED: " $alarm_switch_trigger[$zone_trigger[local.ai_alerted.zone_index].alarm_switch_index]
  730. $alarm_switch_trigger[$zone_trigger[local.ai_alerted.zone_index].alarm_switch_index] douse $player
  731. local.ai_alerted exec global/enable_ai.scr
  732.  
  733. wait 2
  734.  
  735. ai_gofor_alarm_waitforalarm:
  736. //*** wait till the alarm shuts off
  737. while (level.alarm == 1)
  738. {
  739.     wait .1
  740. }
  741.  
  742. goto ai_gofor_alarm_processnext
  743.  
  744. end
  745.  
  746.  
  747. //**************************************************************************
  748. //*** alarm switch trigger thread
  749. //**************************************************************************
  750. alarm_switch_thread:
  751.  
  752. alarm_switch_thread_loop:
  753. local.self waittill trigger
  754.  
  755. //println "ALARM SWITCH THREAD " local.self.alarm_switch_index " : has been triggered"
  756.  
  757. //*** trigger the master alarm thread to go
  758. trigger $waittrigger_alarm_master
  759.  
  760. wait 3
  761. goto alarm_switch_thread_loop
  762.  
  763. end
  764.  
  765.  
  766. //**************************************************************************
  767. //*** alarm system master thread
  768. //**************************************************************************
  769. alarm_system_master:
  770.  
  771. alarm_system_master_loop:
  772. $waittrigger_alarm_master waittill trigger
  773.  
  774. //println "MASTER ALARM THREAD: has been triggered"
  775.  
  776. //*** check whether to turn the alarm on or off
  777. if (level.alarm != 1)
  778. {
  779.     //println "MASTER ALARM THREAD: the alarm is off, turning it on!"
  780.     //*** if the alarms are not on, turn them on
  781.     level.alarm = 1
  782.     level.alarmlights = 1
  783.     
  784.     //*** animate all the switches here
  785.     for (local.i = 1; local.i <= $alarm_switch_trigger.size ; local.i ++)
  786.         {
  787.             $($alarm_switch_trigger[local.i].target) anim turnon
  788.         $($alarm_switch_trigger[local.i].target) playsound alarm_switch
  789.         } 
  790.     
  791.     trigger $waittrigger_alarm_backup_spawning
  792.     trigger $waittrigger_alarm_sound
  793. }
  794. else
  795. {
  796.     //println "MASTER ALARM THREAD: the alarm is on, turning it off!"
  797.     //*** if the alarms are on, turn them off
  798.     
  799.     //*** animate all the switches here
  800.     for (local.i = 1; local.i <= $alarm_switch_trigger.size ; local.i ++)
  801.         {
  802.             $($alarm_switch_trigger[local.i].target) anim turnoff
  803.         $($alarm_switch_trigger[local.i].target) playsound alarm_switch
  804.         } 
  805.  
  806.     level.alarm = 0
  807.     level.alarmlights = 0
  808. }
  809.  
  810. goto alarm_system_master_loop
  811.  
  812. end
  813.  
  814.  
  815. //**************************************************************************
  816. //*** alarm system sound thread
  817. //**************************************************************************
  818. alarm_system_sound:
  819.  
  820. alarm_system_sound_loop:
  821. $waittrigger_alarm_sound waittill trigger
  822.  
  823. //*** play sounds on all the alarm points
  824. for (local.i = 1; local.i <= $alarm_sound.size ; local.i ++)
  825. {
  826.     if ($alarm_sound[local.i].sound_alias != NIL)
  827.         {
  828.         //println "ALARM SYSTEM SOUND PLAY: alias: " $alarm_sound[local.i].sound_alias
  829.             $alarm_sound[local.i] loopsound $alarm_sound[local.i].sound_alias
  830.         }
  831. }
  832.  
  833. //*** wait for the alarms to go off
  834. while (level.alarm == 1)
  835. {
  836.     wait .1
  837. }
  838.  
  839. //*** stop the sounds on all the alarmpoints
  840. for (local.i = 1; local.i <= $alarm_sound.size ; local.i ++)
  841. {
  842.     if ($alarm_sound[local.i].sound_alias != NIL)
  843.         {
  844.             $alarm_sound[local.i] stoploopsound
  845.         }
  846. }
  847.  
  848. goto alarm_system_sound_loop
  849.  
  850. end
  851.  
  852.  
  853. //**************************************************************************
  854. //*** alarm system backup spawning thread
  855. //**************************************************************************
  856. alarm_system_backup_spawn:
  857.  
  858. alarm_system_backup_spawn_loop:
  859. $waittrigger_alarm_backup_spawning waittill trigger
  860.  
  861. //println "BACKUP SPAWNING: alarms sounded, spawning reinforcements"
  862.  
  863. wait 1
  864.  
  865. //*** loop while the alarm is on
  866. while (level.alarm == 1)
  867. {
  868.     //println "BACKUP SPAWNING: .backup_spawner.size value: " $zone_trigger[$player.zone_index].backup_spawner.size
  869.     //*** check to see if there are any spawners for this area
  870.     if ($zone_trigger[$player.zone_index].backup_spawner.size == -1)
  871.         {
  872.             //println "BACKUP SPAWNING: there are no spawners for zone: " $zone_trigger[$player.zone_index].zone " skipping spawning"
  873.         goto alarm_system_backup_spawn_skip
  874.         }
  875.     
  876.     //*** there are spawners, cycle through and spawn guys that don't already exist for this zone up to the maximum allowed
  877.     //println "BACKUP SPAWNING: starting cycling for backup guys"
  878.     for (local.i = 1; local.i <= $zone_trigger[$player.zone_index].backup_spawner.size ; local.i ++)
  879.         {
  880.         //println "BACKUP SPAWNING: spawning guys in zone: " $zone_trigger[$player.zone_index].zone
  881.         //println "BACKUP SPAWNING: There are: " $zone_trigger[$player.zone_index].backup_spawner.size " spawners in this zone"
  882.             if (level.ai_alarm_backup_total < level.ai_alarm_backup_max)
  883.                 {
  884.             //println "BACKUP SPAWNING: the max number of guys has not been reached, continue spawning"
  885.                     //*** grab the actual spawner to use
  886.             local.spawner = $zone_trigger[$player.zone_index].backup_spawner[local.i]
  887.             
  888.             //*** check to see if this guy already exists
  889.             if ($(local.spawner.spawn_targetname) == NULL)
  890.                         {
  891.                     //println "BACKUP SPAWNING: spawning at spawner: " local.spawner
  892.                     
  893.                     //*** spawn the guy and grab him into a variable
  894.                     //println "BACKUP SPAWNING: spawning guys targetname: " local.spawner.spawn_targetname
  895.                     //println "BACKUP SPAWNING: spawning guys model: " local.spawner.spawn_model
  896.                     //println "BACKUP SPAWNING: spawning guys gun: " local.spawner.spawn_weapon
  897.                     //println "BACKUP SPAWNING: spawning guys origin: " local.spawner.origin
  898.                 
  899.                 /*                    
  900.                     spawn local.spawner.spawn_model targetname local.spawner.spawn_targetname voicetype local.spawner.voicetype
  901.                     local.dude = $(local.spawner.spawn_targetname)
  902.                     
  903.                     //*** set the values into the AI from the spawner
  904.                     local.dude.weapon = local.spawner.spawn_weapon
  905.                     local.dude.type_attack = local.spawner.type_attack
  906.                     local.dude.hearing = local.spawner.hearing
  907.                     local.dude.sight = local.spawner.sight
  908.                     local.dude.fov = local.spawner.fov
  909.                     local.dude.leash = local.spawner.leash
  910.                     local.dude.mindist = local.spawner.mindist
  911.                     local.dude.maxdist = local.spawner.maxdist
  912.                     local.dude.health = local.spawner.health
  913.                     local.dude.soundawareness = local.spawner.soundawareness
  914.                     local.dude.noticescale = local.spawner.noticescale
  915.                     local.dude.fixedleash = local.spawner.fixedleash
  916.                     local.dude.enemysharerange = local.spawner.enemysharerange
  917.                     //local.dude.voicetype = local.spawner.voicetype
  918.                     local.dude.accuracy = local.spawner.accuracy
  919.                     local.dude.ammo_grenade = local.spawner.ammo_grenade
  920.                     local.dude.alarmnode = local.spawner.alarmnode
  921.                     */
  922.                 
  923.                 //*** spawn the guy in
  924.                 local.dude = waitthread global/spawner.scr::spawner_activate_targetname local.spawner
  925.                     
  926.                 //*** launch his ondeath thread
  927.                     local.dude thread ai_backup_death
  928.                     
  929.                     //*** reposition him in the world
  930.                     //local.dude.origin = local.spawner.origin
  931.                     
  932.                     //*** increment the counter for AI in the level
  933.                     level.ai_alarm_backup_total ++
  934.                     
  935.                     //*** if the alarmnode is filled, run there, else run to player
  936.                     if (local.dude.alarmnode == NIL || local.dude.alarmnode == "" || local.dude.alarmnode == NULL)
  937.                                 {
  938.                     //local.dude.movedoneradius = 192
  939.                                     //local.dude exec global/runto.scr $player
  940.                     //local.dude forceactivate
  941.                     //local.dude attackplayer
  942.                     local.dude thread alarm_system_backup_dude
  943.                                 }
  944.                     else
  945.                     {
  946.                     //local.dude forceactivate
  947.                         //local.dude attackplayer
  948.                     local.dude thread alarm_system_backup_dude
  949.                     }
  950.  
  951.                         }
  952.             else
  953.             {
  954.                 //*** the guy already exists, abort
  955.                 //println "BACKUP SPAWNING: " local.spawner.spawn_targetname " backup guy already exists, checking next guy in zone: " $zone_trigger[$player.zone_index].zone
  956.             }
  957.             
  958.             //*** clear the variable
  959.             local.dude = NULL
  960.                 }
  961.         }
  962.  
  963. //*** wait the backup cycle time before checking to spawn in more guys or not
  964. alarm_system_backup_spawn_skip:    
  965. wait level.ai_alarm_backup_time
  966. }
  967.  
  968. //*** the alarm is over, reset thread
  969. goto alarm_system_backup_spawn_loop
  970.  
  971. end
  972.  
  973.  
  974. //**************************************************************************
  975. //*** alarm system backup dude's routine
  976. //**************************************************************************
  977. alarm_system_backup_dude:
  978.  
  979. //println "ALARM DUDE: " local.self " setting movedone radius"
  980. local.self.movedoneradius = 256
  981. local.self forceactivate
  982.  
  983. //println "ALARM DUDE: " local.self " running to player"
  984. local.self exec global/runto.scr $player
  985. local.self waittill movedone
  986.  
  987. local.self exec global/stand.scr
  988.  
  989. wait 5
  990. alarm_system_backup_dude_loop:
  991. //*** check to see if the player is far enough away to remove the guy
  992. while (local.self.thinkstate != "attack" && isalive local.self)
  993. {
  994.     //println "ALARM DUDE: " local.self " cansee player: " (local.self cansee $player 90 16000)
  995.     //println "ALARM DUDE: " local.self " is within " level.backup_remove_distance " units of player: " (vector_within local.self.origin $player.origin level.backup_remove_distance)
  996.     //entity cansee entity fov distance
  997.     if ($player cansee local.self 90 16000 == 0 && vector_within local.self.origin $player.origin level.backup_remove_distance == 0)
  998.         {
  999.             goto alarm_system_backup_dude_gone
  1000.         }
  1001.     
  1002.     wait 1
  1003. }
  1004.  
  1005. if !(isalive local.self)
  1006. {
  1007.     //println "ALARM DUDE: " local.self " is dead"
  1008.     goto alarm_system_backup_dude_done
  1009. }
  1010.  
  1011. wait 3
  1012.  
  1013. goto alarm_system_backup_dude_loop
  1014.  
  1015. alarm_system_backup_dude_gone:
  1016. //println "ALARM DUDE: " local.self " is being removed"
  1017. local.self remove
  1018.  
  1019. alarm_system_backup_dude_done:
  1020. end
  1021.  
  1022.  
  1023. //*************************************************************************************
  1024. //*************************************************************************************
  1025. //
  1026. // SPECIAL FUNCTIONS
  1027. //
  1028. //*************************************************************************************
  1029. //*************************************************************************************
  1030.  
  1031. //**************************************************************************
  1032. //*** find an alarm ringer guy
  1033. //**************************************************************************
  1034. find_guy local.find_name:
  1035.  
  1036. for (local.i = 1; local.i <= $ai_alarm.size ; local.i ++)
  1037. {
  1038.     if ($ai_alarm[local.i].find_name == local.find_name)
  1039.         {
  1040.             local.result = $ai_alarm[local.i]
  1041.         goto find_guy_end
  1042.         }
  1043. }
  1044.  
  1045. println "^~^~^ ALARM SYSTEM FIND GUY: There was no $ai_alarm with a .find_name of: " local.find_name
  1046.     
  1047. find_guy_end:
  1048.  
  1049. end local.result
  1050.