From 9a96d0bff56f1969c68bb52a2f33296095bdc67d Mon Sep 17 00:00:00 2001 From: BobTheBob <32057864+BobTheBob9@users.noreply.github.com> Date: Tue, 31 Aug 2021 23:14:58 +0100 Subject: move to new mod format --- .../scripts/vscripts/_utility_shared.nut | 4069 -------------------- 1 file changed, 4069 deletions(-) delete mode 100644 Northstar.CustomServers/scripts/vscripts/_utility_shared.nut (limited to 'Northstar.CustomServers/scripts/vscripts/_utility_shared.nut') diff --git a/Northstar.CustomServers/scripts/vscripts/_utility_shared.nut b/Northstar.CustomServers/scripts/vscripts/_utility_shared.nut deleted file mode 100644 index e3cb0dbfb..000000000 --- a/Northstar.CustomServers/scripts/vscripts/_utility_shared.nut +++ /dev/null @@ -1,4069 +0,0 @@ -untyped - -globalize_all_functions - -const DEV_DRAWALLTRIGGERS = 0 - -global const CHARGE_TOOL = "sp_weapon_arc_tool" - -global const TRIG_FLAG_NONE = 0 -global const TRIG_FLAG_PLAYERONLY = 0x0001 -global const TRIG_FLAG_NPCONLY = 0x0002 -global const TRIG_FLAG_NOCONTEXTBUSY = 0x0004 -global const TRIG_FLAG_ONCE = 0x0008 -global const TRIG_FLAG_EXCLUSIVE = 0x0010 // can only be triggered by entities passed in at creation -global const TRIG_FLAG_DEVDRAW = 0x0020 -global const TRIG_FLAG_START_DISABLED = 0x0040 -global const TRIG_FLAG_NO_PHASE_SHIFT = 0x0080 -global const float MAP_EXTENTS = 128*128 -/* -const TRIG_FLAG_ = 0x0080 -const TRIG_FLAG_ = 0x0100*/ - -global const TRIGGER_INTERNAL_SIGNAL = "OnTrigger" - -global const CALCULATE_SEQUENCE_BLEND_TIME = -1.0 - -global struct ArrayDistanceEntry -{ - float distanceSqr - entity ent - vector origin -} - -global struct GravityLandData -{ - array points - TraceResults& traceResults - float elapsedTime -} - -global struct FirstPersonSequenceStruct -{ - string firstPersonAnim = "" - string thirdPersonAnim = "" - string firstPersonAnimIdle = "" - string thirdPersonAnimIdle = "" - string relativeAnim = "" - string attachment = "" - bool teleport = false - bool noParent = false - float blendTime = CALCULATE_SEQUENCE_BLEND_TIME - float firstPersonBlendOutTime = -1.0 - bool noViewLerp = false - bool hideProxy = false - void functionref( entity ) viewConeFunction = null - vector ornull origin = null - vector ornull angles = null - bool enablePlanting = false - float setInitialTime = 0.0 //set the starting point of the animation in seconds - bool useAnimatedRefAttachment = false //Position entity using ref every frame instead of using root motion - bool renderWithViewModels = false - bool gravity = false // force gravity command on sequence - bool playerPushable = false - array< string > thirdPersonCameraAttachments = [] - bool thirdPersonCameraVisibilityChecks = false - entity thirdPersonCameraEntity = null - bool snapPlayerFeetToEyes = true -} - -global struct FrontRightDotProductsStruct -{ - float forwardDot = 0.0 - float rightDot = 0.0 -} - -global struct RaySphereIntersectStruct -{ - bool result - float enterFrac - float leaveFrac -} - -void function Utility_Shared_Init() -{ - RegisterSignal( TRIGGER_INTERNAL_SIGNAL ) - RegisterSignal( "devForcedWin" ) - - #document( "IsAlive", "Returns true if the given ent is not null, and is alive." ) - #document( "ArrayWithin", "Remove ents from array that are out of range" ) -} - -#if DEV -// short cut for the console -// script gp()[0].Die( gp()[1] ) -array function gp() -{ - return GetPlayerArray() -} -#endif - -void function InitWeaponScripts() -{ - SmartAmmo_Init() - - // WEAPON SCRIPTS - ArcCannon_Init() - Grenade_FileInit() - Vortex_Init() - -// #if SERVER -// PrecacheProjectileEntity( "grenade_frag" ) -// PrecacheProjectileEntity( "crossbow_bolt" ) -// #endif - - MpWeaponDroneBeam_Init() - MpWeaponDroneRocket_Init() - MpWeaponDronePlasma_Init() - MpWeaponTurretPlasma_Init() - MpWeaponTurretLaser_Init() - MpWeaponSuperSpectre_Init() - MpWeaponGunshipLauncher_Init() - MpWeaponFragDrone_Init() - MpAbilityShifter_Init() - MpTitanabilityBubbleShield_Init() - MpTitanabilityAmpedWall_Init() - MpTitanabilityFusionCore_Init() - MpTitanweapon40mm_Init() - MpTitanWeaponpredatorcannon_Init() - MpTitanweaponRocketeetRocketStream_Init() - MpTitanweaponMeteor_Init() - MpTitanWeapon_SniperInit() - MpTitanweaponVortexShield_Init() - MpTitanweaponXo16_Init() - MpWeaponDefender_Init() - MpWeaponDmr_Init() - MpWeaponProximityMine_Init() - MpWeaponRocketLauncher_Init() - MpWeaponNPCRocketLauncher_Init() - MpWeaponSatchel_Init() - MpWeaponSmartPistol_Init() - MpWeaponSniper_Init() - MpWeaponLSTAR_Init() - MpTitanWeaponParticleAccelerator_Init() - MpWeaponMegaTurret_Init() - MpWeaponZipline_Init() - SpWeaponHoldBeam_Init() - MpTitanweaponArcBall_Init() - MpWeaponDeployableCover_Init() - MpTitanAbilityBasicBlock_Init() - MpTitanAbilityLaserTrip_Init() - MpTitanWeaponArcWave_Init() - MpTitanWeaponFlameWave_Init() - MpWeaponAlternatorSMG_Init() - MpWeaponGreandeElectricSmoke_Init() - MpWeaponGrenadeGravity_Init() - MpWeaponDeployableCloakfield_Init() - MpWeaponTether_Init() - MpWeaponTripWire_Init() - MpTitanAbilitySmartCore_Init() - MpTitanAbilitySlowTrap_Init() - MpTitanAbilityPowerShot_Init() - MpTitanAbilityAmmoSwap_Init() - MpTitanAbilityRocketeerAmmoSwap_Init() - MpTitanAbilityHeatShield_Init() - SonarGrenade_Init() - MpTitanAbilityGunShield_Init() - MpTitanWeaponLaserLite_Init() - MpTitanWeaponSword_Init() - MpTitanAbilityHover_Init() - MpTitanWeaponTrackerRockets_Init() - MpTitanWeaponStunLaser_Init() - MpTitanWeaponShoulderRockets_Init() - MpTitanAbilitySmoke_Init() - #if MP - MpWeaponArcTrap_Init() - #endif - - #if SERVER - BallLightning_Init() - #endif -} - -float function GetCurrentPlaylistVarFloat( string val, float useVal ) -{ - var result = GetCurrentPlaylistVarOrUseValue( val, useVal + "" ) - if ( result == null || result == "" ) - return 0.0 - - return float( result ) -} - -void function SetSkinForTeam( entity ent, int team ) -{ - if ( team == TEAM_IMC ) - ent.SetSkin( 0 ) - else if ( team == TEAM_MILITIA ) - ent.SetSkin( 1 ) -} - -void function TableDump( table Table, int depth = 0 ) -{ - if ( depth > 4 ) - return - - foreach ( k, v in Table ) - { - printl( "Key: " + k + " Value: " + v ) - if ( type( v ) == "table" && depth ) - TableDump( expect table( v ), depth + 1 ) - } -} - -/*entity function GetVortexWeapon( entity player ) -{ - for ( int weaponIndex = 0; weaponIndex < 2; weaponIndex++ ) - { - entity weapon = player.GetOffhandWeapon( weaponIndex ) - if ( !IsValid( weapon ) ) - continue - if ( weapon.GetWeaponClassName() != "mp_titanweapon_vortex_shield" ) - continue - return weapon - } - - Assert( false, "Vortex weapon not found!" ) - unreachable -}*/ - -entity function GetClosest( array entArray, vector origin, float maxdist = -1.0 ) -{ - Assert( entArray.len() > 0 ) - - entity bestEnt = entArray[ 0 ] - float bestDistSqr = DistanceSqr( bestEnt.GetOrigin(), origin ) - - for ( int i = 1; i < entArray.len(); i++ ) - { - entity newEnt = entArray[ i ] - float newDistSqr = LengthSqr( newEnt.GetOrigin() - origin ) - - if ( newDistSqr < bestDistSqr ) - { - bestEnt = newEnt - bestDistSqr = newDistSqr - } - } - - if ( maxdist >= 0.0 ) - { - if ( bestDistSqr > maxdist * maxdist ) - return null - } - - return bestEnt -} - -entity function GetClosest2D( array entArray, vector origin, float maxdist = -1.0 ) -{ - Assert( entArray.len() > 0, "Empty array!" ) - - entity bestEnt = entArray[ 0 ] - float bestDistSqr = DistanceSqr( bestEnt.GetOrigin(), origin ) - - for ( int i = 1; i < entArray.len(); i++ ) - { - entity newEnt = entArray[ i ] - float newDistSqr = Length2DSqr( newEnt.GetOrigin() - origin ) - - if ( newDistSqr < bestDistSqr ) - { - bestEnt = newEnt - bestDistSqr = newDistSqr - } - } - - if ( maxdist >= 0.0 ) - { - if ( bestDistSqr > maxdist * maxdist ) - return null - } - - return bestEnt -} - -bool function GameModeHasCapturePoints() -{ - #if CLIENT - return clGlobal.hardpointStringIDs.len() > 0 - #elseif SERVER - return svGlobal.hardpointStringIDs.len() > 0 - #endif -} - -entity function GetFarthest( array entArray, vector origin ) -{ - Assert( entArray.len() > 0, "Empty array!" ) - - entity bestEnt = entArray[0] - float bestDistSqr = DistanceSqr( bestEnt.GetOrigin(), origin ) - - for ( int i = 1; i < entArray.len(); i++ ) - { - entity newEnt = entArray[ i ] - float newDistSqr = DistanceSqr( newEnt.GetOrigin(), origin ) - - if ( newDistSqr > bestDistSqr ) - { - bestEnt = newEnt - bestDistSqr = newDistSqr - } - } - - return bestEnt -} - -int function GetClosestIndex( array Array, vector origin ) -{ - Assert( Array.len() > 0 ) - - int index = 0 - float distSqr = LengthSqr( Array[ index ].GetOrigin() - origin ) - - entity newEnt - float newDistSqr - for ( int i = 1; i < Array.len(); i++ ) - { - newEnt = Array[ i ] - newDistSqr = LengthSqr( newEnt.GetOrigin() - origin ) - - if ( newDistSqr < distSqr ) - { - index = i - distSqr = newDistSqr - } - } - - return index -} - -// nothing in the game uses the format "Table.r/g/b/a"... wtf is the point of this function -table function StringToColors( string colorString, string delimiter = " " ) -{ - PerfStart( PerfIndexShared.StringToColors + SharedPerfIndexStart ) - array tokens = split( colorString, delimiter ) - - Assert( tokens.len() >= 3 ) - - table Table = {} - Table.r <- int( tokens[0] ) - Table.g <- int( tokens[1] ) - Table.b <- int( tokens[2] ) - - if ( tokens.len() == 4 ) - Table.a <- int( tokens[3] ) - else - Table.a <- 255 - - PerfEnd( PerfIndexShared.StringToColors + SharedPerfIndexStart ) - return Table -} - -// TODO: Set return type to array when SetColor() accepts this type -function ColorStringToArray( string colorString ) -{ - array tokens = split( colorString, " " ) - - Assert( tokens.len() >= 3 && tokens.len() <= 4 ) - - array colorArray - foreach ( token in tokens ) - colorArray.append( int( token ) ) - - return colorArray -} - -// Evaluate a generic order ( coefficientArray.len() - 1 ) polynomial -// e.g. to evaluate (Ax + B), call EvaluatePolynomial(x, A, B) -// Note that EvaluatePolynomial(x) returns 0 and -// EvaluatePolynomial(x, A) returns A, which are technically correct -// but perhaps not what you expect -float function EvaluatePolynomial( float x, array coefficientArray ) -{ - float sum = 0.0 - - for ( int i = 0; i < coefficientArray.len() - 1; ++i ) - sum += coefficientArray[ i ] * pow( x, coefficientArray.len() -1 - i ) - - if ( coefficientArray.len() >= 1 ) - sum += coefficientArray[ coefficientArray.len() - 1 ] - - return sum -} - -void function WaitForever() -{ - #if SERVER - svGlobal.levelEnt.WaitSignal( "forever" ) - #elseif CLIENT - clGlobal.levelEnt.WaitSignal( "forever" ) - #endif -} - -#if SERVER - -bool function ShouldDoReplay( entity player, entity attacker, float replayTime, int methodOfDeath ) -{ - if ( ShouldDoReplayIsForcedByCode() ) - { - print( "ShouldDoReplay(): Doing a replay because code forced it." ); - return true - } - - if ( GetCurrentPlaylistVarInt( "replay_disabled", 0 ) == 1 ) - { - print( "ShouldDoReplay(): Not doing a replay because 'replay_disabled' is enabled in the current playlist.\n" ); - return false - } - - switch( methodOfDeath ) - { - case eDamageSourceId.human_execution: - case eDamageSourceId.titan_execution: - { - print( "ShouldDoReplay(): Not doing a replay because the player died from an execution.\n" ); - return false - } - } - - if ( level.nv.replayDisabled ) - { - print( "ShouldDoReplay(): Not doing a replay because replays are disabled for the level.\n" ); - return false - } - - if ( Time() - player.p.connectTime <= replayTime ) //Bad things happen if we try to do a kill replay that lasts longer than the player entity existing on the server - { - print( "ShouldDoReplay(): Not doing a replay because the player is not old enough.\n" ); - return false - } - - if ( player == attacker ) - { - print( "ShouldDoReplay(): Not doing a replay because the attacker is the player.\n" ); - return false - } - - if ( player.IsBot() == true ) - { - print( "ShouldDoReplay(): Not doing a replay because the player is a bot.\n" ); - return false - } - - return AttackerShouldTriggerReplay( attacker ) -} - -// Don't let things like killbrushes show replays -bool function AttackerShouldTriggerReplay( entity attacker ) -{ - if ( !IsValid( attacker ) ) - { - print( "AttackerShouldTriggerReplay(): Not doing a replay because the attacker is not valid.\n" ) - return false - } - - if ( attacker.IsPlayer() ) - { - print( "AttackerShouldTriggerReplay(): Doing a replay because the attacker is a player.\n" ) - return true - } - - if ( attacker.IsNPC() ) - { - print( "AttackerShouldTriggerReplay(): Doing a replay because the attacker is an NPC.\n" ) - return true - } - - print( "AttackerShouldTriggerReplay(): Not doing a replay by default.\n" ) - return false -} -#endif // #if SERVER - -vector function RandomVec( float range ) -{ - // could rewrite so it doesnt make a box of random. - vector vec = Vector( 0, 0, 0 ) - vec.x = RandomFloatRange( -range, range ) - vec.y = RandomFloatRange( -range, range ) - vec.z = RandomFloatRange( -range, range ) - - return vec -} - -function ArrayValuesToTableKeys( arr ) -{ - Assert( type( arr ) == "array", "Not an array" ) - - local resultTable = {} - for ( int i = 0; i < arr.len(); ++ i) - { - resultTable[ arr[ i ] ] <- 1 - } - - return resultTable -} - -function TableKeysToArray( tab ) -{ - Assert( type( tab ) == "table", "Not a table" ) - - local resultArray = [] - resultArray.resize( tab.len() ) - int currentArrayIndex = 0 - foreach ( key, val in tab ) - { - resultArray[ currentArrayIndex ] = key - ++currentArrayIndex - } - - return resultArray -} - -function TableRandom( Table ) -{ - Assert( type( Table ) == "table", "Not a table" ) - - local Array = [] - - foreach ( entry, contents in Table ) - { - Array.append( contents ) - } - - return Array.getrandom() -} - -int function RandomWeightedIndex( array Array ) -{ - int count = Array.len() - Assert( count != 0, "Array is empty" ) - - int sum = int( ( count * ( count + 1 ) ) / 2.0 ) // ( n * ( n + 1 ) ) / 2 - int randInt = RandomInt( sum ) - for ( int i = 0 ; i < count ; i++ ) - { - int rangeForThisIndex = count - i - if ( randInt < rangeForThisIndex ) - return i - - randInt -= rangeForThisIndex - } - - Assert( 0 ) - unreachable -} - -bool function IsValid_ThisFrame( entity ent ) -{ - if ( ent == null ) - return false - - return expect bool( ent.IsValidInternal() ) -} - -bool function IsAlive( entity ent ) -{ - if ( ent == null ) - return false - if ( !ent.IsValidInternal() ) - return false - - return ent.IsEntAlive() -} - -#if DEV && SERVER -void function vduon() -{ - PlayConversationToAll( "TitanReplacement" ) -} - -void function playconvtest( string conv ) -{ - entity player = GetPlayerArray()[0] - array guys = GetAllSoldiers() - if ( !guys.len() ) - { - printt( "No AI!!" ) - return - } - entity guy = GetClosest( guys, player.GetOrigin() ) - if ( conv in player.s.lastAIConversationTime ) - delete player.s.lastAIConversationTime[ conv ] - - printt( "Play ai conversation " + conv ) - PlaySquadConversationToAll( conv, guy ) -} -#endif //DEV - -void function FighterExplodes( entity ship ) -{ - vector origin = ship.GetOrigin() - vector angles = ship.GetAngles() - EmitSoundAtPosition( TEAM_UNASSIGNED, origin, "AngelCity_Scr_RedeyeWeaponExplos" ) - #if SERVER - PlayFX( FX_HORNET_DEATH, origin ) - #else - int fxid = GetParticleSystemIndex( FX_HORNET_DEATH ) - StartParticleEffectInWorld( fxid, origin, angles ) - #endif -} - -vector function PositionOffsetFromEnt( entity ent, float offsetX, float offsetY, float offsetZ ) -{ - vector angles = ent.GetAngles() - vector origin = ent.GetOrigin() - origin += AnglesToForward( angles ) * offsetX - origin += AnglesToRight( angles ) * offsetY - origin += AnglesToUp( angles ) * offsetZ - return origin -} - -vector function PositionOffsetFromOriginAngles( vector origin, vector angles, float offsetX, float offsetY, float offsetZ ) -{ - origin += AnglesToForward( angles ) * offsetX - origin += AnglesToRight( angles ) * offsetY - origin += AnglesToUp( angles ) * offsetZ - return origin -} - - -bool function IsMenuLevel() -{ - return IsLobby() -} - -function Dump( package, depth = 0 ) -{ - if ( depth > 6 ) - return - - foreach ( k, v in package ) - { - for ( int i = 0; i < depth; i++ ) - print( " ") - - if ( IsTable( package ) ) - printl( "Key: " + k + " Value: " + v ) - if ( IsArray( package ) ) - printl( "Index: " + k + " Value: " + v ) - - if ( IsTable( v ) || IsArray( v ) ) - Dump( v, depth + 1 ) - } -} - -bool function UseShortNPCTitles() -{ - return GetCurrentPlaylistVarInt( "npc_short_titles", 0 ) ? true : false -} - -string function GetShortNPCTitle( int team ) -{ - return GetTeamName( team ) -} - -bool function IsIMCOrMilitiaTeam( int team ) -{ - return team == TEAM_MILITIA || team == TEAM_IMC -} - -int function GetOtherTeam( int team ) -{ - if ( team == TEAM_IMC ) - return TEAM_MILITIA - - if ( team == TEAM_MILITIA ) - return TEAM_IMC - - Assert( false, "Trying to GetOtherTeam() for team: " + team + " that is neither Militia nor IMC" ) - unreachable -} - -float function VectorDot_PlayerToOrigin( entity player, vector targetOrigin ) -{ - vector playerEyePosition = player.EyePosition() - vector vecToEnt = ( targetOrigin - playerEyePosition ) - vecToEnt.Norm() - - // GetViewVector() only works on the player - float dotVal = vecToEnt.Dot( player.GetViewVector() ) - return dotVal -} - -float function VectorDot_DirectionToOrigin( entity player, vector direction, vector targetOrigin ) -{ - vector playerEyePosition = player.EyePosition() - vector vecToEnt = ( targetOrigin - playerEyePosition ) - vecToEnt.Norm() - - // GetViewVector() only works on the player - float dotVal = DotProduct( vecToEnt, direction ) - return dotVal -} - -void function WaitUntilWithinDistance( entity player, entity titan, float dist ) -{ - float distSqr = dist * dist - for ( ;; ) - { - if ( !IsAlive( titan ) ) - return - - if ( IsAlive( player ) ) - { - if ( DistanceSqr( player.GetOrigin(), titan.GetOrigin() ) <= distSqr ) - return - } - wait 0.1 - } -} - -void function WaitUntilBeyondDistance( entity player, entity titan, float dist ) -{ - float distSqr = dist * dist - for ( ;; ) - { - if ( !IsAlive( titan ) ) - return - - if ( IsAlive( player ) ) - { - if ( DistanceSqr( player.GetOrigin(), titan.GetOrigin() ) > distSqr ) - return - } - wait 0.1 - } -} - -bool function IsModelViewer() -{ - return GetMapName() == "mp_model_viewer" -} - - -//----------------------------------// -// Tweening functions // -// Pass in a fraction 0.0 - 1.0 // -// Get a fraction back 0.0 - 1.0 // -//----------------------------------// - -// simple linear tweening - no easing, no acceleration -float function Tween_Linear( float frac ) -{ - Assert( frac >= 0.0 && frac <= 1.0 ) - return frac -} - -// quadratic easing out - decelerating to zero velocity -float function Tween_QuadEaseOut( float frac ) -{ - Assert( frac >= 0.0 && frac <= 1.0 ) - return -1.0 * frac*(frac-2) -} - -// exponential easing out - decelerating to zero velocity -float function Tween_ExpoEaseOut( float frac ) -{ - Assert( frac >= 0.0 && frac <= 1.0 ) - return -pow( 2.0, -10.0 * frac ) + 1.0 -} - -float function Tween_ExpoEaseIn( float frac ) -{ - Assert( frac >= 0.0 && frac <= 1.0 ) - return pow( 2, 10 * ( frac - 1 ) ); -} - -bool function LegalOrigin( vector origin ) -{ - if ( fabs( origin.x ) > MAX_WORLD_COORD ) - return false - - if ( fabs( origin.y ) > MAX_WORLD_COORD ) - return false - - if ( fabs( origin.z ) > MAX_WORLD_COORD ) - return false - - return true -} - -vector function AnglesOnSurface( surfaceNormal, playerVelocity ) -{ - playerVelocity.Norm() - vector right = CrossProduct( playerVelocity, surfaceNormal ) - vector forward = CrossProduct( surfaceNormal, right ) - vector angles = VectorToAngles( forward ) - angles.z = atan2( right.z, surfaceNormal.z ) * RAD_TO_DEG - - return angles -} - -vector function ClampToWorldspace( vector origin ) -{ - // temp solution for start positions that are outside the world bounds - origin.x = clamp( origin.x, -MAX_WORLD_COORD, MAX_WORLD_COORD ) - origin.y = clamp( origin.y, -MAX_WORLD_COORD, MAX_WORLD_COORD ) - origin.z = clamp( origin.z, -MAX_WORLD_COORD, MAX_WORLD_COORD ) - - return origin -} - -function UseReturnTrue( user, usee ) -{ - return true -} - -function ControlPanel_CanUseFunction( playerUser, controlPanel ) -{ - expect entity( playerUser ) - expect entity( controlPanel ) - - // Does a simple cone FOV check from the screen to the player's eyes - int maxAngleToAxisAllowedDegrees = 60 - - vector playerEyePos = playerUser.EyePosition() - int attachmentIndex = controlPanel.LookupAttachment( "PANEL_SCREEN_MIDDLE" ) - - Assert( attachmentIndex != 0 ) - vector controlPanelScreenPosition = controlPanel.GetAttachmentOrigin( attachmentIndex ) - vector controlPanelScreenAngles = controlPanel.GetAttachmentAngles( attachmentIndex ) - vector controlPanelScreenForward = AnglesToForward( controlPanelScreenAngles ) - - vector screenToPlayerEyes = Normalize( playerEyePos - controlPanelScreenPosition ) - - return DotProduct( screenToPlayerEyes, controlPanelScreenForward ) > deg_cos( maxAngleToAxisAllowedDegrees ) -} - -function SentryTurret_CanUseFunction( playerUser, sentryTurret ) -{ - expect entity( playerUser ) - expect entity( sentryTurret ) - - // Does a simple cone FOV check from the screen to the player's eyes - int maxAngleToAxisAllowedDegrees = 90 - - vector playerEyePos = playerUser.EyePosition() - int attachmentIndex = sentryTurret.LookupAttachment( "turret_player_use" ) - - Assert( attachmentIndex != 0 ) - vector sentryTurretUsePosition = sentryTurret.GetAttachmentOrigin( attachmentIndex ) - vector sentryTurretUseAngles = sentryTurret.GetAttachmentAngles( attachmentIndex ) - vector sentryTurretUseForward = AnglesToForward( sentryTurretUseAngles ) - - vector useToPlayerEyes = Normalize( playerEyePos - sentryTurretUsePosition ) - - return DotProduct( useToPlayerEyes, sentryTurretUseForward ) > deg_cos( maxAngleToAxisAllowedDegrees ) -} - -void function ArrayRemoveInvalid( array ents ) -{ - for ( int i = ents.len() - 1; i >= 0; i-- ) - { - if ( !IsValid( ents[ i ] ) ) - ents.remove( i ) - } -} - -bool function HasDamageStates( entity ent ) -{ - if ( !IsValid( ent ) ) - return false - return ( "damageStateInfo" in ent.s ) -} - -bool function HasHitData( entity ent ) -{ - return ( "hasHitData" in ent.s && expect bool( ent.s.hasHitData ) ) -} - -FrontRightDotProductsStruct function GetFrontRightDots( entity baseEnt, entity relativeEnt, string optionalTag = "" ) -{ - if ( optionalTag != "" ) - { - int attachIndex = baseEnt.LookupAttachment( optionalTag ) - vector origin = baseEnt.GetAttachmentOrigin( attachIndex ) - vector angles = baseEnt.GetAttachmentAngles( attachIndex ) - angles.x = 0 - angles.z = 0 - vector forward = AnglesToForward( angles ) - vector right = AnglesToRight( angles ) - - vector targetOrg = relativeEnt.GetOrigin() - vector vecToEnt = ( targetOrg - origin ) -// printt( "vecToEnt ", vecToEnt ) - vecToEnt.z = 0 - - vecToEnt.Norm() - - - FrontRightDotProductsStruct result - result.forwardDot = DotProduct( vecToEnt, forward ) - result.rightDot = DotProduct( vecToEnt, right ) - - // red: forward for incoming ent - //DebugDrawLine( origin, origin + vecToEnt * 150, 255, 0, 0, true, 5 ) - - // green: tag forward - //DebugDrawLine( origin, origin + forward * 150, 0, 255, 0, true, 5 ) - - // blue: tag right - //DebugDrawLine( origin, origin + right * 150, 0, 0, 255, true, 5 ) - return result - } - - vector targetOrg = relativeEnt.GetOrigin() - vector origin = baseEnt.GetOrigin() - vector vecToEnt = ( targetOrg - origin ) - vecToEnt.Norm() - - FrontRightDotProductsStruct result - result.forwardDot = vecToEnt.Dot( baseEnt.GetForwardVector() ) - result.rightDot = vecToEnt.Dot( baseEnt.GetRightVector() ) - return result -} - - - -array function GetAllPointsOnBezier( array points, int numSegments, float debugDrawTime = 0.0 ) -{ - Assert( points.len() >= 2 ) - Assert( numSegments > 0 ) - array curvePoints = [] - - // Debug draw the points used for the curve - if ( debugDrawTime ) - { - for ( int i = 0; i < points.len() - 1; i++ ) - DebugDrawLine( points[i], points[i + 1], 150, 150, 150, true, debugDrawTime ) - } - - for ( int i = 0; i < numSegments; i++ ) - { - float t = ( i.tofloat() / ( numSegments.tofloat() - 1.0 ) ).tofloat() - curvePoints.append( GetSinglePointOnBezier( points, t ) ) - } - - return curvePoints -} - -vector function GetSinglePointOnBezier( array points, float t ) -{ - // evaluate a point on a bezier-curve. t goes from 0 to 1.0 - - array lastPoints = clone points - for(;;) - { - array newPoints = [] - for ( int i = 0; i < lastPoints.len() - 1; i++ ) - newPoints.append( lastPoints[i] + ( lastPoints[i+1] - lastPoints[i] ) * t ) - - if ( newPoints.len() == 1 ) - return newPoints[0] - - lastPoints = newPoints - } - - unreachable -} - -bool function GetDoomedState( entity ent ) -{ - entity soul = ent.GetTitanSoul() - if ( !IsValid( soul ) ) - return false - - return soul.IsDoomed() -} - -bool function TitanCoreInUse( entity player ) -{ - Assert( player.IsTitan() ) - - if ( !IsAlive( player ) ) - return false - - return Time() < SoulTitanCore_GetExpireTime( player.GetTitanSoul() ) -} - - -// Return float or null -function GetTitanCoreTimeRemaining( entity player ) -{ - if ( !player.IsTitan() ) - return null - - entity soul = player.GetTitanSoul() - - if ( !soul ) - return null - - return SoulTitanCore_GetExpireTime( soul ) - Time() -} - -bool function CoreAvailableDuringDoomState() -{ - return true -} - -bool function HasAntiTitanWeapon( entity guy ) -{ - foreach ( weapon in guy.GetMainWeapons() ) - { - if ( weapon.GetWeaponType() == WT_ANTITITAN ) - return true - } - return false -} - -float function GetTitanCoreActiveTime( entity player ) -{ - entity weapon = player.GetOffhandWeapon( OFFHAND_EQUIPMENT ) - - if ( !IsValid( weapon ) ) - { - printt( "WARNING: tried to get core active time, but core weapon was invalid." ) - printt( "titan is alive? " + IsAlive( player ) ) - return 5.0 // default - } - - return GetTitanCoreDurationFromWeapon( weapon ) -} - -float function GetTitanCoreChargeTime( entity player ) -{ - entity weapon = player.GetOffhandWeapon( OFFHAND_EQUIPMENT ) - - if ( !IsValid( weapon ) ) - { - printt( "WARNING: tried to get core charge time, but core weapon was invalid." ) - printt( "titan is alive? " + IsAlive( player ) ) - return 1.0 // default - } - - return GetTitanCoreChargeTimeFromWeapon( weapon ) -} - -float function GetTitanCoreChargeTimeFromWeapon( entity weapon ) -{ - return expect float( weapon.GetWeaponInfoFileKeyField( "chargeup_time" ) ) -} - -float function GetTitanCoreBuildTimeFromWeapon( entity weapon ) -{ - return expect float( weapon.GetWeaponInfoFileKeyField( "core_build_time" ).tofloat() ) -} - -float function GetTitanCoreDurationFromWeapon( entity weapon ) -{ - float coreDuration = weapon.GetCoreDuration() - - entity player = weapon.GetWeaponOwner() - if ( IsValid( player ) && player.IsPlayer() ) - { - if ( PlayerHasPassive( player, ePassives.PAS_MARATHON_CORE ) ) - coreDuration *= TITAN_CORE_MARATHON_CORE_MULTIPLIER - } - - return coreDuration -} - -float function GetCoreBuildTime( entity titan ) -{ - if ( titan.IsPlayer() ) - titan = GetTitanFromPlayer( titan ) - - Assert( titan != null ) - - entity coreWeapon = titan.GetOffhandWeapon( OFFHAND_EQUIPMENT ) - - if ( !IsValid( coreWeapon ) ) - { - //printt( "WARNING: tried to set build timer, but core weapon was invalid." ) - //printt( "titan is alive? " + IsAlive( titan ) ) - return 200.0 // default - } - - - return GetTitanCoreBuildTimeFromWeapon( coreWeapon ) -} - -string function GetCoreShortName( entity titan ) -{ - entity coreWeapon = titan.GetOffhandWeapon( OFFHAND_EQUIPMENT ) - - if ( !IsValid( coreWeapon ) ) - { - printt( "WARNING: tried to get core name, but core weapon was invalid." ) - printt( "titan is alive? " + IsAlive( titan ) ) - return "#HUD_READY" - } - - string name = expect string( coreWeapon.GetWeaponInfoFileKeyField( "shortprintname" ) ) - return name -} - -string ornull function GetCoreOSConversationName( entity titan, string event ) -{ - entity coreWeapon = titan.GetOffhandWeapon( OFFHAND_EQUIPMENT ) - - if ( !IsValid( coreWeapon ) ) - { - printt( "WARNING: tried to get core sound for " + event + ", but core weapon was invalid." ) - printt( "titan is alive? " + IsAlive( titan ) ) - return null - } - - var alias = coreWeapon.GetWeaponInfoFileKeyField( "dialog_" + event ) - - if ( alias == null ) - return null - - expect string( alias ) - - return alias -} - -entity function GetTitanFromPlayer( entity player ) -{ - Assert( player.IsPlayer() ) - if ( player.IsTitan() ) - return player - - return player.GetPetTitan() -} - -int function GetNuclearPayload( entity player ) -{ - if ( !GetDoomedState( player ) ) - return 0 - - int payload = 0 - if ( PlayerHasPassive( player, ePassives.PAS_NUCLEAR_CORE ) ) - payload += 2 - - if ( PlayerHasPassive( player, ePassives.PAS_BUILD_UP_NUCLEAR_CORE ) ) - payload += 1 - - return payload -} - -entity function GetCloak( entity ent ) -{ - return GetOffhand( ent, "mp_ability_cloak" ) -} - -entity function GetOffhand( entity ent, string classname ) -{ - entity offhand = ent.GetOffhandWeapon( OFFHAND_LEFT ) - if ( IsValid( offhand ) && offhand.GetWeaponClassName() == classname ) - return offhand - - offhand = ent.GetOffhandWeapon( OFFHAND_RIGHT ) - if ( IsValid( offhand ) && offhand.GetWeaponClassName() == classname ) - return offhand - - return null -} - -bool function IsCloaked( entity ent ) -{ - return ent.IsCloaked( true ) //pass true to ignore flicker time - -} - -float function TimeSpentInCurrentState() -{ - return Time() - expect float( level.nv.gameStateChangeTime ) -} - -float function DotToAngle( float dot ) -{ - return acos( dot ) * RAD_TO_DEG -} - -float function AngleToDot( float angle ) -{ - return cos( angle * DEG_TO_RAD ) -} - -int function GetGameState() -{ - return expect int( GetServerVar( "gameState" ) ) -} - -bool function GamePlaying() -{ - return GetGameState() == eGameState.Playing -} - -bool function GamePlayingOrSuddenDeath() -{ - int gameState = GetGameState() - return gameState == eGameState.Playing || gameState == eGameState.SuddenDeath -} - -bool function IsOdd( int num ) -{ - return ( num % 2 ) == 1 -} - -bool function IsEven( int num ) -{ - return !IsOdd( num ) -} - -vector function VectorReflectionAcrossNormal( vector vec, vector normal ) -{ - return ( vec - normal * ( 2 * DotProduct( vec, normal ) ) ) -} - -// Return an array of entities ordered from farthest to closest to the specified origin -array function ArrayFarthest( array entArray, vector origin ) -{ - array allResults = ArrayDistanceResults( entArray, origin ) - - allResults.sort( DistanceCompareFarthest ) - - array returnEntities - - foreach ( result in allResults ) - returnEntities.append( result.ent ) - - // the actual distances aren't returned - return returnEntities -} - -// Return an array of vectors ordered from closest to furthest from the specified origin -array function ArrayFarthestVector( array vecArray, vector origin ) -{ - array allResults = ArrayDistanceResultsVector( vecArray, origin ) - - allResults.sort( DistanceCompareFarthest ) - - array returnVecs - - foreach ( result in allResults ) - returnVecs.append( result.origin ) - - return returnVecs -} - -// Return an array of entities ordered from closest to furthest from the specified origin -array function ArrayClosest( array entArray, vector origin ) -{ - array allResults = ArrayDistanceResults( entArray, origin ) - - allResults.sort( DistanceCompareClosest ) - - array returnEntities - - foreach ( result in allResults ) - returnEntities.append( result.ent ) - - return returnEntities -} - -// Return an array of vectors ordered from closest to furthest from the specified origin -array function ArrayClosestVector( array vecArray, vector origin ) -{ - array allResults = ArrayDistanceResultsVector( vecArray, origin ) - - allResults.sort( DistanceCompareClosest ) - - array returnVecs - - foreach ( result in allResults ) - returnVecs.append( result.origin ) - - return returnVecs -} - -array function ArrayClosestWithinDistance( array entArray, vector origin, float maxDistance ) -{ - array allResults = ArrayDistanceResults( entArray, origin ) - float maxDistSq = maxDistance * maxDistance - - allResults.sort( DistanceCompareClosest ) - - array returnEntities - - foreach ( result in allResults ) - { - if ( result.distanceSqr > maxDistSq ) - break - - returnEntities.append( result.ent ) - } - - return returnEntities -} - -array function ArrayClosestVectorWithinDistance( array vecArray, vector origin, float maxDistance ) -{ - array allResults = ArrayDistanceResultsVector( vecArray, origin ) - float maxDistSq = maxDistance * maxDistance - - allResults.sort( DistanceCompareClosest ) - - array returnVecs - - foreach ( result in allResults ) - { - if ( result.distanceSqr > maxDistSq ) - break - - returnVecs.append( result.origin ) - } - - return returnVecs -} - -// Return an array of entities ordered from closest to furthest from the specified origin, ignoring z -array function ArrayClosest2D( array entArray, vector origin ) -{ - array allResults = ArrayDistance2DResults( entArray, origin ) - - allResults.sort( DistanceCompareClosest ) - - array returnEntities - - foreach ( result in allResults ) - returnEntities.append( result.ent ) - - return returnEntities -} - -// Return an array of entities ordered from closest to furthest from the specified origin, ignoring z -array function ArrayClosest2DVector( array entArray, vector origin ) -{ - array allResults = ArrayDistance2DResultsVector( entArray, origin ) - - allResults.sort( DistanceCompareClosest ) - - array returnVecs - - foreach ( result in allResults ) - returnVecs.append( result.origin ) - - return returnVecs -} - -array function ArrayClosest2DWithinDistance( array entArray, vector origin, float maxDistance ) -{ - array allResults = ArrayDistance2DResults( entArray, origin ) - float maxDistSq = maxDistance * maxDistance - - allResults.sort( DistanceCompareClosest ) - - array returnEntities - - foreach ( result in allResults ) - { - if ( result.distanceSqr > maxDistSq ) - break - - returnEntities.append( result.ent ) - } - - return returnEntities -} - -// Return an array of entities ordered from closest to furthest from the specified origin, ignoring z -array function ArrayClosest2DVectorWithinDistance( array entArray, vector origin, float maxDistance ) -{ - array allResults = ArrayDistance2DResultsVector( entArray, origin ) - float maxDistSq = maxDistance * maxDistance - - allResults.sort( DistanceCompareClosest ) - - array returnVecs - - foreach ( result in allResults ) - { - if ( result.distanceSqr > maxDistSq ) - break - - returnVecs.append( result.origin ) - } - - return returnVecs -} - -bool function ArrayEntityWithinDistance( array entArray, vector origin, float distance ) -{ - float distSq = distance * distance - foreach( entity ent in entArray ) - { - if ( DistanceSqr( ent.GetOrigin(), origin ) <= distSq ) - return true - } - return false -} - -function TableRemove( Table, entry ) -{ - Assert( typeof Table == "table" ) - - foreach ( index, tableEntry in Table ) - { - if ( tableEntry == entry ) - { - Table[ index ] = null - } - } -} - -function TableInvert( Table ) -{ - table invertedTable = {} - foreach ( key, value in Table ) - invertedTable[ value ] <- key - - return invertedTable -} - -int function DistanceCompareClosest( ArrayDistanceEntry a, ArrayDistanceEntry b ) -{ - if ( a.distanceSqr > b.distanceSqr ) - return 1 - else if ( a.distanceSqr < b.distanceSqr ) - return -1 - - return 0; -} - -int function DistanceCompareFarthest( ArrayDistanceEntry a, ArrayDistanceEntry b ) -{ - if ( a.distanceSqr < b.distanceSqr ) - return 1 - else if ( a.distanceSqr > b.distanceSqr ) - return -1 - - return 0; -} - -array function ArrayDistanceResults( array entArray, vector origin ) -{ - array allResults - - foreach ( ent in entArray ) - { - ArrayDistanceEntry entry - - vector entOrigin = ent.GetOrigin() - if ( IsSpawner( ent ) ) - { - var spawnKVs = ent.GetSpawnEntityKeyValues() - entOrigin = StringToVector( string( spawnKVs.origin ) ) - } - entry.distanceSqr = DistanceSqr( entOrigin, origin ) - entry.ent = ent - entry.origin = entOrigin - - allResults.append( entry ) - } - - return allResults -} - -array function ArrayDistanceResultsVector( array vecArray, vector origin ) -{ - array allResults - - foreach ( vec in vecArray ) - { - ArrayDistanceEntry entry - - entry.distanceSqr = DistanceSqr( vec, origin ) - entry.ent = null - entry.origin = vec - - allResults.append( entry ) - } - - return allResults -} - -array function ArrayDistance2DResults( array entArray, vector origin ) -{ - array allResults - - foreach ( ent in entArray ) - { - ArrayDistanceEntry entry - - vector entOrigin = ent.GetOrigin() - - entry.distanceSqr = Distance2DSqr( entOrigin, origin ) - entry.ent = ent - entry.origin = entOrigin - - allResults.append( entry ) - } - - return allResults -} - -array function ArrayDistance2DResultsVector( array vecArray, vector origin ) -{ - array allResults - - foreach ( vec in vecArray ) - { - ArrayDistanceEntry entry - - entry.distanceSqr = Distance2DSqr( vec, origin ) - entry.ent = null - entry.origin = vec - - allResults.append( entry ) - } - - return allResults -} - -GravityLandData function GetGravityLandData( vector startPos, vector parentVelocity, vector objectVelocity, float timeLimit, bool bDrawPath = false, float bDrawPathDuration = 0.0, array pathColor = [ 255, 255, 0 ] ) -{ - GravityLandData returnData - - Assert( timeLimit > 0 ) - - float MAX_TIME_ELAPSE = 6.0 - float timeElapsePerTrace = 0.1 - - float sv_gravity = 750.0 - float ent_gravity = 1.0 - float gravityScale = 1.0 - - vector traceStart = startPos - vector traceEnd = traceStart - float traceFrac - int traceCount = 0 - - objectVelocity += parentVelocity - - while( returnData.elapsedTime <= timeLimit ) - { - objectVelocity.z -= ( ent_gravity * sv_gravity * timeElapsePerTrace * gravityScale ) - - traceEnd += objectVelocity * timeElapsePerTrace - returnData.points.append( traceEnd ) - if ( bDrawPath ) - DebugDrawLine( traceStart, traceEnd, pathColor[0], pathColor[1], pathColor[2], false, bDrawPathDuration ) - - traceFrac = TraceLineSimple( traceStart, traceEnd, null ) - traceCount++ - if ( traceFrac < 1.0 ) - { - returnData.traceResults = TraceLine( traceStart, traceEnd, null, TRACE_MASK_SHOT, TRACE_COLLISION_GROUP_NONE ) - return returnData - } - traceStart = traceEnd - returnData.elapsedTime += timeElapsePerTrace - } - - return returnData -} - -float function GetPulseFrac( rate = 1, startTime = 0 ) -{ - return (1 - cos( ( Time() - startTime ) * (rate * (2*PI)) )) / 2 -} - -bool function IsPetTitan( titan ) -{ - Assert( titan.IsTitan() ) - - return titan.GetTitanSoul().GetBossPlayer() != null -} - -vector function StringToVector( string vecString, string delimiter = " " ) -{ - array tokens = split( vecString, delimiter ) - - Assert( tokens.len() >= 3 ) - - return Vector( float( tokens[0] ), float( tokens[1] ), float( tokens[2] ) ) -} - -float function GetShieldHealthFrac( entity ent ) -{ - if ( !IsAlive( ent ) ) - return 0.0 - - if ( HasSoul( ent ) ) - { - entity soul = ent.GetTitanSoul() - if ( IsValid( soul ) ) - ent = soul - } - - int shieldHealth = ent.GetShieldHealth() - int shieldMaxHealth = ent.GetShieldHealthMax() - - if ( shieldMaxHealth == 0 ) - return 0.0 - - return float( shieldHealth ) / float( shieldMaxHealth ) -} - -vector function HackGetDeltaToRef( vector origin, vector angles, entity ent, string anim ) -{ - AnimRefPoint animStartPos = ent.Anim_GetStartForRefPoint( anim, origin, angles ) - - vector delta = origin - animStartPos.origin - return origin + delta -} - -vector function HackGetDeltaToRefOnPlane( vector origin, vector angles, entity ent, string anim, vector up ) -{ - AnimRefPoint animStartPos = ent.Anim_GetStartForRefPoint( anim, origin, angles ) - - vector delta = origin - animStartPos.origin - vector nDelta = Normalize( delta ) - vector xProd = CrossProduct( nDelta, up ) - vector G = CrossProduct( up, xProd ) - vector planarDelta = G * DotProduct( delta, G ) - vector P = origin + planarDelta - -// DebugDrawLine( origin + delta, origin, 255, 0, 0, true, 1.0 ) -// DebugDrawLine( P, origin, 0,255, 100, true, 1.0 ) - - return P -} - -TraceResults function GetViewTrace( entity ent ) -{ - vector traceStart = ent.EyePosition() - vector traceEnd = traceStart + (ent.GetPlayerOrNPCViewVector() * 56756) // longest possible trace given our map size limits - array ignoreEnts = [ ent ] - - return TraceLine( traceStart, traceEnd, ignoreEnts, TRACE_MASK_SHOT, TRACE_COLLISION_GROUP_NONE ) -} - -function GetModSourceID( modString ) -{ - foreach ( name, id in getconsttable().eModSourceId ) - { - if ( string( name ) == modString ) - return id - } - - return null -} - -void function ArrayRemoveDead( array entArray ) -{ - for ( int i = entArray.len() - 1; i >= 0; i-- ) - { - if ( !IsAlive( entArray[ i ] ) ) - entArray.remove( i ) - } -} - -array function GetSortedPlayers( IntFromEntityCompare compareFunc, int team ) -{ - array players - - if ( team ) - players = GetPlayerArrayOfTeam( team ) - else - players = GetPlayerArray() - - players.sort( compareFunc ) - - return players -} - - -// Sorts by kills and resolves ties in this order: fewest deaths, most titan kills, most assists -int function CompareKills( entity a, entity b ) -{ - int aVal = a.GetPlayerGameStat( PGS_KILLS ) - int bVal = b.GetPlayerGameStat( PGS_KILLS ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - - aVal = a.GetPlayerGameStat( PGS_DEATHS ) - bVal = b.GetPlayerGameStat( PGS_DEATHS ) - - if ( aVal > bVal ) - return 1 - else if ( aVal < bVal ) - return -1 - - aVal = a.GetPlayerGameStat( PGS_TITAN_KILLS ) - bVal = b.GetPlayerGameStat( PGS_TITAN_KILLS ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - - aVal = a.GetPlayerGameStat( PGS_ASSISTS ) - bVal = b.GetPlayerGameStat( PGS_ASSISTS ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - - return 0 -} - -// Sorts by kills and resolves ties in this order: fewest deaths, most titan kills, most assists -int function CompareAssaultScore( entity a, entity b ) -{ - int aVal = a.GetPlayerGameStat( PGS_ASSAULT_SCORE ) - int bVal = b.GetPlayerGameStat( PGS_ASSAULT_SCORE ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - - return 0 -} - -int function CompareScore( entity a, entity b ) -{ - int aVal = a.GetPlayerGameStat( PGS_SCORE ) - int bVal = b.GetPlayerGameStat( PGS_SCORE ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - - return 0 -} - -int function CompareAssault( entity a, entity b ) -{ - int aVal = a.GetPlayerGameStat( PGS_ASSAULT_SCORE ) - int bVal = b.GetPlayerGameStat( PGS_ASSAULT_SCORE ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - - return 0 -} - -int function CompareDefense( entity a, entity b ) -{ - int aVal = a.GetPlayerGameStat( PGS_DEFENSE_SCORE ) - int bVal = b.GetPlayerGameStat( PGS_DEFENSE_SCORE ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - - return 0 -} - -int function CompareLTS( entity a, entity b ) -{ - int result = CompareTitanKills( a, b ) - if ( result != 0 ) - return result - - int aVal = a.GetPlayerGameStat( PGS_ASSAULT_SCORE ) - int bVal = b.GetPlayerGameStat( PGS_ASSAULT_SCORE ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - - return 0 -} - -int function CompareCP( entity a, entity b ) -{ - // Capture Point sorting. Sort priority = assault + defense > pilot kills > titan kills > death - - { - int aVal = a.GetPlayerGameStat( PGS_ASSAULT_SCORE ) - int bVal = b.GetPlayerGameStat( PGS_ASSAULT_SCORE ) - - aVal += a.GetPlayerGameStat( PGS_DEFENSE_SCORE ) - bVal += b.GetPlayerGameStat( PGS_DEFENSE_SCORE ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - } - - // 3) Pilot Kills - { - int aVal = a.GetPlayerGameStat( PGS_KILLS ) - int bVal = b.GetPlayerGameStat( PGS_KILLS ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - } - - // 3) Titan Kills - { - int aVal = a.GetPlayerGameStat( PGS_TITAN_KILLS ) - int bVal = b.GetPlayerGameStat( PGS_TITAN_KILLS ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - } - - // 4) Deaths - { - int aVal = a.GetPlayerGameStat( PGS_DEATHS ) - int bVal = b.GetPlayerGameStat( PGS_DEATHS ) - - if ( aVal < bVal ) - return -1 - else if ( aVal > bVal ) - return 1 - } - - return 0 -} - - -int function CompareCTF( entity a, entity b ) -{ - // Capture the flag sorting. Sort priority = flag captures > flag returns > pilot kills > titan kills > death - - // 1) Flag Captures - int result = CompareAssault( a, b ) - if ( result != 0 ) - return result - - // 2) Flag Returns - result = CompareDefense( a, b ) - if ( result != 0 ) - return result - - // 3) Pilot Kills - int aVal = a.GetPlayerGameStat( PGS_KILLS ) - int bVal = b.GetPlayerGameStat( PGS_KILLS ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - - // 3) Titan Kills - aVal = a.GetPlayerGameStat( PGS_TITAN_KILLS ) - bVal = b.GetPlayerGameStat( PGS_TITAN_KILLS ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - - // 4) Deaths - aVal = a.GetPlayerGameStat( PGS_DEATHS ) - bVal = b.GetPlayerGameStat( PGS_DEATHS ) - - if ( aVal < bVal ) - return -1 - else if ( aVal > bVal ) - return 1 - - return 0 -} - -int function CompareSpeedball( entity a, entity b ) -{ - // Capture the flag sorting. Sort priority = pilot kills > flag captures > death - - // 1) Pilot Kills - int aVal = a.GetPlayerGameStat( PGS_KILLS ) - int bVal = b.GetPlayerGameStat( PGS_KILLS ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - - // 2) Flag Captures - int result = CompareAssault( a, b ) - if ( result != 0 ) - return result - - // 3) Deaths - aVal = a.GetPlayerGameStat( PGS_DEATHS ) - bVal = b.GetPlayerGameStat( PGS_DEATHS ) - - if ( aVal < bVal ) - return -1 - else if ( aVal > bVal ) - return 1 - - return 0 -} - -int function CompareMFD( entity a, entity b ) -{ - // 1) Marks Killed - int result = CompareAssault( a, b ) - if ( result != 0 ) - return result - - // 2) Marks Outlasted - result = CompareDefense( a, b ) - if ( result != 0 ) - return result - - // 3) Pilot Kills - int aVal = a.GetPlayerGameStat( PGS_KILLS ) - int bVal = b.GetPlayerGameStat( PGS_KILLS ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - - // 4) Titan Kills - aVal = a.GetPlayerGameStat( PGS_TITAN_KILLS ) - bVal = b.GetPlayerGameStat( PGS_TITAN_KILLS ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - - // 5) Deaths - aVal = a.GetPlayerGameStat( PGS_DEATHS ) - bVal = b.GetPlayerGameStat( PGS_DEATHS ) - - if ( aVal < bVal ) - return -1 - else if ( aVal > bVal ) - return 1 - - return 0 -} - -int function CompareScavenger( entity a, entity b ) -{ - // 1) Ore Captured - int result = CompareAssault( a, b ) - if ( result != 0 ) - return result - - // 2) Pilot Kills - int aVal = a.GetPlayerGameStat( PGS_KILLS ) - int bVal = b.GetPlayerGameStat( PGS_KILLS ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - - // 3) Titan Kills - aVal = a.GetPlayerGameStat( PGS_TITAN_KILLS ) - bVal = b.GetPlayerGameStat( PGS_TITAN_KILLS ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - - // 4) Deaths - aVal = a.GetPlayerGameStat( PGS_DEATHS ) - bVal = b.GetPlayerGameStat( PGS_DEATHS ) - - if ( aVal < bVal ) - return -1 - else if ( aVal > bVal ) - return 1 - - return 0 -} - -int function CompareFW( entity a, entity b ) -{ - // Capture Point sorting. Sort priority = assault + defense > pilot kills > titan kills > death - - { - int aVal = a.GetPlayerGameStat( PGS_ASSAULT_SCORE ) - int bVal = b.GetPlayerGameStat( PGS_ASSAULT_SCORE ) - - aVal += a.GetPlayerGameStat( PGS_DEFENSE_SCORE ) - bVal += b.GetPlayerGameStat( PGS_DEFENSE_SCORE ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - } - - // 3) Pilot Kills - { - int aVal = a.GetPlayerGameStat( PGS_KILLS ) - int bVal = b.GetPlayerGameStat( PGS_KILLS ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - } - - // 3) Titan Kills - { - int aVal = a.GetPlayerGameStat( PGS_TITAN_KILLS ) - int bVal = b.GetPlayerGameStat( PGS_TITAN_KILLS ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - } - - // 4) Deaths - { - int aVal = a.GetPlayerGameStat( PGS_DEATHS ) - int bVal = b.GetPlayerGameStat( PGS_DEATHS ) - - if ( aVal < bVal ) - return -1 - else if ( aVal > bVal ) - return 1 - } - - return 0 -} - -int function CompareHunter( entity a, entity b ) -{ - // Capture Point sorting. Sort priority = assault + defense > pilot kills > titan kills > death - - { - int aVal = a.GetPlayerGameStat( PGS_ASSAULT_SCORE ) - int bVal = b.GetPlayerGameStat( PGS_ASSAULT_SCORE ) - - aVal += a.GetPlayerGameStat( PGS_DEFENSE_SCORE ) - bVal += b.GetPlayerGameStat( PGS_DEFENSE_SCORE ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - } - - // 3) Pilot Kills - { - int aVal = a.GetPlayerGameStat( PGS_KILLS ) - int bVal = b.GetPlayerGameStat( PGS_KILLS ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - } - - // 3) Titan Kills - { - int aVal = a.GetPlayerGameStat( PGS_TITAN_KILLS ) - int bVal = b.GetPlayerGameStat( PGS_TITAN_KILLS ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - } - - // 4) Deaths - { - int aVal = a.GetPlayerGameStat( PGS_DEATHS ) - int bVal = b.GetPlayerGameStat( PGS_DEATHS ) - - if ( aVal < bVal ) - return -1 - else if ( aVal > bVal ) - return 1 - } - - return 0 -} - -// Sorts by kills, deaths and then cash -int function CompareATCOOP( entity a, entity b ) -{ - int aVal = a.GetPlayerGameStat( PGS_KILLS ) - int bVal = b.GetPlayerGameStat( PGS_KILLS ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - - aVal = a.GetPlayerGameStat( PGS_DEATHS ) - bVal = b.GetPlayerGameStat( PGS_DEATHS ) - - if ( aVal > bVal ) - return 1 - else if ( aVal < bVal ) - return -1 - - aVal = a.GetPlayerGameStat( PGS_SCORE ) - bVal = b.GetPlayerGameStat( PGS_SCORE ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - - return 0 -} - -int function CompareFD( entity a, entity b ) -{ - int aVal = a.GetPlayerGameStat( PGS_DETONATION_SCORE ) - int bVal = b.GetPlayerGameStat( PGS_DETONATION_SCORE ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - - return 0 -} - -int function CompareTitanKills( entity a, entity b ) -{ - int aVal = a.GetPlayerGameStat( PGS_TITAN_KILLS ) - int bVal = b.GetPlayerGameStat( PGS_TITAN_KILLS ) - - if ( aVal < bVal ) - return 1 - else if ( aVal > bVal ) - return -1 - - return 0 -} - -bool function TitanEjectIsDisabled() -{ - return GetGlobalNetBool( "titanEjectEnabled" ) == false -} - -bool function IsHitEffectiveVsTitan( entity victim, int damageType ) -{ - Assert( victim.IsTitan() ) - - if ( victim.IsPlayer() ) - { - if ( PlayerHasPassive( victim, ePassives.PAS_BERSERKER ) ) - return false - } - - if ( !( damageType & DF_CRITICAL ) && ( damageType & DF_BULLET || damageType & DF_MAX_RANGE ) ) - return false - - return true -} - -bool function IsHitEffectiveVsNonTitan( entity victim, int damageType ) -{ - if ( damageType & DF_BULLET || damageType & DF_MAX_RANGE ) - return false; - - return true -} - -bool function IsPilot( entity ent ) -{ - if ( !IsValid( ent ) ) - return false - - if ( !ent.IsPlayer() ) - return false - - if ( ent.IsTitan() ) - return false - - return true -} - -bool function IsPilotDecoy( entity ent ) -{ - if ( !IsValid( ent ) ) - return false - - if ( ent.GetClassName() != "player_decoy" ) - return false - - return true -} - -string function HardpointIDToString( int id ) -{ - array hardpointIDString = [ "a", "b", "c" ] - - Assert( id >= 0 && id < hardpointIDString.len() ) - - return hardpointIDString[ id ] -} - -string function Dev_TeamIDToString( id ) -{ - if ( id == TEAM_IMC ) - return "IMC" - if ( id == TEAM_MILITIA ) - return "MIL" - - return "UNASSIGNED/UNKNOWN TEAM NAME" -} - -array function ArrayWithin( array Array, vector origin, float maxDist ) -{ - float maxDistSqr = maxDist * maxDist - - array resultArray = [] - foreach ( ent in Array ) - { - float distSqr = DistanceSqr( origin, ent.GetOrigin() ) - if ( distSqr <= maxDistSqr ) - resultArray.append( ent ) - } - return resultArray -} - -function GetTitanChassis( entity titan ) -{ - if ( !("titanChassis" in titan.s ) ) - { - if ( HasSoul( titan ) ) - { - entity soul = titan.GetTitanSoul() - titan.s.titanChassis <- GetSoulTitanSubClass( soul ) - } - else - { - return "Invalid Chassis" - } - } - - return titan.s.titanChassis -} - -vector function ClampVectorToCube( vector vecStart, vector vec, vector cubeOrigin, float cubeSize ) -{ - float halfCubeSize = cubeSize * 0.5 - vector cubeMins = < -halfCubeSize, -halfCubeSize, -halfCubeSize > - vector cubeMaxs = < halfCubeSize, halfCubeSize, halfCubeSize > - - return ClampVectorToBox( vecStart, vec, cubeOrigin, cubeMins, cubeMaxs ) -} - -vector function ClampVectorToBox( vector vecStart, vector vec, vector cubeOrigin, vector cubeMins, vector cubeMaxs ) -{ - float smallestClampScale = 1.0 - vector vecEnd = vecStart + vec - - smallestClampScale = ClampVectorComponentToCubeMax( cubeOrigin.x, cubeMaxs.x, vecStart.x, vecEnd.x, vec.x, smallestClampScale ) - smallestClampScale = ClampVectorComponentToCubeMax( cubeOrigin.y, cubeMaxs.y, vecStart.y, vecEnd.y, vec.y, smallestClampScale ) - smallestClampScale = ClampVectorComponentToCubeMax( cubeOrigin.z, cubeMaxs.z, vecStart.z, vecEnd.z, vec.z, smallestClampScale ) - smallestClampScale = ClampVectorComponentToCubeMin( cubeOrigin.x, cubeMins.x, vecStart.x, vecEnd.x, vec.x, smallestClampScale ) - smallestClampScale = ClampVectorComponentToCubeMin( cubeOrigin.y, cubeMins.y, vecStart.y, vecEnd.y, vec.y, smallestClampScale ) - smallestClampScale = ClampVectorComponentToCubeMin( cubeOrigin.z, cubeMins.z, vecStart.z, vecEnd.z, vec.z, smallestClampScale ) - - return vec * smallestClampScale -} - -float function ClampVectorComponentToCubeMax( float cubeOrigin, float cubeSize, float vecStart, float vecEnd, float vec, float smallestClampScale ) -{ - float max = cubeOrigin + cubeSize - float clearance = fabs( vecStart - max ) - if ( vecEnd > max ) - { - float scale = fabs( clearance / ( ( vecStart + vec ) - vecStart ) ) - if ( scale > 0 && scale < smallestClampScale ) - return scale - } - - return smallestClampScale -} - -float function ClampVectorComponentToCubeMin( float cubeOrigin, float cubeSize, float vecStart, float vecEnd, float vec, float smallestClampScale ) -{ - float min = cubeOrigin - cubeSize - float clearance = fabs( min - vecStart ) - if ( vecEnd < min ) - { - float scale = fabs( clearance / ( ( vecStart + vec ) - vecStart ) ) - if ( scale > 0 && scale < smallestClampScale ) - return scale - } - - return smallestClampScale -} - -bool function PointInCapsule( vector vecBottom, vector vecTop, float radius, vector point ) -{ - return GetDistanceFromLineSegment( vecBottom, vecTop, point ) <= radius -} - -bool function PointInCylinder( vector vecBottom, vector vecTop, float radius, vector point ) -{ - if ( GetDistanceFromLineSegment( vecBottom, vecTop, point ) > radius ) - return false - - vector bottomVec = Normalize( vecTop - vecBottom ) - vector pointToBottom = Normalize( point - vecBottom ) - - vector topVec = Normalize( vecBottom - vecTop ) - vector pointToTop = Normalize( point - vecTop ) - - if ( DotProduct( bottomVec, pointToBottom ) < 0 ) - return false - - if ( DotProduct( topVec, pointToTop ) < 0.0 ) - return false - - return true -} - -float function AngleDiff( float ang, float targetAng ) -{ - float delta = ( targetAng - ang ) % 360.0 - if ( targetAng > ang ) - { - if ( delta >= 180.0 ) - delta -= 360.0; - } - else - { - if ( delta <= -180.0 ) - delta += 360.0; - } - return delta -} - - -float function ClampAngle( float ang ) -{ - while( ang > 360 ) - ang -= 360 - while( ang < 0 ) - ang += 360 - return ang -} - -float function ClampAngle180( float ang ) -{ - while( ang > 180 ) - ang -= 180 - while( ang < -180 ) - ang += 180 - return ang -} - -vector function ShortestRotation( vector ang, vector targetAng ) -{ - return Vector( AngleDiff( ang.x, targetAng.x ), AngleDiff( ang.y, targetAng.y ), AngleDiff( ang.z, targetAng.z ) ) -} - -int function GetWinningTeam() -{ - if ( level.nv.winningTeam != null ) - return expect int( level.nv.winningTeam ) - - if ( IsFFAGame() ) - return GetWinningTeam_FFA() - - if ( IsRoundBased() ) - { - if ( GameRules_GetTeamScore2( TEAM_IMC ) > GameRules_GetTeamScore2( TEAM_MILITIA ) ) - return TEAM_IMC - - if ( GameRules_GetTeamScore2( TEAM_MILITIA ) > GameRules_GetTeamScore2( TEAM_IMC ) ) - return TEAM_MILITIA - } - else - { - if ( GameRules_GetTeamScore( TEAM_IMC ) > GameRules_GetTeamScore( TEAM_MILITIA ) ) - return TEAM_IMC - - if ( GameRules_GetTeamScore( TEAM_MILITIA ) > GameRules_GetTeamScore( TEAM_IMC ) ) - return TEAM_MILITIA - } - - return TEAM_UNASSIGNED -} - -int function GetWinningTeam_FFA() -{ - if ( level.nv.winningTeam != null ) - return expect int( level.nv.winningTeam ) - - int maxScore = 0 - int playerTeam - int currentScore - int winningTeam = TEAM_UNASSIGNED - - foreach( player in GetPlayerArray() ) - { - playerTeam = player.GetTeam() - if ( IsRoundBased() ) - currentScore = GameRules_GetTeamScore2( playerTeam ) - else - currentScore = GameRules_GetTeamScore( playerTeam ) - - if ( currentScore == maxScore) //Treat multiple teams as having the same score as no team winning - winningTeam = TEAM_UNASSIGNED - - if ( currentScore > maxScore ) - { - maxScore = currentScore - winningTeam = playerTeam - } - } - - return winningTeam - -} - -void function EmitSkyboxSoundAtPosition( vector positionInSkybox, string sound, float skyboxScale = 0.001, bool clamp = false ) -{ - if ( IsServer() ) - clamp = true // sounds cannot play outside 16k limit on server - vector position = SkyboxToWorldPosition( positionInSkybox, skyboxScale, clamp ) - EmitSoundAtPosition( TEAM_UNASSIGNED, position, sound ) -} - -vector function SkyboxToWorldPosition( vector positionInSkybox, float skyboxScale = 0.001, bool clamp = true ) -{ - Assert( skyboxScale > 0 ) - Assert( "skyboxCamOrigin" in level ) - - vector position = Vector( 0.0, 0.0, 0.0 ) - vector skyOrigin = expect vector( level.skyboxCamOrigin ) - - #if CLIENT - position = ( positionInSkybox - skyOrigin ) * ( 1.0 / skyboxScale ) - - if ( clamp ) - { - entity localViewPlayer = GetLocalViewPlayer() - Assert( localViewPlayer ) - vector localViewPlayerOrg = localViewPlayer.GetOrigin() - - position = localViewPlayerOrg + ClampVectorToCube( localViewPlayerOrg, position - localViewPlayerOrg, Vector( 0.0, 0.0, 0.0 ), 32000.0 ) - } - #else - position = ( positionInSkybox - skyOrigin ) * ( 1.0 / skyboxScale ) - - if ( clamp ) - position = ClampVectorToCube( Vector( 0.0, 0.0, 0.0 ), position, Vector( 0.0, 0.0, 0.0 ), 32000.0 ) - #endif // CLIENT - - return position -} - -void function FadeOutSoundOnEntityAfterDelay( entity ent, string soundAlias, float delay, float fadeTime ) -{ - if ( !IsValid( ent ) ) - return - - ent.EndSignal( "OnDestroy" ) - wait delay - FadeOutSoundOnEntity( ent, soundAlias, fadeTime ) -} - -function GetRandomKeyFromWeightedTable( Table ) -{ - local weightTotal = 0.0 - foreach ( key, value in Table ) - { - weightTotal += value - } - - local randomValue = RandomFloat( weightTotal ) - - foreach ( key, value in Table ) - { - if ( randomValue <= weightTotal && randomValue >= weightTotal - value) - return key - weightTotal -= value - } -} - -bool function IsMatchOver() -{ - if ( IsRoundBased() && level.nv.gameEndTime ) - return true - else if ( !IsRoundBased() && level.nv.gameEndTime && Time() > level.nv.gameEndTime ) - return true - - return false -} - -bool function IsScoringNonStandard() -{ - return expect bool( level.nv.nonStandardScoring ) -} - -bool function IsRoundBased() -{ - return expect bool( level.nv.roundBased ) -} - -int function GetRoundsPlayed() -{ - return expect int( level.nv.roundsPlayed ) -} - -bool function IsEliminationBased() -{ - return Riff_EliminationMode() != eEliminationMode.Default -} - -bool function IsPilotEliminationBased() -{ - return ( Riff_EliminationMode() == eEliminationMode.Pilots || Riff_EliminationMode() == eEliminationMode.PilotsTitans ) -} - -bool function IsTitanEliminationBased() -{ - return ( Riff_EliminationMode() == eEliminationMode.Titans || Riff_EliminationMode() == eEliminationMode.PilotsTitans ) -} - -bool function IsSingleTeamMode() -{ - return ( 1 == GetCurrentPlaylistVarInt( "max_teams", 2 ) ) -} - -void function __WarpInEffectShared( vector origin, vector angles, string sfx, float preWaitOverride = -1.0 ) -{ - float preWait = 2.0 - float sfxWait = 0.1 - float totalTime = WARPINFXTIME - - if ( sfx == "" ) - sfx = "dropship_warpin" - - if ( preWaitOverride >= 0.0 ) - wait preWaitOverride - else - wait preWait //this needs to go and the const for warpin fx time needs to change - but not this game - the intro system is too dependent on it - - #if CLIENT - int fxIndex = GetParticleSystemIndex( FX_GUNSHIP_CRASH_EXPLOSION_ENTRANCE ) - StartParticleEffectInWorld( fxIndex, origin, angles ) - #else - entity fx = PlayFX( FX_GUNSHIP_CRASH_EXPLOSION_ENTRANCE, origin, angles ) - fx.FXEnableRenderAlways() - fx.DisableHibernation() - #endif // CLIENT - - wait sfxWait - EmitSoundAtPosition( TEAM_UNASSIGNED, origin, sfx ) - - wait totalTime - preWait - sfxWait -} - -void function __WarpOutEffectShared( entity dropship ) -{ - int attach = dropship.LookupAttachment( "origin" ) - vector origin = dropship.GetAttachmentOrigin( attach ) - vector angles = dropship.GetAttachmentAngles( attach ) - - #if CLIENT - int fxIndex = GetParticleSystemIndex( FX_GUNSHIP_CRASH_EXPLOSION_EXIT ) - StartParticleEffectInWorld( fxIndex, origin, angles ) - #else - entity fx = PlayFX( FX_GUNSHIP_CRASH_EXPLOSION_EXIT, origin, angles ) - fx.FXEnableRenderAlways() - fx.DisableHibernation() - #endif // CLIENT - - EmitSoundAtPosition( TEAM_UNASSIGNED, origin, "dropship_warpout" ) -} - -bool function IsSwitchSidesBased() -{ - return (level.nv.switchedSides != null) -} - -int function HasSwitchedSides() //This returns an int instead of a bool! Should rewrite -{ - return expect int( level.nv.switchedSides ) -} - -bool function IsFirstRoundAfterSwitchingSides() -{ - if ( !IsSwitchSidesBased() ) - return false - - if ( IsRoundBased() ) - return level.nv.switchedSides > 0 && GetRoundsPlayed() == level.nv.switchedSides - else - return level.nv.switchedSides > 0 - - unreachable -} - -void function CamBlendFov( entity cam, float oldFov, float newFov, float transTime, float transAccel, float transDecel ) -{ - if ( !IsValid( cam ) ) - return - - cam.EndSignal( "OnDestroy" ) - - float currentTime = Time() - float startTime = currentTime - float endTime = startTime + transTime - - while ( endTime > currentTime ) - { - float interp = Interpolate( startTime, endTime - startTime, transAccel, transDecel ) - cam.SetFOV( GraphCapped( interp, 0.0, 1.0, oldFov, newFov ) ) - wait( 0.0 ) - currentTime = Time() - } -} - -void function CamFollowEnt( entity cam, entity ent, float duration, vector offset = <0.0, 0.0, 0.0>, string attachment = "", bool isInSkybox = false ) -{ - if ( !IsValid( cam ) ) - return - - cam.EndSignal( "OnDestroy" ) - - vector camOrg = Vector( 0.0, 0.0, 0.0 ) - - vector targetPos = Vector( 0.0, 0.0, 0.0 ) - float currentTime = Time() - float startTime = currentTime - float endTime = startTime + duration - vector diff = Vector( 0.0, 0.0, 0.0 ) - int attachID = ent.LookupAttachment( attachment ) - - while ( endTime > currentTime ) - { - camOrg = cam.GetOrigin() - - if ( attachID <= 0 ) - targetPos = ent.GetOrigin() - else - targetPos = ent.GetAttachmentOrigin( attachID ) - - if ( isInSkybox ) - targetPos = SkyboxToWorldPosition( targetPos ) - diff = ( targetPos + offset ) - camOrg - - cam.SetAngles( VectorToAngles( diff ) ) - - wait( 0.0 ) - - currentTime = Time() - } -} - -void function CamFacePos( entity cam, vector pos, float duration ) -{ - if ( !IsValid( cam ) ) - return - - cam.EndSignal( "OnDestroy" ) - - float currentTime = Time() - float startTime = currentTime - float endTime = startTime + duration - vector diff = Vector( 0.0, 0.0, 0.0 ) - - while ( endTime > currentTime ) - { - diff = pos - cam.GetOrigin() - - cam.SetAngles( VectorToAngles( diff ) ) - - wait( 0.0 ) - - currentTime = Time() - } -} - -void function CamBlendFromFollowToAng( entity cam, entity ent, vector endAng, float transTime, float transAccel, float transDecel ) -{ - if ( !IsValid( cam ) ) - return - - cam.EndSignal( "OnDestroy" ) - - vector camOrg = cam.GetOrigin() - - float currentTime = Time() - float startTime = currentTime - float endTime = startTime + transTime - - while ( endTime > currentTime ) - { - vector diff = ent.GetOrigin() - camOrg - vector anglesToEnt = VectorToAngles( diff ) - - float frac = Interpolate( startTime, endTime - startTime, transAccel, transDecel ) - - vector newAngs = anglesToEnt + ShortestRotation( anglesToEnt, endAng ) * frac - - cam.SetAngles( newAngs ) - - wait( 0.0 ) - - currentTime = Time() - } -} - -void function CamBlendFromPosToPos( entity cam, vector startPos, vector endPos, float transTime, float transAccel, float transDecel ) -{ - if ( !IsValid( cam ) ) - return - - cam.EndSignal( "OnDestroy" ) - - float currentTime = Time() - float startTime = currentTime - float endTime = startTime + transTime - vector diff = endPos - startPos - - while ( endTime > currentTime ) - { - float frac = Interpolate( startTime, endTime - startTime, transAccel, transDecel ) - - vector newAngs = startPos + diff * frac - - cam.SetOrigin( newAngs ) - - wait( 0.0 ) - - currentTime = Time() - } -} - -void function CamBlendFromAngToAng( entity cam, vector startAng, vector endAng, float transTime, float transAccel, float transDecel ) -{ - if ( !IsValid( cam ) ) - return - - cam.EndSignal( "OnDestroy" ) - - float currentTime = Time() - float startTime = currentTime - float endTime = startTime + transTime - - while ( endTime > currentTime ) - { - float frac = Interpolate( startTime, endTime - startTime, transAccel, transDecel ) - - vector newAngs = startAng + ShortestRotation( startAng, endAng ) * frac - - cam.SetAngles( newAngs ) - - wait( 0.0 ) - - currentTime = Time() - } -} - -int function AddBitMask( int bitsExisting, int bitsToAdd ) -{ - return bitsExisting | bitsToAdd -} - -int function RemoveBitMask( int bitsExisting, int bitsToRemove ) -{ - return bitsExisting & ( ~bitsToRemove ) -} - -bool function HasBitMask( int bitsExisting, int bitsToCheck ) -{ - int bitsCommon = bitsExisting & bitsToCheck - return bitsCommon == bitsToCheck -} - -float function GetDeathCamLength( entity player ) -{ - if ( !GamePlayingOrSuddenDeath() ) - return DEATHCAM_TIME_SHORT - else - return DEATHCAM_TIME - - unreachable -} - -float function GetRespawnButtonCamTime( player ) -{ - if ( !GamePlayingOrSuddenDeath() ) - return DEATHCAM_TIME_SHORT + RESPAWN_BUTTON_BUFFER - else - return DEATHCAM_TIME + RESPAWN_BUTTON_BUFFER - - unreachable -} - -float function GetKillReplayAfterTime( player ) -{ - if ( IsSingleplayer() ) - return 4.0 - - if ( !GamePlayingOrSuddenDeath() ) - return KILL_REPLAY_AFTER_KILL_TIME_SHORT - - return KILL_REPLAY_AFTER_KILL_TIME -} - -function IntroPreviewOn() -{ - local bugnum = GetBugReproNum() - switch( bugnum ) - { - case 1337: - case 13371: - case 13372: - case 13373: - case 1338: - case 13381: - case 13382: - case 13383: - return bugnum - - default: - return null - } -} - -bool function EntHasModelSet( entity ent ) -{ - asset modelName = ent.GetModelName() - - if ( modelName == $"" || modelName == $"?" ) - return false - - return true -} - -string function GenerateTitanOSAlias( entity player, string aliasSuffix ) -{ - //HACK: Temp fix for blocker bug. Fixing correctly next. - if ( IsSingleplayer() ) - { - return "diag_gs_titanBt_" + aliasSuffix - } - else - { - entity titan - if ( player.IsTitan() ) - titan = player - else - titan = player.GetPetTitan() - - Assert( IsValid( titan ) ) - string titanCharacterName = GetTitanCharacterName( titan ) - string primeTitanString = "" - - if ( IsTitanPrimeTitan( titan ) ) - primeTitanString = "_prime" - - string modifiedAlias = "diag_gs_titan" + titanCharacterName + primeTitanString + "_" + aliasSuffix - return modifiedAlias - } - unreachable -} - -void function AddCallback_OnUseEntity( entity ent, callbackFunc ) -{ - AssertParameters( callbackFunc, 2, "ent, player" ) - - if ( !( "onUseEntityCallbacks" in ent.s ) ) - ent.s.onUseEntityCallbacks <- [] - - Assert( !ent.s.onUseEntityCallbacks.contains( callbackFunc ), "Already added " + FunctionToString( callbackFunc ) + " with AddCalback_OnUseEntity" ) - ent.s.onUseEntityCallbacks.append( callbackFunc ) -} - -void function SetWaveSpawnType( int spawnType ) -{ - shGlobal.waveSpawnType = spawnType -} - -int function GetWaveSpawnType() -{ - return shGlobal.waveSpawnType -} - -void function SetWaveSpawnInterval( float interval ) -{ - shGlobal.waveSpawnInterval = interval -} - -float function GetWaveSpawnInterval() -{ - return shGlobal.waveSpawnInterval -} - -bool function IsArcTitan( entity npc ) -{ - return npc.GetAISettingsName() == "npc_titan_arc" -} - -bool function IsNukeTitan( entity npc ) -{ - return npc.GetAISettingsName() == "npc_titan_nuke" -} - -bool function IsMortarTitan( entity npc ) -{ - return npc.GetAISettingsName() == "npc_titan_mortar" -} - -bool function IsFragDrone( entity npc ) -{ - #if SERVER - return npc.GetClassName() == "npc_frag_drone" - #endif - - #if CLIENT - return npc.GetSignifierName() == "npc_frag_drone" - #endif -} - -bool function IsSniperSpectre( entity npc ) -{ - return false -} - -bool function IsVortexSphere( entity ent ) -{ - return ( ent.GetClassName() == "vortex_sphere" ) -} - -bool function PointIsWithinBounds( vector point, vector mins, vector maxs ) -{ - Assert( mins.x < maxs.x ) - Assert( mins.y < maxs.y ) - Assert( mins.z < maxs.z ) - - return ( ( point.z >= mins.z && point.z <= maxs.z ) && - ( point.x >= mins.x && point.x <= maxs.x ) && - ( point.y >= mins.y && point.y <= maxs.y ) ) -} - -int function GetSpStartIndex() -{ - //HACK -> this should use some other code driven thing, not GetBugReproNum - int index = GetBugReproNum() - - if ( index < 0 ) - return 0 - - return index -} - -// return all living soldiers -array function GetAllSoldiers() -{ - return GetNPCArrayByClass( "npc_soldier" ) -} - -int function GameTeams_GetNumLivingPlayers( int teamIndex = TEAM_ANY ) -{ - int noOfLivingPlayers = 0 - - array players - if ( teamIndex == TEAM_ANY ) - players = GetPlayerArray() - else - players = GetPlayerArrayOfTeam( teamIndex ) - - foreach ( player in players ) - { - if ( !IsAlive( player ) ) - continue - - ++noOfLivingPlayers - } - - return noOfLivingPlayers -} - -bool function GameTeams_TeamHasDeadPlayers( int team ) -{ - array teamPlayers = GetPlayerArrayOfTeam( team ) - foreach ( entity teamPlayer in teamPlayers ) - { - if ( !IsAlive( teamPlayer ) ) - return true - } - return false -} - -typedef EntitiesDidLoadCallbackType void functionref() -array _EntitiesDidLoadTypedCallbacks - -void function RunCallbacks_EntitiesDidLoad() -{ - // reloading the level so don't do callbacks - if ( "forcedReloading" in level ) - return - - foreach ( callback in _EntitiesDidLoadTypedCallbacks ) - { - thread callback() - } -} - -void function AddCallback_EntitiesDidLoad( EntitiesDidLoadCallbackType callback ) -{ - _EntitiesDidLoadTypedCallbacks.append( callback ) -} - -bool function IsTitanNPC( entity ent ) -{ - return ent.IsTitan() && ent.IsNPC() -} - -entity function InflictorOwner( entity inflictor ) -{ - if ( IsValid( inflictor ) ) - { - entity inflictorOwner = inflictor.GetOwner() - if ( IsValid( inflictorOwner ) ) - inflictor = inflictorOwner - } - - return inflictor -} - -bool function IsPlayerControlledSpectre( entity ent ) -{ - return ent.GetClassName() == "npc_spectre" && ent.GetBossPlayer() != null -} - -bool function IsPlayerControlledTurret( entity ent ) -{ - return IsTurret( ent ) && ent.GetBossPlayer() != null -} - -bool function TitanShieldDecayEnabled() -{ - return ( GetCurrentPlaylistVarInt( "titan_shield_decay", 0 ) == 1 ) -} - -bool function TitanShieldRegenEnabled() -{ - return ( GetCurrentPlaylistVarInt( "titan_shield_regen", 0 ) == 1 ) -} - -bool function DoomStateDisabled() -{ - return ( GetCurrentPlaylistVarString( "titan_doomstate_variation", "default" ) == "disabled" || GetCurrentPlaylistVarString( "titan_doomstate_variation", "default" ) == "lastsegment" ) -} - -bool function NoWeaponDoomState() -{ - return ( GetCurrentPlaylistVarString( "titan_doomstate_variation", "default" ) == "noweapon" ) -} - -entity function GetPetTitanOwner( entity titan ) -{ - array players = GetPlayerArray() - entity foundPlayer - foreach ( player in players ) - { - if ( player.GetPetTitan() == titan ) - { - Assert( foundPlayer == null, player + " and " + foundPlayer + " both own " + titan ) - foundPlayer = player - } - } - - return foundPlayer -} - -entity function GetSoulFromPlayer( entity player ) -{ - Assert( player.IsPlayer(), "argument should be a player" ) - - if ( player.IsTitan() ) - return player.GetTitanSoul() - else if ( IsValid( player.GetPetTitan() ) ) - return player.GetPetTitan().GetTitanSoul() - - return null -} - -string function GetPlayerBodyType( player ) -{ - return expect string( player.GetPlayerSettingsField( "weaponClass" ) ) -} - - -void function SetTeam( entity ent, int team ) -{ - #if CLIENT - ent.Code_SetTeam( team ) - #else - if ( ent.IsPlayer() ) - { - ent.Code_SetTeam( team ) - } - else if ( ent.IsNPC() ) - { - int currentTeam = ent.GetTeam() - bool alreadyAssignedValidTeam = ( currentTeam == TEAM_IMC || currentTeam == TEAM_MILITIA ) - - ent.Code_SetTeam( team ) - - if ( ent.GetModelName() == $"" ) - return - - FixupTitle( ent ) - - if ( IsGrunt( ent ) || IsSpectre( ent ) ) - { - if ( IsMultiplayer() ) - { - int eHandle = ent.GetEncodedEHandle() - - array players = GetPlayerArray() - foreach ( player in players ) - { - Remote_CallFunction_Replay( player, "ServerCallback_UpdateOverheadIconForNPC", eHandle ) - } - } - } - else if ( IsShieldDrone( ent ) ) - { - if ( team == 0 ) - { - // anybody can use neutral shield drone - ent.SetUsable() - } - else - { - // only friendlies use a team shield drone - ent.SetUsableByGroup( "friendlies pilot" ) - } - } - - table modelTable = ent.CreateTableFromModelKeyValues() - - if ( !( "teamSkin" in modelTable ) ) - return - - if ( alreadyAssignedValidTeam && ( !( "swapTeamOnLeech" in modelTable.teamSkin ) ) ) - return - - SetSkinForTeam( ent, team ) - } - else - { - ent.Code_SetTeam( team ) - } - #endif -} - -void function PrintTraceResults( TraceResults results ) -{ - printt( "TraceResults: " ) - printt( "=========================" ) - printt( "hitEnt: " + results.hitEnt ) - printt( "endPos: " + results.endPos ) - printt( "surfaceNormal: " + results.surfaceNormal ) - printt( "surfaceName: " + results.surfaceName ) - printt( "fraction: " + results.fraction ) - printt( "fractionLeftSolid: " + results.fractionLeftSolid ) - printt( "hitGroup: " + results.hitGroup ) - printt( "startSolid: " + results.startSolid ) - printt( "allSolid: " + results.allSolid ) - printt( "hitSky: " + results.hitSky ) - printt( "contents: " + results.contents ) - printt( "=========================" ) -} - -bool function PROTO_AlternateDoomedState() -{ - return ( GetCurrentPlaylistVarInt( "infinite_doomed_state", 1 ) == 1 ) -} - -bool function PROTO_VariableRegenDelay() -{ - return ( GetCurrentPlaylistVarInt( "variable_regen_delay", 1 ) == 1 ) -} - -bool function PROTO_AutoTitansDisabled() -{ - return ( GetCurrentPlaylistVarInt( "always_enable_autotitans", 1 ) == 0 ) -} - -bool function TitanDamageRewardsTitanCoreTime() -{ - if ( GetCurrentPlaylistVarInt( "titan_core_from_titan_damage", 0 ) != 0 ) - return true - return false -} - -vector function ClampToMap( vector pos ) -{ - return IterateAxis( pos, LimitAxisToMapExtents ) -} - -vector function IterateAxis( vector pos, float functionref( float ) func ) -{ - pos.x = func( pos.x ) - pos.y = func( pos.y ) - pos.z = func( pos.z ) - return pos -} - -float function LimitAxisToMapExtents( float axisVal ) -{ - if ( axisVal >= MAP_EXTENTS ) - axisVal = MAP_EXTENTS - 1 - else if ( axisVal <= -MAP_EXTENTS ) - axisVal = -( MAP_EXTENTS - 1 ) - return axisVal -} - -bool function PilotSpawnOntoTitanIsEnabledInPlaylist( entity player ) -{ - if ( GetCurrentPlaylistVarInt( "titan_spawn_deploy_enabled", 0 ) != 0 ) - return true - return false -} - -bool function PlayerCanSpawnIntoTitan( entity player ) -{ - if ( !PilotSpawnOntoTitanIsEnabledInPlaylist( player ) ) - return false - - entity titan = player.GetPetTitan() - - if ( !IsAlive( titan ) ) - return false - - if ( GetDoomedState( titan ) ) - return false - - if ( titan.ContextAction_IsActive() ) - return false - - return false // turned off until todd figures out how to enable -} - -array< vector > function EntitiesToOrigins( array< entity > ents ) -{ - array origins - - foreach ( ent in ents ) - { - origins.append( ent.GetOrigin() ) - } - - return origins -} - -vector function GetMedianOriginOfEntities( array ents ) -{ - array origins = EntitiesToOrigins( ents ) - return GetMedianOrigin( origins ) -} - -vector function GetMedianOrigin( array origins ) -{ - if ( origins.len() == 1 ) - return origins[0] - - vector median - - int middleIndex1 - int middleIndex2 - - if ( IsEven( origins.len() ) ) - { - middleIndex1 = origins.len() / 2 - middleIndex2 = middleIndex1 - } - else - { - middleIndex1 = int( floor( origins.len() / 2.0 ) ) - middleIndex2 = middleIndex1 + 1 - } - - origins.sort( CompareVecX ) - median.x = ( origins[ middleIndex1 ].x + origins[ middleIndex2 ].x ) / 2.0 - - origins.sort( CompareVecY ) - median.y = ( origins[ middleIndex1 ].y + origins[ middleIndex2 ].y ) / 2.0 - - origins.sort( CompareVecZ ) - median.z = ( origins[ middleIndex1 ].z + origins[ middleIndex2 ].z ) / 2.0 - - return median -} - -int function CompareVecX( vector a, vector b ) -{ - if ( a.x > b.x ) - return 1 - - return -1 -} - -int function CompareVecY( vector a, vector b ) -{ - if ( a.y > b.y ) - return 1 - - return -1 -} - -int function CompareVecZ( vector a, vector b ) -{ - if ( a.z > b.z ) - return 1 - - return -1 -} - -float function GetFractionAlongPath( array nodes, vector p ) -{ - float totalDistance = GetPathDistance( nodes ) - - // See which segment we are currently on (closest to) - int closestSegment = -1 - float closestDist = 9999 - for( int i = 0 ; i < nodes.len() - 1; i++ ) - { - float dist = GetDistanceSqrFromLineSegment( nodes[i].GetOrigin(), nodes[i + 1].GetOrigin(), p ) - if ( closestSegment < 0 || dist < closestDist ) - { - closestSegment = i - closestDist = dist - } - } - Assert( closestSegment >= 0 ) - Assert( closestSegment < nodes.len() - 1 ) - - // Get the distance along the path already traveled - float distTraveled = 0.0 - for( int i = 0 ; i < closestSegment; i++ ) - { - //DebugDrawLine( nodes[i].GetOrigin(), nodes[i + 1].GetOrigin(), 255, 255, 0, true, 0.1 ) - distTraveled += Distance( nodes[i].GetOrigin(), nodes[i+1].GetOrigin() ) - } - - // Add the distance traveled on current segment - vector closestPointOnSegment = GetClosestPointOnLineSegment( nodes[closestSegment].GetOrigin(), nodes[closestSegment + 1].GetOrigin(), p ) - //DebugDrawLine( nodes[closestSegment].GetOrigin(), closestPointOnSegment, 255, 255, 0, true, 0.1 ) - distTraveled += Distance( nodes[closestSegment].GetOrigin(), closestPointOnSegment ) - - return clamp( distTraveled / totalDistance, 0.0, 1.0 ) -} - -float function GetPathDistance( array nodes ) -{ - float totalDist = 0.0 - for( int i = 0 ; i < nodes.len() - 1; i++ ) - { - //DebugDrawSphere( nodes[i].GetOrigin(), 16.0, 255, 0, 0, true, 0.1 ) - totalDist += Distance( nodes[i].GetOrigin(), nodes[i+1].GetOrigin() ) - } - //DebugDrawSphere( nodes[nodes.len() -1].GetOrigin(), 16.0, 255, 0, 0, true, 0.1 ) - - return totalDist -} - -void function WaittillAnimDone( entity animatingEnt ) -{ - waitthread WaittillAnimDone_Thread( animatingEnt ) -} - -void function WaittillAnimDone_Thread( entity animatingEnt ) -{ - if ( animatingEnt.IsPlayer() ) - animatingEnt.EndSignal( "OnDestroy" ) - - animatingEnt.EndSignal( "OnAnimationInterrupted" ) - animatingEnt.WaitSignal( "OnAnimationDone" ) -} - -array function GetEntityLinkChain( entity startNode ) -{ - Assert( IsValid( startNode ) ) - array nodes - nodes.append( startNode ) - while(true) - { - entity nextNode = nodes[nodes.len() - 1].GetLinkEnt() - if ( !IsValid( nextNode ) ) - break - nodes.append( nextNode ) - } - return nodes -} - -float function HealthRatio( entity ent ) -{ - int health = ent.GetHealth() - int maxHealth = ent.GetMaxHealth() - return float( health ) / maxHealth -} - -vector function GetPointOnPathForFraction( array nodes, float frac ) -{ - Assert( frac >= 0 ) - - float totalPathDist = GetPathDistance( nodes ) - float distRemaining = totalPathDist * frac - vector point = nodes[0].GetOrigin() - - for( int i = 0 ; i < nodes.len() - 1; i++ ) - { - float segmentDist = Distance( nodes[i].GetOrigin(), nodes[i+1].GetOrigin() ) - if ( segmentDist <= distRemaining ) - { - // Add the whole segment - distRemaining -= segmentDist - point = nodes[i+1].GetOrigin() - } - else - { - // Fraction ends somewhere in this segment - vector dirVec = Normalize( nodes[i+1].GetOrigin() - nodes[i].GetOrigin() ) - point = nodes[i].GetOrigin() + ( dirVec * distRemaining ) - distRemaining = 0 - } - if ( distRemaining <= 0 ) - break - } - - if ( frac > 1.0 && distRemaining > 0 ) - { - vector dirVec = Normalize( nodes[nodes.len() - 1].GetOrigin() - nodes[nodes.len() - 2].GetOrigin() ) - point = nodes[nodes.len() - 1].GetOrigin() + ( dirVec * distRemaining ) - } - - return point -} - -bool function PlayerBlockedByTeamEMP( entity player ) -{ - return ( player.nv.empEndTime > Time() ) -} - -#if SERVER -void function Embark_Allow( entity player ) -{ - player.SetTitanEmbarkEnabled( true ) -} - -void function Embark_Disallow( entity player ) -{ - player.SetTitanEmbarkEnabled( false ) -} - -void function Disembark_Allow( entity player ) -{ - player.SetTitanDisembarkEnabled( true ) -} - -void function Disembark_Disallow( entity player ) -{ - player.SetTitanDisembarkEnabled( false ) -} -#endif - -bool function CanEmbark( entity player ) -{ - return player.GetTitanEmbarkEnabled() -} - -bool function CanDisembark( entity player ) -{ - return player.GetTitanDisembarkEnabled() -} - -string function GetDroneType( entity npc ) -{ - return expect string( npc.Dev_GetAISettingByKeyField( "drone_type" ) ) -} - -vector function FlattenVector( vector vec ) -{ - return Vector( vec.x, vec.y, 0 ) -} - -vector function FlattenAngles( vector angles ) -{ - return Vector( 0, angles.y, 0 ) -} - -bool function IsHumanSized( entity ent ) -{ - if ( ent.IsPlayer() ) - return ent.IsHuman() - - if ( ent.IsNPC() ) - { - - if ( ent.GetAIClass() == AIC_SMALL_TURRET ) - return true - - string bodyType = ent.GetBodyType() - return bodyType == "human" || bodyType == "marvin" - } - - return false -} - -bool function IsDropship( entity ent ) -{ -#if SERVER - return ent.GetClassName() == "npc_dropship" -#elseif CLIENT - if ( !ent.IsNPC() ) - return false - //Probably should not use GetClassName, but npc_dropship isn't a class so can't use instanceof? - return ( ent.GetClassName() == "npc_dropship" || ent.GetSignifierName() == "npc_dropship" ) -#endif -} - -bool function IsSpecialist( entity ent ) -{ - return IsGrunt( ent ) && ent.IsMechanical() -} - -bool function IsGrunt( entity ent ) -{ -#if SERVER - return ent.IsNPC() && ent.GetClassName() == "npc_soldier" -#elseif CLIENT - return ent.IsNPC() && ent.GetSignifierName() == "npc_soldier" -#endif -} - -bool function IsMarvin( entity ent ) -{ - return ent.IsNPC() && ent.GetAIClass() == AIC_MARVIN -} - -bool function IsSpectre( entity ent ) -{ - return ent.IsNPC() && ent.GetAIClass() == AIC_SPECTRE -} - -bool function IsWorldSpawn( entity ent ) -{ - #if SERVER - return ent.GetClassName() == "worldspawn" - #elseif CLIENT - return ent.GetSignifierName() == "worldspawn" - #endif -} - -bool function IsEnvironment( entity ent ) -{ - #if SERVER - return ent.GetClassName() == "trigger_hurt" - #elseif CLIENT - return ent.GetSignifierName() == "trigger_hurt" - #endif -} - -bool function IsSuperSpectre( entity ent ) -{ -#if SERVER - return ent.GetClassName() == "npc_super_spectre" -#elseif CLIENT - return ent.GetSignifierName() == "npc_super_spectre" -#endif -} - -bool function IsAndroidNPC( entity ent ) -{ - return ( IsSpectre( ent ) || IsStalker( ent ) || IsMarvin( ent ) ) -} - -bool function IsStalker( entity ent ) -{ - return ent.IsNPC() && ( ent.GetAIClass() == AIC_STALKER || ent.GetAIClass() == AIC_STALKER_CRAWLING ) -} - -bool function IsProwler( entity ent ) -{ -#if SERVER - return ent.GetClassName() == "npc_prowler" -#elseif CLIENT - return ent.GetSignifierName() == "npc_prowler" -#endif -} - -bool function IsAirDrone( entity ent ) -{ -#if SERVER - return ent.GetClassName() == "npc_drone" -#elseif CLIENT - return ent.GetSignifierName() == "npc_drone" -#endif -} - -bool function IsPilotElite( entity ent ) -{ -#if SERVER - return ent.GetClassName() == "npc_pilot_elite" -#elseif CLIENT - return ent.GetSignifierName() == "npc_pilot_elite" -#endif -} - -bool function IsAttackDrone( entity ent ) -{ - return ( ent.IsNPC() && !ent.IsNonCombatAI() && IsAirDrone( ent ) ) -} - -bool function IsGunship( entity ent ) -{ -#if SERVER - return ent.GetClassName() == "npc_gunship" -#elseif CLIENT - return ent.GetSignifierName() == "npc_gunship" -#endif -} - -bool function IsMinion( entity ent ) -{ - if ( IsGrunt( ent ) ) - return true - - if ( IsSpectre( ent ) ) - return true - - return false -} - -bool function IsShieldDrone( entity ent ) -{ -#if SERVER - if ( ent.GetClassName() != "npc_drone" ) - return false -#elseif CLIENT - if ( ent.GetSignifierName() != "npc_drone" ) - return false -#endif - - return GetDroneType( ent ) == "drone_type_shield" -} - -#if SERVER -bool function IsTick( entity ent ) -{ - return (ent.IsNPC() && (ent.GetAIClass() == AIC_FRAG_DRONE)) -} - -bool function IsNPCTitan( entity ent ) -{ - return ent.IsNPC() && ent.IsTitan() -} -#endif - -bool function NPC_GruntChatterSPEnabled( entity npc ) -{ - if ( !IsSingleplayer() ) - return false - - if ( !npc.IsNPC() ) - return false - - if ( npc.GetClassName() != "npc_soldier" ) - return false - - return true -} - -RaySphereIntersectStruct function IntersectRayWithSphere( vector rayStart, vector rayEnd, vector sphereOrigin, float sphereRadius ) -{ - RaySphereIntersectStruct intersection - - vector vecSphereToRay = rayStart - sphereOrigin - - vector vecRayDelta = rayEnd - rayStart - float a = DotProduct( vecRayDelta, vecRayDelta ) - - if ( a == 0.0 ) - { - intersection.result = LengthSqr( vecSphereToRay ) <= sphereRadius * sphereRadius - intersection.enterFrac = 0.0 - intersection.leaveFrac = 0.0 - return intersection - } - - float b = 2 * DotProduct( vecSphereToRay, vecRayDelta ) - float c = DotProduct( vecSphereToRay, vecSphereToRay ) - sphereRadius * sphereRadius - float discrim = b * b - 4 * a * c - if ( discrim < 0.0 ) - { - intersection.result = false - return intersection - } - - discrim = sqrt( discrim ) - float oo2a = 0.5 / a - intersection.enterFrac = ( - b - discrim ) * oo2a - intersection.leaveFrac = ( - b + discrim ) * oo2a - - if ( ( intersection.enterFrac > 1.0 ) || ( intersection.leaveFrac < 0.0 ) ) - { - intersection.result = false - return intersection - } - - if ( intersection.enterFrac < 0.0 ) - intersection.enterFrac = 0.0 - if ( intersection.leaveFrac > 1.0 ) - intersection.leaveFrac = 1.0 - - intersection.result = true - return intersection -} - -table function GetTableFromString( string inString ) -{ - if ( inString.len() > 0 ) - return expect table( getconsttable()[ inString ] ) - - return {} -} - -int function GetWeaponDamageNear( entity weapon, entity victim ) -{ - entity weaponOwner = weapon.GetWeaponOwner() - if ( weaponOwner.IsNPC() ) - { - if ( victim.GetArmorType() == ARMOR_TYPE_HEAVY ) - return weapon.GetWeaponSettingInt( eWeaponVar.npc_damage_near_value_titanarmor ) - else - return weapon.GetWeaponSettingInt( eWeaponVar.npc_damage_near_value ) - } - else - { - if ( victim.GetArmorType() == ARMOR_TYPE_HEAVY ) - return weapon.GetWeaponSettingInt( eWeaponVar.damage_near_value_titanarmor ) - else - return weapon.GetWeaponSettingInt( eWeaponVar.damage_near_value ) - } - - unreachable -} - -void function PrintFirstPersonSequenceStruct( FirstPersonSequenceStruct fpsStruct ) -{ - printt( "Printing FirstPersonSequenceStruct:" ) - - printt( "firstPersonAnim: " + fpsStruct.firstPersonAnim ) - printt( "thirdPersonAnim: " + fpsStruct.thirdPersonAnim ) - printt( "firstPersonAnimIdle: " + fpsStruct.firstPersonAnimIdle ) - printt( "thirdPersonAnimIdle: " + fpsStruct.thirdPersonAnimIdle ) - printt( "relativeAnim: " + fpsStruct.relativeAnim ) - printt( "attachment: " + fpsStruct.attachment ) - printt( "teleport: " + fpsStruct.teleport ) - printt( "noParent: " + fpsStruct.noParent ) - printt( "blendTime: " + fpsStruct.blendTime ) - printt( "noViewLerp: " + fpsStruct.noViewLerp ) - printt( "hideProxy: " + fpsStruct.hideProxy ) - printt( "viewConeFunction: " + string( fpsStruct.viewConeFunction ) ) - printt( "origin: " + string( fpsStruct.origin ) ) - printt( "angles: " + string ( fpsStruct.angles ) ) - printt( "enablePlanting: " + fpsStruct.enablePlanting ) - printt( "setInitialTime: " + fpsStruct.setInitialTime ) - printt( "useAnimatedRefAttachment: " + fpsStruct.useAnimatedRefAttachment ) - printt( "renderWithViewModels: " + fpsStruct.renderWithViewModels ) - printt( "gravity: " + fpsStruct.gravity ) - -} - -void function WaitSignalOrTimeout( entity ent, float timeout, string signal1, string signal2 = "", string signal3 = "" ) -{ - Assert( IsValid( ent ) ) - - ent.EndSignal( signal1 ) - - if ( signal2 != "" ) - ent.EndSignal( signal2 ) - - if ( signal3 != "" ) - ent.EndSignal( signal3 ) - - wait( timeout ) -} - -array function GetShortestLineSegmentConnectingLineSegments( vector line1Point1, vector line1Point2, vector line2Point1, vector line2Point2 ) -{ - // From Paul Bourke's algorithm "The shortest line between two lines in 3D" at http://paulbourke.net/geometry/pointlineplane/ - - vector p1 = line1Point1 - vector p2 = line1Point2 - vector p3 = line2Point1 - vector p4 = line2Point2 - vector p13 = p1 - p3 - vector p21 = p2 - p1 - vector p43 = p4 - p3 - - if ( Length( p43 ) < 1.0 ) - { - array resultVectors - resultVectors.append( p4 ) - resultVectors.append( p3 ) - return resultVectors - } - - if ( Length( p21 ) < 1.0 ) - { - array resultVectors - resultVectors.append( p2 ) - resultVectors.append( p1 ) - return resultVectors - } - - float d1343 = p13.x * p43.x + p13.y * p43.y + p13.z * p43.z - float d4321 = p43.x * p21.x + p43.y * p21.y + p43.z * p21.z - float d1321 = p13.x * p21.x + p13.y * p21.y + p13.z * p21.z - float d4343 = p43.x * p43.x + p43.y * p43.y + p43.z * p43.z - float d2121 = p21.x * p21.x + p21.y * p21.y + p21.z * p21.z - - - float denom = d2121 * d4343 - d4321 * d4321 - Assert( fabs( denom ) > 0.01 ) - float numer = d1343 * d4321 - d1321 * d4343 - - float mua = numer / denom - float mub = (d1343 + d4321 * (mua)) / d4343 - - vector resultVec1 - vector resultVec2 - resultVec1.x = p1.x + mua * p21.x - resultVec1.y = p1.y + mua * p21.y - resultVec1.z = p1.z + mua * p21.z - resultVec2.x = p3.x + mub * p43.x - resultVec2.y = p3.y + mub * p43.y - resultVec2.z = p3.z + mub * p43.z - - array resultVectors - resultVectors.append( resultVec1 ) - resultVectors.append( resultVec2 ) - return resultVectors -} - -vector function GetClosestPointToLineSegments( vector line1Point1, vector line1Point2, vector line2Point1, vector line2Point2 ) -{ - array results = GetShortestLineSegmentConnectingLineSegments( line1Point1, line1Point2, line2Point1, line2Point2 ) - Assert( results.len() == 2 ) - return ( results[0] + results[1] ) / 2.0 -} - - -bool function PlayerCanSee( entity player, entity ent, bool doTrace, float degrees ) -{ - float minDot = deg_cos( degrees ) - - // On screen? - float dot = DotProduct( Normalize( ent.GetWorldSpaceCenter() - player.EyePosition() ), player.GetViewVector() ) - if ( dot < minDot ) - return false - - // Can trace to it? - if ( doTrace ) - { - TraceResults trace = TraceLine( player.EyePosition(), ent.GetWorldSpaceCenter(), null, TRACE_MASK_BLOCKLOS, TRACE_COLLISION_GROUP_NONE ) - if ( trace.hitEnt == ent || trace.fraction >= 0.99 ) - return true - else - return false - } - else - return true - - Assert( 0, "shouldn't ever get here") - unreachable -} - -bool function PlayerCanSeePos( entity player, vector pos, bool doTrace, float degrees ) -{ - float minDot = deg_cos( degrees ) - float dot = DotProduct( Normalize( pos - player.EyePosition() ), player.GetViewVector() ) - if ( dot < minDot ) - return false - - if ( doTrace ) - { - TraceResults trace = TraceLine( player.EyePosition(), pos, null, TRACE_MASK_BLOCKLOS, TRACE_COLLISION_GROUP_NONE ) - if ( trace.fraction < 0.99 ) - return false - } - - return true -} - -bool function VectorsFacingSameDirection( vector v1, vector v2, float degreesThreshold ) -{ - float minDot = deg_cos( degreesThreshold ) - float dot = DotProduct( Normalize( v1 ), Normalize( v2 ) ) - return ( dot >= minDot ) -} - -vector function GetRelativeDelta( vector origin, entity ref, string attachment = "" ) -{ - vector pos - vector right - vector forward - vector up - - if ( attachment != "" ) - { - int attachID = ref.LookupAttachment( attachment ) - pos = ref.GetAttachmentOrigin( attachID ) - vector angles = ref.GetAttachmentAngles( attachID ) - right = AnglesToRight( angles ) - forward = AnglesToForward( angles ) - up = AnglesToUp( angles ) - } - else - { - pos = ref.GetOrigin() - right = ref.GetRightVector() - forward = ref.GetForwardVector() - up = ref.GetUpVector() - } - - vector x = GetClosestPointOnLineSegment( pos + right * -16384, pos + right * 16384, origin ) - vector y = GetClosestPointOnLineSegment( pos + forward * -16384, pos + forward * 16384, origin ) - vector z = GetClosestPointOnLineSegment( pos + up * -16384, pos + up * 16384, origin ) - - float distx = Distance(pos, x) - float disty = Distance(pos, y) - float distz = Distance(pos, z) - - if ( DotProduct( x - pos, right ) < 0 ) - distx *= -1 - if ( DotProduct( y - pos, forward ) < 0 ) - disty *= -1 - if ( DotProduct( z - pos, up ) < 0 ) - distz *= -1 - - return Vector( distx, disty, distz ) -} - -#if SERVER -float function GetRoundTimeLimit_ForGameMode() -{ - #if DEV - if ( level.devForcedTimeLimit ) - { - //Make it needed to be called multiple times for RoundBasedGameModes - level.devForcedTimeLimit = 0 - return 0.1 - } - #endif - - #if MP - if ( GameState_GetTimeLimitOverride() >= 0 ) - return GameState_GetTimeLimitOverride() - #endif - - if ( !GameMode_IsDefined( GAMETYPE ) ) - return GetCurrentPlaylistVarFloat( "roundtimelimit", 10 ) - else - return GameMode_GetRoundTimeLimit( GAMETYPE ) - - unreachable -} -#endif - -bool function HasIronRules() -{ - bool result = (GetCurrentPlaylistVarInt( "iron_rules", 0 ) != 0) - return result -} - -vector function GetWorldOriginFromRelativeDelta( vector delta, entity ref ) -{ - vector right = ref.GetRightVector() * delta.x - vector forward = ref.GetForwardVector() * delta.y - vector up = ref.GetUpVector() * delta.z - - return ref.GetOrigin() + right + forward + up -} - -bool function IsHardcoreGameMode() -{ - return GetCurrentPlaylistVarInt( "gm_hardcore_settings", 0 ) == 1 -} - -bool function PlayerHasWeapon( entity player, string weaponName ) -{ - array weapons = player.GetMainWeapons() - weapons.extend( player.GetOffhandWeapons() ) - - foreach ( weapon in weapons ) - { - if ( weapon.GetWeaponClassName() == weaponName ) - return true - } - - return false -} - -bool function PlayerCanUseWeapon( entity player, string weaponClass ) -{ - return ( ( player.IsTitan() && weaponClass == "titan" ) || ( !player.IsTitan() && weaponClass == "human" ) ) -} - -string function GetTitanCharacterName( entity titan ) -{ - Assert( titan.IsTitan() ) - - string setFile - - if ( titan.IsPlayer() ) - { - setFile = titan.GetPlayerSettings() - } - else - { - string aiSettingsFile = titan.GetAISettingsName() - setFile = expect string( Dev_GetAISettingByKeyField_Global( aiSettingsFile, "npc_titan_player_settings" ) ) - } - - return GetTitanCharacterNameFromSetFile( setFile ) -} - -bool function IsTitanPrimeTitan( entity titan ) -{ - Assert( titan.IsTitan() ) - string setFile - - if ( titan.IsPlayer() ) - { - setFile = titan.GetPlayerSettings() - } - else - { - string aiSettingsFile = titan.GetAISettingsName() - setFile = expect string( Dev_GetAISettingByKeyField_Global( aiSettingsFile, "npc_titan_player_settings" ) ) - } - - return Dev_GetPlayerSettingByKeyField_Global( setFile, "isPrime" ) == 1 - -} \ No newline at end of file -- cgit v1.2.3