boiii-scripts/shared/teamgather_shared.gsc
2023-04-13 17:30:38 +02:00

956 lines
33 KiB
Plaintext

#using scripts\codescripts\struct;
#using scripts\shared\callbacks_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\doors_shared;
#using scripts\shared\flagsys_shared;
#using scripts\shared\gameobjects_shared;
#using scripts\shared\scene_shared;
#using scripts\shared\system_shared;
#using scripts\shared\util_shared;
#using scripts\shared\visionset_mgr_shared;
#namespace teamgather;
// 2
#precache( "triggerstring", "TEAM_GATHER_HOLD_FOR_TEAM_ENTER" );
#precache( "string", "TEAM_GATHER_TEAM_STEALTH_ENTER" );
#precache( "string", "TEAM_GATHER_PLAYERS_READY" );
#precache( "string", "TEAM_GATHER_TIME_REMAINING_1" );
#precache( "string", "TEAM_GATHER_TIME_REMAINING_2" );
#precache( "string", "TEAM_GATHER_TIME_REMAINING_3" );
#precache( "string", "TEAM_GATHER_TIME_REMAINING_4" );
#precache( "string", "TEAM_GATHER_TIME_REMAINING_5" );
#precache( "string", "TEAM_GATHER_TIME_REMAINING_6" );
#precache( "string", "TEAM_GATHER_TIME_REMAINING_7" );
#precache( "string", "TEAM_GATHER_TIME_REMAINING_8" );
#precache( "string", "TEAM_GATHER_TIME_REMAINING_9" );
#precache( "string", "TEAM_GATHER_TIME_REMAINING_10" );
#precache( "string", "TEAM_GATHER_TEAM_EVENT_ABORTED" );
#precache( "string", "TEAM_GATHER_PLAYER_STARTING_EVENT" );
#precache( "string", "TEAM_GATHER_NUM_PLAYERS" );
#precache( "string", "TEAM_GATHER_HOLD_TO_GO_NOW" );
#precache( "string", "TEAM_GATHER_GATHER_SUCCESS" );
#precache( "string", "TEAM_GATHER_START_IN_1" );
#precache( "string", "TEAM_GATHER_START_IN_2" );
#precache( "string", "TEAM_GATHER_START_IN_3" );
#precache( "string", "TEAM_GATHER_START_IN_4" );
#precache( "string", "TEAM_GATHER_START_IN_5" );
#precache( "string", "TEAM_GATHER_START_IN_6" );
#precache( "string", "TEAM_GATHER_START_IN_7" );
#precache( "string", "TEAM_GATHER_START_IN_8" );
#precache( "string", "TEAM_GATHER_START_IN_9" );
#precache( "string", "TEAM_GATHER_START_IN_10" );
// 42*4
// 10
// "t7_hud_waypoints_beacon"
// "t7_hud_minimap_beacon_key"
#precache( "material", "T7_hud_prompt_press_64" );
#precache( "material", "T7_hud_prompt_press_64" );
#precache( "fx", "_t6/misc/fx_ui_flagbase_pmc" );
//*****************************************************************************
//*****************************************************************************
class cTeamGather
{
var e_gameobject;
var n_font_scale;
var v_font_color;
var m_gather_fx;
var m_e_interact_entity;
var m_teamgather_complete;
var m_success;
var m_num_players;
var m_num_players_ready;
var m_v_interact_position;
var m_v_interact_angles;
var m_v_gather_position;
var m_e_player_leader; // Player who started the teamgather event
constructor()
{
e_gameobject = undefined;
n_font_scale = 2.0;
v_font_color = ( 1.0, 1.0, 1.0 );
m_teamgather_complete = false;
m_num_players = 0;
m_num_players_ready = 0;
m_gather_fx = undefined;
m_teamgather_complete = false;
m_success = false;
}
destructor()
{
}
//*******************************************************
//*******************************************************
function cleanup()
{
cleanup_floor_effect();
e_gameobject gameobjects::destroy_object( true, true );
}
//*******************************************************
//*******************************************************
function create_teamgather_event( v_interact_pos, v_interact_angles, v_gather_pos, e_interact_entity )
{
m_v_interact_position = v_interact_pos;
m_v_interact_angles = v_interact_angles;
m_e_interact_entity = e_interact_entity;
m_v_gather_position = v_gather_pos;
// Create the interact gameobject
e_gameobject = setup_gameobject( v_interact_pos, undefined, &"TEAM_GATHER_HOLD_FOR_TEAM_ENTER", m_e_interact_entity );
e_gameobject.c_teamgather = self;
// Wait for the interact to be triggered by a player
e_gameobject waittill( "player_interaction" );
// Disable the interaction gameobject
e_gameobject gameobjects::disable_object();
// Add Team Action Advertisement over the door
// Change color of the door
// Spawn the indicator effect on the ground
spawn_floor_effect();
// Highlight Interact Entity - ON
interact_entity_highlight( true );
// MAIN - Wait for the results of the gather, BLOCKING
b_success = gather_players();
// End - Cleanup gather effect on the floor
cleanup_floor_effect();
// Highlight Interact Entity - OFF
interact_entity_highlight( false );
// How did it go?
if( ( isdefined( b_success ) && b_success ) )
{
teamgather_success();
}
else
{
teamgather_failure();
}
return( b_success );
}
//*******************************************************
//*******************************************************
function teamgather_success()
{
if( (0) > 0 )
{
x_off = 0;
y_off = 180;
a_players = get_players_playing();
for( i=0; i<a_players.size; i++ )
{
e_player = a_players[i];
e_player.success_hud_elem = e_player __create_client_hud_elem( "center", "middle", "center", "top", x_off, y_off, n_font_scale, v_font_color, &"TEAM_GATHER_GATHER_SUCCESS" );
}
wait( (0) );
for( i=0; i<a_players.size; i++ )
{
e_player = a_players[i];
e_player.success_hud_elem Destroy();
}
}
}
//*******************************************************
//*******************************************************
function teamgather_failure()
{
x_off = 0;
y_off = 180;
a_players = get_players_playing();
for( i=0; i<a_players.size; i++ )
{
e_player = a_players[i];
e_player.failure_hud_elem = e_player __create_client_hud_elem( "center", "middle", "center", "top", x_off, y_off, n_font_scale, v_font_color, &"TEAM_GATHER_TEAM_EVENT_ABORTED" );
}
wait( (0) );
for( i=0; i<a_players.size; i++ )
{
e_player = a_players[i];
e_player.failure_hud_elem Destroy();
}
}
//*******************************************************
//*******************************************************
function setup_gameobject( v_pos, STR_MODEL, STR_USE_HINT, e_los_ignore_me )
{
n_radius = 48;
// Setup a USE Trigger
e_trigger = spawn( "trigger_radius_use", v_pos, 0, n_radius, 30 );
e_trigger TriggerIgnoreTeam();
e_trigger SetVisibleToAll();
e_trigger SetTeamForTrigger( "none" );
e_trigger UseTriggerRequireLookAt();
e_trigger SetCursorHint( "HINT_NOICON" );
// You can add multiple models into the gameobjects model array, each with their own relative offset
gobj_model_offset = ( 0, 0, 0 );
if( IsDefined(STR_MODEL) )
{
gobj_visuals[0] = spawn( "script_model", v_pos + gobj_model_offset );
gobj_visuals[0] setModel( STR_MODEL );
}
else
{
gobj_visuals = [];
}
// This is the LUA objective name, defined in the gametype LUA script
// CP currently only uses coop
// It defines the look and style of the LUA icons
//gobj_objective_name = &"bomb";
gobj_objective_name = undefined;
// Create the gameobject
gobj_team = "allies";
gobj_trigger = e_trigger;
gobj_offset = ( 0, 0, -5 );
e_object = gameobjects::create_use_object( gobj_team, gobj_trigger, gobj_visuals, gobj_offset, gobj_objective_name );
// Setup gameobject params
e_object gameobjects::allow_use( "any" );
e_object gameobjects::set_use_time( 0.0 ); // How long the progress bar takes to complete
e_object gameobjects::set_use_text( "" );
e_object gameobjects::set_use_hint_text( STR_USE_HINT );
e_object gameobjects::set_visible_team( "any" ); // How can see the gameobject
// Setup gameobject callbacks
e_object.onUse = &onUseGameobject;
// OLD STYLE OBJECTIVES
e_object gameobjects::set_3d_icon( "friendly", "T7_hud_prompt_press_64" );
e_object gameobjects::set_3d_icon( "enemy", "T7_hud_prompt_press_64" );
e_object gameobjects::set_2d_icon( "friendly", "T7_hud_prompt_press_64" );
e_object gameobjects::set_2d_icon( "enemy", "T7_hud_prompt_press_64" );
e_object thread gameobjects::hide_icon_distance_and_los( (1,1,1), 42*20, true, e_los_ignore_me );
return( e_object );
}
//*******************************************************
//*******************************************************
// Called when gameobject has been "used"
function onUseGameobject( player )
{
//iprintlnbold( "Starting Team Gather" );
self.c_teamgather.m_e_player_leader = player;
self notify( "player_interaction" );
}
//*******************************************************
//*******************************************************
// self = class
function spawn_floor_effect()
{
if( !( isdefined( 0 ) && 0 ) )
{
return;
}
v_pos = m_v_gather_position;
// Make sure the gather position is on the plane of the floor
v_start = ( v_pos[0], v_pos[1], v_pos[2]+20 );
v_end = ( v_pos[0], v_pos[1], v_pos[2]-94 );
trace = BulletTrace( v_start, v_end, 0, undefined );
v_floor_pos = trace[ "position" ];
m_gather_fx = spawnFx( "_t6/misc/fx_ui_flagbase_pmc", v_floor_pos );
triggerFx( m_gather_fx );
}
//*******************************************************
//*******************************************************
// self = class
function cleanup_floor_effect()
{
if( !( isdefined( 0 ) && 0 ) )
{
return;
}
if( IsDefined(m_gather_fx) )
{
m_gather_fx Delete();
m_gather_fx = undefined;
}
}
//*******************************************************
//*******************************************************
// self = class
function interact_entity_highlight( highlight_object )
{
if( IsDefined(m_e_interact_entity) )
{
if( ( isdefined( highlight_object ) && highlight_object ) )
{
m_e_interact_entity clientfield::set( "teamgather_material", 1 );
}
else
{
m_e_interact_entity clientfield::set( "teamgather_material", 0 );
}
}
}
//*******************************************************
// Wait for players to gather at the team gather position
//*******************************************************
// self = class
function gather_players()
{
start_player_timer( 10 );
create_player_huds();
// Wait for the gather players function to finish
b_success = teamgather_main_update();
return( b_success );
}
//******************************************************
//******************************************************
// self = class
function create_player_huds()
{
// Display HUD for the players
a_players = get_players_playing();
// Flow goes straight to Success if just 1 player
if( a_players.size <= 1 )
{
return;
}
for( i=0; i<a_players.size; i++ )
{
e_player = a_players[i];
if( e_player == self.m_e_player_leader )
{
self thread display_hud_player_leader( e_player );
}
else
{
self thread display_hud_player_team_member( e_player );
}
}
}
//******************************************************
//******************************************************
function is_teamgather_complete()
{
return( self.m_teamgather_complete );
}
//******************************************************
//******************************************************
function set_teamgather_complete( success )
{
self.m_teamgather_complete = true;
self.m_success = success;
}
//******************************************************
// UPDATE
//******************************************************
// self = class
function teamgather_main_update()
{
// While there's time remaing in the teamgather
while( !is_teamgather_complete() )
{
// Check if the team are in the gather radius
update_players_in_radius( false );
// If all players out of position, trigger failure
if( m_num_players_ready == 0 )
{
set_teamgather_complete( false );
break;
}
// If all the players are in position for, trigger success
if( ( m_num_players > 0 ) && ( m_num_players_ready >= m_num_players) )
{
if( players_in_position( true ) )
{
set_teamgather_complete( true );
break;
}
}
else
{
players_in_position( false );
}
// Update time remaining
time_remaining = get_time_remaining();
if( time_remaining <= 0 )
{
set_teamgather_complete( true );
break;
}
{wait(.05);};
}
// Check for success
if( m_success == true )
{
// Teleport any players out of position into the event area
update_players_in_radius( true );
}
else
{
}
// Cleanup
a_players = get_players_playing();
for( i=0; i<a_players.size; i++ )
{
e_player = a_players[i];
if( ( isdefined( e_player.in_gather_position ) && e_player.in_gather_position ) )
{
e_player util::_enableWeapon();
}
e_player.in_gather_position = undefined;
}
return( m_success );
}
//******************************************************
//******************************************************
// self = class
function players_in_position( in_position )
{
if( ( isdefined( in_position ) && in_position ) )
{
if( !IsDefined(self.in_position_start_time) )
{
self.in_position_start_time = gettime();
}
time = gettime();
dt = ( time - self.in_position_start_time ) / 1000;
if( dt >= (0.0) )
{
return( true );
}
}
else
{
self.in_position_start_time = undefined;
}
return( false );
}
//******************************************************
//******************************************************
// self = class
function update_players_in_radius( force_player_into_position )
{
// Setup
a_players = get_players_playing();
m_num_players = a_players.size;
for( i=0; i<a_players.size; i++ )
{
a_players[i].in_gather_position = undefined;
}
// Update players radius check and weapon state every frame
m_num_players_ready = 0;
for( i=0; i<a_players.size; i++ )
{
e_player = a_players[i];
// Update players gather status
e_player.in_gather_position = is_player_in_gather_position( e_player );
// If force into position flag is set, make sure he's in position
if( ( isdefined( force_player_into_position ) && force_player_into_position ) && !( isdefined( e_player.in_gather_position ) && e_player.in_gather_position ) )
{
teleport_player_into_position( e_player );
}
// If the player is in position, lower his weapon is down
if( ( isdefined( e_player.in_gather_position ) && e_player.in_gather_position ) )
{
e_player player_lowready_state( true );
m_num_players_ready++;
}
// If not in position, lower his weapon
else
{
e_player player_lowready_state( false );
// If its a team member and they aren't in position, they can use the X button to zoom into position
if( e_player != m_e_player_leader )
{
team_member_zoom_button_check( e_player );
}
}
}
}
//******************************************************
//******************************************************
// self = class
function is_player_in_gather_position( e_player )
{
player_valid = true;
// Basic 2d check to see if player is in range
n_dist = Distance2D( e_player.origin, m_v_gather_position );
if( n_dist > (42*5) )
{
player_valid = false;
}
else
{
v_start_pos = ( e_player.origin[0], e_player.origin[1],e_player.origin[2]+32 );
v_end_pos = ( m_v_gather_position[0], m_v_gather_position[1], m_v_gather_position[2] );
// If below the point, reject
if( (e_player.origin[2] - v_end_pos[2]) < -64 )
{
player_valid = false;
}
// Cast a ray to the floor to check no geo is blocking
v_trace = BulletTrace( v_start_pos, v_end_pos, 0, undefined );
v_trace_pos = v_trace[ "position" ];
dz = abs( v_trace_pos[2] - m_v_gather_position[2] );
if( dz > 64 )
{
player_valid = false;
}
}
return( player_valid);
}
//******************************************************
//******************************************************
// self = player
function player_lowready_state( lower_weapon )
{
// Lower weapon
if( lower_weapon )
{
if( self util::isWeaponEnabled() )
{
self util::_disableWeapon();
}
}
// Raise weapon
else
{
if( !(self util::isWeaponEnabled()) )
{
self util::_enableWeapon();
}
}
}
//******************************************************
//******************************************************
// self = class
function team_member_zoom_button_check( e_player )
{
// Did the player request to zoom into position?
if( (e_player UseButtonPressed()) )
{
teleport_player_into_position( e_player );
}
}
//******************************************************
//******************************************************
// self = class
function teleport_player_into_position( e_player )
{
a_players = get_players_playing();
// Keep on creating potential spawn positions until we find one that works
while( 1 )
{
x_offset = RandomFloatRange( -( (42*5) - 42 ), ( (42*5) - 42 ) );
y_offset = RandomFloatRange( -( (42*5) - 42 ), ( (42*5) - 42 ) );
e_player.zoom_pos = ( m_v_gather_position[0]+x_offset, m_v_gather_position[1]+y_offset, m_v_gather_position[2] );
// Need to be away from other players
reject = false;
for( i=0; i<a_players.size; i++ )
{
if( e_player != a_players[i] )
{
dist = Distance2D( e_player.origin, a_players[i].origin );
if( dist < (42*2) )
{
reject = true;
break;
}
}
}
// Make sure its not ahead to the interact position
if( !reject )
{
v_forward = AnglesToForward( m_v_interact_angles );
v_dir = vectornormalize( e_player.zoom_pos - m_v_interact_position );
dp = vectordot( v_forward, v_dir );
// 0.0 = parallel, -ve is safe
if( dp > -0.5 ) // -0.5
{
//iprintlnbold( "Player DP REJECTION" );
reject = true;
}
}
if( reject )
{
break;
}
if( !positionWouldTelefrag( e_player.zoom_pos ) )
{
break;
}
}
// Reposition the player
e_player SetOrigin( e_player.zoom_pos );
// Look at the gather position
v0 = ( self.m_v_interact_position[0], self.m_v_interact_position[1], self.m_v_interact_position[2] );
v1 = ( e_player.zoom_pos[0], e_player.zoom_pos[1], self.m_v_interact_position[2] );
v_dir = vectornormalize( v0 - v1 );
v_angles = VectorToAngles( v_dir );
//level thread teamgather::mike_debug_line( self.m_v_interact_position, e_player.zoom_pos );
e_player SetPlayerAngles( v_angles );
}
//******************************************************
//******************************************************
// self = class
function display_hud_player_leader( e_player )
{
e_player endon( "disconnect" );
y_start = 180;
x_off = 0;
y_off = y_start;
gather_hud_elem = e_player __create_client_hud_elem( "center", "middle", "center", "top", x_off, y_off, n_font_scale, v_font_color, &"TEAM_GATHER_TEAM_STEALTH_ENTER" );
x_off = 0;
y_off = y_start + 100;
ready_hud_elem = e_player __create_client_hud_elem( "center", "middle", "center", "top", x_off, y_off, n_font_scale, v_font_color, "" );
x_off = -45;
y_off = y_start + 130;
execute_hud_elem = e_player __create_client_hud_elem( "left", "middle", "center", "top", x_off, y_off, n_font_scale, v_font_color, "" );
a_time_remaining = array( "0", &"TEAM_GATHER_TIME_REMAINING_1", &"TEAM_GATHER_TIME_REMAINING_2", &"TEAM_GATHER_TIME_REMAINING_3", &"TEAM_GATHER_TIME_REMAINING_4",
&"TEAM_GATHER_TIME_REMAINING_5", &"TEAM_GATHER_TIME_REMAINING_6", &"TEAM_GATHER_TIME_REMAINING_7", &"TEAM_GATHER_TIME_REMAINING_8",
&"TEAM_GATHER_TIME_REMAINING_9", &"TEAM_GATHER_TIME_REMAINING_10" );
while( !is_teamgather_complete() )
{
// Create the text for the number of players ready
// TODO - TEXT WARNING
ready_hud_elem setText( &"TEAM_GATHER_PLAYERS_READY", m_num_players_ready, m_num_players );
// Create the text for the time remaining
time_remaining = get_time_remaining_in_seconds();
execute_hud_elem setText( a_time_remaining[ time_remaining ] );
{wait(.05);};
}
gather_hud_elem Destroy();
ready_hud_elem Destroy();
execute_hud_elem Destroy();
}
//******************************************************
//******************************************************
// self = class
function display_hud_player_team_member( e_player )
{
e_player endon( "disconnect" );
y_start = 180;
x_off = 0;
y_off = y_start;
// TODO - TEXT WARNING
starting_hud_elem = e_player __create_client_hud_elem( "center", "middle", "center", "top", x_off, y_off, n_font_scale, v_font_color, "" );
starting_hud_elem setText( &"TEAM_GATHER_PLAYER_STARTING_EVENT", self.m_e_player_leader ); // self.m_e_player_leader.playername
x_off = -118;
y_off = y_start + 40;
gathered_hud_elem = e_player __create_client_hud_elem( "left", "middle", "center", "top", x_off, y_off, n_font_scale, v_font_color, "" );
x_off = -118 + 172;
y_off = y_start + 40;
start_in_hud_elem = e_player __create_client_hud_elem( "left", "middle", "center", "top", x_off, y_off, n_font_scale, v_font_color, "" );
x_off = 0;
y_off = y_start + 80;
go_hud_elem = e_player __create_client_hud_elem( "center", "middle", "center", "top", x_off, y_off, n_font_scale, v_font_color, "" );
a_start_in = array( "0", &"TEAM_GATHER_START_IN_1", &"TEAM_GATHER_START_IN_2", &"TEAM_GATHER_START_IN_3", &"TEAM_GATHER_START_IN_4",
&"TEAM_GATHER_START_IN_5", &"TEAM_GATHER_START_IN_6", &"TEAM_GATHER_START_IN_7", &"TEAM_GATHER_START_IN_8",
&"TEAM_GATHER_START_IN_9", &"TEAM_GATHER_START_IN_10" );
while( !is_teamgather_complete() )
{
// Display num players gathered
// TODO - TEXT WARNING
gathered_hud_elem setText( &"TEAM_GATHER_NUM_PLAYERS", int(m_num_players_ready), int(m_num_players) );
// Display start in time
time_remaining = get_time_remaining_in_seconds();
start_in_hud_elem setText( a_start_in[ time_remaining ] );
// Can the player use X to teleport to position?
if( ( isdefined( e_player.in_gather_position ) && e_player.in_gather_position ) )
{
go_hud_elem setText( "" );
}
else
{
go_hud_elem setText( &"TEAM_GATHER_HOLD_TO_GO_NOW" );
}
{wait(.05);};
}
starting_hud_elem Destroy();
gathered_hud_elem Destroy();
start_in_hud_elem Destroy();
go_hud_elem Destroy();
}
//******************************************************
//******************************************************
// self = the player
function __create_client_hud_elem( alignX, alignY, horzAlign, vertAlign, xOffset, yOffset, fontScale, color, str_text )
{
hud_elem = NewClientHudElem( self );
hud_elem.elemType = "font";
hud_elem.font = "objective";
hud_elem.alignX = alignX;
hud_elem.alignY = alignY;
hud_elem.horzAlign = horzAlign;
hud_elem.vertAlign = vertAlign;
hud_elem.x += xOffset;
hud_elem.y += yOffset;
hud_elem.foreground = true;
hud_elem.fontScale = fontScale;
hud_elem.alpha = 1;
hud_elem.color = color;
hud_elem.hidewheninmenu = true;
hud_elem SetText( str_text );
return hud_elem;
}
//******************************************************
//******************************************************
// self = class
function start_player_timer( total_time )
{
self.e_gameobject.start_time = gettime();
self.e_gameobject.total_time = total_time;
}
//******************************************************
//******************************************************
// self = class
function get_time_remaining()
{
time = gettime();
dt = ( time - self.e_gameobject.start_time ) / 1000;
time_remaining = self.e_gameobject.total_time - dt;
return( time_remaining );
}
//******************************************************
//******************************************************
// self = class
function get_time_remaining_in_seconds()
{
time_remaining = int ( get_time_remaining() );
time_remaining += 1;
if( time_remaining > 10 )
{
time_remaining = 10;
}
if( time_remaining > 10 )
{
time_remaining = 10;
}
else if( time_remaining < 1 )
{
time_remaining = 1;
}
return( time_remaining );
}
//******************************************************
// Returns an array of "playing" players
//******************************************************
function get_players_playing()
{
a_players = [];
a_all_players = getplayers();
for( i=0; i<a_all_players.size; i++ )
{
e_player = a_all_players[i];
if( e_player.sessionstate == "playing" )
{
a_players[a_players.size] = e_player;
}
}
return( a_players );
}
}
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
function setup_teamgather( v_interact_pos, v_interact_angles, e_interact_entity )
{
// Calculate the gather position
v_forward = AnglesToForward( v_interact_angles );
v_gather_pos = v_interact_pos + ( v_forward * -100.0 );
// Cast a ray to clip the gather positon to the floor
v_start = ( v_gather_pos[0], v_gather_pos[1], v_gather_pos[2] + 20 );
v_end = ( v_gather_pos[0], v_gather_pos[1], v_gather_pos[2] - 100 );
v_trace = BulletTrace( v_start, v_end, 0, undefined );
v_floor_pos = v_trace[ "position" ];
v_gather_pos = ( v_gather_pos[0], v_gather_pos[1], v_floor_pos[2]+10 );
c_teamgather = new cTeamGather();
success = [[ c_teamgather ]]->create_teamgather_event( v_interact_pos, v_interact_angles, v_gather_pos, e_interact_entity );
// Return the player if successful
if( success )
{
e_player = c_teamgather.m_e_player_leader;
}
else
{
e_player = undefined;
}
// TODO: Clean up the class, there is no delete() available....
[[ c_teamgather ]]->cleanup();
return( e_player );
}
//*****************************************************************************
//*****************************************************************************
// *** DEBUG ***
function mike_debug_line( v1, v2 )
{
level notify("hello mike");
self endon( "hello mike" );
while( 1 )
{
/#
line( v1, v2, (0,0,1) );
#/
wait( 0.1 );
}
}