diff options
Diffstat (limited to 'Northstar.CustomServers/scripts/vscripts/ai/_ai_personal_shield.gnut')
-rw-r--r-- | Northstar.CustomServers/scripts/vscripts/ai/_ai_personal_shield.gnut | 371 |
1 files changed, 0 insertions, 371 deletions
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_personal_shield.gnut b/Northstar.CustomServers/scripts/vscripts/ai/_ai_personal_shield.gnut deleted file mode 100644 index f1fbdb80f..000000000 --- a/Northstar.CustomServers/scripts/vscripts/ai/_ai_personal_shield.gnut +++ /dev/null @@ -1,371 +0,0 @@ -global function AiPersonalShield -global function ActivatePersonalShield -const FX_DRONE_SHIELD_WALL_HUMAN = $"P_drone_shield_wall_sm" -const SHIELD_BREAK_FX = $"P_xo_armor_break_CP" -const SHIELD_HEALTH = 620 -global const AI_PERSONAL_SHIELD_PAIN_SHIELD_STYLE = true -const float PERSONAL_SHIELD_HEALTH_FRAC_DAMAGED = 0.5 // below what frac of total health will the personal shield owner want to chatter about shield damage? - -struct -{ - table<entity, entity> npcVortexSpheres -} file - - -void function AiPersonalShield() -{ - PrecacheParticleSystem( FX_DRONE_SHIELD_WALL_HUMAN ) - PrecacheParticleSystem( SHIELD_BREAK_FX ) - AddSyncedMeleeServerCallback( GetSyncedMeleeChooser( "human", "human" ), DisableShieldOnExecution ) -} - -void function DisableShieldOnExecution( SyncedMeleeChooser actions, SyncedMelee action, entity player, entity target ) -{ - if ( !( target in file.npcVortexSpheres ) ) - return - - entity vortex = file.npcVortexSpheres[ target ] - vortex.Destroy() -} - -void function ActivatePersonalShield( entity owner ) -{ - owner.EndSignal( "OnDeath" ) - for ( ;; ) - { - waitthread ActivatePersonalShield_Recreate( owner ) - - // got stunned? make new shield after awhile - wait 15 - } -} - -void function ShieldProtectsOwnerFromMelee( entity ent, var damageInfo ) -{ - entity attacker = DamageInfo_GetAttacker( damageInfo ) - if ( !IsAlive( attacker ) ) - return - if ( !attacker.IsPlayer() ) - return - if ( !IsPilot( attacker ) ) - return - entity weapon = DamageInfo_GetWeapon( damageInfo ) - if ( !IsValid( weapon ) ) - weapon = attacker.GetActiveWeapon() - if ( !IsValid( weapon ) ) - return - var weaponType = weapon.GetWeaponInfoFileKeyField( "weaponType" ) - if ( weaponType != "melee" ) - return - - Assert( ent in file.npcVortexSpheres ) - entity vortexSphere = file.npcVortexSpheres[ ent ] - - float radius = float( vortexSphere.kv.radius ) - float height = float( vortexSphere.kv.height ) - float bullet_fov = float( vortexSphere.kv.bullet_fov ) - float dot = cos( bullet_fov * 0.5 ) - - vector origin = vortexSphere.GetOrigin() - vector angles = vortexSphere.GetAngles() - vector forward = AnglesToForward( angles ) - int team = vortexSphere.GetTeam() - - if ( ProtectedFromShield( attacker, origin, height, radius, bullet_fov, dot, forward ) ) - { - DamageInfo_SetDamage( damageInfo, 0 ) - StunPushBack( attacker, forward ) - } -} - -entity function ActivatePersonalShield_Recreate( entity owner ) -{ - if ( !AI_PERSONAL_SHIELD_PAIN_SHIELD_STYLE ) - AddEntityCallback_OnDamaged( owner, ShieldProtectsOwnerFromMelee ) - //------------------------------ - // Shield vars - //------------------------------ - vector origin = owner.GetOrigin() - vector angles = owner.GetAngles() + Vector( 0, 0, 180 ) - - float shieldWallRadius = 45 // 90 - asset shieldFx = FX_DRONE_SHIELD_WALL_HUMAN - float wallFOV = DRONE_SHIELD_WALL_FOV_HUMAN - float shieldWallHeight = 102 - - //------------------------------ - // Vortex to block the actual bullets - //------------------------------ - entity vortexSphere = CreateEntity( "vortex_sphere" ) - - Assert( !( owner in file.npcVortexSpheres ), owner + " already has a shield" ) - file.npcVortexSpheres[ owner ] <- vortexSphere - vortexSphere.kv.spawnflags = SF_ABSORB_BULLETS | SF_BLOCK_OWNER_WEAPON | SF_BLOCK_NPC_WEAPON_LOF | SF_ABSORB_CYLINDER - vortexSphere.kv.enabled = 0 - vortexSphere.kv.radius = shieldWallRadius - vortexSphere.kv.height = shieldWallHeight - vortexSphere.kv.bullet_fov = wallFOV - vortexSphere.kv.physics_pull_strength = 25 - vortexSphere.kv.physics_side_dampening = 6 - vortexSphere.kv.physics_fov = 360 - vortexSphere.kv.physics_max_mass = 2 - vortexSphere.kv.physics_max_size = 6 - - StatusEffect_AddEndless( vortexSphere, eStatusEffect.destroyed_by_emp, 1.0 ) - - vortexSphere.SetAngles( angles ) // viewvec? - vortexSphere.SetOrigin( origin + Vector( 0, 0, shieldWallRadius - 64 ) ) - vortexSphere.SetMaxHealth( SHIELD_HEALTH ) - vortexSphere.SetHealth( SHIELD_HEALTH ) - SetTeam( vortexSphere, owner.GetTeam() ) - - thread PROTO_VortexSlowsPlayers_PersonalShield( owner, vortexSphere ) - - DispatchSpawn( vortexSphere ) - - EntFireByHandle( vortexSphere, "Enable", "", 0, null, null ) - - vortexSphere.SetTakeDamageType( DAMAGE_YES ) - vortexSphere.ClearInvulnerable() // make particle wall invulnerable to weapon damage. It will still drain over time - - //------------------------------------------ - // Shield wall fx for visuals/health drain - //------------------------------------------ - entity cpoint = CreateEntity( "info_placement_helper" ) - SetTargetName( cpoint, UniqueString( "shield_wall_controlpoint" ) ) - DispatchSpawn( cpoint ) - - entity mover = CreateScriptMover() - mover.SetOrigin( owner.GetOrigin() ) - vector moverAngles = owner.GetAngles() - mover.SetAngles( AnglesCompose( moverAngles, <0,0,180> ) ) - - int fxid = GetParticleSystemIndex( FX_DRONE_SHIELD_WALL_HUMAN ) - entity shieldWallFX = StartParticleEffectOnEntity_ReturnEntity( mover, fxid, FX_PATTACH_ABSORIGIN_FOLLOW, 0 ) - shieldWallFX.DisableHibernation() - EffectSetControlPointEntity( shieldWallFX, 0, mover ) - - //thread DrawArrowOnTag( mover ) - vortexSphere.e.shieldWallFX = shieldWallFX - vector color = GetShieldTriLerpColor( 0.0 ) - - cpoint.SetOrigin( color ) - EffectSetControlPointEntity( shieldWallFX, 1, cpoint ) - SetVortexSphereShieldWallCPoint( vortexSphere, cpoint ) - - #if GRUNTCHATTER_ENABLED - // have to do this, vortex shield isn't an entity that works with AddEntityCallback_OnDamaged - thread PersonalShieldOwner_ReactsToDamage( owner, vortexSphere ) - #endif - - //----------------------- - // Attach shield to owner - //------------------------ - vortexSphere.SetParent( mover ) - - vortexSphere.EndSignal( "OnDestroy" ) - Assert( IsAlive( owner ) ) - owner.EndSignal( "OnDeath" ) - owner.EndSignal( "ArcStunned" ) - mover.EndSignal( "OnDestroy" ) - #if MP - shieldWallFX.EndSignal( "OnDestroy" ) - #endif - - OnThreadEnd( - function() : ( owner, mover, vortexSphere ) - { - delete file.npcVortexSpheres[ owner ] - if ( IsValid( owner ) ) - { - owner.kv.defenseActive = false - if ( !AI_PERSONAL_SHIELD_PAIN_SHIELD_STYLE ) - RemoveEntityCallback_OnDamaged( owner, ShieldProtectsOwnerFromMelee ) - } - - StopShieldWallFX( vortexSphere ) - - if ( IsValid( vortexSphere ) ) - vortexSphere.Destroy() - - if ( IsValid( mover ) ) - { - //PlayFX( SHIELD_BREAK_FX, mover.GetOrigin(), mover.GetAngles() ) - mover.Destroy() - } - } - ) - - owner.kv.defenseActive = true - - for ( ;; ) - { - Assert( IsAlive( owner ) ) - UpdateShieldPosition( mover, owner ) - - #if MP - if ( IsCloaked( owner ) ) - EntFireByHandle( shieldWallFX, "Stop", "", 0, null, null ) - else - EntFireByHandle( shieldWallFX, "Start", "", 0, null, null ) - #endif - } -} - -#if GRUNTCHATTER_ENABLED -void function PersonalShieldOwner_ReactsToDamage( entity owner, entity vortexSphere ) -{ - EndSignal( owner, "OnDeath" ) - EndSignal( vortexSphere, "OnDestroy" ) - - float alertHealth = vortexSphere.GetMaxHealth() * PERSONAL_SHIELD_HEALTH_FRAC_DAMAGED - - while ( vortexSphere.GetHealth() >= alertHealth ) - wait 0.25 - - GruntChatter_TryPersonalShieldDamaged( owner ) //Commenting out to unblock tree. See bug 186062 -} -#endif - -float function GetYawForEnemyOrLKP( entity owner ) -{ - entity enemy = owner.GetEnemy() - if ( !IsValid( enemy ) ) - return owner.GetAngles().y - - vector ornull lkp = owner.LastKnownPosition( enemy ) - if ( lkp == null ) - return owner.GetAngles().y - - expect vector( lkp ) - vector dif = lkp - owner.GetOrigin() - return VectorToAngles( dif ).y -} - -void function UpdateShieldPosition( entity mover, entity owner ) -{ - mover.NonPhysicsMoveTo( owner.GetOrigin(), 0.1, 0.0, 0.0 ) - vector angles = owner.EyeAngles() - float yaw = angles.y - yaw %= 360 - mover.NonPhysicsRotateTo( <0,yaw,180>, 1.35, 0, 0 ) - -// float yaw = GetYawForEnemyOrLKP( owner ) -// float boost = sin( Time() * 1.5 ) * 65 -// yaw += boost -// yaw %= 360 -// mover.NonPhysicsRotateTo( <0,yaw,0>, 0.95, 0, 0 ) - - WaitFrame() -} - -void function PROTO_VortexSlowsPlayers_PersonalShield( entity owner, entity vortexSphere ) -{ - owner.EndSignal( "OnDeath" ) - vortexSphere.EndSignal( "OnDestroy" ) - - float radius = float(vortexSphere.kv.radius ) - float height = float(vortexSphere.kv.height ) - float bullet_fov = float( vortexSphere.kv.bullet_fov ) - float dot = cos( bullet_fov * 0.5 ) - - for ( ;; ) - { - vector origin = vortexSphere.GetOrigin() - vector angles = vortexSphere.GetAngles() - vector forward = AnglesToForward( angles ) - int team = vortexSphere.GetTeam() - - foreach ( player in GetPlayerArray() ) - { - if ( !IsAlive( player ) ) - continue - if ( player.GetTeam() == team ) - continue - if ( VortexStunCheck_PersonalShield( player, origin, height, radius, bullet_fov, dot, forward ) ) - { - player.p.lastDroneShieldStunPushTime = Time() - - if ( AI_PERSONAL_SHIELD_PAIN_SHIELD_STYLE ) - { - Explosion_DamageDefSimple( damagedef_shield_captain_arc_shield, player.GetOrigin(),owner, owner, player.GetOrigin() ) - } - } - } - WaitFrame() - } -} - -bool function ProtectedFromShield( entity player, vector origin, float height, float radius, float bullet_fov, float dotLimit, vector forward ) -{ - vector playerOrg = player.GetOrigin() - vector dif = Normalize( playerOrg - origin ) - - float dot = DotProduct2D( dif, forward ) - return dot >= dotLimit -} - -bool function VortexStunCheck_PersonalShield( entity player, vector origin, float height, float radius, float bullet_fov, float dot, vector forward ) -{ - if ( !IsPilot( player ) ) - return false - - if ( player.IsGodMode() ) - return false - - if ( AI_PERSONAL_SHIELD_PAIN_SHIELD_STYLE ) - { - if ( Time() - player.p.lastDroneShieldStunPushTime < 1.00 ) - return false - } - else - { - if ( Time() - player.p.lastDroneShieldStunPushTime < 1.75 ) - return false - } - - vector playerOrg = player.GetOrigin() - float dist2d = Distance2D( playerOrg, origin ) - - if ( dist2d > radius + 5 ) - return false - if ( dist2d < radius - 15 ) - return false - - float heightOffset = fabs( playerOrg.z - origin.z ) - - if ( heightOffset < 0 || heightOffset > height ) - return false - - if ( !ProtectedFromShield( player, origin, height, radius, bullet_fov, dot, forward ) ) - return false - - if ( AI_PERSONAL_SHIELD_PAIN_SHIELD_STYLE ) - { - const float VORTEX_STUN_DURATION = 1.0 - GiveEMPStunStatusEffects( player, VORTEX_STUN_DURATION + 0.5 ) - float strength = 0.4 - StatusEffect_AddTimed( player, eStatusEffect.emp, strength, VORTEX_STUN_DURATION, 0.5 ) - EmitSoundOnEntityOnlyToPlayer( player, player, "flesh_electrical_damage_1p" ) - } - else - { - StunPushBack( player, forward ) - } - - return true -} - -void function StunPushBack( entity player, vector forward ) -{ - const float VORTEX_STUN_DURATION = 1.0 - GiveEMPStunStatusEffects( player, VORTEX_STUN_DURATION + 0.5 ) - float strength = 0.4 - StatusEffect_AddTimed( player, eStatusEffect.emp, strength, VORTEX_STUN_DURATION, 0.5 ) - thread TempLossOfAirControl( player, VORTEX_STUN_DURATION ) - vector velocity = forward * 300 - velocity.z = 400 - - EmitSoundOnEntityOnlyToPlayer( player, player, "flesh_electrical_damage_1p" ) - player.SetVelocity( velocity ) -} |