iw6-scripts-dev/maps/mp/alien/_deployablebox.gsc
2024-12-11 11:28:08 +01:00

989 lines
24 KiB
Plaintext

#include maps\mp\_utility;
#include common_scripts\utility;
#include maps\mp\gametypes\_hud_util;
#include maps\mp\alien\_utility;
/*
Deployable box killstreaks: the player will be able to place a box in the world and teammates can grab items from it
this will be used on multiple killstreaks where you can place a box in the world with something in it
*/
BOX_TIMEOUT_UPDATE_INTERVAL = 1.0;
DEFAULT_USE_TIME = 3000;
BOX_DEFAULT_HEALTH = 999999; // so that boxes aren't killed in code
init()
{
if ( !IsDefined( level.boxSettings ) )
{
level.boxSettings = [];
}
}
///////////////////////////////////////////////////
// MARKER FUNCTIONS
// 2012-06-21 wallace
// Stole an updated version from _uplink.gsc. Should probably unify all these funcs eventually
//////////////////////////////////////////////////
beginDeployableViaMarker( lifeId, boxType )
{
self thread watchDeployableMarkerCancel( boxType );
self thread watchDeployableMarkerPlacement( boxType, lifeId );
while ( true )
{
result = self waittill_any_return( "deployable_canceled", "deployable_deployed", "death", "disconnect" );
return ( result == "deployable_deployed" );
}
}
tryUseDeployable( lifeId, boxType ) // self == player
{
self thread watchDeployableMarkerCancel( boxType );
self thread watchDeployableMarkerPlacement( boxType, lifeId );
while ( true )
{
result = self waittill_any_return( "deployable_canceled", "deployable_deployed", "death", "disconnect" );
return ( result == "deployable_deployed" );
}
}
watchDeployableMarkerCancel( boxType )
{
self endon( "death" );
self endon( "disconnect" );
self endon( "deployable_deployed" );
boxConfig = level.boxSettings[ boxType ];
currentWeapon = self getCurrentWeapon();
while( currentWeapon == boxConfig.weaponInfo )
{
self waittill( "weapon_change", currentWeapon );
}
self notify( "deployable_canceled" );
}
watchDeployableMarkerPlacement( boxType, lifeId )
{
self endon( "spawned_player" ); // you shouldn't do endon( "death" ) here because this thread needs to run
self endon( "disconnect" );
self endon( "deployable_canceled" );
while( true )
{
self waittill( "grenade_fire", marker, weaponName );
if( isReallyAlive(self) )
{
break;
}
else
{
marker Delete();
}
}
self notify( "deployable_deployed" );
marker.owner = self;
marker.weaponName = weaponName;
self.marker = marker;
marker PlaySoundToPlayer( level.boxSettings[ boxType ].deployedSfx, self );
marker thread markerActivate( lifeId, boxType, ::box_setActive );
}
override_box_moving_platform_death( data )
{
self notify( "death" ); // we're doing this here instead of letting the mover code just delete us so that we can run our necessary clean-up functionality (like removal of the objective marker from the minimap)
}
markerActivate( lifeId, boxType, usedCallback ) // self == marker
{
self notify( "markerActivate" );
self endon( "markerActivate" );
//self waittill( "explode", position );
self waittill( "missile_stuck" );
owner = self.owner;
position = self.origin;
if ( !isDefined( owner ) )
return;
box = createBoxForPlayer( boxType, position, owner );
// For moving platforms.
data = SpawnStruct();
data.linkParent = self GetLinkedParent();
//fixes wall hack exploit with linked items
if ( isDefined( data.linkParent ) && isDefined( data.linkParent.model ) && DeployableExclusion( data.linkParent.model ) )
{
box.origin = data.linkParent.origin;
grandParent = data.linkParent GetLinkedParent();
if ( isDefined( grandParent ) )
data.linkParent = grandParent;
else
data.linkParent = undefined;
}
data.deathOverrideCallback = ::override_box_moving_platform_death;
box thread maps\mp\_movers::handle_moving_platforms( data );
box.moving_platform = data.linkParent;
box SetOtherEnt(owner);
// ES - 2/24/14 - This waitframe is causing an issue where, when deployed on a moving platform, the "death" notification is sent instantly, but is never caught.
wait 0.05;
//self playSound( "sentry_gun_beep" );
box thread [[ usedCallback ]]();
self delete();
if( IsDefined(box) && (box touchingBadTrigger()) )
{
box notify( "death" );
}
}
DeployableExclusion( parentModel )
{
if ( parentModel == "weapon_alien_laser_drill" )
return true;
else if ( IsSubStr( parentModel, "crafting" ) )
return true;
else if ( IsSubStr( parentModel, "scorpion_body" ) )
return true;
return false;
}
isHoldingDeployableBox()
{
curWeap = self GetCurrentWeapon();
if ( IsDefined( curWeap ) )
{
foreach( deplBoxWeap in level.boxSettings )
{
if ( curWeap == deplBoxWeap.weaponInfo )
return true;
}
}
return false;
}
///////////////////////////////////////////////////
// END MARKER FUNCTIONS
//////////////////////////////////////////////////
///////////////////////////////////////////////////
// BOX HANDLER FUNCTIONS
//////////////////////////////////////////////////
get_box_icon( resourceType, dpadName, upgrade_rank )
{
return level.alien_combat_resources[ resourceType][ dpadName ].upgrades[upgrade_rank].dpad_icon;
}
get_resource_type( dpadName )
{
if( !isDefined( dpadName ) )
return undefined;
foreach ( resource_type_name, resource_type in level.alien_combat_resources )
{
if ( IsDefined( resource_type[ dpadName ] ) )
{
return resource_type_name;
}
}
return undefined;
}
createBoxForPlayer( boxType, position, owner )
{
assertEx( isDefined( owner ), "createBoxForPlayer() called without owner specified" );
boxConfig = level.boxSettings[ boxType ];
box = Spawn( "script_model", position );
box setModel( boxConfig.modelBase );
box.health = BOX_DEFAULT_HEALTH;
box.maxHealth = boxConfig.maxHealth;
box.angles = owner.angles;
box.boxType = boxType;
box.owner = owner;
box.team = owner.team;
if ( IsDefined( boxConfig.dpadName ) )
{
box.dpadName = boxConfig.dpadName;
}
if ( IsDefined( boxConfig.maxUses ) )
{
box.usesRemaining = boxConfig.maxUses;
}
player = box.owner;
resource_type = get_resource_type( box.dpadName );
if ( is_combat_resource( resource_type ) )
{
box.upgrade_rank = player maps\mp\alien\_persistence::get_upgrade_level( resource_type );
box.icon_name = get_box_icon( resource_type, box.dpadName, box.upgrade_rank );
}
else
{
AssertEx( isDefined( boxConfig.icon_name ), "For non-combat-resource box, the .icon_name must be specified in the boxConfig struct" );
box.upgrade_rank = 0;
box.icon_name = boxConfig.icon_name;
}
// black box data tracking
level.alienBBData[ "team_item_deployed" ]++;
player maps\mp\alien\_persistence::eog_player_update_stat( "deployables", 1 );
/*
ownername = "";
if ( isdefined( owner.name ) )
ownername = owner.name;
itemname = boxType;
if ( isdefined( box.dpadName ) )
itemname = box.dpadName;
/#
if ( GetDvarInt( "alien_bbprint_debug" ) > 0 )
{
IPrintLnBold( "^8bbprint: aliendeployabledeployed \n" +
" itemname=" + itemname +
" itemlevel=" + box.upgrade_rank +
" itemx,y,z=" + position +
" ownername=" + ownername );
}
#/
bbprint( "aliendeployabledeployed",
"itemname %s itemlevel %s itemx %f itemy %f itemz %f ownername %s ",
itemname,
box.upgrade_rank,
position[0],
position[1],
position[2],
ownername );
*/
box box_setInactive();
box thread box_handleOwnerDisconnect();
box addBoxToLevelArray();
return box;
}
is_combat_resource( resource_type ) { return isDefined( resource_type ); }
box_setActive( skipOwnerUse ) // self == box
{
self setCursorHint( "HINT_NOICON" );
boxConfig = level.boxSettings[ self.boxType ];
self setHintString( boxConfig.hintString );
self.inUse = false;
curObjID = maps\mp\gametypes\_gameobjects::getNextObjID();
Objective_Add( curObjID, "invisible", (0,0,0) );
Objective_Position( curObjID, self.origin );
Objective_State( curObjID, "active" );
if( isDefined( boxConfig.shaderName ) )
Objective_Icon( curObjID, boxConfig.shaderName );
self.objIdFriendly = curObjID;
// use the deployable on the owner once
if ( ( !IsDefined( skipOwnerUse ) || !skipOwnerUse ) && IsDefined( boxConfig.onuseCallback )
&& ( !IsDefined( boxconfig.canUseCallback ) || (self.owner [[ boxConfig.canUseCallback ]]() ) )
)
{
if( isReallyAlive( self.owner ) )
self.owner [[ boxConfig.onUseCallback ]]( self );
}
if ( level.teamBased )
{
Objective_Team( curObjID, self.team );
foreach ( player in level.players )
{
if ( self.team == player.team
&& (!IsDefined(boxConfig.canUseCallback) || player [[ boxConfig.canUseCallback ]](self) )
)
{
self box_SetIcon( player, boxConfig.streakName, boxConfig.headIconOffset );
}
}
}
else
{
Objective_Player( curObjID, self.owner GetEntityNumber() );
if( !IsDefined(boxConfig.canUseCallback) || self.owner [[ boxConfig.canUseCallback ]](self) )
{
self box_SetIcon( self.owner, boxConfig.streakName, boxConfig.headIconOffset );
}
}
self MakeUsable();
self.isUsable = true;
self SetCanDamage( true );
self thread box_handleDamage();
self thread box_handleDeath();
self thread box_timeOut();
self make_entity_sentient_mp( self.team, true );
if ( IsDefined( self.owner ) )
self.owner notify( "new_deployable_box", self );
if (level.teamBased)
{
foreach ( player in level.participants )
{
_box_setActiveHelper( player, self.team == player.team, boxConfig.canUseCallback );
}
}
else
{
foreach ( player in level.participants )
{
_box_setActiveHelper( player, IsDefined( self.owner ) && self.owner == player, boxConfig.canUseCallback );
}
}
if( ( !isdefined( self.air_dropped ) || !self.air_dropped ) && !isPlayingSolo() )
level thread teamPlayerCardSplash( boxConfig.splashName, self.owner, self.team );
self thread box_playerConnected();
self thread box_agentConnected();
}
_box_setActiveHelper( player, bActivate, canUseFunc )
{
if ( bActivate )
{
if ( !IsDefined( canUseFunc ) || player [[ canUseFunc ]](self) )
{
self box_enablePlayerUse( player );
}
else
{
self box_disablePlayerUse( player );
// if this player is already a juggernaut then when they die, let them use the box
self thread doubleDip( player );
}
self thread boxThink( player );
}
else
{
self box_disablePlayerUse( player );
}
}
box_playerConnected() // self == box
{
self endon( "death" );
// when new players connect they need a boxthink thread run on them
while( true )
{
level waittill( "connected", player );
self childthread box_waittill_player_spawn_and_add_box( player );
}
}
box_agentConnected() // self == box
{
self endon( "death" );
// when new agents connect they need a boxthink thread run on them
while( true )
{
level waittill( "spawned_agent_player", agent );
self box_addBoxForPlayer( agent );
}
}
box_waittill_player_spawn_and_add_box( player ) // self == box
{
player waittill( "spawned_player" );
if ( level.teamBased )
{
self box_addBoxForPlayer( player );
}
}
box_playerJoinedTeam( player ) // self == box
{
self endon( "death" );
player endon( "disconnect" );
// when new players connect they need a boxthink thread run on them
while( true )
{
player waittill( "joined_team" );
if ( level.teamBased )
{
self box_addBoxForPlayer( player );
}
}
}
box_addBoxForPlayer( player ) // self == box
{
if ( self.team == player.team )
{
self box_enablePlayerUse( player );
self thread boxThink( player );
self box_SetIcon( player, level.boxSettings[ self.boxType ].streakName, level.boxSettings[ self.boxType ].headIconOffset );
}
else
{
self box_disablePlayerUse( player );
self maps\mp\_entityheadIcons::setHeadIcon( player, "", (0,0,0) );
}
}
box_SetIcon( player, streakName, vOffset )
{
self maps\mp\_entityheadIcons::setHeadIcon( player, self.icon_name, (0, 0, vOffset), 14, 14, undefined, undefined, undefined, undefined, undefined, false );
}
box_enablePlayerUse( player ) // self == box
{
if ( IsPlayer(player) )
self EnablePlayerUse( player );
self.disabled_use_for[player GetEntityNumber()] = false;
}
box_disablePlayerUse( player ) // self == box
{
if ( IsPlayer(player) )
self DisablePlayerUse( player );
self.disabled_use_for[player GetEntityNumber()] = true;
}
box_setInactive()
{
self makeUnusable();
self.isUsable = false;
self maps\mp\_entityheadIcons::setHeadIcon( "none", "", (0,0,0) );
if ( isDefined( self.objIdFriendly ) )
_objective_delete( self.objIdFriendly );
}
box_handleDamage() // self == box
{
boxConfig = level.boxSettings[ self.boxType ];
self maps\mp\gametypes\_damage::monitorDamage(
boxConfig.maxHealth,
boxConfig.damageFeedback,
::boxModifyDamage,
::boxHandleDeathDamage,
true // isKillstreak
);
}
boxModifyDamage( attacker, weapon, type, damage )
{
modifiedDamage = damage;
if( IsExplosiveDamageMOD( type ) )
{
modifiedDamage = damage * 1.5;
}
modifiedDamage = self maps\mp\gametypes\_damage::handleMeleeDamage( weapon, type, modifiedDamage );
modifiedDamage = self maps\mp\gametypes\_damage::handleMissileDamage( weapon, type, modifiedDamage );
modifiedDamage = self maps\mp\gametypes\_damage::handleAPDamage( weapon, type, modifiedDamage, attacker );
return modifiedDamage;
}
boxHandleDeathDamage( attacker, weapon, type, damage )
{
boxConfig = level.boxSettings[ self.boxType ];
self maps\mp\gametypes\_damage::onKillstreakKilled( attacker, weapon, type, damage, boxConfig.xpPopup, boxConfig.voDestroyed );
}
box_handleDeath()
{
self waittill ( "death" );
// this handles cases of deletion
if ( !isDefined( self ) )
return;
self box_setInactive();
self removeBoxFromLevelArray();
boxConfig = level.boxSettings[ self.boxType ];
PlayFX( getfx( "deployablebox_crate_destroy" ), self.origin );
// 2013-03-08 wsh: whould probably validate all the used fields...
if ( IsDefined( boxConfig.deathDamageMax ) )
{
owner = undefined;
if ( IsDefined(self.owner) )
owner = self.owner;
// somewhat hacky:
// shift the origin of the damage because it'll collide with the box otherwise
// we could also apply the damage after we delete the item?
RadiusDamage( self.origin + (0, 0, boxConfig.headIconOffset),
boxConfig.deathDamageRadius,
boxConfig.deathDamageMax,
boxConfig.deathDamageMin,
owner,
"MOD_EXPLOSIVE",
boxConfig.deathWeaponInfo
);
}
wait( 0.1 );
self notify( "deleting" );
self delete();
}
box_handleOwnerDisconnect() // self == box
{
self endon ( "death" );
level endon ( "game_ended" );
self notify ( "box_handleOwner" );
self endon ( "box_handleOwner" );
old_owner = self.owner;
self.owner waittill( "killstreak_disowned" );
// special case for air dropped box to stay when fake owner leaves ( owner was randomly picked )
if ( isdefined( self.air_dropped ) && self.air_dropped )
{
// reassign owner to next avaliable player
foreach ( player in level.players )
{
if ( !isdefined( player ) || ( isdefined( old_owner ) && old_owner == player ) )
continue;
self.owner = player;
self thread box_handleOwnerDisconnect(); // recurse
return;
}
}
// removed if not air dropped or if no host player found (which shouldn't happen)
self notify( "death" );
}
boxThink( player )
{
self endon ( "death" );
self thread boxCaptureThink( player );
if ( !IsDefined(player.boxes) )
{
player.boxes = [];
}
player.boxes[player.boxes.size] = self;
boxConfig = level.boxSettings[ self.boxType ];
for ( ;; )
{
self waittill ( "captured", capturer );
if (capturer == player)
{
player PlayLocalSound( boxConfig.onUseSfx );
if ( IsDefined( boxConfig.onuseCallback ) )
{
player [[ boxConfig.onUseCallback ]]( self );
if ( maps\mp\alien\_utility::is_chaos_mode() )
maps\mp\alien\_chaos::update_pickup_deployable_box_event();
}
// if this is not the owner then give the owner some xp
if( IsDefined( self.owner ) && player != self.owner )
{
self.owner thread maps\mp\gametypes\_rank::xpEventPopup( boxConfig.event );
self.owner thread maps\mp\gametypes\_rank::giveRankXP( "support", boxConfig.useXP );
}
if ( IsDefined( self.usesRemaining ) )
{
self.usesRemaining--;
if ( self.usesRemaining == 0)
{
self box_leave();
break;
}
}
self maps\mp\_entityheadIcons::setHeadIcon( player, "", (0,0,0) );
self box_disablePlayerUse( player );
self thread doubleDip( player );
}
}
}
doubleDip( player ) // self == box
{
self endon( "death" );
player endon( "disconnect" );
// air dropped rewards can not be double dipped
if( isdefined( self.air_dropped ) && self.air_dropped )
return;
// once they die, let them take from the box again
player waittill( "death" );
if( level.teamBased )
{
if( self.team == player.team )
{
self box_SetIcon( player, level.boxSettings[ self.boxType ].streakName, level.boxSettings[ self.boxType ].headIconOffset );
self box_enablePlayerUse( player );
}
}
else
{
if( IsDefined( self.owner ) && self.owner == player )
{
self box_SetIcon( player, level.boxSettings[ self.boxType ].streakName, level.boxSettings[ self.boxType ].headIconOffset );
self box_enablePlayerUse( player );
}
}
}
boxCaptureThink( player ) // self == box
{
while( isDefined( self ) )
{
self waittill( "trigger", tiggerer );
if ( is_aliens() )
{
if ( [[level.boxCaptureThink_alien_func]]( tiggerer ) )
continue;
}
if ( is_chaos_mode() )
{
switch ( self.boxType )
{
case "medic_skill":
case "specialist_skill":
case "tank_skill":
case "engineer_skill":
if( is_true( tiggerer.hasChaosClassSkill ) )
{
tiggerer maps\mp\_utility::setLowerMessage( "cant_use", &"ALIEN_CHAOS_CANT_PICKUP_BONUS", 3 );
continue;
}
else if ( is_true( tiggerer.chaosClassSkillInUse ) )
{
tiggerer maps\mp\_utility::setLowerMessage( "skill_in_use", &"ALIEN_CHAOS_SKILL_IN_USE", 3 );
continue;
}
break;
case "combo_freeze":
if( is_true( tiggerer.hasComboFreeze ) )
{
tiggerer maps\mp\_utility::setLowerMessage( "cant_use", &"ALIEN_CHAOS_CANT_PICKUP_BONUS", 3 );
continue;
}
break;
default:
break;
}
}
if (tiggerer == player
&& self useHoldThink( player, level.boxSettings[ self.boxType ].useTime )
)
{
self notify( "captured", player );
}
}
}
isFriendlyToBox( box )
{
return ( level.teamBased
&& self.team == box.team );
}
box_timeOut() // self == box
{
self endon( "death" );
level endon ( "game_ended" );
if ( box_should_leave_immediately() )
{
wait 0.05;
}
else
{
lifeSpan = level.boxSettings[ self.boxType ].lifeSpan;
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( lifeSpan );
}
self box_leave();
}
box_should_leave_immediately()
{
if ( ( self.boxtype == "deployable_ammo" && self.upgrade_rank == 4 ) || ( self.boxtype == "deployable_specialammo_comb" && self.upgrade_rank == 4 ) ) // stay to regen ammo
return false;
if ( maps\mp\alien\_utility::isPlayingSolo() && ( !isdefined( self.air_dropped ) || !self.air_dropped ) )
return true;
return false;
}
box_leave()
{
// TODO: get sound for this
//if ( isDefined( self.owner ) )
// self.owner thread leaderDialogOnPlayer( "sentry_gone" );
PlayFX( getfx( "deployablebox_crate_destroy" ), self.origin );
wait( 0.05 );
self notify( "death" );
}
deleteOnOwnerDeath( owner ) // self == box.friendlyModel or box.enemyModel, owner == box
{
wait ( 0.25 );
self linkTo( owner, "tag_origin", (0,0,0), (0,0,0) );
owner waittill ( "death" );
box_leave();
}
box_ModelTeamUpdater( showForTeam ) // self == box model (enemy or friendly)
{
self endon ( "death" );
self hide();
foreach ( player in level.players )
{
if ( player.team == showForTeam )
self showToPlayer( player );
}
for ( ;; )
{
level waittill ( "joined_team" );
self hide();
foreach ( player in level.players )
{
if ( player.team == showForTeam )
self showToPlayer( player );
}
}
}
useHoldThink( player, useTime )
{
if ( IsPlayer(player) )
player playerLinkTo( self );
else
player LinkTo( self );
player playerLinkedOffsetEnable();
player.boxParams = SpawnStruct();
player.boxParams.curProgress = 0;
player.boxParams.inUse = true;
player.boxParams.useRate = 0;
if ( isDefined( useTime ) )
{
player.boxParams.useTime = useTime;
}
else
{
player.boxParams.useTime = DEFAULT_USE_TIME;
}
//player _disableWeapon();
player disable_weapon_timeout( ( useTime + 0.05 ), "deployable_weapon_management" );
if ( IsPlayer(player) )
player thread personalUseBar( self );
result = useHoldThinkLoop( player );
assert ( isDefined( result ) );
if ( isAlive( player ) )
{
//player _enableWeapon();
player enable_weapon_wrapper( "deployable_weapon_management" );
player unlink();
}
if ( !isDefined( self ) )
return false;
player.boxParams.inUse = false;
player.boxParams.curProgress = 0;
return ( result );
}
personalUseBar( object ) // self == player
{
self endon( "disconnect" );
useBar = createPrimaryProgressBar( 0, 25 );
useBarText = createPrimaryProgressBarText( 0, 25 );
useBarText setText( level.boxSettings[ object.boxType ].capturingString );
lastRate = -1;
while ( isReallyAlive( self ) && isDefined( object ) && self.boxParams.inUse && object.isUsable && !level.gameEnded )
{
if ( lastRate != self.boxParams.useRate )
{
if( self.boxParams.curProgress > self.boxParams.useTime)
self.boxParams.curProgress = self.boxParams.useTime;
useBar updateBar( self.boxParams.curProgress / self.boxParams.useTime, (1000 / self.boxParams.useTime) * self.boxParams.useRate );
if ( !self.boxParams.useRate )
{
useBar hideElem();
useBarText hideElem();
}
else
{
useBar showElem();
useBarText showElem();
}
}
lastRate = self.boxParams.useRate;
wait ( 0.05 );
}
useBar destroyElem();
useBarText destroyElem();
}
useHoldThinkLoop( player )
{
while( !level.gameEnded && isDefined( self ) && isReallyAlive( player ) && player useButtonPressed() && player.boxParams.curProgress < player.boxParams.useTime )
{
player.boxParams.curProgress += (50 * player.boxParams.useRate);
if ( isDefined( player.objectiveScaler ) )
player.boxParams.useRate = 1 * player.objectiveScaler;
else
player.boxParams.useRate = 1;
if ( player.boxParams.curProgress >= player.boxParams.useTime )
return ( isReallyAlive( player ) );
wait 0.05;
}
return false;
}
disableWhenJuggernaut() // self == box
{
level endon( "game_ended" );
self endon( "death" );
while( true )
{
level waittill( "juggernaut_equipped", player );
self maps\mp\_entityheadIcons::setHeadIcon( player, "", (0,0,0) );
self box_disablePlayerUse( player );
self thread doubleDip( player );
}
}
addBoxToLevelArray() // self == box
{
// put the newly created box in the level array for the box type
level.deployable_box[ self.boxType ][ self GetEntityNumber() ] = self;
}
removeBoxFromLevelArray() // self == box
{
level.deployable_box[ self.boxType ][ self GetEntityNumber() ] = undefined;
}
default_canUseDeployable( boxEnt ) // self == player
{
if( ( isDefined( boxEnt ) && boxEnt.owner == self || self maps\mp\alien\_prestige::prestige_getNoDeployables() == 1.0 ) && !isdefined( boxEnt.air_dropped ) )
{
return false;
}
return true;
}
default_OnUseDeployable( boxent ) //self =a player
{
self thread maps\mp\alien\_persistence::deployablebox_used_track( boxEnt );
maps\mp\alien\_utility::deployable_box_onuse_message( boxent );
}
default_tryUseDeployable( lifeId, BOX_TYPE ) // self == player
{
result = self maps\mp\alien\_combat_resources::alien_beginDeployableViaMarker( lifeId, BOX_TYPE );
if( ( !IsDefined( result ) || !result ) )
{
return false;
}
return true;
}
init_deployable( BOX_TYPE, boxconfig )
{
if ( !IsDefined( level.boxSettings ) )
{
level.boxSettings = [];
}
level.boxSettings[ BOX_TYPE ] = boxConfig;
if ( !IsDefined( level.killStreakFuncs ) )
{
level.killStreakFuncs = [];
}
//level.killStreakFuncs[ BOX_TYPE ] = ::default_tryUseDeployable;
level.deployable_box[ BOX_TYPE ] = []; // storing each created box in their own array
}