Advertisement
Guest User

Untitled

a guest
Sep 29th, 2010
299
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 40.51 KB | None | 0 0
  1. //#include maps\mp\_utility;
  2. #include common_scripts\utility;
  3.  
  4. init()
  5. {
  6. if ( getdvar( "scr_elevator_disabled" ) == "1" )
  7. return;
  8.  
  9. // skip if no elevators in this level
  10. elevator_groups = getentarray( "elevator_group", "targetname" );
  11. if ( !isdefined( elevator_groups ) )
  12. return;
  13. if ( !elevator_groups.size )
  14. return;
  15.  
  16. // Press and hold &&1 to call elevator.
  17. precacheString( &"ELEVATOR_CALL_HINT" );
  18. // Press and hold &&1 to use elevator.
  19. precacheString( &"ELEVATOR_USE_HINT" );
  20. // Press and hold &&1 to select floor.
  21. precacheString( &"ELEVATOR_FLOOR_SELECT_HINT" );
  22.  
  23. precacheMenu( "elevator_floor_selector" );
  24.  
  25. thread elevator_update_global_dvars();
  26.  
  27. // find and build all elevators in the level
  28. level.elevators = [];
  29.  
  30. // elevator construction dvars:
  31. // vertical units for "call button" to link near by elevator per floor
  32. level.elevator_callbutton_link_v = elevator_get_dvar_int( "scr_elevator_callbutton_link_v", "96" );
  33. // horizontal units for "call button" to link near by elevator per floor
  34. level.elevator_callbutton_link_h = elevator_get_dvar_int( "scr_elevator_callbutton_link_h", "256" );
  35.  
  36. build_elevators();
  37. position_elevators();
  38. elevator_call();
  39.  
  40. if ( !level.elevators.size )
  41. return;
  42.  
  43. foreach ( elevator in level.elevators )
  44. {
  45. elevator thread elevator_think();
  46. elevator thread elevator_sound_think();
  47. }
  48.  
  49. thread elevator_debug();
  50. }
  51.  
  52. elevator_update_global_dvars()
  53. {
  54. while ( 1 )
  55. {
  56. level.elevator_accel = elevator_get_dvar( "scr_elevator_accel", "0.2" ); // acceleration time in seconds
  57. level.elevator_decel = elevator_get_dvar( "scr_elevator_decel", "0.2" ); // deceleration time in seconds
  58. level.elevator_music = elevator_get_dvar_int( "scr_elevator_music", "1" ); // elevator music
  59. level.elevator_speed = elevator_get_dvar_int( "scr_elevator_speed", "96" ); // units per second
  60. level.elevator_innerdoorspeed = elevator_get_dvar_int( "scr_elevator_innerdoorspeed", "14" ); // inner door speed
  61. level.elevator_outterdoorspeed = elevator_get_dvar_int( "scr_elevator_outterdoorspeed", "16" ); // outter door speed
  62. level.elevator_return = elevator_get_dvar_int( "scr_elevator_return", "0" ); // 1: elevator returns to original floor
  63. level.elevator_waittime = elevator_get_dvar_int( "scr_elevator_waittime", "6" ); // wait in seconds before closing door
  64. level.elevator_aggressive_call = elevator_get_dvar_int( "scr_elevator_aggressive_call", "0" ); // calls all available elevators to floor
  65. level.elevator_debug = elevator_get_dvar_int( "debug_elevator", "0" ); // 2: full 1: simple, 0: debug off
  66.  
  67. // mp & sp default differences:
  68. if ( isSP() )
  69. {
  70. level.elevator_motion_detection = elevator_get_dvar_int( "scr_elevator_motion_detection", "0" );// calls elevators via motion detection
  71. }
  72. else
  73. {
  74. level.elevator_motion_detection = elevator_get_dvar_int( "scr_elevator_motion_detection", "1" );// calls elevators via motion detection
  75. }
  76.  
  77. wait 1;
  78. }
  79. }
  80.  
  81. //==========================================================================//
  82. // === ELEVATOR LOGIC === //
  83. //==========================================================================//
  84.  
  85. elevator_think()
  86. {
  87. // self is elevator, self.e[]
  88. self elevator_fsm( "[A]" );
  89. }
  90.  
  91. elevator_call()
  92. {
  93. foreach ( callbutton in level.elevator_callbuttons )
  94. callbutton thread monitor_callbutton();
  95. }
  96.  
  97. floor_override( inside_trig )
  98. {
  99. self endon( "elevator_moving" );
  100.  
  101. self.floor_override = 0;
  102. self.overrider = undefined;
  103.  
  104. while ( 1 )
  105. {
  106. inside_trig waittill( "trigger", player );
  107. self.floor_override = 1;
  108. self.overrider = player;
  109. break;
  110. }
  111. self notify( "floor_override" );
  112. }
  113.  
  114. elevator_fsm( state )
  115. {
  116. /* finite state machine
  117.  
  118. state A: rest
  119. state B: closing doors - interrupt threaded
  120. state C: opening doors
  121. state D: moving elevator
  122. ?1: if not resting at initial floor
  123.  
  124. .-------delay-------.
  125. | |
  126. ?1 V
  127. start --> [A] --inside_trig--> [B] --delay--> [D]
  128. ^ | |
  129. | door_trig |
  130. | | |
  131. | V |
  132. '-----delay------- [C] <---delay---'
  133. */
  134.  
  135. /* self is elevator, self.e[] */
  136.  
  137. self.eState = state;
  138.  
  139. door_trig = self get_housing_door_trigger(); // triggers door interrupt
  140. inside_trig = self get_housing_inside_trigger(); // presence
  141.  
  142. while ( 1 )
  143. {
  144. //state A: rest
  145. if ( self.eState == "[A]" )
  146. {
  147. // ?1: if not resting at initial floor
  148. if ( level.elevator_return && ( self get_curFloor() != self get_initFloor() ) )
  149. {
  150. self.moveto_floor = self get_initFloor();
  151. self thread floor_override( inside_trig );
  152. self waittill_or_timeout( "floor_override", level.elevator_waittime );
  153.  
  154. if ( self.floor_override && isdefined( self.overrider ) && isPlayer( self.overrider ) )
  155. self get_floor( self.overrider );
  156.  
  157. self.eState = "[B]";
  158. continue;
  159. }
  160.  
  161. // wait for player use trigger
  162. while ( 1 )
  163. {
  164. // if elevator already has destination but interrupted, it should continue previous order
  165. if ( self.moveto_floor == self get_curFloor() )
  166. param = inside_trig discrete_waittill( "trigger" );
  167. else
  168. param = "elevator_called"; // as if called onto the destination floor
  169.  
  170. // elevator call hack
  171. if ( isString( param ) && ( param == "elevator_called" ) && ( self.moveto_floor != self get_curFloor() ) )
  172. {
  173. self.eState = "[B]";
  174. break;
  175. }
  176.  
  177. if ( isdefined( param ) && isPlayer( param ) && isAlive( param ) )
  178. {
  179. isTouching_trigger = ( param istouching( inside_trig ) );
  180. isTouching_motion_trigger = ( isdefined( inside_trig.motion_trigger ) && param istouching( inside_trig.motion_trigger ) );
  181. player_isTouching_trigger = ( isTouching_trigger || isTouching_motion_trigger );
  182.  
  183. if ( player_isTouching_trigger )
  184. {
  185. player = param;
  186. self get_floor( player );
  187.  
  188. if ( self.moveto_floor == self get_curFloor() )
  189. continue;
  190.  
  191. self.eState = "[B]";
  192. break;
  193. }
  194. }
  195. }
  196. }
  197.  
  198. //state B: closing doors - interrupt threaded
  199. if ( self.eState == "[B]" )
  200. {
  201. self thread elevator_interrupt( door_trig );
  202. floor_num = self get_curFloor();
  203.  
  204. // call to close doors
  205. self thread close_inner_doors();
  206. self thread close_outer_doors( floor_num );
  207.  
  208. self waittill_any( "closed_inner_doors", "interrupted" ); // Wait for inner doors to close for the safty of our valued customers.
  209.  
  210. if ( self.elevator_interrupted )
  211. {
  212. self.eState = "[C]";
  213. continue;
  214. }
  215.  
  216. self.eState = "[D]";
  217. continue;
  218. }
  219.  
  220. //state C: opening doors
  221. if ( self.eState == "[C]" )
  222. {
  223. floor_num = self get_curFloor();
  224.  
  225. self thread open_inner_doors();
  226. self thread open_outer_doors( floor_num );
  227.  
  228. self waittill( "opened_floor_" + floor_num + "_outer_doors" );
  229.  
  230. if ( self.elevator_interrupted )
  231. {
  232. self.eState = "[B]";
  233. continue;
  234. }
  235.  
  236. self.eState = "[A]";
  237. continue;
  238. }
  239.  
  240. //state D: moving elevator
  241. if ( self.eState == "[D]" )
  242. {
  243. assertex( isdefined( self.moveto_floor ), "Missing destination floor number" );
  244.  
  245. if ( self.moveto_floor != self get_curFloor() )
  246. {
  247. self thread elevator_move( self.moveto_floor );
  248. self waittill( "elevator_moved" );
  249. }
  250.  
  251. self.eState = "[C]";
  252. continue;
  253. }
  254. }
  255. }
  256.  
  257. monitor_callbutton()
  258. {
  259. while ( 1 )
  260. {
  261. // call button used by player
  262. player = self discrete_waittill( "trigger" );
  263.  
  264. call_floor = undefined;
  265. call_elevators = [];
  266. // fake loop, always loop only once
  267. foreach ( idx, linked_elevators in self.e )
  268. {
  269. call_floor = idx;
  270. call_elevators = linked_elevators;
  271. }
  272. assert( isdefined( call_floor ) && isdefined( call_elevators ) && call_elevators.size );
  273.  
  274. elevator_called = 0;
  275.  
  276. // prefilter elevators to see if any already at this floor
  277. foreach ( elevator in call_elevators )
  278. {
  279. moving = elevator elevator_floor_update();
  280.  
  281. // if in non-aggressive mode; this elevator is already stationary at the requested floor, we skip!
  282. if ( !level.elevator_aggressive_call && !moving )
  283. {
  284. if ( elevator get_curFloor() == call_floor )
  285. {
  286. elevator_called = 1;
  287. call_elevators = [];
  288. break;
  289. }
  290. }
  291. }
  292.  
  293. // check all elevators to see if any can be called to this floor
  294. foreach ( elevator in call_elevators )
  295. {
  296. if ( elevator.eState == "[A]" )
  297. {
  298. // call only elevators in a state of rest [A]
  299. elevator call_elevator( call_floor );
  300.  
  301. elevator_called = 1;
  302.  
  303. // aggressive call
  304. if ( !level.elevator_aggressive_call )
  305. break;
  306. }
  307. }
  308.  
  309. if ( elevator_called )
  310. self playsound( "elev_bell_ding" );
  311. }
  312. }
  313.  
  314. call_elevator( call_floor )
  315. {
  316. self.moveto_floor = call_floor;
  317.  
  318. // call elevator via trigger hack
  319. inside_trigger = self get_housing_inside_trigger();
  320. inside_trigger notify( "trigger", "elevator_called" );
  321. if ( level.elevator_motion_detection )
  322. inside_trigger.motion_trigger notify( "trigger", "elevator_called" );
  323. }
  324.  
  325. // opens menu to select floors
  326. get_floor( player )
  327. {
  328. // skips popup menu if only two floors present
  329. bifloor = self get_outer_doorsets();
  330. if ( bifloor.size == 2 )
  331. {
  332. curFloor = self get_curFloor();
  333. self.moveto_floor = !curFloor;
  334. return;
  335. }
  336.  
  337. player openpopupmenu( "elevator_floor_selector" );
  338. player setClientDvar( "player_current_floor", self get_curFloor() );
  339.  
  340. while ( 1 )
  341. {
  342. player waittill( "menuresponse", menu, response );
  343.  
  344. if ( menu == "elevator_floor_selector" )
  345. {
  346. if ( response != "none" )
  347. self.moveto_floor = int( response );
  348.  
  349. break;
  350. }
  351. }
  352. }
  353.  
  354. elevator_interrupt( door_trig )
  355. {
  356. self notify( "interrupt_watch" );
  357. level notify( "elevator_interior_button_pressed" );
  358. self endon( "interrupt_watch" ); // no duplicate interrupts
  359. self endon( "elevator_moving" );
  360.  
  361. self.elevator_interrupted = 0;
  362. wait 0.5;// buffer time to have the door jitter...
  363. door_trig waittill( "trigger", player );
  364.  
  365. /*while ( 1 )
  366. {
  367. wait 0.5; // buffer time to have the door jitter... realisticaly, im serious!
  368.  
  369. door_trig waittill( "trigger", player );
  370. if ( isdefined( player ) && isPlayer( player ) )
  371. break;
  372. }*/
  373.  
  374. self notify( "interrupted" );
  375. self.elevator_interrupted = 1;
  376.  
  377. //self elevator_fsm( "[C]" );
  378. }
  379.  
  380. // returns if elevator is moving, also updates the floor number if not moving
  381. elevator_floor_update()
  382. {
  383. mainframe = self get_housing_mainframe();
  384. cur_pos = mainframe.origin;
  385.  
  386. moving = 1;
  387. foreach ( idx, eFloor in self get_outer_doorsets() )
  388. {
  389. floor_pos = self.e[ "floor" + idx + "_pos" ];
  390. if ( cur_pos == floor_pos )
  391. {
  392. self.e[ "current_floor" ] = idx;
  393. moving = 0;
  394. }
  395. }
  396.  
  397. return moving;
  398. }
  399.  
  400. elevator_sound_think()
  401. {
  402. // self is elevator, self.e[]
  403. // play elevator sounds on notify of behavior
  404.  
  405. // always play musak
  406. musak_model = self get_housing_musak_model();
  407.  
  408. if ( level.elevator_music && isdefined( musak_model ) )
  409. musak_model playloopsound( "elev_musak_loop" );
  410.  
  411. self thread listen_for ( "closing_inner_doors" );
  412. self thread listen_for ( "opening_inner_doors" );
  413. self thread listen_for ( "closed_inner_doors" );
  414. self thread listen_for ( "opened_inner_doors" );
  415.  
  416. foreach ( idx, eFloor in self get_outer_doorsets() )
  417. {
  418. self thread listen_for ( "closing_floor_" + idx + "_outer_doors" );
  419. self thread listen_for ( "opening_floor_" + idx + "_outer_doors" );
  420. self thread listen_for ( "closed_floor_" + idx + "_outer_doors" );
  421. self thread listen_for ( "opened_floor_" + idx + "_outer_doors" );
  422. }
  423.  
  424. self thread listen_for ( "interrupted" );
  425. //self thread listen_for( "interrupt_watch" );
  426. self thread listen_for ( "elevator_moving" );
  427. self thread listen_for ( "elevator_moved" );
  428. }
  429.  
  430. /*
  431. -elev_musak_loop,,music/mx_musak_stolen_elev_proc1.wav,1,1,foley,1,1,120,500,effects1,,,rlooping,,all_mp
  432. -elev_door_open,,events/elev_door_open1.wav,1,1,foley,0.95,1.05,120,2500,voice,,,,,all_mp
  433. -elev_door_close,,events/elev_door_close1.wav,1,1,foley,0.95,1.05,120,2500,voice,,,,,all_mp
  434. -elev_door_interupt,,events/elev_door_interupt1.wav,1,1,foley,0.95,1.05,120,2500,voice,,,,,all_mp
  435. -elev_bell_ding,,events/elev_bell_ding1.wav,1,1,foley,1,1,120,2500,voice,,,,,all_mp
  436. -elev_run_start,,events/elev_run_start01.wav,1,1,foley,1,1,120,500,voice,,,,,all_mp
  437. -elev_run_loop,,events/elev_run_loop01.wav,1,1,foley,1,1,120,500,voice,,,rlooping,,all_mp
  438. -elev_run_end,,events/elev_run_stop01.wav,1,1,foley,1,1,120,500,voice,,,,,all_mp
  439. */
  440.  
  441. listen_for ( msg )
  442. {
  443. while ( 1 )
  444. {
  445. self waittill( msg );
  446. mainframe = self get_housing_mainframe();
  447.  
  448. if ( issubstr( msg, "closing_" ) )
  449. mainframe playsound( "elev_door_close" );
  450.  
  451. if ( issubstr( msg, "opening_" ) )
  452. mainframe playsound( "elev_door_open" );
  453.  
  454. if ( msg == "elevator_moving" )
  455. {
  456. mainframe playsound( "elev_run_start" );
  457. mainframe playloopsound( "elev_run_loop" );
  458. }
  459.  
  460. if ( msg == "interrupted" )
  461. mainframe playsound( "elev_door_interupt" );
  462.  
  463. if ( msg == "elevator_moved" )
  464. {
  465. mainframe stoploopsound( "elev_run_loop" );
  466. mainframe playsound( "elev_run_end" );
  467. mainframe playsound( "elev_bell_ding" );
  468. }
  469.  
  470. //if ( isdefined( level.players[0] ) && level.elevator_debug )
  471. // level.players[0] iprintln( "(e" + self.e[ "id" ] + ") " + msg );
  472. }
  473. }
  474.  
  475. //==========================================================================//
  476. // === MOVEMENTS === //
  477. //==========================================================================//
  478.  
  479. // position elevators
  480. position_elevators()
  481. {
  482. // closing all outer doors on floors elevator isnt at
  483. foreach ( e, elevator in level.elevators )
  484. {
  485. elevator.moveto_floor = elevator get_curFloor();
  486.  
  487. foreach ( floor_num, outer_doorset in elevator get_outer_doorsets() )
  488. {
  489. if ( elevator get_curFloor() != floor_num )
  490. elevator thread close_outer_doors( floor_num );
  491. }
  492. }
  493. }
  494.  
  495. elevator_move( floor_num )
  496. {
  497. // self is elevator, self.e[]
  498. self notify( "elevator_moving" );
  499. self endon( "elevator_moving" );
  500.  
  501. mainframe = self get_housing_mainframe();
  502. delta_vec = self.e[ "floor" + floor_num + "_pos" ] - mainframe.origin;
  503.  
  504. speed = level.elevator_speed;
  505. dist = abs( distance( self.e[ "floor" + floor_num + "_pos" ], mainframe.origin ) );
  506. moveTime = dist / speed;
  507.  
  508. // move housing:
  509. mainframe moveTo( mainframe.origin + delta_vec, moveTime, moveTime * level.elevator_accel, moveTime * level.elevator_decel );
  510.  
  511. // move doors and triggers and other script models
  512. foreach ( part in self get_housing_children() )
  513. {
  514. moveto_pos = part.origin + delta_vec;
  515.  
  516. if ( !issubstr( part.classname, "trigger_" ) )
  517. part moveTo( moveto_pos, moveTime, moveTime * level.elevator_accel, moveTime * level.elevator_decel );
  518. else
  519. part.origin = moveto_pos;
  520. }
  521.  
  522. // making sure elevator housing gets to destination floor
  523. self waittill_finish_moving( mainframe, self.e[ "floor" + floor_num + "_pos" ] );
  524.  
  525. self notify( "elevator_moved" );
  526. }
  527.  
  528. close_inner_doors()
  529. {
  530. // self is elevator set
  531. self notify( "closing_inner_doors" );
  532. self endon( "closing_inner_doors" ); // when interrupted
  533. self endon( "opening_inner_doors" ); // when interrupted
  534.  
  535. left_door = self get_housing_leftdoor(); // ent
  536. right_door = self get_housing_rightdoor(); // ent
  537.  
  538. mainframe = self get_housing_mainframe(); // ent
  539. old_closed_pos = self get_housing_closedpos(); // vec
  540. closed_pos = ( old_closed_pos[ 0 ], old_closed_pos[ 1 ], mainframe.origin[ 2 ] ); // adjusted closed position after floor change
  541.  
  542. speed = level.elevator_innerdoorspeed; // scaler
  543. dist = abs( distance( left_door.origin, closed_pos ) ); // scaler
  544. moveTime = dist / speed; // scaler
  545.  
  546. left_door moveTo( closed_pos, moveTime, moveTime * 0.1, moveTime * 0.25 );
  547. right_door moveTo( closed_pos, moveTime, moveTime * 0.1, moveTime * 0.25 );
  548.  
  549. self waittill_finish_moving( left_door, closed_pos, right_door, closed_pos );
  550. self notify( "closed_inner_doors" );
  551. }
  552.  
  553. open_inner_doors()
  554. {
  555. // self is elevator set
  556. self notify( "opening_inner_doors" );
  557. self endon( "opening_inner_doors" ); // when interrupted
  558.  
  559. left_door = self get_housing_leftdoor(); // ent
  560. right_door = self get_housing_rightdoor(); // ent
  561.  
  562. mainframe = self get_housing_mainframe(); // ent
  563. old_left_opened_pos = self get_housing_leftdoor_opened_pos(); // vec
  564. old_right_opened_pos = self get_housing_rightdoor_opened_pos(); // vec
  565.  
  566. left_opened_pos = ( old_left_opened_pos[ 0 ], old_left_opened_pos[ 1 ], mainframe.origin[ 2 ] );
  567. right_opened_pos = ( old_right_opened_pos[ 0 ], old_right_opened_pos[ 1 ], mainframe.origin[ 2 ] );
  568.  
  569. speed = level.elevator_innerdoorspeed; // scaler
  570. dist = abs( distance( left_opened_pos, right_opened_pos ) * 0.5 ); // scaler
  571. moveTime = ( dist / speed ) * 0.5; // scaler
  572.  
  573. left_door moveTo( left_opened_pos, moveTime, moveTime * 0.1, moveTime * 0.25 );
  574. right_door moveTo( right_opened_pos, moveTime, moveTime * 0.1, moveTime * 0.25 );
  575.  
  576. self waittill_finish_moving( left_door, left_opened_pos, right_door, right_opened_pos );
  577. self notify( "opened_inner_doors" );
  578. }
  579.  
  580. // close outer elevator doors per floor
  581. close_outer_doors( floor_num )
  582. {
  583. // self is elevator set
  584. self notify( "closing_floor_" + floor_num + "_outer_doors" );
  585. self endon( "closing_floor_" + floor_num + "_outer_doors" ); // when interrupted
  586. self endon( "opening_floor_" + floor_num + "_outer_doors" ); // when interrupted
  587.  
  588. left_door = self get_outer_leftdoor( floor_num ); // ent
  589. right_door = self get_outer_rightdoor( floor_num ); // ent
  590.  
  591. left_opened_pos = self get_outer_leftdoor_openedpos( floor_num ); // vec
  592. closed_pos = self get_outer_closedpos( floor_num ); // vec
  593.  
  594. speed = level.elevator_outterdoorspeed; // scaler
  595. dist = abs( distance( left_opened_pos, closed_pos ) ); // scaler
  596. moveTime = dist / speed; // scaler
  597.  
  598. left_door moveTo( closed_pos, moveTime, moveTime * 0.1, moveTime * 0.25 );
  599. right_door moveTo( closed_pos, moveTime, moveTime * 0.1, moveTime * 0.25 );
  600.  
  601. self waittill_finish_moving( left_door, closed_pos, right_door, closed_pos );
  602. self notify( "closed_floor_" + floor_num + "_outer_doors" );
  603. }
  604.  
  605. // open outer elevator doors per floor
  606. open_outer_doors( floor_num )
  607. {
  608. // self is elevator set
  609. level notify( "elevator_doors_opening" );
  610. self notify( "opening_floor_" + floor_num + "_outer_doors" );
  611. self endon( "opening_floor_" + floor_num + "_outer_doors" ); // when interrupted
  612.  
  613. left_door = self get_outer_leftdoor( floor_num ); // ent
  614. right_door = self get_outer_rightdoor( floor_num ); // ent
  615.  
  616. left_opened_pos = self get_outer_leftdoor_openedpos( floor_num ); // vec
  617. right_opened_pos = self get_outer_rightdoor_openedpos( floor_num ); // vec
  618. closed_pos = self get_outer_closedpos( floor_num ); // vec
  619.  
  620. speed = level.elevator_outterdoorspeed; // scaler
  621. dist = abs( distance( left_opened_pos, closed_pos ) ); // scaler
  622. moveTime = ( dist / speed ) * 0.5; // scaler
  623.  
  624. left_door moveTo( left_opened_pos, moveTime, moveTime * 0.1, moveTime * 0.25 );
  625. right_door moveTo( right_opened_pos, moveTime, moveTime * 0.1, moveTime * 0.25 );
  626.  
  627. self waittill_finish_moving( left_door, left_opened_pos, right_door, right_opened_pos );
  628. self notify( "opened_floor_" + floor_num + "_outer_doors" );
  629. }
  630.  
  631. //==========================================================================//
  632. // === BUILD ELEVATORS === //
  633. //==========================================================================//
  634.  
  635. // builds elevators into 'level.elevators' struct array containing parts list
  636. build_elevators()
  637. {
  638. // triggers that enclose elevator, to distinguish between elevators
  639. elevator_groups = getentarray( "elevator_group", "targetname" );
  640. assertex( isdefined( elevator_groups ) && ( elevator_groups.size ), "Radiant: Missing elevator bounding origins" );
  641.  
  642. elevator_housings = getentarray( "elevator_housing", "targetname" );
  643. assertex( isdefined( elevator_housings ) && ( elevator_housings.size >= elevator_groups.size ), "Fail! Missing the whole elevator, script_brushmodel with [targetname = elevator_housing] must be correctly placed" );
  644.  
  645. // sets of elevator outter door prefabs placed
  646. elevator_doorsets = getentarray( "elevator_doorset", "targetname" );
  647. assertex( isdefined( elevator_doorsets ) && ( elevator_doorsets.size >= elevator_groups.size ), "Radiant: Missing elevator door(s)" );
  648.  
  649. // build found elevators
  650. foreach ( elevator_bound in elevator_groups )
  651. {
  652. elevator_bound_end = getent( elevator_bound.target, "targetname" );
  653.  
  654. min_max_xy = [];
  655. min_max_xy[ 0 ] = min( elevator_bound.origin[ 0 ], elevator_bound_end.origin[ 0 ] );// min_x
  656. min_max_xy[ 1 ] = max( elevator_bound.origin[ 0 ], elevator_bound_end.origin[ 0 ] );// max_x
  657. min_max_xy[ 2 ] = min( elevator_bound.origin[ 1 ], elevator_bound_end.origin[ 1 ] );// min_y
  658. min_max_xy[ 3 ] = max( elevator_bound.origin[ 1 ], elevator_bound_end.origin[ 1 ] );// max_y
  659.  
  660. parts = spawnstruct();
  661. parts.e[ "id" ] = level.elevators.size;
  662.  
  663. // === build elevator housing ===
  664. /*
  665. Elevator's mainframe brushmodel
  666.  
  667. script_brushmodel targeting:
  668. "elevator_housing" -> left door -> right door -> door trigger -> inside trigger
  669.  
  670. Housing is the body that moves between floors
  671. */
  672. parts.e[ "housing" ] = [];
  673. parts.e[ "housing" ][ "mainframe" ] = [];
  674.  
  675. foreach ( elevator_housing in elevator_housings )
  676. {
  677. if ( elevator_housing isInbound( min_max_xy ) )
  678. {
  679. parts.e[ "housing" ][ "mainframe" ][ parts.e[ "housing" ][ "mainframe" ].size ] = elevator_housing;
  680.  
  681. if ( elevator_housing.classname == "script_model" )
  682. continue;
  683.  
  684. if ( elevator_housing.code_classname == "light" )
  685. continue;
  686.  
  687. inner_leftdoor = getent( elevator_housing.target, "targetname" );
  688. parts.e[ "housing" ][ "left_door" ] = inner_leftdoor;
  689. parts.e[ "housing" ][ "left_door_opened_pos" ] = inner_leftdoor.origin;
  690.  
  691. inner_rightdoor = getent( inner_leftdoor.target, "targetname" );
  692. parts.e[ "housing" ][ "right_door" ] = inner_rightdoor;
  693. parts.e[ "housing" ][ "right_door_opened_pos" ] = inner_rightdoor.origin;
  694.  
  695. inner_door_closed_pos = ( inner_leftdoor.origin - inner_rightdoor.origin ) * ( 0.5, 0.5, 0.5 ) + inner_rightdoor.origin;
  696. parts.e[ "housing" ][ "door_closed_pos" ] = inner_door_closed_pos;
  697.  
  698. door_trigger = getent( inner_rightdoor.target, "targetname" );
  699. parts.e[ "housing" ][ "door_trigger" ] = door_trigger;
  700.  
  701. inside_trigger = getent( door_trigger.target, "targetname" );
  702. parts.e[ "housing" ][ "inside_trigger" ] = inside_trigger;
  703. inside_trigger make_discrete_trigger();
  704.  
  705. // for motion triggers
  706. inside_trigger.motion_trigger = spawn( "trigger_radius", elevator_housing.origin, 0, 64, 128 );
  707. assert( isdefined( inside_trigger.motion_trigger ) );
  708. }
  709. }
  710. assert( isdefined( parts.e[ "housing" ] ) );
  711.  
  712. // === build elevator outer doorsets ===
  713. /*
  714. Elevator's outer door sets ( per floor ) are chained together from a script_origin
  715. targeting to the left door, then left door targets to right door
  716.  
  717. Outer door sets are bodies that only moves to open/close
  718. */
  719. parts.e[ "outer_doorset" ] = [];
  720. foreach ( elevator_doorset in elevator_doorsets )
  721. {
  722. if ( elevator_doorset isInbound( min_max_xy ) )
  723. {
  724.  
  725. // closed for lighting is for compiling lighting in the closed position rather than the open position.
  726. door_starts_closed = isdefined( elevator_doorset.script_noteworthy ) && elevator_doorset.script_noteworthy == "closed_for_lighting";
  727.  
  728. door_set_id = parts.e[ "outer_doorset" ].size;
  729.  
  730. parts.e[ "outer_doorset" ][ door_set_id ] = [];
  731. parts.e[ "outer_doorset" ][ door_set_id ][ "door_closed_pos" ] = elevator_doorset.origin;
  732.  
  733. leftdoor = getent( elevator_doorset.target, "targetname" );
  734. parts.e[ "outer_doorset" ][ door_set_id ][ "left_door" ] = leftdoor;
  735. parts.e[ "outer_doorset" ][ door_set_id ][ "left_door_opened_pos" ] = leftdoor.origin;
  736.  
  737. rightdoor = getent( leftdoor.target, "targetname" );
  738. parts.e[ "outer_doorset" ][ door_set_id ][ "right_door" ] = rightdoor;
  739. parts.e[ "outer_doorset" ][ door_set_id ][ "right_door_opened_pos" ] = rightdoor.origin;
  740.  
  741. //put them back into the would be positions
  742. if( door_starts_closed )
  743. {
  744. left_door_vec = elevator_doorset.origin - leftdoor.origin;
  745. elevator_doorset.origin = leftdoor.origin;
  746. leftdoor.origin += left_door_vec;
  747. rightdoor.origin -= left_door_vec;
  748. parts.e[ "outer_doorset" ][ door_set_id ][ "door_closed_pos" ] = elevator_doorset.origin;
  749. parts.e[ "outer_doorset" ][ door_set_id ][ "left_door_opened_pos" ] = leftdoor.origin;
  750. parts.e[ "outer_doorset" ][ door_set_id ][ "right_door_opened_pos" ] = rightdoor.origin;
  751. }
  752. }
  753. }
  754. assert( isdefined( parts.e[ "outer_doorset" ] ) );
  755.  
  756. // bubble sort floors
  757. for ( i = 0; i < parts.e[ "outer_doorset" ].size - 1; i++ )
  758. {
  759. for ( j = 0; j < parts.e[ "outer_doorset" ].size - 1 - i; j++ )
  760. {
  761. if ( parts.e[ "outer_doorset" ][ j + 1 ][ "door_closed_pos" ][ 2 ] < parts.e[ "outer_doorset" ][ j ][ "door_closed_pos" ][ 2 ] )
  762. {
  763. //swap j-1 with j
  764. temp_left_door = parts.e[ "outer_doorset" ][ j ][ "left_door" ];
  765. temp_left_door_opened_pos = parts.e[ "outer_doorset" ][ j ][ "left_door_opened_pos" ];
  766. temp_right_door = parts.e[ "outer_doorset" ][ j ][ "right_door" ];
  767. temp_right_door_opened_pos = parts.e[ "outer_doorset" ][ j ][ "right_door_opened_pos" ];
  768. temp_closed_pos = parts.e[ "outer_doorset" ][ j ][ "door_closed_pos" ];
  769.  
  770. parts.e[ "outer_doorset" ][ j ][ "left_door" ] = parts.e[ "outer_doorset" ][ j + 1 ][ "left_door" ];
  771. parts.e[ "outer_doorset" ][ j ][ "left_door_opened_pos" ] = parts.e[ "outer_doorset" ][ j + 1 ][ "left_door_opened_pos" ];
  772. parts.e[ "outer_doorset" ][ j ][ "right_door" ] = parts.e[ "outer_doorset" ][ j + 1 ][ "right_door" ];
  773. parts.e[ "outer_doorset" ][ j ][ "right_door_opened_pos" ] = parts.e[ "outer_doorset" ][ j + 1 ][ "right_door_opened_pos" ];
  774. parts.e[ "outer_doorset" ][ j ][ "door_closed_pos" ] = parts.e[ "outer_doorset" ][ j + 1 ][ "door_closed_pos" ];
  775.  
  776. parts.e[ "outer_doorset" ][ j + 1 ][ "left_door" ] = temp_left_door;
  777. parts.e[ "outer_doorset" ][ j + 1 ][ "left_door_opened_pos" ] = temp_left_door_opened_pos;
  778. parts.e[ "outer_doorset" ][ j + 1 ][ "right_door" ] = temp_right_door;
  779. parts.e[ "outer_doorset" ][ j + 1 ][ "right_door_opened_pos" ] = temp_right_door_opened_pos;
  780. parts.e[ "outer_doorset" ][ j + 1 ][ "door_closed_pos" ] = temp_closed_pos;
  781. }
  782. }
  783. }
  784.  
  785. // === build elevator floor pos ===
  786. floor_pos = [];
  787. foreach ( i, doorset in parts.e[ "outer_doorset" ] )
  788. {
  789. mainframe = parts get_housing_mainframe();
  790.  
  791. floor_pos = ( mainframe.origin[ 0 ], mainframe.origin[ 1 ], doorset[ "door_closed_pos" ][ 2 ] );
  792. parts.e[ "floor" + i + "_pos" ] = floor_pos;
  793.  
  794. if ( mainframe.origin == floor_pos )
  795. {
  796. parts.e[ "initial_floor" ] = i;
  797. parts.e[ "current_floor" ] = i;
  798. }
  799. }
  800.  
  801. // === save build info ===
  802. level.elevators[ level.elevators.size ] = parts;
  803.  
  804. // trash all script origins no longer needed
  805. elevator_bound delete();
  806. elevator_bound_end delete();
  807. }
  808. foreach ( elevator_doorset in elevator_doorsets )
  809. elevator_doorset delete();
  810.  
  811. build_call_buttons();
  812.  
  813. if ( !level.elevator_motion_detection )
  814. setup_hints();
  815.  
  816. // turn on all primary lights for elevators if they have em
  817. foreach ( elevator in level.elevators )
  818. {
  819. pLights = elevator get_housing_primarylight();
  820. if ( isdefined( pLights ) && pLights.size )
  821. {
  822. foreach ( pLight in pLights )
  823. pLight setlightintensity( 0.75 );
  824. }
  825. }
  826. }
  827.  
  828. build_call_buttons()
  829. {
  830. level.elevator_callbuttons = getentarray( "elevator_call", "targetname" );
  831. assertex( isdefined( level.elevator_callbuttons ) && ( level.elevator_callbuttons.size > 1 ), "Missing or not enough elevator call buttons" );
  832.  
  833. // per call button
  834. foreach ( callbutton in level.elevator_callbuttons )
  835. {
  836. callbutton.e = [];
  837. callbutton_v_vec = ( 0, 0, callbutton.origin[ 2 ] );
  838. callbutton_h_vec = ( callbutton.origin[ 0 ], callbutton.origin[ 1 ], 0 );
  839.  
  840. temp_elevator_list = [];
  841. // per elevator
  842. foreach ( e_idx, elevator in level.elevators )
  843. {
  844. // per floor
  845. foreach ( f_idx, eFloor in elevator get_outer_doorsets() )
  846. {
  847. v_vec = ( 0, 0, elevator.e[ "floor" + f_idx + "_pos" ][ 2 ] );
  848. h_vec = ( elevator.e[ "floor" + f_idx + "_pos" ][ 0 ], elevator.e[ "floor" + f_idx + "_pos" ][ 1 ], 0 );
  849.  
  850. if ( abs( distance( callbutton_v_vec, v_vec ) ) <= level.elevator_callbutton_link_v )
  851. {
  852. if ( abs( distance( callbutton_h_vec, h_vec ) ) <= level.elevator_callbutton_link_h )
  853. {
  854. temp_elevator_list[ temp_elevator_list.size ] = elevator; // build list of elevators linked on floor f_idx
  855. callbutton.e[ f_idx ] = temp_elevator_list;
  856. }
  857. }
  858. }
  859. }
  860. callbutton make_discrete_trigger();
  861. assertex( isdefined( callbutton.e ) && callbutton.e.size, "Elevator call button at " + callbutton.origin + " failed to grab near by elevators, placed too far?" );
  862.  
  863. // build motion detection triggers for motion triggered calls
  864. callbutton.motion_trigger = spawn( "trigger_radius", callbutton.origin + ( 0, 0, -32 ), 0, 32, 64 );
  865. }
  866. }
  867.  
  868. setup_hints()
  869. {
  870. // elevator inside use trigger hint
  871. foreach ( elevator in level.elevators )
  872. {
  873. use_trig = elevator get_housing_inside_trigger();
  874. floors = elevator get_outer_doorsets();
  875. num_of_floors = floors.size;
  876.  
  877. use_trig SetCursorHint( "HINT_NOICON" );
  878. if ( num_of_floors > 2 )
  879. // Press and hold &&1 to select floor.
  880. use_trig setHintString( &"ELEVATOR_FLOOR_SELECT_HINT" );
  881. else
  882. // Press and hold &&1 to use elevator.
  883. use_trig setHintString( &"ELEVATOR_USE_HINT" );
  884. }
  885.  
  886. // elevator call button hint
  887. foreach ( callbutton in level.elevator_callbuttons )
  888. {
  889. callbutton SetCursorHint( "HINT_NOICON" );
  890. // Press and hold &&1 to call elevator.
  891. callbutton setHintString( &"ELEVATOR_CALL_HINT" );
  892. }
  893. }
  894.  
  895. //==========================================================================//
  896. // === HELPERS === //
  897. //==========================================================================//
  898.  
  899. // setup discrete trigger for discrete waittill
  900. make_discrete_trigger()
  901. {
  902. self.enabled = 1; // enable now for disabling trigger
  903. self disable_trigger(); // disable trigger, enable again only when waittill on
  904. }
  905.  
  906. // trigger only exist when waittill upon
  907. discrete_waittill( msg )
  908. {
  909. assert( isdefined( self.motion_trigger ) );
  910.  
  911. self enable_trigger(); // this is for disabling trigger immediately after triggering
  912.  
  913. if ( level.elevator_motion_detection )
  914. self.motion_trigger waittill( msg, param );
  915. else
  916. self waittill( msg, param );
  917.  
  918. self disable_trigger();
  919. return param;
  920. }
  921.  
  922.  
  923. enable_trigger()
  924. {
  925. if ( !self.enabled )
  926. {
  927. self.enabled = 1;
  928. self.origin += ( 0, 0, 10000 );
  929.  
  930. if ( isdefined( self.motion_trigger ) )
  931. self.motion_trigger.origin += ( 0, 0, 10000 );
  932. }
  933. }
  934.  
  935. disable_trigger()
  936. {
  937. self notify( "disable_trigger" );
  938. if ( self.enabled )
  939. self thread disable_trigger_helper();
  940. }
  941.  
  942. disable_trigger_helper()
  943. {
  944. self endon( "disable_trigger" );
  945. self.enabled = 0;
  946. wait 1.5;
  947. self.origin += ( 0, 0, -10000 );
  948.  
  949. if ( isdefined( self.motion_trigger ) )
  950. self.motion_trigger.origin += ( 0, 0, -10000 );
  951. }
  952.  
  953. // ========== OUTER DOOR SETS ===========
  954. // returns array of outer doorsets for this floor - ent[]
  955. get_outer_doorset( floor_num )
  956. {
  957. return self.e[ "outer_doorset" ][ floor_num ];
  958. }
  959.  
  960. // returns array of floors of doorsets - int[]
  961. get_outer_doorsets()
  962. {
  963. return self.e[ "outer_doorset" ];
  964. }
  965.  
  966. // returns outer door closed position for this floor - vec
  967. get_outer_closedpos( floor_num )
  968. {
  969. return self.e[ "outer_doorset" ][ floor_num ][ "door_closed_pos" ];
  970. }
  971.  
  972. // returns left door entity for this floor - ent
  973. get_outer_leftdoor( floor_num )
  974. {
  975. return self.e[ "outer_doorset" ][ floor_num ][ "left_door" ];
  976. }
  977.  
  978. // returns right door entity for this floor - ent
  979. get_outer_rightdoor( floor_num )
  980. {
  981. return self.e[ "outer_doorset" ][ floor_num ][ "right_door" ];
  982. }
  983.  
  984. // returns left door opened position for this floor - vec
  985. get_outer_leftdoor_openedpos( floor_num )
  986. {
  987. return self.e[ "outer_doorset" ][ floor_num ][ "left_door_opened_pos" ];
  988. }
  989.  
  990. // returns right door opened position for this floor - vec
  991. get_outer_rightdoor_openedpos( floor_num )
  992. {
  993. return self.e[ "outer_doorset" ][ floor_num ][ "right_door_opened_pos" ];
  994. }
  995.  
  996. // ========= HOUSING =========
  997. // returns all the entities that will move when the elevator moves between floors - ent[]
  998. get_housing_children()
  999. {
  1000. children = [];
  1001.  
  1002. door_trig = self get_housing_door_trigger();
  1003. use_trig = self get_housing_inside_trigger();
  1004. motion_trig = use_trig.motion_trigger;
  1005. left_door = self get_housing_leftdoor();
  1006. right_door = self get_housing_rightdoor();
  1007.  
  1008. children[ children.size ] = door_trig;
  1009. children[ children.size ] = use_trig;
  1010. children[ children.size ] = left_door;
  1011. children[ children.size ] = right_door;
  1012.  
  1013. if ( isdefined( motion_trig ) )
  1014. children[ children.size ] = motion_trig;
  1015.  
  1016. // append script models as children of elevator moving body
  1017. script_models = self get_housing_models();
  1018. foreach ( eModel in script_models )
  1019. children[ children.size ] = eModel;
  1020.  
  1021. // append primary light(s) as children of elevator moving body
  1022. primarylights = get_housing_primarylight();
  1023. foreach ( pLight in primarylights )
  1024. children[ children.size ] = pLight;
  1025.  
  1026. return children;
  1027. }
  1028.  
  1029. // returns only the mainframe script_brushmodel, there can only be one per elevator! - ent
  1030. get_housing_mainframe()
  1031. {
  1032. parts = self.e[ "housing" ][ "mainframe" ];
  1033.  
  1034. housing_model = undefined;
  1035. foreach ( part in parts )
  1036. {
  1037. if ( part.classname != "script_model" && part.code_classname != "light" )
  1038. {
  1039. assertex( !isdefined( housing_model ), "Fail! Found more than one elevator housing script_brushmodels per elevator" );
  1040. housing_model = part;
  1041. }
  1042. }
  1043. assertex( isdefined( housing_model ), "Epic fail! No elevator housing script_brushmodel found" );
  1044. return housing_model;
  1045. }
  1046.  
  1047. // returns an array of script_models used as part of the elevator prefab - ent[]
  1048. get_housing_models()
  1049. {
  1050. parts = self.e[ "housing" ][ "mainframe" ];
  1051. temp_model_array = [];
  1052.  
  1053. foreach ( part in parts )
  1054. {
  1055. if ( part.classname == "script_model" )
  1056. temp_model_array[ temp_model_array.size ] = part;
  1057. }
  1058. return temp_model_array;
  1059. }
  1060.  
  1061. // returns an array of lights - ent[]
  1062. get_housing_primarylight()
  1063. {
  1064. parts = self.e[ "housing" ][ "mainframe" ];
  1065. temp_primarylights = [];
  1066.  
  1067. foreach ( part in parts )
  1068. {
  1069. if ( part.code_classname == "light" )
  1070. temp_primarylights[ temp_primarylights.size ] = part;
  1071. }
  1072. return temp_primarylights;
  1073. }
  1074.  
  1075. // returns a single model to play elevator music on, this must exist and only one! - ent
  1076. get_housing_musak_model()
  1077. {
  1078. models = self get_housing_models();
  1079. musak_model = undefined;
  1080.  
  1081. foreach ( eModel in models )
  1082. {
  1083. if ( isdefined( eModel.script_noteworthy ) && eModel.script_noteworthy == "play_musak" )
  1084. musak_model = eModel;
  1085. }
  1086. //assertex( isdefined( musak_model ), "Fail! Missing script_model to play elevator music on, [script_noteworthy = play_musak]" );
  1087.  
  1088. return musak_model;
  1089. }
  1090.  
  1091. // returns interrupt trigger for elevator doors - ent trig
  1092. get_housing_door_trigger()
  1093. {
  1094. return self.e[ "housing" ][ "door_trigger" ];
  1095. }
  1096.  
  1097. // returns trigger for floor selection inside the elevator - ent trig
  1098. get_housing_inside_trigger()
  1099. {
  1100. return self.e[ "housing" ][ "inside_trigger" ];
  1101. }
  1102.  
  1103. // returns inner door's closing position - vec
  1104. get_housing_closedpos()
  1105. {
  1106. return self.e[ "housing" ][ "door_closed_pos" ];
  1107. }
  1108.  
  1109. // returns inner left door entity - ent
  1110. get_housing_leftdoor()
  1111. {
  1112. return self.e[ "housing" ][ "left_door" ];
  1113. }
  1114.  
  1115. // returns inner right door entity - ent
  1116. get_housing_rightdoor()
  1117. {
  1118. return self.e[ "housing" ][ "right_door" ];
  1119. }
  1120.  
  1121. // returns inner left door opened position - vec
  1122. get_housing_leftdoor_opened_pos()
  1123. {
  1124. return self.e[ "housing" ][ "left_door_opened_pos" ];
  1125. }
  1126.  
  1127. // returns inner right door opened position - vec
  1128. get_housing_rightdoor_opened_pos()
  1129. {
  1130. return self.e[ "housing" ][ "right_door_opened_pos" ];
  1131. }
  1132.  
  1133. // floor currently the elevator is on - int
  1134. get_curFloor()
  1135. {
  1136. moving = self elevator_floor_update();
  1137. return self.e[ "current_floor" ];
  1138. }
  1139.  
  1140. // floor elevator initially at on level load - int
  1141. get_initFloor()
  1142. {
  1143. return self.e[ "initial_floor" ];
  1144. }
  1145.  
  1146. waittill_finish_moving( ent1, ent1_moveto_pos, ent2, ent2_moveto_pos )
  1147. {
  1148. if ( !isdefined( ent2 ) && !isdefined( ent2_moveto_pos ) )
  1149. {
  1150. ent2 = ent1;
  1151. ent2_moveto_pos = ent1_moveto_pos;
  1152. }
  1153.  
  1154. while ( 1 )
  1155. {
  1156. ent1_current_pos = ent1.origin;
  1157. etn2_current_pos = ent2.origin;
  1158.  
  1159. if ( ent1_current_pos == ent1_moveto_pos && etn2_current_pos == ent2_moveto_pos )
  1160. break;
  1161.  
  1162. wait 0.05;
  1163. }
  1164. }
  1165.  
  1166. // return test of min max bound on xy plane, self = entity being tested - bool
  1167. isInbound( bounding_box )
  1168. {
  1169.  
  1170. assertex( isdefined( self ) && isdefined( self.origin ), "Fail! Can not test bounds with the entity called on" );
  1171.  
  1172. // the box isn't working on the angle that I have so I'm going to do it by a sphere shape.. -Nate
  1173. //special case cause I don't know if a sphere will break other levels.
  1174. if( level.script == "plaza" || level.script == "highrise_test" )
  1175. return isInBoundingSpere( bounding_box );
  1176.  
  1177. v_x = self.origin[ 0 ];
  1178. v_y = self.origin[ 1 ];
  1179.  
  1180. min_x = bounding_box[ 0 ];
  1181. max_x = bounding_box[ 1 ];
  1182. min_y = bounding_box[ 2 ];
  1183. max_y = bounding_box[ 3 ];
  1184.  
  1185. return ( v_x >= min_x && v_x <= max_x && v_y >= min_y && v_y <= max_y );
  1186. }
  1187.  
  1188. isInBoundingSpere( bounding_box )
  1189. {
  1190. v_x = self.origin[ 0 ];
  1191. v_y = self.origin[ 1 ];
  1192. min_x = bounding_box[ 0 ];
  1193. max_x = bounding_box[ 1 ];
  1194. min_y = bounding_box[ 2 ];
  1195. max_y = bounding_box[ 3 ];
  1196.  
  1197. mid_x = (min_x + max_x )/2;
  1198. mid_y = (min_y + max_y )/2;
  1199. radius = abs( Distance( (min_x,min_y,0 ), (mid_x,mid_y,0)) );
  1200. return( abs( distance( (v_x,v_y,0), (mid_x,mid_y,0) ) ) < radius );
  1201. }
  1202.  
  1203. waittill_or_timeout( msg, timer )
  1204. {
  1205. self endon( msg );
  1206. wait( timer );
  1207. }
  1208.  
  1209. elevator_get_dvar_int( dvar, def )
  1210. {
  1211. return int( elevator_get_dvar( dvar, def ) );
  1212. }
  1213.  
  1214. elevator_get_dvar( dvar, def )
  1215. {
  1216. if ( getdvar( dvar ) != "" )
  1217. return getdvarfloat( dvar );
  1218. else
  1219. {
  1220. setdvar( dvar, def );
  1221. return def;
  1222. }
  1223. }
  1224.  
  1225. elevator_debug()
  1226. {
  1227. if ( !level.elevator_debug )
  1228. return;
  1229.  
  1230. //print3d(<origin>, <text>, <color>, <alpha>, <scale>, <duration> )
  1231.  
  1232. while ( 1 )
  1233. {
  1234. // simple debug info:
  1235.  
  1236. if ( level.elevator_debug != 2 )
  1237. continue;
  1238.  
  1239. // full debug info:
  1240.  
  1241. // print all parts for all elevators
  1242. foreach ( i, elevator in level.elevators )
  1243. {
  1244. mainframe = elevator get_housing_mainframe();
  1245. musak_model = elevator get_housing_musak_model();
  1246.  
  1247. print3d( musak_model.origin, "[e" + i + "]musak_origin", ( 0.75, 0.75, 1.0 ), 1, 0.25, 20 );
  1248. print3d( mainframe.origin, "[e" + i + "]mainframe", ( 0.75, 0.75, 1.0 ), 1, 0.25, 20 );
  1249. print3d( elevator.e[ "housing" ][ "left_door" ].origin, "[e" + i + "]left door", ( 0.75, 0.75, 1.0 ), 1, 0.25, 20 );
  1250. print3d( elevator.e[ "housing" ][ "right_door" ].origin, "[e" + i + "]right door", ( 0.75, 0.75, 1.0 ), 1, 0.25, 20 );
  1251. print3d( elevator.e[ "housing" ][ "door_closed_pos" ], "[e" + i + "]->|<-", ( 0.75, 0.75, 1.0 ), 1, 0.25, 20 );
  1252. print3d( elevator.e[ "housing" ][ "inside_trigger" ].origin, "[e" + i + "]USE", ( 0.75, 0.75, 1.0 ), 1, 0.25, 20 );
  1253.  
  1254. foreach ( j, eFloor in elevator.e[ "outer_doorset" ] )
  1255. {
  1256. print3d( eFloor[ "left_door" ].origin + ( 0, 0, 8 ), "[e" + i + "][f" + j + "]left door", ( 0.75, 1.0, 0.75 ), 1, 0.25, 20 );
  1257. print3d( eFloor[ "right_door" ].origin + ( 0, 0, 8 ), "[e" + i + "][f" + j + "]right door", ( 0.75, 1.0, 0.75 ), 1, 0.25, 20 );
  1258. print3d( eFloor[ "door_closed_pos" ] + ( 0, 0, 8 ), "[e" + i + "][f" + j + "]->|<-", ( 0.75, 1.0, 0.75 ), 1, 0.25, 20 );
  1259. print3d( elevator.e[ "floor" + j + "_pos" ] + ( 0, 0, 8 ), "[e" + i + "][f" + j + "]stop", ( 1.0, 0.75, 0.75 ), 1, 0.25, 20 );
  1260. }
  1261. }
  1262.  
  1263. // per button
  1264. foreach ( callbutton in level.elevator_callbuttons )
  1265. {
  1266. print3d( callbutton.origin, "linked to:", ( 0.75, 0.75, 1.0 ), 1, 0.25, 20 );
  1267.  
  1268. // per floor
  1269. foreach ( f_idx, eFloor in callbutton.e )
  1270. {
  1271. // per elevator linked
  1272. printoffset = 0;
  1273. foreach ( e_idx, eLinked in eFloor )
  1274. {
  1275. printoffset++ ;
  1276. // e_idx is used to offset print
  1277. print_pos = callbutton.origin + ( 0, 0, ( printoffset ) * ( -4 ) );
  1278. print3d( print_pos, "[f" + f_idx + "][e" + eLinked.e[ "id" ] + "]", ( 0.75, 0.75, 1.0 ), 1, 0.25, 20 );
  1279. }
  1280. }
  1281. }
  1282.  
  1283. wait 0.05;
  1284. }
  1285. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement