614 lines
15 KiB
Plaintext
614 lines
15 KiB
Plaintext
|
|
||
|
object supply_crate {
|
||
|
void preinit();
|
||
|
void syncFields();
|
||
|
void init();
|
||
|
void destroy();
|
||
|
|
||
|
float OnUpdateCrosshairInfo( entity p );
|
||
|
void OnKilled( entity inflictor, entity attacker, float damage, vector direction, float location );
|
||
|
|
||
|
void vSetDeployableOwner( entity p );
|
||
|
void OnOwnerChanged();
|
||
|
|
||
|
void vOnDeploy();
|
||
|
void OnDeployedChanged() { vOnDeploy(); }
|
||
|
|
||
|
|
||
|
void Idle();
|
||
|
void Supply();
|
||
|
|
||
|
void LogLifeTime();
|
||
|
|
||
|
void SetupCommandMap();
|
||
|
|
||
|
void UpdateGUI();
|
||
|
|
||
|
void Fizzle();
|
||
|
void RemoveThread( float removeTime );
|
||
|
void vRemoveObject() { Fizzle(); }
|
||
|
boolean vIsSupplyDrop() { return true; }
|
||
|
float vGetSupplyDropCreationTime();
|
||
|
|
||
|
boolean vBlockVehicleSpawn() { return true; }
|
||
|
|
||
|
void vOnBindMasterDestroyed();
|
||
|
|
||
|
void BoundsKillThread();
|
||
|
void DropSoundThread();
|
||
|
|
||
|
void HideParachute();
|
||
|
|
||
|
void OnFizzleChanged();
|
||
|
void OnSupplyCountChanged();
|
||
|
|
||
|
void vBindToEntity( entity ent );
|
||
|
|
||
|
boolean vDropItemTrace( vector tStart, vector tEnd, entity passEntity, vector targetPos );
|
||
|
boolean ValidDropTrace( vector originalPos );
|
||
|
boolean vAllowDrop();
|
||
|
|
||
|
float GetSupplyCrateIndex();
|
||
|
float GetSupplyCrateCount();
|
||
|
|
||
|
float supplyCount;
|
||
|
float supplyMax;
|
||
|
float lastSupplyCount;
|
||
|
|
||
|
float creationTime;
|
||
|
|
||
|
float repairRange;
|
||
|
float commandMapHandle;
|
||
|
float commandMapHandleEnemy;
|
||
|
|
||
|
string packageName;
|
||
|
|
||
|
player owner;
|
||
|
entity vGetOwner() { return owner; }
|
||
|
|
||
|
handle objectName;
|
||
|
|
||
|
float usedProficiency;
|
||
|
|
||
|
handle statUsed;
|
||
|
handle statTimeUsed;
|
||
|
handle statNumDestroyed;
|
||
|
|
||
|
boolean removeThreadActive;
|
||
|
boolean deployed;
|
||
|
boolean fizzle;
|
||
|
|
||
|
entity bindEntity;
|
||
|
|
||
|
boolean allowDrop;
|
||
|
}
|
||
|
|
||
|
void supply_crate::syncFields() {
|
||
|
syncBroadcast( "supplyCount" );
|
||
|
syncBroadcast( "owner" );
|
||
|
syncBroadcast( "deployed" );
|
||
|
syncBroadcast( "fizzle" );
|
||
|
|
||
|
syncCallback( "owner", "OnOwnerChanged" );
|
||
|
syncCallback( "deployed", "OnDeployedChanged" );
|
||
|
syncCallback( "fizzle", "OnFizzleChanged" );
|
||
|
syncCallback( "supplyCount", "OnSupplyCountChanged" );
|
||
|
}
|
||
|
|
||
|
void supply_crate::preinit() {
|
||
|
repairRange = MetresToInches( getFloatKeyWithDefault( "repair_range", 2.5f ) );
|
||
|
packageName = getKey( "pck_items" );
|
||
|
supplyMax = getFloatKeyWithDefault( "max_supply", 50.f );
|
||
|
supplyCount = supplyMax;
|
||
|
lastSupplyCount = supplyMax;
|
||
|
|
||
|
objectName = sys.localizeString( getKey( "object_name" ) );
|
||
|
|
||
|
usedProficiency = GetProficiency( getKey( "prof_used" ) );
|
||
|
|
||
|
creationTime = sys.getTime();
|
||
|
|
||
|
commandMapHandle = -1;
|
||
|
commandMapHandleEnemy = -1;
|
||
|
|
||
|
statUsed = -1;
|
||
|
statTimeUsed = -1;
|
||
|
statNumDestroyed = -1;
|
||
|
|
||
|
string statName = getKey( "stat_name" );
|
||
|
if ( statName != "" ) {
|
||
|
statUsed = sys.allocStatInt( statName + "_uses" );
|
||
|
statTimeUsed = sys.allocStatInt( statName + "_time_used" );
|
||
|
statNumDestroyed = sys.allocStatInt( statName + "_killed" );
|
||
|
}
|
||
|
|
||
|
creationTime = sys.getTime();
|
||
|
|
||
|
setContents( CONTENTS_RENDERMODEL | CONTENTS_PLAYERCLIP | CONTENTS_VEHICLECLIP | CONTENTS_FLYERHIVECLIP );
|
||
|
}
|
||
|
|
||
|
void supply_crate::init() {
|
||
|
SetupCommandMap();
|
||
|
|
||
|
if ( !sys.isClient() ) {
|
||
|
owner.binAdd( self );
|
||
|
player p = owner;
|
||
|
if ( p != $null_entity ) {
|
||
|
p.setPlayerSupplyCrateState( self, false );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
setState( "Idle" );
|
||
|
}
|
||
|
|
||
|
void supply_crate::destroy() {
|
||
|
sys.freeCMIcon( self, commandMapHandle );
|
||
|
sys.freeCMIcon( self, commandMapHandleEnemy );
|
||
|
|
||
|
LogLifeTime();
|
||
|
|
||
|
sys.killThread( "RemoveThread_" + getName() );
|
||
|
|
||
|
if ( !sys.isClient() ) {
|
||
|
player p = owner;
|
||
|
if ( p != $null_entity ) {
|
||
|
p.setPlayerSupplyCrateState( self, true );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( owner == sys.getLocalPlayer() ) {
|
||
|
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.supplyCrateHealth0", 0 );
|
||
|
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.supplyCrateSupplies0", 0 );
|
||
|
|
||
|
float count = GetSupplyCrateCount();
|
||
|
if ( count < 2 ) {
|
||
|
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.supplyCrateHealth1", 0 );
|
||
|
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.supplyCrateSupplies1", 0 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( owner != $null_entity ) {
|
||
|
owner.binRemove( self );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void supply_crate::vOnDeploy() {
|
||
|
if ( !sys.isClient() ) {
|
||
|
deployed = true;
|
||
|
|
||
|
G_GiveDeployBonus( owner, self );
|
||
|
}
|
||
|
|
||
|
float hitGroundEffect = getFloatKey( "play_hitground_effect" );
|
||
|
if ( hitGroundEffect ) {
|
||
|
startSound( "snd_drop", SND_DEPLOYABLE_IDLE );
|
||
|
playEffect( "fx_hitground", "origin", false );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void supply_crate::LogLifeTime() {
|
||
|
if ( owner == $null_entity ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
float t = sys.getTime() - creationTime;
|
||
|
sys.increaseStatInt( statTimeUsed, owner.getEntityNumber(), t );
|
||
|
}
|
||
|
|
||
|
void supply_crate::Idle() {
|
||
|
if ( sys.isClient() ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
sys.wait( 0.1f );
|
||
|
|
||
|
thread BoundsKillThread();
|
||
|
while ( true ) {
|
||
|
if ( isAtRest() ) {
|
||
|
if ( bindEntity != $null_entity ) {
|
||
|
if ( !sys.isClient() ) {
|
||
|
bind( bindEntity );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( !removeThreadActive ) {
|
||
|
thread DropSoundThread();
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
sys.waitFrame();
|
||
|
}
|
||
|
sys.killThread( "BoundsKillThread_" + getName() );
|
||
|
|
||
|
while ( true ) {
|
||
|
sys.wait( 1.f );
|
||
|
if ( !removeThreadActive ) {
|
||
|
Supply();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void supply_crate::Supply() {
|
||
|
vector mins, maxs;
|
||
|
|
||
|
mins = getAbsMins() - '32 32 0';
|
||
|
maxs = getAbsMaxs() + '32 32 8';
|
||
|
|
||
|
entitiesInBounds( mins, maxs, CONTENTS_BODY | CONTENTS_SLIDEMOVER, 1.0f );
|
||
|
filterEntitiesByClass( "idPlayer", 1 );
|
||
|
float count = filterEntitiesByAllegiance( TA_FLAG_FRIEND, 1 );
|
||
|
|
||
|
float i;
|
||
|
for ( i = 0; i < count; i++ ) {
|
||
|
entity p = getBoundsCacheEntity( i );
|
||
|
if ( p.getHealth() <= 0 ) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if ( p.givePackage( packageName ) ) {
|
||
|
supplyCount = supplyCount - 1;
|
||
|
OnSupplyCountChanged();
|
||
|
|
||
|
if ( owner != $null_entity ) {
|
||
|
if ( owner != p ) {
|
||
|
if ( usedProficiency != -1 ) {
|
||
|
owner.giveProficiency( usedProficiency, 1.f, $null, "supply crate used" );
|
||
|
}
|
||
|
sys.increaseStatInt( statUsed, owner.getEntityNumber(), 1 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( supplyCount == 0 ) {
|
||
|
vRemoveObject();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void supply_crate::SetupCommandMap() {
|
||
|
commandMapHandle = sys.allocCMIcon( self, getFloatKey( "icon_sort_cm" ) );
|
||
|
float commandMapSize = getFloatKeyWithDefault( "icon_size_cm", 16.f );
|
||
|
|
||
|
sys.setCMIconDrawMode( commandMapHandle, DM_ROTATED_MATERIAL );
|
||
|
sys.setCMIconSize( commandMapHandle, commandMapSize );
|
||
|
sys.setCMIconColorMode( commandMapHandle, CM_ALLEGIANCE );
|
||
|
sys.setCMIconMaterial( commandMapHandle, GetMaterial( getKey( "mtr_commandmap" ) ) );
|
||
|
sys.setCMIconFlag( commandMapHandle, CMF_ALWAYSKNOWN | CMF_TEAMONLY );
|
||
|
|
||
|
commandMapHandleEnemy = sys.allocCMIcon( self, getFloatKey( "icon_sort_cm" ) );
|
||
|
sys.setCMIconDrawMode( commandMapHandleEnemy, DM_ROTATED_MATERIAL );
|
||
|
sys.setCMIconSize( commandMapHandleEnemy, commandMapSize );
|
||
|
sys.setCMIconColorMode( commandMapHandleEnemy, CM_ALLEGIANCE );
|
||
|
sys.setCMIconMaterial( commandMapHandleEnemy, GetMaterial( getKey( "mtr_commandmap" ) ) );
|
||
|
sys.setCMIconFlag( commandMapHandleEnemy, CMF_ENEMYONLY );
|
||
|
}
|
||
|
|
||
|
float supply_crate::OnUpdateCrosshairInfo( entity p ) {
|
||
|
if ( !sys.doClientSideStuff() ) {
|
||
|
return 1.f;
|
||
|
}
|
||
|
|
||
|
float allegiance = getEntityAllegiance( p );
|
||
|
vector color = GetAllegianceColor( allegiance );
|
||
|
|
||
|
chSetNumLines( 0 );
|
||
|
|
||
|
float index;
|
||
|
|
||
|
index = chAddLine();
|
||
|
chSetLineColor( index, color, 1.f );
|
||
|
chSetLineTextIndex( index, objectName );
|
||
|
chSetLineType( index, CI_TEXT );
|
||
|
chSetLineSize( index, 0, 0 );
|
||
|
|
||
|
index = chAddLine();
|
||
|
chSetLineColor( index, color, 0.5f );
|
||
|
chSetLineType( index, CI_BAR );
|
||
|
chSetLineFraction( index, getHealth() / getMaxHealth() );
|
||
|
chSetLineSize( index, 100, CROSSHAIR_INFO_BAR_HEIGHT );
|
||
|
|
||
|
if ( allegiance == TA_FRIEND ) {
|
||
|
index = chAddLine();
|
||
|
chSetLineTextIndex( index, g_locStr_Supplies );
|
||
|
chSetLineColor( index, color, 1.f );
|
||
|
chSetLineType( index, CI_TEXT );
|
||
|
chSetLineSize( index, 0, 0 );
|
||
|
|
||
|
index = chAddLine();
|
||
|
chSetLineColor( index, color, 0.5f );
|
||
|
chSetLineType( index, CI_BAR );
|
||
|
chSetLineFraction( index, supplyCount / supplyMax );
|
||
|
chSetLineSize( index, 100, CROSSHAIR_INFO_BAR_HEIGHT );
|
||
|
}
|
||
|
|
||
|
return 1.f;
|
||
|
}
|
||
|
|
||
|
void supply_crate::OnKilled( entity inflictor, entity attacker, float damage, vector direction, float location ) {
|
||
|
if ( !sys.isClient() ) {
|
||
|
player attackPlayer = attacker;
|
||
|
if ( attackPlayer != $null_entity ) {
|
||
|
if ( getEntityAllegiance( inflictor ) == TA_ENEMY ) {
|
||
|
sys.increaseStatInt( statNumDestroyed, attackPlayer.getEntityNumber(), 1 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Fizzle();
|
||
|
|
||
|
entity next;
|
||
|
entity current;
|
||
|
for ( current = getNextTeamEntity(); current != $null_entity; current = next ) {
|
||
|
next = current.getNextTeamEntity();
|
||
|
current.vOnBindMasterDestroyed();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void supply_crate::vSetDeployableOwner( entity p ) {
|
||
|
owner = p;
|
||
|
OnOwnerChanged();
|
||
|
}
|
||
|
|
||
|
void supply_crate::UpdateGUI() {
|
||
|
sys.threadName( "UpdateGUI_" + getName() );
|
||
|
while( true ) {
|
||
|
if ( !removeThreadActive ) {
|
||
|
float index = GetSupplyCrateIndex();
|
||
|
if ( index == 0 ) {
|
||
|
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.supplyCrateHealth0", getHealth() / getMaxHealth() );
|
||
|
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.supplyCrateSupplies0", supplyCount / supplyMax );
|
||
|
if ( GetSupplyCrateCount() == 1 ) {
|
||
|
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.supplyCrateHealth1", 0 );
|
||
|
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.supplyCrateSupplies1", 0 );
|
||
|
}
|
||
|
} else if ( index == 1 ) {
|
||
|
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.supplyCrateHealth1", getHealth() / getMaxHealth() );
|
||
|
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.supplyCrateSupplies1", supplyCount / supplyMax );
|
||
|
}
|
||
|
}
|
||
|
sys.waitFrame();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void supply_crate::OnOwnerChanged() {
|
||
|
if ( owner == sys.getLocalPlayer() ) {
|
||
|
sys.killThread( "UpdateGUI_" + getName() );
|
||
|
thread UpdateGUI();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void supply_crate::BoundsKillThread() {
|
||
|
float damageIndex = GetDamage( getKey( "dmg_crush" ) );
|
||
|
|
||
|
while ( true ) {
|
||
|
vector mins = getAbsMins();
|
||
|
vector maxs = getAbsMaxs();
|
||
|
mins += '8 8 -32';
|
||
|
maxs -= '8 8 0';
|
||
|
|
||
|
float count = entitiesInBounds( mins, maxs, MASK_SHOT_RENDERMODEL | MASK_SHOT_BOUNDINGBOX, 1 );
|
||
|
float index;
|
||
|
for ( index = 0; index < count; index++ ) {
|
||
|
entity other = getBoundsCacheEntity( index );
|
||
|
if ( other == self ) {
|
||
|
continue;
|
||
|
}
|
||
|
if ( other != $null_entity ) {
|
||
|
other.applyDamage( $null_entity, self, '0 0 -1', damageIndex, 1.f, $null_entity );
|
||
|
}
|
||
|
|
||
|
vehicle_base v = other;
|
||
|
if ( v != $null_entity ) {
|
||
|
vRemoveObject();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( removeThreadActive ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
sys.waitFrame();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void supply_crate::Fizzle() {
|
||
|
if ( removeThreadActive ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
startSound( "snd_drop", SND_DEPLOYABLE );
|
||
|
playEffect( "fx_fizzle", "", 0 );
|
||
|
|
||
|
HideParachute();
|
||
|
|
||
|
hide();
|
||
|
disablePhysics();
|
||
|
forceDisableClip();
|
||
|
removeThreadActive = true;
|
||
|
fizzle = true;
|
||
|
|
||
|
if ( !sys.isClient() ) {
|
||
|
thread RemoveThread( 2.0 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void supply_crate::RemoveThread( float removeTime ) {
|
||
|
sys.wait( removeTime );
|
||
|
remove();
|
||
|
}
|
||
|
|
||
|
float supply_crate::vGetSupplyDropCreationTime() {
|
||
|
return creationTime;
|
||
|
}
|
||
|
|
||
|
void supply_crate::DropSoundThread() {
|
||
|
startSound( "snd_drop", SND_DEPLOYABLE );
|
||
|
}
|
||
|
|
||
|
void supply_crate::HideParachute() {
|
||
|
if ( !sys.isClient() ) {
|
||
|
float index;
|
||
|
float count = entitiesOfCollection( "parachutes" );
|
||
|
for ( index = 0; index < count; index++ ) {
|
||
|
entity other = getBoundsCacheEntity( index );
|
||
|
if ( other.vGetOwner() == self ) {
|
||
|
other.vCancel();
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void supply_crate::OnFizzleChanged() {
|
||
|
if ( sys.isClient() ) {
|
||
|
Fizzle();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void supply_crate::OnSupplyCountChanged() {
|
||
|
entity p = sys.getLocalPlayer();
|
||
|
if ( p == $null_entity ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( supplyCount < lastSupplyCount ) {
|
||
|
startSound( "snd_supply", SND_DEPLOYABLE_IDLE );
|
||
|
}
|
||
|
lastSupplyCount = supplyCount;
|
||
|
}
|
||
|
|
||
|
void supply_crate::vOnBindMasterDestroyed() {
|
||
|
if ( !sys.isClient() ) {
|
||
|
unbind();
|
||
|
Fizzle();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void supply_crate::vBindToEntity( entity ent ) {
|
||
|
bindEntity = ent;
|
||
|
}
|
||
|
|
||
|
boolean supply_crate::vDropItemTrace( vector tStart, vector tEnd, entity passEntity, vector targetPos ) {
|
||
|
allowDrop = true;
|
||
|
|
||
|
float frac = sys.tracePoint( tStart, tEnd, CONTENTS_SOLID | CONTENTS_MOVEABLECLIP | CONTENTS_PLAYERCLIP, passEntity );
|
||
|
vector pos = sys.getTraceEndPos() + '0 0 1'; // just a tiny bit off of ground as it might not be flat
|
||
|
if ( frac == 1.0f || sys.getTraceNormal() * vec3_up < 0.99f ) {
|
||
|
if ( sys.fabs( pos_z - targetPos_z ) > 128 ) {
|
||
|
allowDrop = false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
// try to avoid clipping into buildings
|
||
|
if ( !sys.checkContents( pos, getMins(), getMaxs(), CONTENTS_SOLID | CONTENTS_MOVEABLECLIP | CONTENTS_PLAYERCLIP, passEntity ) ) {
|
||
|
if ( sys.fabs( pos_z - targetPos_z ) > 128 ) {
|
||
|
allowDrop = false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
vector size = getSize();
|
||
|
pos_x = pos_x + size_x / 2;
|
||
|
pos_y = pos_y + size_y / 2;
|
||
|
|
||
|
vector cratePos;
|
||
|
cratePos_x = pos_x - size_x;
|
||
|
cratePos_y = pos_y - size_y;
|
||
|
cratePos_z = pos_z;
|
||
|
sys.trace( cratePos + '0 0 2048', cratePos + '0 0 -128', getMins(), getMaxs(), CONTENTS_SOLID | CONTENTS_MOVEABLECLIP | CONTENTS_PLAYERCLIP, passEntity );
|
||
|
if ( ValidDropTrace( cratePos ) ) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
cratePos_x = pos_x;
|
||
|
cratePos_y = pos_y - size_y;
|
||
|
sys.trace( cratePos + '0 0 2048', cratePos + '0 0 -128', getMins(), getMaxs(), CONTENTS_SOLID | CONTENTS_MOVEABLECLIP | CONTENTS_PLAYERCLIP, passEntity );
|
||
|
if ( ValidDropTrace( cratePos ) ) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
cratePos_x = pos_x - size_x;
|
||
|
cratePos_y = pos_y;
|
||
|
sys.trace( cratePos + '0 0 2048', cratePos + '0 0 -128', getMins(), getMaxs(), CONTENTS_SOLID | CONTENTS_MOVEABLECLIP | CONTENTS_PLAYERCLIP, passEntity );
|
||
|
if ( ValidDropTrace( cratePos ) ) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
cratePos_x = pos_x;
|
||
|
cratePos_y = pos_y;
|
||
|
sys.trace( cratePos + '0 0 2048', cratePos + '0 0 -128', getMins(), getMaxs(), CONTENTS_SOLID | CONTENTS_MOVEABLECLIP | CONTENTS_PLAYERCLIP, passEntity );
|
||
|
if ( ValidDropTrace( cratePos ) ) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
sys.tracePoint( tStart, tEnd, CONTENTS_SOLID | CONTENTS_MOVEABLECLIP | CONTENTS_PLAYERCLIP, passEntity );
|
||
|
if ( sys.fabs( pos_z - targetPos_z ) > 128 ) {
|
||
|
allowDrop = false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
boolean supply_crate::ValidDropTrace( vector originalPos ) {
|
||
|
vector pos = sys.getTraceEndPos();
|
||
|
if ( sys.fabs( pos_z - originalPos_z ) > 4 ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if ( sys.getTraceFraction() == 1.0f
|
||
|
|| ( sys.getTraceNormal() * vec3_up < 0.99f )
|
||
|
|| ( sys.getTraceSurfaceFlags() & SURF_NOIMPACT )
|
||
|
|| ( sys.getTraceEntity() != $null_entity && sys.getTraceEntity() != sys.getEntity( "worldspawn" ) ) ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
float supply_crate::GetSupplyCrateIndex() {
|
||
|
if ( owner == $null_entity ) {
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
float i;
|
||
|
float num = owner.binGetSize();
|
||
|
float index = 0;
|
||
|
|
||
|
for ( i = 0; i < num; i++ ) {
|
||
|
entity other = owner.binGet( i );
|
||
|
if ( other.inCollection( "supply_crate" ) ) {
|
||
|
if ( other == self ) {
|
||
|
return index;
|
||
|
} else {
|
||
|
index++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
float supply_crate::GetSupplyCrateCount() {
|
||
|
if ( owner == $null_entity ) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
float i;
|
||
|
float num = owner.binGetSize();
|
||
|
float count = 0;
|
||
|
|
||
|
for ( i = 0; i < num; i++ ) {
|
||
|
entity other = owner.binGet( i );
|
||
|
if ( other.inCollection( "supply_crate" ) ) {
|
||
|
count++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
boolean supply_crate::vAllowDrop() {
|
||
|
return allowDrop;
|
||
|
}
|