diff options
author | BobTheBob <32057864+BobTheBob9@users.noreply.github.com> | 2021-06-22 14:30:49 +0100 |
---|---|---|
committer | BobTheBob <32057864+BobTheBob9@users.noreply.github.com> | 2021-06-22 14:30:49 +0100 |
commit | 207facbc402f5639cbcd31f079214351ef605cf2 (patch) | |
tree | 4710b2a88dd64f3dfea1609d31a5de9141640951 /Northstar.CustomServers/scripts/vscripts/weapons/_ball_lightning.gnut | |
parent | c2d438568df6d98cf731807e30eaa7da31e5ea52 (diff) | |
download | NorthstarMods-207facbc402f5639cbcd31f079214351ef605cf2.tar.gz NorthstarMods-207facbc402f5639cbcd31f079214351ef605cf2.zip |
initial commit after moving to new repo
Diffstat (limited to 'Northstar.CustomServers/scripts/vscripts/weapons/_ball_lightning.gnut')
-rw-r--r-- | Northstar.CustomServers/scripts/vscripts/weapons/_ball_lightning.gnut | 363 |
1 files changed, 363 insertions, 0 deletions
diff --git a/Northstar.CustomServers/scripts/vscripts/weapons/_ball_lightning.gnut b/Northstar.CustomServers/scripts/vscripts/weapons/_ball_lightning.gnut new file mode 100644 index 000000000..9aae59e54 --- /dev/null +++ b/Northstar.CustomServers/scripts/vscripts/weapons/_ball_lightning.gnut @@ -0,0 +1,363 @@ +untyped + +global function BallLightning_Init +global function AttachBallLightning +global function AttachBallLightningToProp +global function CreateBallLightning +global function DestroyBallLightningOnEnt +global function GetBallLightningFromEnt + +global function RegisterBallLightningDamage + +global function BallLightningZapFX +global function BallLightningZapTargets +global function BallLightningZapConnectionFX + +struct { + table< string, float > uniqueStrings +} file + +function BallLightning_Init() +{ + PrecacheParticleSystem( BALL_LIGHTNING_ZAP_FX ) + + if ( BALL_LIGHTNING_FX_TABLE != "" ) + PrecacheImpactEffectTable( BALL_LIGHTNING_FX_TABLE ) + + RegisterBallLightningDamage( eDamageSourceId.mp_weapon_arc_launcher ) + RegisterBallLightningDamage( eDamageSourceId.mp_titanweapon_arc_ball ) + RegisterBallLightningDamage( eDamageSourceId.mp_weapon_arc_trap ) +} + +function AttachBallLightning( entity weapon, entity projectile ) +{ + Assert( !( "ballLightning" in projectile.s ) ) + + int damageSourceId + entity owner + + if ( weapon.IsProjectile() ) + { + owner = weapon.GetOwner() + damageSourceId = weapon.ProjectileGetDamageSourceID() + } + else + { + owner = weapon.GetWeaponOwner() + damageSourceId = weapon.GetDamageSourceID() + } + + + entity ball = CreateBallLightning( owner, damageSourceId, projectile.GetOrigin(), projectile.GetAngles() ) + ball.SetParent( projectile ) + projectile.s.ballLightning <- ball +} + +void function DestroyBallLightningOnEnt( entity prop ) +{ + if ( "ballLightning" in prop.s ) + { + prop.s.ballLightning.Destroy() + delete prop.s.ballLightning + } +} + + +entity function AttachBallLightningToProp( entity prop, entity owner, int damageSourceId ) +{ + entity ball = CreateBallLightning( owner, damageSourceId, prop.GetOrigin(), prop.GetAngles() ) + ball.SetParent( prop ) + prop.s.ballLightning <- ball + return ball +} + +entity function CreateBallLightning( entity owner, int damageSourceId, vector origin, vector angles ) +{ + entity ballLightning = CreateScriptMover( origin, angles ) + ballLightning.SetOwner( owner ) + SetTeam( ballLightning, owner.GetTeam() ) + + thread BallLightningThink( ballLightning, damageSourceId ) + return ballLightning +} + +void function RegisterBallLightningDamage( int damageSourceId ) +{ + AddDamageCallbackSourceID( damageSourceId, OnBallLightningDamage ) +} + +void function OnBallLightningDamage( entity victim, var damageInfo ) +{ + float damage = DamageInfo_GetDamage( damageInfo ) + + if ( damage <= 0 ) + return + + if ( victim.IsWorld() ) + return + + if ( victim.IsProjectile() ) + return + + if ( DamageInfo_GetCustomDamageType( damageInfo ) & (DF_EXPLOSION | DF_IMPACT) ) + return + + // if ( IsHumanSized( victim ) ) + // { + // DamageInfo_SetDamage( damageInfo, 0 ) + // return + // } + + entity ballLightning = DamageInfo_GetInflictor( damageInfo ) + + if ( victim == ballLightning ) + return + + if ( victim.GetParent() == ballLightning ) + return + + if ( !IsTargetEntValid( ballLightning, victim, ballLightning.e.ballLightningData ) ) + { + DamageInfo_SetDamage( damageInfo, 0 ) + return + } + + vector origin = DamageInfo_GetDamagePosition( damageInfo ) + int hitBox = DamageInfo_GetHitBox( damageInfo ) + + string tag = GetEntityCenterTag( victim ) + thread BallLightningZapConnectionFX( ballLightning, victim, tag, ballLightning.e.ballLightningData ) + BallLightningZapFX( ballLightning, victim, tag, ballLightning.e.ballLightningData ) +} + +void function BallLightningThink( entity ballLightning, int damageSourceId ) +{ + ballLightning.EndSignal( "OnDestroy" ) + + EmitSoundOnEntity( ballLightning, "Weapon_Arc_Ball_Loop" ) + + local data = {} + + OnThreadEnd( + function() : ( ballLightning, data ) + { + if ( IsValid( ballLightning ) ) + StopSoundOnEntity( ballLightning, "Weapon_Arc_Ball_Loop" ) + } + ) + + int inflictorTeam = ballLightning.GetTeam() + ballLightning.e.ballLightningTargetsIdx = CreateScriptManagedEntArray() + + WaitEndFrame() + + while( 1 ) + { + for( int i=0; i<BALL_LIGHTNING_BURST_NUM; i++ ) + { + if ( BALL_LIGHTNING_BURST_NUM > 1 ) + wait BALL_LIGHTNING_BURST_PAUSE + + vector origin = ballLightning.GetOrigin() + BallLightningZapTargets( ballLightning, origin, inflictorTeam, damageSourceId, ballLightning.e.ballLightningData, false ) + } + wait BALL_LIGHTNING_BURST_DELAY + } +} + +void function BallLightningZapTargets( entity ballLightning, vector origin, int inflictorTeam, int damageSourceId, BallLightningData fxData, bool single ) +{ + RadiusDamage( + origin, // origin + ballLightning.GetOwner(), // owner + ballLightning, // inflictor + fxData.damageToPilots, // normal damage + fxData.damage, // heavy armor damage + fxData.radius, // inner radius + fxData.radius, // outer radius + SF_ENVEXPLOSION_NO_DAMAGEOWNER, // explosion flags + 0, // distanceFromAttacker + 0, // explosionForce + fxData.deathPackage, // damage flags + damageSourceId // damage source id + ) +} + +string function GetEntityCenterTag( entity target ) +{ + string tag = "center" + + if ( IsHumanSized( target ) ) + tag = "CHESTFOCUS" + else if ( target.IsTitan() ) + tag = "HIJACK" + else if ( IsSuperSpectre( target ) || IsAirDrone( target ) ) + tag = "CHESTFOCUS" + else if ( IsDropship( target ) ) + tag = "ORIGIN" + else if ( target.GetClassName() == "npc_turret_mega" ) + tag = "ATTACH" + + return tag +} + +bool function IsTargetEntValid( entity ballLightning, entity target, BallLightningData fxData ) +{ + if ( !IsValid( target ) ) + return false + + vector origin = ballLightning.GetOrigin() + + if ( target == ballLightning ) + return false + + if ( target == ballLightning.GetParent() ) + return false + + if ( target.GetParent() == ballLightning.GetParent() ) + return false + + // if ( target.IsPlayer() && !target.IsTitan() ) + // return false + + if ( fabs( origin.z - target.GetOrigin().z ) > fxData.height ) + return false + + if ( GetBugReproNum() != 131703 ) + { + if ( target.GetModelName() == $"" ) + return false + } + + if ( !( target.GetClassName() in ArcCannonTargetClassnames ) ) + return false + + vector entityCenter = target.GetWorldSpaceCenter() + + if ( target.GetModelName() != $"" ) + { + string tag = GetEntityCenterTag( target ) + int index = target.LookupAttachment( tag ) + + if ( index == 0 ) + return false + + entityCenter = target.GetAttachmentOrigin( index ) + } + + vector fwd = AnglesToForward( ballLightning.GetAngles() ) + vector fwdToEnemy = Normalize( entityCenter - ballLightning.GetOrigin() ) + + float dot = DotProduct( fwd, fwdToEnemy ) + + if ( dot < fxData.minDot ) + return false + + + if ( IsHumanSized( target ) ) + { + float maxDist = fxData.humanRadius + if ( Distance( entityCenter, ballLightning.GetOrigin() ) > maxDist ) + return false + } + + // array<entity> ignoreEnts = [ target, ballLightning ] + // if ( ballLightning.GetParent() != null ) + // ignoreEnts.append( ballLightning.GetParent() ) + + // TraceResults trace = TraceLine( ballLightning.GetOrigin(), entityCenter, ignoreEnts, TRACE_MASK_SHOT, TRACE_COLLISION_GROUP_BLOCK_WEAPONS ) + + // if ( trace.fraction < 1 ) + // return false + + VortexBulletHit ornull vortexHit = VortexBulletHitCheck( ballLightning.GetOwner(), ballLightning.GetOrigin(), entityCenter ) + + if ( vortexHit ) + return false + + return true +} + +void function BallLightningZapConnectionFX( entity ballLightning, entity target, string tag, BallLightningData fxData ) +{ + if ( fxData.zapFx != $"" ) + { + // Control point sets the end position of the effect + entity cpEnd = CreateEntity( "info_placement_helper" ) + SetTargetName( cpEnd, GetUniqueCpString() ) + cpEnd.SetParent( target, tag, false, 0.0 ) + DispatchSpawn( cpEnd ) + + entity zapBeam = CreateEntity( "info_particle_system" ) + zapBeam.kv.cpoint1 = cpEnd.GetTargetName() + + zapBeam.SetValueForEffectNameKey( fxData.zapFx ) + zapBeam.kv.start_active = 0 + zapBeam.SetOwner( ballLightning ) + zapBeam.kv.VisibilityFlags = ENTITY_VISIBLE_TO_EVERYONE + zapBeam.SetParent( ballLightning, "", false, 0.0 ) + DispatchSpawn( zapBeam ) + + zapBeam.Fire( "Start" ) + + OnThreadEnd( + function() : ( zapBeam, cpEnd ) + { + if ( IsValid( zapBeam ) ) + zapBeam.Destroy() + if ( IsValid( cpEnd ) ) + cpEnd.Destroy() + } + ) + + ballLightning.EndSignal( "OnDestroy" ) + target.EndSignal( "OnDestroy" ) + target.EndSignal( "OnDeath" ) + + if ( fxData.zapLifetime > 0 ) + { + wait fxData.zapLifetime + } + } +} + +void function BallLightningZapFX( entity ballLightning, entity target, string tag, BallLightningData fxData ) +{ + int index = target.LookupAttachment( tag ) + + vector entityCenter = target.GetAttachmentOrigin( index ) + + if ( fxData.zapImpactTable != "" ) + PlayImpactFXTable( entityCenter, ballLightning.GetOwner(), fxData.zapImpactTable, SF_ENVEXPLOSION_INCLUDE_ENTITIES ) + + EmitSoundOnEntity( ballLightning, fxData.zapSound ) + thread FadeOutSoundOnEntityAfterDelay( ballLightning, fxData.zapSound, 0.2, 0.2 ) +} + +// This is to minimize creation of new Unique Strings +string function GetUniqueCpString() +{ + foreach ( string uString, float useTime in file.uniqueStrings ) + { + if ( useTime + BALL_LIGHTNING_ZAP_LIFETIME*2 > Time() ) + continue + + file.uniqueStrings[ uString ] = Time() + return uString + } + + string newString = UniqueString( "ball_lightning_cpEnd" ) + + // printt( "Generated new string " + newString ) + + file.uniqueStrings[ newString ] <- Time() + return newString +} + +entity function GetBallLightningFromEnt( entity ent ) +{ + if ( "ballLightning" in ent.s ) + return expect entity( ent.s.ballLightning ) + + return null +}
\ No newline at end of file |