etqw-sdk/base/script/weapons/lightningpistol.script

408 lines
8.9 KiB
Plaintext

/***********************************************************************
weapon_lightningpistol.script
***********************************************************************/
object weapon_lightningpistol : weapon_base {
void preinit();
void init();
void destroy();
void Idle();
void Fire();
void Raise();
void Lower();
void Cleanup();
void UpdateLightningEffect( vector hitPos, vector hitDir, float traceFraction, vector traceNormal );
void DoLightning( boolean doDamage );
void Overheat();
void Reload() { Overheat(); }
void LoadScopeGUI();
void FreeScopeGUI();
void OnIronSightsEnabled() { hide(); }
void OnIronSightsDisabled() { show(); }
void OnBecomeViewWeapon();
void OnFinishViewWeapon();
float range;
object effect;
object effectImpact;
float worldMuzzle;
entity worldModel;
float localMuzzle;
float scopeGUIHandle;
handle statNumFired;
float lightningDamage;
boolean dryfireAttack;
}
void weapon_lightningpistol::preinit() {
range = getFloatKeyWithDefault( "range", 2048 );
string statName = getKey( "stat_name" );
if ( statName != "" ) {
statNumFired = sys.allocStatInt( statName + "_shots_fired" );
}
lightningDamage = GetDamage( getKey( "dmg_lightning" ) );
}
void weapon_lightningpistol::init() {
worldModel = getWorldModel( 0 );
worldMuzzle = worldModel.getJointHandle( "muzzle" );
localMuzzle = getJointHandle( "muzzle" );
weaponState( "Raise", 0 );
}
void weapon_lightningpistol::destroy() {
stopSound( SND_WEAPON_FIRE2 );
killEffect( "fx_muzzle_flash" );
FreeScopeGUI();
if ( effect != $null_entity ) {
effect.remove();
}
if ( effectImpact != $null_entity ) {
effectImpact.remove();
}
if ( ShouldRunGuis() ) {
KillUpdateHeat();
}
}
void weapon_lightningpistol::Cleanup() {
FreeScopeGUI();
DisableIronSights();
stopSound( SND_WEAPON_FIRE2 );
}
void weapon_lightningpistol::Idle() {
myPlayer.disableSprint( 0.f );
weaponReady();
if ( ironSightsEnabled ) {
playCycle( ANIMCHANNEL_ALL, "idle_zoom" );
} else {
playCycle( ANIMCHANNEL_ALL, "idle" );
}
while ( true ) {
if ( WEAPON_LOWERWEAPON ) {
weaponState( "Lower", 4 );
}
CheckIronSights();
// dryfire sound
if ( myPlayer.getButton( PK_ATTACK ) ) {
if ( !dryfireAttack && !ammoAvailable( 0 ) ) {
if ( myPlayer == sys.getLocalViewPlayer() ) {
startSound( "snd_dryfire", SND_WEAPON_DRYFIRE );
dryfireAttack = true;
}
}
} else {
dryfireAttack = false;
}
if ( ( sys.getTime() >= reFire ) ) {
if ( WEAPON_ATTACK ) {
if ( ammoAvailable( 0 ) > 0 ) {
weaponState( "Fire", 0 );
}
}
}
if ( myPlayer.AI_SPRINT ) {
weaponState( "Sprint", 4 );
}
UpdateCharge();
sys.waitFrame();
}
}
void weapon_lightningpistol::Fire() {
myPlayer.disableSprint( 1.f );
PlayFireSound();
startSound( "snd_fire_loop", SND_WEAPON_FIRE2 );
// start firing - create the lightning effect
effect = spawnClientEffect( "fx_lightning" );
if ( effect != $null_entity ) {
effect.setEffectLooping( 1 );
}
float nextAnimation = 0;
while ( ammoAvailable( 0 ) > 0 && WEAPON_ATTACK ) {
if ( sys.getTime() > nextAnimation ) {
if ( !sys.isClient() ) {
if ( myPlayer != $null_entity ) {
sys.increaseStatInt( statNumFired, myPlayer.getEntityNumber(), 1 );
}
}
PlayFireEffect();
playAnim( ANIMCHANNEL_ALL, "fire" );
nextAnimation = sys.getTime() + fireRate;
AmmoCheckClip( 0 );
DoLightning( true );
} else {
DoLightning( false );
}
if ( IsOverheated() ) {
if ( effect != $null_entity ) {
effect.remove();
}
if ( effectImpact != $null_entity ) {
effectImpact.remove();
}
stopSound( SND_WEAPON_FIRE2 );
weaponState( "Overheat", 4 );
}
CheckIronSights();
if ( WEAPON_LOWERWEAPON ) {
break;
}
sys.waitFrame();
}
if ( !ammoAvailable( 0 ) ) {
if ( !dryfireAttack ) {
if ( myPlayer == sys.getLocalViewPlayer() ) {
startSound( "snd_dryfire", SND_WEAPON_DRYFIRE );
dryfireAttack = true;
}
}
weaponHolstered();
// nextWeapon();
}
if ( effect != $null_entity ) {
effect.remove();
}
if ( effectImpact != $null_entity ) {
effectImpact.remove();
}
stopSound( SND_WEAPON_FIRE2 );
weaponState( "Idle", 0 );
}
void weapon_lightningpistol::UpdateLightningEffect( vector hitPos, vector hitDir, float traceFraction, vector traceNormal ) {
vector muzzlePos;
if ( !sys.doClientSideStuff() ) {
return;
}
if ( sys.getLocalViewPlayer() != myPlayer || pm_thirdperson.getBoolValue() ) {
muzzlePos = worldModel.getJointPos( worldMuzzle );
if ( effect != $null_entity ) {
effect.unbind();
effect.setOrigin( muzzlePos );
}
} else {
if ( effect != $null_entity ) {
effect.unbind();
effect.setOrigin( '0 0 0' );
effect.bindToJoint( self, "muzzle", 0 );
}
muzzlePos = getJointPos( localMuzzle );
}
vector dir = hitPos - muzzlePos;
vector angles;
float len = sys.vecLengthSquared( dir );
dir = sys.vecNormalize( dir );
float dp = dir * hitDir;
if ( len < 1500 || dp < 0.f ) {
dir = hitDir;
} else
if ( len < 2000 ) {
float blend = (len - 1500) / 500;
dir = dir * blend + hitDir * (1-blend);
}
// the beam
if ( effect != $null_entity ) {
effect.setEffectEndOrigin( hitPos );
angles = sys.vecToAngles( dir );
effect.setAngles( angles );
}
// impact effect
if ( traceFraction < 1.0f ) {
if ( effectImpact == $null_entity ) {
effectImpact = spawnClientEffect( "fx_lightning_hit" );
if ( effectImpact != $null_entity ) {
effectImpact.setEffectLooping( 1 );
}
}
} else {
if ( effectImpact != $null_entity ) {
effectImpact.remove();
}
}
if ( effectImpact != $null_entity ) {
effectImpact.setOrigin( hitPos );
if ( traceFraction < 1.0f ) {
dir = traceNormal;
} else {
dir = -dir;
}
angles = sys.vecToAngles( dir );
effectImpact.setAngles( angles );
}
}
void weapon_lightningpistol::DoLightning( boolean doDamage ) {
fired();
float mask = MASK_PROJECTILE | MASK_SHOT_BOUNDINGBOX;
if ( sys.isClient() ) {
mask = mask | CONTENTS_WATER;
}
sys.enablePlayerHeadModels();
melee( mask, range, true, true );
vector traceEnd = getMeleeEndPos();
vector startPos = myPlayer.getViewOrigin();
vector dir = traceEnd - startPos;
dir = sys.vecNormalize( dir );
float traceFraction = getMeleeFraction();
vector traceNormal = getMeleeNormal();
entity collisionEnt = getMeleeEntity();
string collisionSurface = getMeleeSurfaceType();
if ( doDamage ) {
if ( collisionEnt != $null_entity ) {
// TODO: This could possibly be done with meleeAttack instead
object traceObject = saveMeleeTrace();
collisionEnt.applyDamage( self, myPlayer, dir, lightningDamage, 1.f - getMeleeFraction(), traceObject );
sys.freeTrace( traceObject );
spawnClientCrawlEffect( "fx_crawl", collisionEnt, 0.5 );
}
UseAmmo_Stroyent( 0 );
AddHeat();
}
sys.disablePlayerHeadModels();
UpdateLightningEffect( traceEnd, dir, traceFraction, traceNormal );
}
void weapon_lightningpistol::Overheat() {
boolean wasEnabled = false;
float lastZoomState;
wasEnabled = ironSightsEnabled;
if ( wasEnabled ) {
show();
DisableIronSights();
waitUntil( !ironSightsThreadActive );
}
weaponReloading();
stopSound( SND_WEAPON_FIRE2 );
if ( effect != $null_entity ) {
effect.remove();
}
if ( effectImpact != $null_entity ) {
effectImpact.remove();
effectImpact = $null_entity;
}
StartCooling();
playAnim( ANIMCHANNEL_ALL, "overheat" );
waitUntil( animDone( ANIMCHANNEL_ALL, 4 ) );
FinishCooling();
/*if ( wasEnabled ) {
EnableIronSights();
waitUntil( !ironSightsThreadActive );
}*/
weaponState( "Idle", 4 );
}
void weapon_lightningpistol::Raise() {
if ( ShouldRunGuis() ) {
CreateUpdateHeat();
}
Base_Raise();
}
void weapon_lightningpistol::Lower() {
stopSound( SND_WEAPON_FIRE2 );
if ( ShouldRunGuis() ) {
KillUpdateHeat();
}
Base_Lower();
}
void weapon_lightningpistol::LoadScopeGUI() {
FreeScopeGUI();
scopeGUIHandle = sys.allocHudModule( getKey( "gui_sniper_scope" ), getFloatKeyWithDefault( "hud_sort", 0 ), false );
}
void weapon_lightningpistol::FreeScopeGUI() {
if ( scopeGUIHandle != -1 ) {
sys.freeHudModule( scopeGUIHandle );
scopeGUIHandle = -1;
}
}
void weapon_lightningpistol::OnBecomeViewWeapon() {
if ( localIronSightsEffectsActive ) {
AddLocalIronSightsEffects();
}
if ( ShouldRunGuis() ) {
CreateUpdateHeat();
}
UpdateCrosshair();
}
void weapon_lightningpistol::OnFinishViewWeapon() {
KillUpdateHeat();
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.weaponReloadTime", 0 );
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "weapons.cooling", 0.f );
RemoveLocalIronSightsEffects();
}