984 lines
24 KiB
Plaintext
984 lines
24 KiB
Plaintext
/***********************************************************************
|
|
|
|
util.script
|
|
|
|
This defines utility functions for scripts
|
|
|
|
***********************************************************************/
|
|
|
|
object rules {
|
|
boolean IsStopwatch();
|
|
float GetFloatKeyWithSuffix( entity ent, string key, float defaultValue );
|
|
}
|
|
|
|
rules gameRules;
|
|
|
|
vector g_colorGreen;
|
|
vector g_colorRed;
|
|
vector g_colorLtGray;
|
|
vector g_colorWhite;
|
|
vector g_colorYellow;
|
|
vector g_colorBlue;
|
|
|
|
vector g_vectorDown;
|
|
vector g_vectorUp;
|
|
vector g_vectorZero;
|
|
|
|
float g_radarMaterial;
|
|
|
|
vector vec3_origin;
|
|
vector vec3_up;
|
|
vector vec3_down;
|
|
|
|
wstring wstr_empty;
|
|
handle invalid_handle;
|
|
|
|
float g_ammoStroyent;
|
|
float g_ammoStroyentPacket;
|
|
float g_ammoMachinePistol;
|
|
float g_ammoGrenade;
|
|
float g_ammoAssaultRifle;
|
|
float g_ammoShotgun;
|
|
float g_ammoSniperRifle;
|
|
float g_ammoPistol;
|
|
float g_ammoRocketLauncher;
|
|
float g_ammoGPMG;
|
|
|
|
float g_proficiencyLightWeapons;
|
|
|
|
float g_proficiencyFieldOps;
|
|
float g_proficiencyMedic;
|
|
float g_proficiencyEngineer;
|
|
float g_proficiencyCovertOps;
|
|
float g_proficiencySoldier;
|
|
|
|
float g_proficiencyTechnician;
|
|
float g_proficiencyOppressor;
|
|
float g_proficiencyConstructor;
|
|
float g_proficiencyInfiltrator;
|
|
float g_proficiencyAggressor;
|
|
|
|
float g_proficiencyBattleSense;
|
|
float g_proficiencyVehicle;
|
|
|
|
float g_playerClassSoldier;
|
|
float g_playerClassMedic;
|
|
float g_playerClassCovertOps;
|
|
float g_playerClassEngineer;
|
|
float g_playerClassFieldOps;
|
|
|
|
float g_playerClassAggressor;
|
|
float g_playerClassTechnician;
|
|
float g_playerClassConstructor;
|
|
float g_playerClassOppressor;
|
|
float g_playerClassInfiltrator;
|
|
|
|
handle g_locStr_Destroyed;
|
|
handle g_locStr_Disabled;
|
|
handle g_locStr_Range;
|
|
handle g_locStr_Meters;
|
|
handle g_locStr_Capture;
|
|
handle g_locStr_SpawnHost;
|
|
handle g_locStr_Supplies;
|
|
handle g_locStr_SupplyCrate;
|
|
handle g_locStr_Unconscious;
|
|
handle g_locStr_Dead;
|
|
handle g_locStr_Hacking;
|
|
handle g_locStr_Arming;
|
|
handle g_locStr_Disarming;
|
|
handle g_locStr_Repairing;
|
|
handle g_locStr_Constructing;
|
|
handle g_locStr_Capturing;
|
|
handle g_locStr_Liberating;
|
|
handle g_locStr_Implanting;
|
|
handle g_locStr_Disguising;
|
|
handle g_locStr_Charge;
|
|
handle g_locStr_Landmine;
|
|
handle g_locStr_Tripmine;
|
|
handle g_locStr_Proxmine;
|
|
handle g_locStr_Scrambler;
|
|
handle g_locStr_DoNotOwnTerritory;
|
|
handle g_locStr_NoCharge;
|
|
handle g_locStr_Dismantle;
|
|
handle g_locStr_Drone;
|
|
handle g_locStr_Scud;
|
|
handle g_locStr_Airstrike;
|
|
handle g_locStr_Completed;
|
|
handle g_locStr_Objective;
|
|
handle g_locStr_UnarmedMine;
|
|
handle g_locStr_SelfArmingTripmine;
|
|
handle g_locStr_SelfArmingProxymine;
|
|
handle g_locStr_UnarmedTripmine;
|
|
handle g_locStr_UnarmedProxymine;
|
|
handle g_locStr_Spotting;
|
|
handle g_locStr_Reviving;
|
|
handle g_locStr_BadObjective;
|
|
handle g_locStr_Someone;
|
|
handle g_locStr_TeleportBeacon;
|
|
|
|
float g_primaryObjectiveIndex;
|
|
|
|
object task {
|
|
}
|
|
|
|
object team_base {
|
|
float GetFireSupportDelayScale() { return 1.f; }
|
|
}
|
|
|
|
object cvar {
|
|
}
|
|
|
|
team_base stroggTeam;
|
|
team_base gdfTeam;
|
|
|
|
cvar g_disableVehicleSpawns;
|
|
cvar pm_thirdperson;
|
|
cvar bse_projectileEffect;
|
|
cvar g_friendlyColor;
|
|
cvar g_neutralColor;
|
|
cvar g_enemyColor;
|
|
cvar g_maxProficiency;
|
|
cvar g_fasterSpawn;
|
|
cvar si_rules;
|
|
cvar g_noVehicleSpawnInvulnerability;
|
|
cvar g_objectiveDecayTime;
|
|
|
|
cvar g_drawMineIcons;
|
|
cvar g_allowMineIcons;
|
|
cvar g_mineIconSize;
|
|
cvar g_mineIconAlphaScale;
|
|
|
|
cvar g_aptWarning;
|
|
|
|
object gameplay_base;
|
|
gameplay_base gameplayManager;
|
|
|
|
/*
|
|
==================
|
|
abs
|
|
|
|
Returns the absolute value of a number
|
|
==================
|
|
*/
|
|
float abs( float value ) {
|
|
if ( value < 0 ) {
|
|
return value * -1;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
/*
|
|
==================
|
|
rint
|
|
|
|
Returns the nearest integer value of a number
|
|
==================
|
|
*/
|
|
float rint( float value ) {
|
|
return sys.floor( value + 0.5f );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
min
|
|
|
|
Returns the lowest of two numbers
|
|
==================
|
|
*/
|
|
float min( float value1, float value2 ) {
|
|
if ( value1 < value2 ) {
|
|
return value1;
|
|
}
|
|
return value2;
|
|
}
|
|
|
|
/*
|
|
==================
|
|
max
|
|
|
|
Returns the highest of two numbers
|
|
==================
|
|
*/
|
|
float max( float value1, float value2 ) {
|
|
if ( value1 > value2 ) {
|
|
return value1;
|
|
}
|
|
return value2;
|
|
}
|
|
|
|
/*
|
|
==================
|
|
delayRemoveThread
|
|
|
|
Service thread for delayRemove.
|
|
==================
|
|
*/
|
|
void delayRemoveThread( entity ent, float mytime ) {
|
|
sys.wait( mytime );
|
|
ent.remove();
|
|
}
|
|
|
|
/*
|
|
==================
|
|
delayRemove
|
|
|
|
Causes an entity to be removed after a specified amount of time.
|
|
==================
|
|
*/
|
|
void delayRemove( entity ent, float mytime ) {
|
|
thread delayRemoveThread( ent, mytime );
|
|
}
|
|
|
|
#define InchesToMetres( value ) ( ( value ) * 0.0254f )
|
|
#define MetresToInches( value ) ( ( value ) * 39.37f )
|
|
#define UPStoKPH( value ) ( InchesToMetres( value ) * 3.6f )
|
|
#define KPHtoUPS( value ) ( MetresToInches( value ) / 3.6f )
|
|
|
|
/*
|
|
==================
|
|
GetQuickChat
|
|
==================
|
|
*/
|
|
float GetQuickChat( string value ) {
|
|
return sys.getDeclIndex( sys.getDeclType( "quickChatDef" ), value );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
GetStringMap
|
|
==================
|
|
*/
|
|
float GetStringMap( string value ) {
|
|
return sys.getDeclIndex( sys.getDeclType( "stringMap" ), value );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
GetTargetFilter
|
|
==================
|
|
*/
|
|
float GetTargetFilter( string value ) {
|
|
return sys.getDeclIndex( sys.getDeclType( "targetInfo" ), value );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
GetEntityDef
|
|
==================
|
|
*/
|
|
float GetEntityDef( string value ) {
|
|
return sys.getDeclIndex( sys.getDeclType( "entityDef" ), value );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
GetToolTip
|
|
==================
|
|
*/
|
|
float GetToolTip( string value ) {
|
|
return sys.getDeclIndex( sys.getDeclType( "toolTip" ), value );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
GetMaterial
|
|
==================
|
|
*/
|
|
float GetMaterial( string value ) {
|
|
return sys.getDeclIndex( sys.getDeclType( "material" ), value );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
GetTable
|
|
==================
|
|
*/
|
|
float GetTable( string value ) {
|
|
return sys.getDeclIndex( sys.getDeclType( "table" ), value );
|
|
}
|
|
|
|
|
|
/*
|
|
==================
|
|
GetProficiency
|
|
==================
|
|
*/
|
|
float GetProficiency( string value ) {
|
|
return sys.getDeclIndex( sys.getDeclType( "proficiencyItem" ), value );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
GetProficiencyType
|
|
==================
|
|
*/
|
|
float GetProficiencyType( string value ) {
|
|
return sys.getDeclIndex( sys.getDeclType( "proficiencyType" ), value );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
GetPlayerClass
|
|
==================
|
|
*/
|
|
float GetPlayerClass( string value ) {
|
|
return sys.getDeclIndex( sys.getDeclType( "playerClass" ), value );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
GetAmmoType
|
|
==================
|
|
*/
|
|
float GetAmmoType( string value ) {
|
|
return sys.getDeclIndex( sys.getDeclType( "ammoDef" ), value );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
GetDamage
|
|
==================
|
|
*/
|
|
float GetDamage( string value ) {
|
|
return sys.getDeclIndex( sys.getDeclType( "damageDef" ), value );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
GetDeployObject
|
|
==================
|
|
*/
|
|
float GetDeployObject( string value ) {
|
|
return sys.getDeclIndex( sys.getDeclType( "deployObject" ), value );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
GetPlayerTask
|
|
==================
|
|
*/
|
|
float GetPlayerTask( string value ) {
|
|
return sys.getDeclIndex( sys.getDeclType( "task" ), value );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
GetNumDeployObjects
|
|
==================
|
|
*/
|
|
float GetNumDeployObjects() {
|
|
return sys.getDeclCount( sys.getDeclType( "deployObject" ) );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
GetSoundShader
|
|
==================
|
|
*/
|
|
float GetSoundShader( string value ) {
|
|
return sys.getDeclIndex( sys.getDeclType( "sound" ), value );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
GetSoundShaderName
|
|
==================
|
|
*/
|
|
string GetSoundShaderName( float index ) {
|
|
return sys.getDeclName( sys.getDeclType( "sound" ), index );
|
|
}
|
|
|
|
|
|
/*
|
|
==================
|
|
SetupColors
|
|
==================
|
|
*/
|
|
void SetupColors() {
|
|
g_colorGreen = '0 1 0';
|
|
g_colorRed = '1 0 0';
|
|
g_colorLtGray = '0.75 0.75 0.75';
|
|
g_colorWhite = '1 1 1';
|
|
g_colorYellow = '1 1 0';
|
|
g_colorBlue = '0 0 1';
|
|
g_radarMaterial = GetMaterial( "_white_depth" );
|
|
g_vectorUp = '0 0 1';
|
|
g_vectorDown = '0 0 -1';
|
|
g_vectorZero = g_vectorZero;
|
|
}
|
|
|
|
|
|
/*
|
|
==================
|
|
GetAllegianceColor
|
|
==================
|
|
*/
|
|
|
|
vector GetAllegianceColor( float allegiance ) {
|
|
if ( allegiance == TA_FRIEND ) {
|
|
return g_friendlyColor.getVectorValue();
|
|
}
|
|
|
|
if ( allegiance == TA_ENEMY ) {
|
|
return g_enemyColor.getVectorValue();
|
|
}
|
|
|
|
return g_neutralColor.getVectorValue();
|
|
}
|
|
|
|
#define AngleDiff( a1, a2 ) sys.angleNormalize180( a1 - a2 )
|
|
|
|
string GetGlobalString( string key ) {
|
|
float def = GetEntityDef( "globalConstants" );
|
|
return sys.getEntityDefKey( def, key );
|
|
}
|
|
|
|
float GetGlobalInt( string key ) {
|
|
float def = GetEntityDef( "globalConstants" );
|
|
return sys.getEntityDefIntKey( def, key );
|
|
}
|
|
|
|
float GetGlobalFloat( string key ) {
|
|
float def = GetEntityDef( "globalConstants" );
|
|
return sys.getEntityDefFloatKey( def, key );
|
|
}
|
|
|
|
vector GetGlobalVector( string key ) {
|
|
float def = GetEntityDef( "globalConstants" );
|
|
return sys.getEntityDefVectorKey( def, key );
|
|
}
|
|
|
|
float MakeTerritoryIcon( entity ent ) {
|
|
float materialHandle = GetMaterial( ent.getKey( "mtr_territory" ) );
|
|
if ( materialHandle == -1 ) {
|
|
return -1;
|
|
}
|
|
|
|
vector worldMins;
|
|
vector worldMaxs;
|
|
|
|
entity other = ent.getEntityKey( "target_playzone" );
|
|
if ( other == $null_entity ) {
|
|
worldMins = sys.getWorldMins();
|
|
worldMaxs = sys.getWorldMaxs();
|
|
} else {
|
|
worldMins = other.getMins();
|
|
worldMaxs = other.getMaxs();
|
|
worldMins = sys.toWorldSpace( worldMins, other );
|
|
worldMaxs = sys.toWorldSpace( worldMaxs, other );
|
|
}
|
|
|
|
float territoryIconHandle = sys.allocCMIcon( ent, 100 );
|
|
|
|
vector worldSize = worldMaxs - worldMins;
|
|
|
|
vector temp;
|
|
|
|
temp = ent.getVectorKey( "territory_start" );
|
|
|
|
vector objectStart;
|
|
objectStart_x = worldMins_x + ( temp_x * worldSize_x );
|
|
objectStart_y = worldMins_y + ( temp_y * worldSize_y );
|
|
|
|
temp = ent.getVectorKey( "territory_end" );
|
|
|
|
vector objectEnd;
|
|
objectEnd_x = worldMins_x + ( temp_x * worldSize_x );
|
|
objectEnd_y = worldMins_y + ( temp_y * worldSize_y );
|
|
|
|
// sys.println( objectStart );
|
|
// sys.println( objectEnd );
|
|
|
|
vector objectSize = objectEnd - objectStart;
|
|
|
|
sys.setCMIconSize2d( territoryIconHandle, objectSize_x, objectSize_y );
|
|
sys.setCMIconSizeMode( territoryIconHandle, SM_WORLD );
|
|
sys.setCMIconFlag( territoryIconHandle, CMF_ALWAYSKNOWN );
|
|
sys.setCMIconFlag( territoryIconHandle, CMF_NOADJUST );
|
|
sys.setCMIconColorMode( territoryIconHandle, CM_ALLEGIANCE );
|
|
sys.setCMIconPositionMode( territoryIconHandle, PM_FIXED );
|
|
sys.setCMIconOrigin( territoryIconHandle, ( objectStart + objectEnd ) * 0.5f );
|
|
sys.setCMIconMaterial( territoryIconHandle, materialHandle );
|
|
|
|
return territoryIconHandle;
|
|
}
|
|
|
|
void FreeTerritoryIcon( entity territory, float territoryIconHandle ) {
|
|
if ( territoryIconHandle != -1 ) {
|
|
sys.freeCMIcon( territory, territoryIconHandle );
|
|
territoryIconHandle = -1;
|
|
}
|
|
}
|
|
|
|
void G_ProjectCircleDecal( float decalHandle, vector size, float depth, vector position, vector color ) {
|
|
vector startPos = position + ( g_vectorUp * depth * 0.5f );
|
|
|
|
vector forward;
|
|
forward_x = size_x * 0.5f;
|
|
|
|
vector side;
|
|
side_y = size_y * 0.5f;
|
|
|
|
sys.resetDecal( decalHandle );
|
|
sys.projectDecal( decalHandle, startPos + ( forward + side ), g_vectorDown, depth, 1, size, 0.f, color );
|
|
sys.projectDecal( decalHandle, startPos + ( forward - side ), g_vectorDown, depth, 1, size, 90.f, color );
|
|
sys.projectDecal( decalHandle, startPos + ( -forward + side ), g_vectorDown, depth, 1, size, 180.f, color );
|
|
sys.projectDecal( decalHandle, startPos + ( -forward + -side ), g_vectorDown, depth, 1, size, 270.f, color );
|
|
}
|
|
|
|
handle g_fireSupportStateStr;
|
|
void G_StringForFireSupportState( float state ) {
|
|
// todo: move the calls to localizeString to (even more!) globals?
|
|
// (yes)
|
|
if ( state == MPS_OUT_OF_RANGE ) {
|
|
g_fireSupportStateStr = sys.localizeString( "game/fire_sup/out_of_range" );
|
|
return;
|
|
}
|
|
if ( state == MPS_READY || state == MPS_NOT_LOCKED ) {
|
|
g_fireSupportStateStr = sys.localizeString( "game/fire_sup/ready" );
|
|
return;
|
|
}
|
|
if ( state == MPS_RELOADING ) {
|
|
g_fireSupportStateStr = sys.localizeString( "game/fire_sup/reloading" );
|
|
return;
|
|
}
|
|
if ( state == MPS_WAITING ) {
|
|
g_fireSupportStateStr = sys.localizeString( "game/fire_sup/waiting" );
|
|
return;
|
|
}
|
|
if ( state == MPS_DISABLED ) {
|
|
g_fireSupportStateStr = sys.localizeString( "game/fire_sup/disabled" );
|
|
return;
|
|
}
|
|
if ( state == MPS_NONE_ACTIVE ) {
|
|
g_fireSupportStateStr = sys.localizeString( "game/fire_sup/not_deployed" );
|
|
return;
|
|
}
|
|
if ( state == MPS_FIRING_PREPARE || state == MPS_FIRING ) {
|
|
g_fireSupportStateStr = sys.localizeString( "game/fire_sup/firing" );
|
|
return;
|
|
}
|
|
if ( state == MPS_LOCKING ) {
|
|
g_fireSupportStateStr = sys.localizeString( "game/fire_sup/locking" );
|
|
return;
|
|
}
|
|
if ( state == MPS_LOCKED ) {
|
|
g_fireSupportStateStr = sys.localizeString( "game/fire_sup/acquired" );
|
|
return;
|
|
}
|
|
|
|
if ( state == MPS_INVALID ) {
|
|
g_fireSupportStateStr = sys.localizeString( "game/fire_sup/invalid" );
|
|
return;
|
|
}
|
|
|
|
if ( state == MPS_LOCKED_ROCKETS ) {
|
|
g_fireSupportStateStr = sys.localizeString( "game/fire_sup/acquired/rockets" );
|
|
return;
|
|
}
|
|
|
|
g_fireSupportStateStr = sys.localizeString( "game/misc/unknown" );
|
|
}
|
|
|
|
void G_DelayRemoveEntity( entity ent, float delay ) {
|
|
sys.wait( delay );
|
|
ent.remove();
|
|
}
|
|
|
|
void G_DelayFireSupport( entity p, entity other, float delay ) {
|
|
team_base team = other.getGameTeam();
|
|
sys.setTargetTimerValue( sys.allocTargetTimer( FIRESUPPORT_TIMER_NAME ), p, sys.getTime() + ( delay * team.GetFireSupportDelayScale() ) );
|
|
sys.setTargetTimerValue( sys.allocTargetTimer( FIRESUPPORT_TIMER_START_NAME ), p, sys.getTime() );
|
|
}
|
|
|
|
/*
|
|
============
|
|
Localization
|
|
============
|
|
*/
|
|
|
|
// build the localized range string, e.g. "Range: 42m"
|
|
wstring G_BuildRangeStr( float range ) {
|
|
sys.pushLocString( int( range ) );
|
|
sys.pushLocStringIndex( g_locStr_Meters );
|
|
return sys.localizeStringArgs( "game/range" );
|
|
}
|
|
|
|
#define CLAMP( value, min, max ) \
|
|
if ( value < ( min ) ) value = ( min ); \
|
|
else if ( value > ( max ) ) value = ( max );
|
|
|
|
/*
|
|
==================
|
|
|
|
CallManualDeploy
|
|
|
|
bypasses the code, directly calls in a deployable
|
|
|
|
==================
|
|
*/
|
|
entity CallManualDeploy( string deployObject, string deployItem, object deployTeam, vector location, float angle ) {
|
|
if ( sys.isClient() ) {
|
|
return $null_entity;
|
|
}
|
|
|
|
float itemDef = GetEntityDef( deployItem );
|
|
|
|
entity obj = sys.spawn( deployObject );
|
|
obj.setGameTeam( deployTeam );
|
|
obj.vSetDeploymentParms( itemDef, -1, location, angle );
|
|
|
|
return obj.vGetItem();
|
|
}
|
|
|
|
/*
|
|
==================
|
|
|
|
G_TryFireScud
|
|
|
|
finds a scud launcher and attempts to fire at an entity
|
|
|
|
==================
|
|
*/
|
|
boolean G_TryFireScud( entity firer, entity targetEnt ) {
|
|
|
|
// TODO: Make it so that you can use sys to do entitiesOfCollection type stuff
|
|
entity worldspawn = sys.getEntity( "worldspawn" );
|
|
|
|
// set any MCP up to fire
|
|
float count = worldspawn.entitiesOfCollection( "mcp" );
|
|
|
|
float i;
|
|
for ( i = 0; i < count; i++ ) {
|
|
entity ent = worldspawn.getBoundsCacheEntity( i );
|
|
|
|
if ( ent.vFireScud( firer, targetEnt ) ) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
float G_CountMinesOwnedByEntity( entity p ) {
|
|
p.entitiesOfCollection( "mine" );
|
|
float count = p.filterEntitiesByAllegiance( TA_FLAG_FRIEND, 1 );
|
|
|
|
float number;
|
|
float index;
|
|
for ( index = 0; index < count; index++ ) {
|
|
entity mine = p.getBoundsCacheEntity( index );
|
|
|
|
if ( mine.vGetOwner() == p ) {
|
|
number++;
|
|
}
|
|
}
|
|
return number;
|
|
}
|
|
|
|
|
|
|
|
object firesupport_marker {
|
|
void preinit();
|
|
void DoWarning();
|
|
|
|
float range;
|
|
float endTime;
|
|
float nextPlayTime;
|
|
float warningRange;
|
|
string warningSound;
|
|
string warningSoundEnemy;
|
|
}
|
|
|
|
void firesupport_marker::preinit() {
|
|
range = getFloatKey( "range" );
|
|
endTime = sys.getTime() + getFloatKey( "warning_time" );
|
|
nextPlayTime = getFloatKey( "next_play_time" );
|
|
warningRange = getFloatKey( "warning_range" );
|
|
warningSound = getKey( "snd_ff_warning" );
|
|
warningSoundEnemy = getKey( "snd_ff_warning_enemy" );
|
|
|
|
thread DoWarning();
|
|
}
|
|
|
|
void firesupport_marker::DoWarning() {
|
|
while ( true ) {
|
|
entitiesOfCollection( "players" );
|
|
float playerCount = filterEntitiesByRadius( getWorldOrigin(), warningRange, 1 );
|
|
|
|
float i = 0;
|
|
for( i = 0; i < playerCount; i++ ) {
|
|
entity p = getBoundsCacheEntity( i );
|
|
if ( getEntityAllegiance( p ) == TA_FRIEND ) {
|
|
p.vPlayFFWarning( warningSound, nextPlayTime );
|
|
}/* else {
|
|
p.vPlayFFWarning( warningSoundEnemy, nextPlayTime );
|
|
}*/
|
|
}
|
|
|
|
if ( sys.getTime() > endTime ) {
|
|
break;
|
|
}
|
|
|
|
sys.wait( 1.f );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
boolean G_CheckFireSupportBlock( vector location, entity myPlayer ) {
|
|
myPlayer.entitiesOfCollection( "fs_block" );
|
|
float count = myPlayer.filterEntitiesByAllegiance( TA_FLAG_FRIEND, 1 );
|
|
|
|
float index;
|
|
for ( index = 0; index < count; index++ ) {
|
|
firesupport_marker marker = myPlayer.getBoundsCacheEntity( index );
|
|
if ( marker == $null_entity ) {
|
|
continue;
|
|
}
|
|
|
|
float range = marker.range * marker.range;
|
|
|
|
if ( sys.vecLengthSquared( location - marker.getWorldOrigin() ) < range ) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
entity G_CreateFiringMarker( entity ent, entity current, vector location ) {
|
|
if ( current == $null_entity ) {
|
|
string marker = ent.getKey( "def_firesupport_marker" );
|
|
if ( marker != "" ) {
|
|
current = sys.spawn( marker );
|
|
}
|
|
}
|
|
if ( current != $null_entity ) {
|
|
current.setOrigin( location );
|
|
current.setGameTeam( ent.getGameTeam() );
|
|
}
|
|
return current;
|
|
}
|
|
|
|
void G_NotifyNoCharge( entity p ) {
|
|
if( p == sys.getLocalViewPlayer() ) {
|
|
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.needsCharge", 1 );
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
BoundsDamage
|
|
==================
|
|
*/
|
|
void BoundsDamage( entity self, float dmgIndex ) {
|
|
vector mins = self.getAbsMins();
|
|
vector maxs = self.getAbsMaxs();
|
|
mins_z = mins_z - 64;
|
|
|
|
//sys.debugBounds( g_colorRed, mins, maxs, 0 );
|
|
|
|
float count = self.entitiesInBounds( mins, maxs, MASK_SHOT_RENDERMODEL | MASK_SHOT_BOUNDINGBOX, 1 );
|
|
float index;
|
|
for ( index = 0; index < count; index++ ) {
|
|
entity other = self.getBoundsCacheEntity( index );
|
|
if ( other == self ) {
|
|
continue;
|
|
}
|
|
if ( other != $null_entity ) {
|
|
if ( self.touchesBounds( other ) ) {
|
|
other.applyDamage( $null_entity, self, vec3_down, dmgIndex, 1.f, $null_entity );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
LocalBoundsDamage
|
|
==================
|
|
*/
|
|
void LocalBoundsDamage( vector mins, vector maxs, entity self, entity inflictor, float dmgIndex ) {
|
|
float count = self.entitiesInLocalBounds( mins, maxs, MASK_SHOT_RENDERMODEL | MASK_SHOT_BOUNDINGBOX );
|
|
float index;
|
|
for ( index = 0; index < count; index++ ) {
|
|
entity other = self.getBoundsCacheEntity( index );
|
|
if ( other == self ) {
|
|
continue;
|
|
}
|
|
if ( other == inflictor ) {
|
|
continue;
|
|
}
|
|
if ( other != $null_entity ) {
|
|
other.applyDamage( $null_entity, inflictor, vec3_down, dmgIndex, 1.f, $null_entity );
|
|
}
|
|
}
|
|
}
|
|
|
|
// more util files
|
|
#include "script/misc/zoomwidget.script"
|
|
|
|
void G_GiveSpottingProficiency( entity spotter ) {
|
|
spotter.vGiveSpotProficiency();
|
|
}
|
|
|
|
// Gordon: FIXME: These wont work, as many places they are being called from map scripts, which aren't run on the client, I also don't like the way this is set up anyway
|
|
void G_PlayObjectiveCompletedRoll( float team ) {
|
|
sys.assert( team == GDF || team == STROGG );
|
|
if ( team == GDF ) {
|
|
sys.startSoundDirect( gdfTeam.getKey( "snd_objective_complete_roll" ), SND_ANY );
|
|
} else {
|
|
sys.startSoundDirect( stroggTeam.getKey( "snd_objective_complete_roll" ), SND_ANY );
|
|
}
|
|
}
|
|
|
|
void G_PlayObjectiveCompletedRollEnt( entity ent ) {
|
|
sys.assert( ent != $null_entity && ent.getGameTeam() != $null_entity );
|
|
if ( ent.getGameTeam() == stroggTeam ) {
|
|
G_PlayObjectiveCompletedRoll( GDF );
|
|
} else {
|
|
G_PlayObjectiveCompletedRoll( STROGG );
|
|
}
|
|
}
|
|
|
|
void G_GiveDeployBonus( entity owner, entity item ) {
|
|
entity territory = sys.getTerritoryForPoint( item.getWorldOrigin(), $null_entity, 0.f, item.getIntKey( "deploybonus_requireactive" ) );
|
|
if ( territory != $null_entity ) {
|
|
owner.giveProficiency( GetProficiency( item.getKey( "prof_deploybonus" ) ), 1.f, $null, "item deployed" );
|
|
}
|
|
}
|
|
|
|
void G_SetPrimaryObjectiveIndex( float objIndex ) {
|
|
entity worldspawn = sys.getEntity( "worldspawn" );
|
|
|
|
g_primaryObjectiveIndex = objIndex;
|
|
|
|
float count = worldspawn.entitiesOfCollection( "objective_markers" );
|
|
float index;
|
|
for ( index = 0; index < count; index++ ) {
|
|
entity other = worldspawn.getBoundsCacheEntity( index );
|
|
other.vOnDeploy();
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
RangeUpdateThread
|
|
low frequency updates if crosshair distance is larger than CROSSHAIR_TRACE_DIST.
|
|
==================
|
|
*/
|
|
void RangeUpdateThread( player p, float maxDist ) {
|
|
vector forward;
|
|
vector tStart;
|
|
vector tEnd;
|
|
float dist;
|
|
|
|
if ( maxDist <= 0 || maxDist < CROSSHAIR_TRACE_DIST ) {
|
|
sys.warning( "Unexpected maxDist value: " + maxDist );
|
|
return;
|
|
}
|
|
|
|
while ( true ) {
|
|
sys.wait( 1.0f );
|
|
if ( !p.IsSniperScopeUp() ) {
|
|
continue;
|
|
}
|
|
|
|
dist = p.getCrosshairDistance( false );
|
|
if ( dist >= CROSSHAIR_TRACE_DIST ) {
|
|
forward = sys.angToForward( p.getViewAngles() );
|
|
tStart = ( forward * ( CROSSHAIR_TRACE_DIST - 128 ) ) + p.getViewOrigin();
|
|
tEnd = forward * maxDist + p.getViewOrigin();
|
|
sys.tracePoint( tStart, tEnd, MASK_SHOT_RENDERMODEL | CONTENTS_SHADOWCOLLISION | CONTENTS_SLIDEMOVER | CONTENTS_BODY | CONTENTS_PROJECTILE | CONTENTS_CROSSHAIRSOLID, p );
|
|
dist = CROSSHAIR_TRACE_DIST + sys.getTraceFraction() * ( maxDist - ( CROSSHAIR_TRACE_DIST - 128 ) );
|
|
if ( sys.getTraceFraction() == 1.0f || ( sys.getTraceSurfaceFlags() & SURF_NOIMPACT ) ) {
|
|
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "weapons.distance", -1 );
|
|
} else {
|
|
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "weapons.distance", dist );
|
|
}
|
|
} else {
|
|
// reset distance value
|
|
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "weapons.distance", -2 );
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
G_ContainsBounds
|
|
Check if one set of bounds is completely inside another set of bounds
|
|
==================
|
|
*/
|
|
boolean G_ContainsBounds( vector aMins, vector aMaxs, vector bMins, vector bMaxs, float epsilon ) {
|
|
// check mins
|
|
if ( aMins_x > bMins_x + epsilon ) {
|
|
return false;
|
|
}
|
|
|
|
if ( aMins_y > bMins_y + epsilon ) {
|
|
return false;
|
|
}
|
|
|
|
if ( aMins_z > bMins_z + epsilon ) {
|
|
return false;
|
|
}
|
|
|
|
// check maxs
|
|
if ( aMaxs_x < bMaxs_x - epsilon ) {
|
|
return false;
|
|
}
|
|
|
|
if ( aMaxs_y < bMaxs_y - epsilon ) {
|
|
return false;
|
|
}
|
|
|
|
if ( aMaxs_z < bMaxs_z - epsilon ) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
entity G_FindDeployedMCP() {
|
|
// TODO: Make it so that you can use sys to do entitiesOfCollection type stuff
|
|
entity worldspawn = sys.getEntity( "worldspawn" );
|
|
|
|
float count = worldspawn.entitiesOfCollection( "mcp" );
|
|
|
|
float i;
|
|
for ( i = 0; i < count; i++ ) {
|
|
entity ent = worldspawn.getBoundsCacheEntity( i );
|
|
|
|
if ( ent.vIsDeployed() ) {
|
|
return ent;
|
|
}
|
|
}
|
|
|
|
return $null_entity;
|
|
}
|
|
|
|
entity G_FindMiningLaserMaterials() {
|
|
entity worldspawn = sys.getEntity( "worldspawn" );
|
|
|
|
// this is a nasty hack
|
|
float entityDef = GetEntityDef( "gameplay/construction/mining_laser/objective" );
|
|
if ( entityDef == -1 ) {
|
|
sys.error( "G_FindMiningLaserMaterials - No entityDef called 'gameplay/construction/mining_laser/objective'" );
|
|
return $null_entity;
|
|
}
|
|
|
|
float count = worldspawn.entitiesOfType( entityDef );
|
|
if ( count > 1 ) {
|
|
sys.error( "G_FindMiningLaserMaterials - More than one 'gameplay/construction/mining_laser/objective' spawned" );
|
|
return $null_entity;
|
|
}
|
|
|
|
if ( count < 1 ) {
|
|
return $null_entity;
|
|
}
|
|
|
|
return worldspawn.getBoundsCacheEntity( 0 );
|
|
}
|