namespace map_alphalabs3 { #define CRANE_NONE 0 #define CRANE_FORWARD 1 #define CRANE_BACK 2 #define CRANE_LEFT 3 #define CRANE_RIGHT 4 #define CRANE_UP 5 #define CRANE_DOWN 6 #define CRANE_DROP 7 #define CRANE_PICKUP 8 #define CRANE_TRANSFER 9 vector crane_mins = '2072 -56 -184'; vector crane_maxs = '2352 296 -48'; vector crane_pos; float command = CRANE_NONE; float bad_object_count = 0; // How many bad objects have we disposed of so far ? float crane_have_object = false; // Is the crane currently holding an object ? float crane_light_state = false; entity bindEntity; entity laserEntity; entity tracestopEntity; /*********************************************************************** Sounds ***********************************************************************/ void cache_crane_sounds() { sys.cacheSoundShader( "al3_crane_fingers_open" ); sys.cacheSoundShader( "al3_crane_fingers_close" ); sys.cacheSoundShader( "al3_crane_loop" ); sys.cacheSoundShader( "al3_crane_end" ); sys.cacheSoundShader( "al3_crane_updown_loop" ); sys.cacheSoundShader( "al3_crane_updown_end" ); } void sound_crane_fingers_open() { $crane.startSoundShader ("al3_crane_fingers_open", SND_CHANNEL_VOICE2 ); } void sound_crane_fingers_close() { $crane.startSoundShader ("al3_crane_fingers_close", SND_CHANNEL_VOICE2 ); } void sound_crane_loop() { $crane_carrier.startSoundShader ("al3_crane_loop", SND_CHANNEL_VOICE2 ); } void sound_crane_stop() { $crane_carrier.startSoundShader ("al3_crane_end", SND_CHANNEL_VOICE2 ); } void sound_crane_updown_loop() { $crane_carrier.startSoundShader ("al3_crane_updown_loop", SND_CHANNEL_VOICE2 ); } void sound_crane_updown_end() { $crane_carrier.startSoundShader ("al3_crane_updown_end", SND_CHANNEL_VOICE2 ); } /*********************************************************************** Crane ***********************************************************************/ /* ============ update_laser updates laser color and checks if we can pick up an object ============ */ void update_laser() { vector begin = $crane_trace_start.getWorldOrigin(); vector send = $crane_stoptrace_end.getWorldOrigin(); vector lend = $laser_trace_end.getWorldOrigin(); sys.trace( begin, send, '0 0 0', '0 0 0', MASK_SOLID|CONTENTS_RENDERMODEL, $crane_hang ); tracestopEntity = sys.getTraceEntity(); sys.trace( begin, lend, '0 0 0', '0 0 0', MASK_SOLID|CONTENTS_RENDERMODEL, $crane_hang ); laserEntity = sys.getTraceEntity(); if ( !( !laserEntity ) && ( laserEntity != $world ) ) { // can't move down further once the laser detects an object if ( !( !tracestopEntity ) && ( tracestopEntity != $world ) && ( command == CRANE_DOWN ) ) { command = CRANE_NONE; } if ( !crane_light_state ) { $crane_light.setColor( .9, .25, .25 ); $cg_right.setGuiParm ( "gui_parm1" , 1); $cg_left.setGuiParm ( "gui_parm1" , 1); sys.trigger( $crane_speaker ); crane_light_state = true; } } else if ( crane_light_state ) { $crane_light.setColor( .2, .8, .9 ); $cg_right.setGuiParm ( "gui_parm1" , 0); $cg_left.setGuiParm ( "gui_parm1" , 0); sys.trigger( $crane_speaker ); crane_light_state = false; } } /* ============ crane_move ============ */ void crane_move( entity part, float dir, float amount, float stopOnCommand ) { float cmd; if ( amount < 0.01 ) { return; } if ( ( dir == UP ) || ( dir == DOWN ) ) { sound_crane_updown_loop(); } else { sound_crane_loop(); } part.move( dir, amount ); if ( !stopOnCommand ) { sys.waitFor( part ); } else { cmd = command; while( command == cmd ) { sys.waitFrame(); update_laser(); if ( !part.isMoving() ) { break; } } part.stopMoving(); } if ( ( dir == UP ) || ( dir == DOWN ) ) { sound_crane_updown_end(); } else { sound_crane_stop(); } crane_pos = $crane_position.getWorldOrigin(); } /* ============ crane_cmd_drop unbind and open the claw ============ */ void crane_cmd_drop() { sound_crane_fingers_open(); $crane.setFingerAngle( -60 ); bindEntity.unbind(); bindEntity = $null_entity; crane_have_object = false; update_laser(); $main_control_gui.setGuiParm ( "gui_parm1" , 0); } /* ============ crane_pickup close the claw and bind ============ */ void crane_cmd_pickup() { vector begin, end; string bindJoint, bindBody; if ( !( !bindEntity ) ) { return; } crane_have_object = false; bindJoint = bindBody = ""; sound_crane_fingers_close(); $crane.setFingerAngle( 20 ); sys.wait( 2.0f ); $crane.stopFingers(); begin = $crane_trace_start.getWorldOrigin(); end = $crane_trace_end.getWorldOrigin(); sys.trace( begin, end, '0 0 0', '0 0 0', MASK_SOLID|CONTENTS_RENDERMODEL, $crane_hang ); bindEntity = sys.getTraceEntity(); if ( !( !bindEntity ) && ( bindEntity != $world ) ) { bindJoint = sys.getTraceJoint(); if ( bindJoint ) { bindBody = sys.getTraceBody(); if ( bindBody ) { bindEntity.setKey( "bindConstraint bind1", "fixed " + bindBody + " " + bindJoint ); bindEntity.bindToJoint( $crane, "crane", 1 ); crane_have_object = true; } } else { bindEntity.bindToJoint( $crane, "crane", 1 ); crane_have_object = true; } } // automatically move up crane_move( $crane_hang, UP, crane_maxs_z - crane_pos_z, false ); if ( !crane_have_object ) { sound_crane_fingers_open(); $crane.setFingerAngle( -60 ); bindEntity = $null_entity; } else { $main_control_gui.setGuiParm ( "gui_parm1" , 1); } } /* ============ kill_lastobject ============ */ void kill_lastobject( entity lastobject ) { $main_control_gui.setGuiParm( "gui_parm1" , 1 ); //sys.print( "kill_lastobject: " + lastobject.getName() + "\n" ); if ( ( lastobject != $bad_object_1 ) && ( lastobject != $bad_object_2 ) ) { // deleting the player != smart if ( lastobject.getKey( "spawnclass" ) != "idPlayer" ) { lastobject.remove(); } return; } lastobject.remove(); bad_object_count++; if ( bad_object_count == 1 ) { thread crossFadeEnt ($puke_light, '0 0.52 0.07', '0 0.26 0.035', 5.0); sys.wait (5); sys.trigger ($cranewarning_2); } else if ( bad_object_count == 2 ) { sys.trigger ($crane_fog); thread crossFadeEnt ($puke_light, '0 0.26 0.035', '0 0 0', 5.0); sys.wait (5); sys.trigger ($cranewarning_3); // Get rid of the trigger_once for the computer voice, if they // haven't triggered it yet. $toxin_trigger.remove(); sys.trigger ($disposal_door); sys.trigger ($disposal_setshaderparm); sys.trigger ($cgdoors_setshaderparm); sys.trigger ($clear_colorchange); $disposal_outer_gui.setGuiParm( "gui_parm1", 1 ); $disposal_inner_gui.setGuiParm( "gui_parm1", 1 ); $dd_light1.setColor (0.0, 0.5, 0.0); $dd_light2.setColor (0.0, 0.5, 0.0); $dd_green_dec.show (); $dd_red_dec.hide (); sys.trigger ($trigger_relay_262); sys.wait (5); sys.trigger ($alpha3_sarge1); sys.wait (7); sys.trigger ($trigger_relay_264); } } /* ============ crane_cmd_transfer move crane to the drop off point only if it has an object bound drop the bound object eventually this will send the object to the new area ============ */ void crane_cmd_transfer() { float move_x, move_y, move_z; float xdir, ydir, zdir; float xrdir, yrdir, zrdir; vector drop_point; if ( !crane_have_object ) { return; } $crane_carrier.speed( 40 ); $crane_top.speed( 40 ); // // How are we going to get to the receptible ? // drop_point = $crane_drop.getWorldOrigin(); // Calculate X movement if ( crane_pos_x >= drop_point_x ) { move_x = crane_pos_x - drop_point_x; xdir = WEST; xrdir = EAST; } else { move_x = drop_point_x - crane_pos_x; xdir = EAST; xrdir = WEST; } // Calculate Y movement if ( crane_pos_y >= drop_point_y ) { move_y = crane_pos_y - drop_point_y; ydir = SOUTH; yrdir = NORTH; } else { move_y = drop_point_y - crane_pos_y; ydir = NORTH; yrdir = SOUTH; } sound_crane_loop(); $crane_carrier.move( ydir, move_y ); sys.waitFor( $crane_carrier ); sound_crane_stop(); sound_crane_loop(); $crane_top.move( xdir, move_x ); sys.waitFor( $crane_top ); sound_crane_stop(); sys.wait( 1 ); crane_cmd_drop(); sys.wait( 0.5 ); sound_crane_loop(); $crane_top.move( xrdir, move_x ); sys.waitFor( $crane_top ); sound_crane_stop(); sound_crane_loop(); $crane_carrier.move( yrdir, move_y ); sys.waitFor( $crane_carrier ); sound_crane_stop(); $crane_top.speed( 30 ); $crane_carrier.speed( 30 ); } /* ============ crane_update_loop ============ */ void crane_update_loop() { while( 1 ) { command = CRANE_NONE; while( command == CRANE_NONE ) { update_laser(); sys.waitFrame(); } if ( command == CRANE_FORWARD ) { if ( crane_pos_x > crane_mins_x ) { crane_move( $crane_top, WEST, crane_pos_x - crane_mins_x, true ); } } else if ( command == CRANE_BACK ) { if ( crane_pos_x < crane_maxs_x ) { crane_move( $crane_top, EAST, crane_maxs_x - crane_pos_x, true ); } } else if ( command == CRANE_LEFT ) { if ( crane_pos_y > crane_mins_y ) { crane_move( $crane_carrier, SOUTH, crane_pos_y - crane_mins_y, true ); } } else if ( command == CRANE_RIGHT ) { if ( crane_pos_y < crane_maxs_y ) { crane_move( $crane_carrier, NORTH, crane_maxs_y - crane_pos_y, true ); } } else if ( command == CRANE_UP ) { if ( crane_pos_z < crane_maxs_y ) { crane_move( $crane_hang, UP, crane_maxs_z - crane_pos_z, true ); } } else if ( command == CRANE_DOWN ) { if ( ( crane_pos_z > crane_mins_z ) && !bindEntity && ( !tracestopEntity || ( tracestopEntity == $world ) ) ) { crane_move( $crane_hang, DOWN, crane_pos_z - crane_mins_z, true ); } } else if ( command == CRANE_DROP ) { crane_cmd_drop(); } else if ( command == CRANE_PICKUP ) { crane_cmd_pickup(); } else if ( command == CRANE_TRANSFER ) { crane_cmd_transfer(); } } } /*********************************************************************** User interface ***********************************************************************/ void crane_forward() { command = CRANE_FORWARD; } void crane_back() { command = CRANE_BACK; } void crane_left() { command = CRANE_LEFT; } void crane_right() { command = CRANE_RIGHT; } void crane_up() { command = CRANE_UP; } void crane_down() { command = CRANE_DOWN; } void crane_stop() { command = CRANE_NONE; } void crane_drop() { command = CRANE_DROP; } void crane_pickup() { command = CRANE_PICKUP; } void crane_transfer() { command = CRANE_TRANSFER; } /*********************************************************************** initialization ***********************************************************************/ /* ============ init_crane ============ */ void init_crane() { cache_crane_sounds(); crane_pos = $crane_position.getWorldOrigin(); $crane_light.bindToJoint( $crane, "crane", 1 ); // crane_position $crane_trace_start.bindToJoint( $crane, "crane", 1 ); $crane_trace_end.bindToJoint( $crane, "crane", 1 ); $crane_stoptrace_end.bindToJoint( $crane, "crane", 1 ); $laser_trace_end.bindToJoint( $crane, "crane", 1 ); $crane_carrier.speed( 30 ); $crane_top.speed( 30 ); $crane_hang.speed( 45 ); $crane_top.bind( $crane_carrier ); $crane_hang.bind( $crane_top ); $crane.bind( $crane_hang ); $crane.setFingerAngle( -60 ); thread crane_update_loop(); } /* namespace map_alphalabs3 */ }