aboutsummaryrefslogtreecommitdiff
path: root/Northstar.CustomServers/scripts/vscripts/_bubble_shield.gnut
diff options
context:
space:
mode:
Diffstat (limited to 'Northstar.CustomServers/scripts/vscripts/_bubble_shield.gnut')
-rw-r--r--Northstar.CustomServers/scripts/vscripts/_bubble_shield.gnut524
1 files changed, 0 insertions, 524 deletions
diff --git a/Northstar.CustomServers/scripts/vscripts/_bubble_shield.gnut b/Northstar.CustomServers/scripts/vscripts/_bubble_shield.gnut
deleted file mode 100644
index 30758becd..000000000
--- a/Northstar.CustomServers/scripts/vscripts/_bubble_shield.gnut
+++ /dev/null
@@ -1,524 +0,0 @@
-global function BubbleShield_Init
-
-global function CreateBubbleShield
-global function IsTitanWithinBubbleShield
-global function TitanHasBubbleShieldWeapon
-global function LetTitanPlayerShootThroughBubbleShield
-global function CreateGenericBubbleShield
-global function CreateParentedBubbleShield
-
-global function WaitUntilTitanStandsOrDies
-global function DestroyBubbleShield
-global function CreateBubbleShieldWithSettings
-
-const float SHIELD_TITAN_DAMAGE_FLOOR = 250.0
-const float SHIELD_TITAN_DAMAGE_CEILING = 16000 //Some arbitrarily large number really
-const float SHIELD_PILOT_DAMAGE_FLOOR = 30.0
-const float SHIELD_PILOT_DAMAGE_CEILING = 60.0
-const float SHIELD_NPC_DAMAGE_FLOOR = 30.0
-
-const float SHIELD_FADE_ARBITRARY_DELAY = 3.0
-const float SHIELD_FADE_ENDCAP_DELAY = 1.0
-
-const float SHIELD_DISTANCE_TO_DESTROY = 40
-
-struct BubbleShieldDamageStruct
-{
- float damageFloor
- float damageCeiling
- array<float> quadraticPolynomialCoefficients //Should actually be float[3], but because float[ 3 ] and array<float> are different types and this needs to be fed into EvaluatePolynomial make it an array<float> instead
-}
-
-struct
-{
- BubbleShieldDamageStruct titanDamageStruct
- BubbleShieldDamageStruct pilotDamageStruct
- BubbleShieldDamageStruct aiDamageStruct
-
-}file
-
-
-void function BubbleShield_Init()
-{
- RegisterSignal( "TitanBrokeBubbleShield" )
- RegisterSignal( "NewBubbleShield" )
- RegisterSignal( "StopBubbleShieldDamage" )
-
- InitBubbleShieldDamageStructValues( file.titanDamageStruct, SHIELD_TITAN_DAMAGE_FLOOR, SHIELD_TITAN_DAMAGE_CEILING, [ 12.0, 5.0, 2.0 ] )
- InitBubbleShieldDamageStructValues( file.pilotDamageStruct, SHIELD_PILOT_DAMAGE_FLOOR, SHIELD_PILOT_DAMAGE_CEILING, [ 2.0, 1.0, 1.0 ] )
- InitBubbleShieldDamageStructValues( file.aiDamageStruct, SHIELD_PILOT_DAMAGE_FLOOR, SHIELD_PILOT_DAMAGE_CEILING, [ 2.0, 1.0, 1.0 ] )
-}
-
-void function InitBubbleShieldDamageStructValues( BubbleShieldDamageStruct damageStruct, float damageFloor, float damageCeiling, array<float> quadPolynomialCoeffs )
-{
- damageStruct.damageFloor = damageFloor
- damageStruct.damageCeiling = damageCeiling
- damageStruct.quadraticPolynomialCoefficients = quadPolynomialCoeffs
-}
-
-void function CreateBubbleShield( entity titan, vector origin, vector angles )
-{
- if ( !IsAlive( titan ) )
- return
-
- titan.Signal( "ClearDisableTitanfall" )
-
- entity soul = titan.GetTitanSoul()
- entity player = soul.GetBossPlayer()
-
- if ( !IsValid( player ) )
- return
-
- if ( !svGlobal.bubbleShieldEnabled )
- return
-
- player.EndSignal( "OnDestroy" )
-
- float embarkTime = GetBubbleShieldDuration( player )
- float bubTime = embarkTime + SHIELD_FADE_ARBITRARY_DELAY + SHIELD_FADE_ENDCAP_DELAY
-
- soul.Signal( "NewBubbleShield" )
- entity bubbleShield = CreateBubbleShieldWithSettings( titan.GetTeam(), origin, angles, player, bubTime )
- bubbleShield.SetBossPlayer( player ) // so code knows AI should try to shoot at titan inside shield
- soul.soul.bubbleShield = bubbleShield
-
- player.SetTitanBubbleShieldTime( Time() + GetBubbleShieldDuration( player ) ) //This sets the time to display "Titan Shielded" on the HUD
-
- AI_CreateDangerousArea_Static( bubbleShield, null, TITAN_BUBBLE_SHIELD_INVULNERABILITY_RANGE, titan.GetTeam(), true, true, origin )
-
- //titan.SetNPCPriorityOverride( 1 )
-
- OnThreadEnd(
- function () : ( titan, soul, player, bubbleShield )
- {
- if ( IsValid( player ) )
- player.SetTitanBubbleShieldTime( 0 ) //This sets the time to display "Titan Shielded" on the HUD
-
- CleanupTitanBubbleShieldVars( titan, soul, bubbleShield )
-
- }
- )
-
- waitthread WaitUntilShieldFades( player, titan, bubbleShield, bubTime + 4.0 )
-}
-
-void function MonitorTitanMovement( entity soul, entity bubbleShield )
-{
- entity titan = soul.GetTitan()
- soul.EndSignal( "OnDestroy" )
- soul.EndSignal( "OnTitanDeath" )
- bubbleShield.EndSignal( "OnDestroy" )
- titan.EndSignal( "OnDestroy" )
-
- vector startPos = titan.GetOrigin()
- float endTime = Time() + SHIELD_FADE_ARBITRARY_DELAY
- while( endTime >= Time() )
- {
- if ( Distance( titan.GetOrigin(), startPos ) > SHIELD_DISTANCE_TO_DESTROY )
- break
-
- wait 0.1
- }
-
- soul.Signal( "TitanBrokeBubbleShield" )
-}
-
-void function CreateGenericBubbleShield( entity titan, vector origin, vector angles, float duration = 9999.0 )
-{
- if ( !IsAlive( titan ) )
- return
-
- entity soul = titan.GetTitanSoul()
- soul.Signal( "NewBubbleShield" )
- entity bubbleShield = CreateBubbleShieldWithSettings( titan.GetTeam(), origin, angles, titan, 9999 )
- soul.soul.bubbleShield = bubbleShield
-
- titan.SetNPCPriorityOverride( 10 )
-
- OnThreadEnd(
- function () : ( titan, soul, bubbleShield )
- {
- CleanupTitanBubbleShieldVars( titan, soul, bubbleShield )
- }
- )
-
- waitthread WaitUntilShieldFades( null, titan, bubbleShield, duration )
-}
-
-void function CreateParentedBubbleShield( entity titan, vector origin, vector angles, float duration = 9999.0 )
-{
- if ( !IsAlive( titan ) )
- return
-
- entity soul = titan.GetTitanSoul()
- soul.Signal( "NewBubbleShield" )
- entity bubbleShield = CreateBubbleShieldWithSettings( titan.GetTeam(), origin, angles, titan, 9999 )
- soul.soul.bubbleShield = bubbleShield
-
- titan.SetNPCPriorityOverride( 10 )
-
- OnThreadEnd(
- function () : ( titan, soul, bubbleShield )
- {
- CleanupTitanBubbleShieldVars( titan, soul, bubbleShield )
- }
- )
-
- soul.EndSignal( "OnTitanDeath" )
- soul.EndSignal( "OnDestroy" )
-
- soul.soul.bubbleShield.SetParent( titan, "ORIGIN" )
- table bubleshieldDotS = expect table( soul.soul.bubbleShield.s )
- entity friendlyColoredFX = expect entity (bubleshieldDotS.friendlyColoredFX )
- entity enemyColoredFX = expect entity (bubleshieldDotS.enemyColoredFX )
- friendlyColoredFX.SetParent( soul.soul.bubbleShield )
- enemyColoredFX.SetParent( soul.soul.bubbleShield )
-
- wait duration
-}
-
-void function CleanupTitanBubbleShieldVars( entity titan, entity soul, entity bubbleShield )
-{
- DestroyBubbleShield( bubbleShield )
-
- if ( IsValid( soul ) ){
- soul.soul.bubbleShield = null
- }
-
- if ( IsAlive( titan ) )
- titan.ClearNPCPriorityOverride()
-}
-
-void function DestroyBubbleShield( entity bubbleShield )
-{
- if ( IsValid( bubbleShield ) )
- {
- ClearChildren( bubbleShield )
- bubbleShield.Destroy()
- }
-}
-
-entity function CreateBubbleShieldWithSettings( int team, vector origin, vector angles, entity owner = null, float duration = 9999 )
-{
- entity bubbleShield = CreateEntity( "prop_dynamic" )
- bubbleShield.SetValueForModelKey( $"models/fx/xo_shield.mdl" )
- bubbleShield.kv.solid = SOLID_VPHYSICS
- bubbleShield.kv.rendercolor = "81 130 151"
- bubbleShield.kv.contents = (int(bubbleShield.kv.contents) | CONTENTS_NOGRAPPLE)
- bubbleShield.SetOrigin( origin )
- bubbleShield.SetAngles( angles )
- // Blocks bullets, projectiles but not players and not AI
- bubbleShield.kv.CollisionGroup = TRACE_COLLISION_GROUP_BLOCK_WEAPONS
- bubbleShield.SetBlocksRadiusDamage( true )
- DispatchSpawn( bubbleShield )
- bubbleShield.Hide()
-
- SetTeam( bubbleShield, team )
- array<entity> bubbleShieldFXs
-
- vector coloredFXOrigin = origin + Vector( 0, 0, 25 )
- table bubbleShieldDotS = expect table( bubbleShield.s )
- if ( team == TEAM_UNASSIGNED )
- {
- entity neutralColoredFX = StartParticleEffectInWorld_ReturnEntity( BUBBLE_SHIELD_FX_PARTICLE_SYSTEM_INDEX, coloredFXOrigin, <0, 0, 0> )
- SetTeam( neutralColoredFX, team )
- bubbleShieldDotS.neutralColoredFX <- neutralColoredFX
- bubbleShieldFXs.append( neutralColoredFX )
- }
- else
- {
- //Create friendly and enemy colored particle systems
- entity friendlyColoredFX = StartParticleEffectInWorld_ReturnEntity( BUBBLE_SHIELD_FX_PARTICLE_SYSTEM_INDEX, coloredFXOrigin, <0, 0, 0> )
- SetTeam( friendlyColoredFX, team )
- friendlyColoredFX.kv.VisibilityFlags = ENTITY_VISIBLE_TO_FRIENDLY
- EffectSetControlPointVector( friendlyColoredFX, 1, FRIENDLY_COLOR_FX )
-
- entity enemyColoredFX = StartParticleEffectInWorld_ReturnEntity( BUBBLE_SHIELD_FX_PARTICLE_SYSTEM_INDEX, coloredFXOrigin, <0, 0, 0> )
- SetTeam( enemyColoredFX, team )
- enemyColoredFX.kv.VisibilityFlags = ENTITY_VISIBLE_TO_ENEMY
- EffectSetControlPointVector( enemyColoredFX, 1, ENEMY_COLOR_FX )
-
- bubbleShieldDotS.friendlyColoredFX <- friendlyColoredFX
- bubbleShieldDotS.enemyColoredFX <- enemyColoredFX
- bubbleShieldFXs.append( friendlyColoredFX )
- bubbleShieldFXs.append( enemyColoredFX )
- }
-
- #if MP
- DisableTitanfallForLifetimeOfEntityNearOrigin( bubbleShield, origin, TITANHOTDROP_DISABLE_ENEMY_TITANFALL_RADIUS )
- #endif
-
- EmitSoundOnEntity( bubbleShield, "BubbleShield_Sustain_Loop" )
-
- thread CleanupBubbleShield( bubbleShield, bubbleShieldFXs, duration )
- thread BubbleShieldDamageEnemies( bubbleShield, owner )
-
- return bubbleShield
-}
-
-void function CleanupBubbleShield( entity bubbleShield, array<entity> bubbleShieldFXs, float fadeTime )
-{
- bubbleShield.EndSignal( "OnDestroy" )
-
- OnThreadEnd(
- function () : ( bubbleShield, bubbleShieldFXs )
- {
- if ( IsValid_ThisFrame( bubbleShield ) )
- {
- StopSoundOnEntity( bubbleShield, "BubbleShield_Sustain_Loop" )
- EmitSoundOnEntity( bubbleShield, "BubbleShield_End" )
- DestroyBubbleShield( bubbleShield )
- }
-
- foreach ( fx in bubbleShieldFXs )
- {
- if ( IsValid_ThisFrame( fx ) )
- {
- EffectStop( fx )
- }
- }
- }
- )
-
- wait fadeTime
-}
-
-void function WaitUntilShieldFades( entity player, entity titan, entity bubbleShield, float failTime )
-{
- bubbleShield.EndSignal( "OnDestroy" )
- entity soul = titan.GetTitanSoul()
- soul.EndSignal( "OnDestroy" )
- soul.EndSignal( "OnTitanDeath" )
- soul.EndSignal( "NewBubbleShield" )
-
- soul.EndSignal( "TitanBrokeBubbleShield" )
-
- if ( player != null )
- waitthread WaitUntilPlayerTitanStandsOrDies( player, titan, failTime )
- else
- waitthread WaitUntilTitanStandsOrDies( titan, failTime )
-
- // have to add this since OnTitanDeath is somewhat unreliable, especially in the middle of titan transfer
- if ( !IsAlive( soul.GetTitan() ) )
- return
-
- thread MonitorTitanMovement( soul, bubbleShield )
- wait SHIELD_FADE_ARBITRARY_DELAY
-}
-
-void function WaitUntilPlayerTitanStandsOrDies( entity player, entity titan, float failTime )
-{
- waitthread WaitUntilTitanStandsOrDies( titan, failTime )
-
- if ( !IsAlive( player ) )
- return
-
- if ( IsPlayerEmbarking( player ) && player.Anim_IsActive() )
- WaittillAnimDone( player )
-}
-
-void function WaitUntilTitanStandsOrDies( entity titan, float timeout = -1.0 )
-{
- titan.EndSignal( "OnDeath" )
- titan.EndSignal( "ChangedTitanMode" )
- float endTime = Time() + timeout
-
- for ( ;; )
- {
- if ( titan.GetTitanSoul().GetStance() == STANCE_STAND )
- return
-
- if ( Time() > endTime && timeout != -1 )
- break
-
- wait 0.2
- }
-}
-
-void function BubbleShieldDamageEnemies( entity bubbleShield, entity bubbleShieldPlayer )
-{
- bubbleShield.EndSignal( "OnDestroy" )
- if ( IsValid( bubbleShieldPlayer ) )
- bubbleShieldPlayer.EndSignal( "OnDestroy" )
-
- bubbleShield.EndSignal( "StopBubbleShieldDamage" )
-
- entity trigger = CreateEntity( "trigger_cylinder" )
- trigger.SetRadius( TITAN_BUBBLE_SHIELD_INVULNERABILITY_RANGE )
- trigger.SetAboveHeight( TITAN_BUBBLE_SHIELD_CYLINDER_TRIGGER_HEIGHT ) //Still not quite a sphere, will see if close enough
- trigger.SetBelowHeight( 0 )
- trigger.SetOrigin( bubbleShield.GetOrigin() )
- trigger.SetParent( bubbleShield )
- DispatchSpawn( trigger )
-
- trigger.SearchForNewTouchingEntity() //JFS: trigger.GetTouchingEntities() will not return entities already in the trigger unless this is called. See bug 202843
-
- /*DebugDrawCylinder( trigger.GetOrigin(), <270,0,0>, TITAN_BUBBLE_SHIELD_INVULNERABILITY_RANGE, TITAN_BUBBLE_SHIELD_CYLINDER_TRIGGER_HEIGHT, 255, 255, 255, true, 20.0 )
- DebugDrawSphere( bubbleShield.GetOrigin(), TITAN_BUBBLE_SHIELD_INVULNERABILITY_RANGE, 255, 0, 0, true, 20 )*/
- OnThreadEnd(
- function() : ( trigger )
- {
- trigger.Destroy()
- }
- )
-
- float refreshLowerBound = 0.5
- float refreshUpperBound = 0.8
-
- table<entity, int> soulTable = {}
- table<entity, int> npcTable = {}
- table<entity, int> pilotTable = {}
-
- table<entity, int> countTable
-
- while ( true )
- {
- array<entity> touchingEnts = trigger.GetTouchingEntities()
-
- foreach( touchingEnt in touchingEnts )
- {
- if ( touchingEnt.IsTitan() )
- countTable = soulTable
- else if( touchingEnt.IsPlayer() )
- countTable = pilotTable
- else
- countTable = npcTable
-
- DamageEntWithinBubbleShield( bubbleShield, bubbleShieldPlayer, touchingEnt, countTable )
- }
-
- wait RandomFloatRange( refreshLowerBound, refreshUpperBound )
- }
-}
-
-void function LetTitanPlayerShootThroughBubbleShield( entity titanPlayer )
-{
- Assert( titanPlayer.IsTitan() )
-
- entity soul = titanPlayer.GetTitanSoul()
- entity bubbleShield = soul.soul.bubbleShield
-
- if ( !IsValid( bubbleShield ) )
- return
-
- bubbleShield.SetOwner( titanPlayer ) //After this, player is able to fire out from shield. WATCH OUT FOR POTENTIAL COLLISION BUGS!
-
- thread MonitorLastFireTime( titanPlayer )
- thread StopPlayerShootThroughBubbleShield( titanPlayer, bubbleShield )
-}
-
-void function StopPlayerShootThroughBubbleShield( entity player, entity bubbleShield )
-{
- player.EndSignal( "OnDeath" )
- player.WaitSignal( "OnChangedPlayerClass" ) //Kill this thread once player gets out of the Titan
-
- if ( !IsValid( bubbleShield ) )
- return
-
- bubbleShield.SetOwner( null )
-}
-
-void function MonitorLastFireTime( entity player )
-{
- player.EndSignal( "OnDestroy" )
- player.EndSignal( "OnChangedPlayerClass" ) //Kill this thread once player gets out of the Titan
-
- player.WaitSignal( "OnPrimaryAttack" ) //Sent when player fires his weapon
- //printt( "Player fired weapon! in MonitorLastFireTime" )
-
- entity soul = player.GetTitanSoul()
-
- if ( !IsValid( soul ) )
- return
-
- soul.Signal( "TitanBrokeBubbleShield" ) //WaitUntilShieldFades will end when this signal is sent
-}
-
-void function DamageEntWithinBubbleShield( entity bubbleShield, entity bubbleShieldPlayer, entity touchingEnt, table<entity, int> countTable, )
-{
- int ownerTeam = IsValid( bubbleShieldPlayer ) ? bubbleShieldPlayer.GetTeam() : bubbleShield.GetTeam()
- if ( !BubbleShieldShouldDamage( bubbleShield, ownerTeam, touchingEnt ) )
- return
-
- entity entInCountTable = null
-
- if ( touchingEnt.IsTitan() )
- {
- entity soul = touchingEnt.GetTitanSoul()
- if ( !IsValid( soul ) )
- return
-
- entInCountTable = soul
- }
- else
- {
- entInCountTable = touchingEnt
- }
-
- if ( IsValid( entInCountTable ) && !( entInCountTable in countTable ) )
- countTable[ entInCountTable ] <- 0
-
- int timesTouched = ++countTable[ entInCountTable ]
-
- BubbleShieldDamageStruct damageStruct
-
- if ( touchingEnt.IsTitan() )
- damageStruct = file.titanDamageStruct
- else if ( touchingEnt.IsPlayer() )
- damageStruct = file.pilotDamageStruct
- else
- damageStruct = file.aiDamageStruct
-
- float damageAmount = damageStruct.damageFloor + EvaluatePolynomial( float ( countTable[ entInCountTable ] ), damageStruct.quadraticPolynomialCoefficients )
-
- //printt( "Damage amount: " + damageAmount + ", touchingEnt: " + touchingEnt )
-
- touchingEnt.TakeDamage( damageAmount, bubbleShieldPlayer, bubbleShield, { origin = bubbleShield.GetOrigin(), damageSourceId=eDamageSourceId.bubble_shield } )
- StatusEffect_AddTimed( touchingEnt, eStatusEffect.emp, 0.1, 1.0, 0.2 )
-
- EmitSoundOnEntity( bubbleShield, "titan_energyshield_damage" )
-}
-
-bool function BubbleShieldShouldDamage( entity bubbleShield, int ownerTeam, entity ent )
-{
- if ( !IsAlive( ent ) )
- return false
-
- if ( ownerTeam == ent.GetTeam() )
- return false
-
- /*if ( ent.IsTitan() && IsTitanWithinBubbleShield( ent ) )
- return false*/
-
- if ( ! ( ent instanceof CBaseCombatCharacter ) ) //Projectiles etc won't get damaged
- return false
-
- float distSqr = DistanceSqr( bubbleShield.GetOrigin(), ent.GetOrigin() )
-
- return distSqr <= TITAN_BUBBLE_SHIELD_INVULNERABILITY_RANGE_SQUARED
-}
-
-bool function IsTitanWithinBubbleShield( entity titan )
-{
- if ( !IsAlive( titan ) )
- return false
-
- entity soul = titan.GetTitanSoul()
-
- if ( !IsValid( soul ) ) //Bug 152438. Defensive coding, but there's a small window after embarking where the npc Titan doesn't have a soul anymore but can be damaged
- return false
-
- if ( !IsValid( soul.soul.bubbleShield ) )
- return false
-
- return DistanceSqr( soul.soul.bubbleShield.GetOrigin(), titan.GetOrigin() ) < TITAN_BUBBLE_SHIELD_INVULNERABILITY_RANGE * TITAN_BUBBLE_SHIELD_INVULNERABILITY_RANGE
-}
-
-bool function TitanHasBubbleShieldWeapon( entity titan )
-{
- entity weapon = titan.GetActiveWeapon()
- if ( IsValid( weapon ) && IsValid( weapon.w.bubbleShield ) )
- return true
-
- return false
-}