2019-09-19 22:42:45 +00:00
//-------------------------------------------------------------------------
/*
Copyright ( C ) 2010 - 2019 EDuke32 developers and contributors
Copyright ( C ) 2019 Nuke . YKT
This file is part of NBlood .
NBlood is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
See the GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*/
//-------------------------------------------------------------------------
2019-09-21 18:59:54 +00:00
# include "ns.h" // Must come before everything else!
2019-09-19 22:42:45 +00:00
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include "build.h"
2020-12-09 14:56:32 +00:00
2019-09-19 22:42:45 +00:00
# include "blood.h"
2020-12-03 17:00:07 +00:00
# include "bloodactor.h"
2019-09-19 22:42:45 +00:00
2019-09-22 06:39:22 +00:00
BEGIN_BLD_NS
2021-12-29 21:56:21 +00:00
void FirePitchfork ( int , PLAYER * pPlayer ) ;
void FireSpray ( int , PLAYER * pPlayer ) ;
void ThrowCan ( int , PLAYER * pPlayer ) ;
void DropCan ( int , PLAYER * pPlayer ) ;
void ExplodeCan ( int , PLAYER * pPlayer ) ;
void ThrowBundle ( int , PLAYER * pPlayer ) ;
void DropBundle ( int , PLAYER * pPlayer ) ;
void ExplodeBundle ( int , PLAYER * pPlayer ) ;
void ThrowProx ( int , PLAYER * pPlayer ) ;
void DropProx ( int , PLAYER * pPlayer ) ;
void ThrowRemote ( int , PLAYER * pPlayer ) ;
void DropRemote ( int , PLAYER * pPlayer ) ;
void FireRemote ( int , PLAYER * pPlayer ) ;
void FireShotgun ( int nTrigger , PLAYER * pPlayer ) ;
void EjectShell ( int , PLAYER * pPlayer ) ;
void FireTommy ( int nTrigger , PLAYER * pPlayer ) ;
void FireSpread ( int nTrigger , PLAYER * pPlayer ) ;
void AltFireSpread ( int nTrigger , PLAYER * pPlayer ) ;
void AltFireSpread2 ( int nTrigger , PLAYER * pPlayer ) ;
void FireFlare ( int nTrigger , PLAYER * pPlayer ) ;
void AltFireFlare ( int nTrigger , PLAYER * pPlayer ) ;
void FireVoodoo ( int nTrigger , PLAYER * pPlayer ) ;
void AltFireVoodoo ( int nTrigger , PLAYER * pPlayer ) ;
void DropVoodoo ( int nTrigger , PLAYER * pPlayer ) ;
void FireTesla ( int nTrigger , PLAYER * pPlayer ) ;
void AltFireTesla ( int nTrigger , PLAYER * pPlayer ) ;
void FireNapalm ( int nTrigger , PLAYER * pPlayer ) ;
void FireNapalm2 ( int nTrigger , PLAYER * pPlayer ) ;
void AltFireNapalm ( int nTrigger , PLAYER * pPlayer ) ;
void FireLifeLeech ( int nTrigger , PLAYER * pPlayer ) ;
void AltFireLifeLeech ( int nTrigger , PLAYER * pPlayer ) ;
void FireBeast ( int nTrigger , PLAYER * pPlayer ) ;
typedef void ( * QAVTypeCast ) ( int , void * ) ;
2019-09-19 22:42:45 +00:00
2020-11-17 08:03:10 +00:00
void ( * qavClientCallback [ ] ) ( int , void * ) =
2019-09-19 22:42:45 +00:00
{
2020-11-17 08:03:10 +00:00
( QAVTypeCast ) FirePitchfork ,
( QAVTypeCast ) FireSpray ,
( QAVTypeCast ) ThrowCan ,
( QAVTypeCast ) DropCan ,
( QAVTypeCast ) ExplodeCan ,
( QAVTypeCast ) ThrowBundle ,
( QAVTypeCast ) DropBundle ,
( QAVTypeCast ) ExplodeBundle ,
( QAVTypeCast ) ThrowProx ,
( QAVTypeCast ) DropProx ,
( QAVTypeCast ) ThrowRemote ,
( QAVTypeCast ) DropRemote ,
( QAVTypeCast ) FireRemote ,
( QAVTypeCast ) FireShotgun ,
( QAVTypeCast ) EjectShell ,
( QAVTypeCast ) FireTommy ,
( QAVTypeCast ) AltFireSpread2 ,
( QAVTypeCast ) FireSpread ,
( QAVTypeCast ) AltFireSpread ,
( QAVTypeCast ) FireFlare ,
( QAVTypeCast ) AltFireFlare ,
( QAVTypeCast ) FireVoodoo ,
( QAVTypeCast ) AltFireVoodoo ,
( QAVTypeCast ) FireTesla ,
( QAVTypeCast ) AltFireTesla ,
( QAVTypeCast ) FireNapalm ,
( QAVTypeCast ) FireNapalm2 ,
( QAVTypeCast ) FireLifeLeech ,
( QAVTypeCast ) FireBeast ,
( QAVTypeCast ) AltFireLifeLeech ,
( QAVTypeCast ) DropVoodoo ,
( QAVTypeCast ) AltFireNapalm ,
} ;
enum
2019-09-19 22:42:45 +00:00
{
2021-12-29 21:56:21 +00:00
nClientFirePitchfork ,
nClientFireSpray ,
nClientThrowCan ,
nClientDropCan ,
nClientExplodeCan ,
nClientThrowBundle ,
nClientDropBundle ,
nClientExplodeBundle ,
nClientThrowProx ,
nClientDropProx ,
nClientThrowRemote ,
nClientDropRemote ,
nClientFireRemote ,
nClientFireShotgun ,
nClientEjectShell ,
nClientFireTommy ,
nClientAltFireSpread2 ,
nClientFireSpread ,
nClientAltFireSpread ,
nClientFireFlare ,
nClientAltFireFlare ,
nClientFireVoodoo ,
nClientAltFireVoodoo ,
nClientFireTesla ,
nClientAltFireTesla ,
nClientFireNapalm ,
nClientFireNapalm2 ,
nClientFireLifeLeech ,
nClientFireBeast ,
nClientAltFireLifeLeech ,
nClientDropVoodoo ,
nClientAltFireNapalm ,
2020-11-17 08:03:10 +00:00
} ;
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-05-05 23:16:10 +00:00
bool checkLitSprayOrTNT ( PLAYER * pPlayer )
2021-12-29 21:56:21 +00:00
{
switch ( pPlayer - > curWeapon )
{
case kWeapSpraycan :
switch ( pPlayer - > weaponState )
{
case 5 :
case 6 :
return 1 ;
case 7 :
if ( VanillaMode ( ) )
return 0 ;
return 1 ;
}
break ;
case kWeapDynamite :
switch ( pPlayer - > weaponState )
{
case 4 :
case 5 :
case 6 :
return 1 ;
}
break ;
}
return 0 ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-04-17 08:34:12 +00:00
static bool BannedUnderwater ( int nWeapon )
2019-09-19 22:42:45 +00:00
{
2021-12-29 21:56:21 +00:00
return nWeapon = = kWeapSpraycan | | nWeapon = = kWeapDynamite ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static bool CheckWeaponAmmo ( PLAYER * pPlayer , int weapon , int ammotype , int count )
{
if ( gInfiniteAmmo )
return 1 ;
if ( ammotype = = - 1 )
return 1 ;
if ( weapon = = kWeapRemote & & pPlayer - > weaponAmmo = = 11 & & pPlayer - > weaponState = = 11 )
return 1 ;
if ( weapon = = kWeapLifeLeech & & pPlayer - > actor - > xspr . health > 0 )
return 1 ;
return pPlayer - > ammoCount [ ammotype ] > = count ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static bool CheckAmmo ( PLAYER * pPlayer , int ammotype , int count )
{
if ( gInfiniteAmmo )
return 1 ;
if ( ammotype = = - 1 )
return 1 ;
if ( pPlayer - > curWeapon = = kWeapRemote & & pPlayer - > weaponAmmo = = 11 & & pPlayer - > weaponState = = 11 )
return 1 ;
if ( pPlayer - > curWeapon = = kWeapLifeLeech & & pPlayer - > actor - > xspr . health > = unsigned ( count < < 4 ) )
return 1 ;
return pPlayer - > ammoCount [ ammotype ] > = count ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static bool checkAmmo2 ( const PLAYER * pPlayer , int ammotype , int amount )
2019-09-19 22:42:45 +00:00
{
2021-12-29 21:56:21 +00:00
if ( gInfiniteAmmo )
return 1 ;
if ( ammotype = = - 1 )
return 1 ;
return pPlayer - > ammoCount [ ammotype ] > = amount ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void SpawnBulletEject ( PLAYER * pPlayer , int a2 , int a3 )
2019-09-19 22:42:45 +00:00
{
2021-12-29 21:56:21 +00:00
POSTURE * pPosture = & pPlayer - > pPosture [ pPlayer - > lifeMode ] [ pPlayer - > posture ] ;
2022-01-30 17:09:26 +00:00
pPlayer - > zView = pPlayer - > actor - > int_pos ( ) . Z - pPosture - > eyeAboveZ ;
2021-12-29 21:56:21 +00:00
int dz = pPlayer - > zWeapon - ( pPlayer - > zWeapon - pPlayer - > zView ) / 2 ;
fxSpawnEjectingBrass ( pPlayer - > actor , dz , a2 , a3 ) ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
void SpawnShellEject ( PLAYER * pPlayer , int a2 , int a3 )
2019-09-19 22:42:45 +00:00
{
2021-12-29 21:56:21 +00:00
POSTURE * pPosture = & pPlayer - > pPosture [ pPlayer - > lifeMode ] [ pPlayer - > posture ] ;
2022-01-30 17:09:26 +00:00
pPlayer - > zView = pPlayer - > actor - > int_pos ( ) . Z - pPosture - > eyeAboveZ ;
2021-12-29 21:56:21 +00:00
int t = pPlayer - > zWeapon - pPlayer - > zView ;
int dz = pPlayer - > zWeapon - t + ( t > > 2 ) ;
fxSpawnEjectingShell ( pPlayer - > actor , dz , a2 , a3 ) ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2019-09-19 22:42:45 +00:00
void WeaponInit ( void )
{
2021-12-29 21:56:21 +00:00
auto doInit = [ ] ( const int base )
{
for ( int i = base ; i < ( kQAVEnd + base ) ; i + + )
{
auto pQAV = getQAV ( i ) ;
if ( ! pQAV )
I_Error ( " Could not load QAV %d \n " , i ) ;
}
} ;
doInit ( 0 ) ;
doInit ( 10000 ) ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-04-11 10:42:59 +00:00
void WeaponPrecache ( )
2020-01-02 11:01:18 +00:00
{
2021-12-29 21:56:21 +00:00
auto doPrecache = [ ] ( const int base )
{
for ( int i = base ; i < ( kQAVEnd + base ) ; i + + )
{
auto pQAV = getQAV ( i ) ;
if ( pQAV )
pQAV - > Precache ( ) ;
}
} ;
doPrecache ( 0 ) ;
doPrecache ( 10000 ) ;
2020-01-02 11:01:18 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void WeaponDraw ( PLAYER * pPlayer , int shade , double xpos , double ypos , int palnum )
{
assert ( pPlayer ! = NULL ) ;
if ( pPlayer - > weaponQav = = kQAVNone )
return ;
auto pQAV = getQAV ( pPlayer - > weaponQav ) ;
int duration ;
double smoothratio ;
qavProcessTimer ( pPlayer , pQAV , & duration , & smoothratio , pPlayer - > weaponState = = - 1 , pPlayer - > curWeapon = = kWeapShotgun & & pPlayer - > weaponState = = 7 ) ;
pQAV - > x = int ( xpos ) ;
pQAV - > y = int ( ypos ) ;
int flags = 2 ;
int nInv = powerupCheck ( pPlayer , kPwUpShadowCloak ) ;
if ( nInv > = 120 * 8 | | ( nInv ! = 0 & & ( PlayClock & 32 ) ) )
{
shade = - 128 ;
flags | = 1 ;
}
pQAV - > Draw ( xpos , ypos , duration , flags , shade , palnum , true , smoothratio ) ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void WeaponPlay ( PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
2021-12-29 21:56:21 +00:00
assert ( pPlayer ! = NULL ) ;
if ( pPlayer - > weaponQav = = kQAVNone )
return ;
auto pQAV = getQAV ( pPlayer - > weaponQav ) ;
int nTicks = pQAV - > duration - pPlayer - > weaponTimer ;
pQAV - > Play ( nTicks - 4 , nTicks , pPlayer - > qavCallback , pPlayer ) ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void StartQAV ( PLAYER * pPlayer , int nWeaponQAV , int callback = - 1 , bool looped = false )
{
assert ( nWeaponQAV < kQAVEnd ) ;
auto res_id = qavGetCorrectID ( nWeaponQAV ) ;
auto pQAV = getQAV ( res_id ) ;
pPlayer - > weaponQav = res_id ;
pPlayer - > weaponTimer = pQAV - > duration ;
pPlayer - > qavCallback = callback ;
pPlayer - > qavLoop = looped ;
pPlayer - > qavLastTick = I_GetTime ( pQAV - > ticrate ) ;
pPlayer - > qavTimer = pQAV - > duration ;
//pQAV->Preload();
WeaponPlay ( pPlayer ) ;
pPlayer - > weaponTimer - = 4 ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
static void SetQAV ( PLAYER * pPlayer , int nWeaponQAV )
2021-08-28 06:36:27 +00:00
{
2021-12-29 21:56:21 +00:00
assert ( nWeaponQAV < kQAVEnd ) ;
pPlayer - > weaponQav = qavGetCorrectID ( nWeaponQAV ) ;
pPlayer - > qavTimer = 0 ;
pPlayer - > qavLastTick = 0 ;
2021-08-28 06:36:27 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2019-09-19 22:42:45 +00:00
struct WEAPONTRACK
{
2021-12-29 21:56:21 +00:00
int aimSpeedHorz ;
int aimSpeedVert ;
int angleRange ;
int thingAngle ;
int seeker ;
bool bIsProjectile ;
2019-09-19 22:42:45 +00:00
} ;
WEAPONTRACK gWeaponTrack [ ] = {
2021-12-29 21:56:21 +00:00
{ 0 , 0 , 0 , 0 , 0 , false } ,
{ 0x6000 , 0x6000 , 0x71 , 0x55 , 0x111111 , false } ,
{ 0x8000 , 0x8000 , 0x71 , 0x55 , 0x2aaaaa , true } ,
{ 0x10000 , 0x10000 , 0x38 , 0x1c , 0 , false } ,
{ 0x6000 , 0x8000 , 0x38 , 0x1c , 0 , false } ,
{ 0x6000 , 0x6000 , 0x38 , 0x1c , 0x2aaaaa , true } ,
{ 0x6000 , 0x6000 , 0x71 , 0x55 , 0 , true } ,
{ 0x6000 , 0x6000 , 0x71 , 0x38 , 0 , true } ,
{ 0x8000 , 0x10000 , 0x71 , 0x55 , 0x255555 , true } ,
{ 0x10000 , 0x10000 , 0x71 , 0 , 0 , true } ,
{ 0x10000 , 0x10000 , 0xaa , 0 , 0 , false } ,
{ 0x6000 , 0x6000 , 0x71 , 0x55 , 0 , true } ,
{ 0x6000 , 0x6000 , 0x71 , 0x55 , 0 , true } ,
{ 0x6000 , 0x6000 , 0x71 , 0x55 , 0 , false } ,
2019-09-19 22:42:45 +00:00
} ;
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void UpdateAimVector ( PLAYER * pPlayer )
{
assert ( pPlayer ! = NULL ) ;
auto plActor = pPlayer - > actor ;
2022-01-30 17:09:26 +00:00
int x = plActor - > int_pos ( ) . X ;
int y = plActor - > int_pos ( ) . Y ;
2021-12-29 21:56:21 +00:00
int z = pPlayer - > zWeapon ;
Aim aim ;
2022-08-16 21:15:49 +00:00
aim . dx = bcos ( plActor - > int_ang ( ) ) ;
aim . dy = bsin ( plActor - > int_ang ( ) ) ;
2021-12-29 21:56:21 +00:00
aim . dz = pPlayer - > slope ;
WEAPONTRACK * pWeaponTrack = & gWeaponTrack [ pPlayer - > curWeapon ] ;
DBloodActor * targetactor = nullptr ;
pPlayer - > aimTargetsCount = 0 ;
int autoaim = Autoaim ( pPlayer - > nPlayer ) ;
if ( autoaim = = 1 | | ( autoaim = = 2 & & ! pWeaponTrack - > bIsProjectile ) | | pPlayer - > curWeapon = = kWeapVoodooDoll | | pPlayer - > curWeapon = = kWeapLifeLeech )
{
int nClosest = 0x7fffffff ;
BloodStatIterator it ( kStatDude ) ;
while ( auto actor = it . Next ( ) )
{
if ( plActor = = actor )
continue ;
if ( ! gGameOptions . bFriendlyFire & & IsTargetTeammate ( pPlayer , actor ) )
continue ;
if ( actor - > spr . flags & 32 )
continue ;
if ( ! ( actor - > spr . flags & 8 ) )
continue ;
2022-01-30 17:09:26 +00:00
int x2 = actor - > int_pos ( ) . X ;
int y2 = actor - > int_pos ( ) . Y ;
int z2 = actor - > int_pos ( ) . Z ;
2021-12-29 21:56:21 +00:00
int nDist = approxDist ( x2 - x , y2 - y ) ;
if ( nDist = = 0 | | nDist > 51200 )
continue ;
if ( pWeaponTrack - > seeker )
{
int t = DivScale ( nDist , pWeaponTrack - > seeker , 12 ) ;
2022-09-01 18:56:12 +00:00
x2 + = ( actor - > int_vel ( ) . X * t ) > > 12 ;
y2 + = ( actor - > int_vel ( ) . Y * t ) > > 12 ;
z2 + = ( actor - > int_vel ( ) . Z * t ) > > 8 ;
2021-12-29 21:56:21 +00:00
}
2022-08-16 21:17:01 +00:00
int lx = x + MulScale ( Cos ( plActor - > int_ang ( ) ) , nDist , 30 ) ;
int ly = y + MulScale ( Sin ( plActor - > int_ang ( ) ) , nDist , 30 ) ;
2021-12-29 21:56:21 +00:00
int lz = z + MulScale ( pPlayer - > slope , nDist , 10 ) ;
int zRange = MulScale ( 9460 , nDist , 10 ) ;
int top , bottom ;
GetActorExtents ( actor , & top , & bottom ) ;
if ( lz - zRange > bottom | | lz + zRange < top )
continue ;
int angle = getangle ( x2 - x , y2 - y ) ;
2022-08-16 21:15:49 +00:00
if ( abs ( ( ( angle - plActor - > int_ang ( ) + 1024 ) & 2047 ) - 1024 ) > pWeaponTrack - > angleRange )
2021-12-29 21:56:21 +00:00
continue ;
2021-12-30 15:51:56 +00:00
if ( pPlayer - > aimTargetsCount < 16 & & cansee ( x , y , z , plActor - > sector ( ) , x2 , y2 , z2 , actor - > sector ( ) ) )
2021-12-29 21:56:21 +00:00
pPlayer - > aimTargets [ pPlayer - > aimTargetsCount + + ] = actor ;
// Inlined?
int dz = ( lz - z2 ) > > 8 ;
int dy = ( ly - y2 ) > > 4 ;
int dx = ( lx - x2 ) > > 4 ;
int nDist2 = ksqrt ( dx * dx + dy * dy + dz * dz ) ;
if ( nDist2 > = nClosest )
continue ;
DUDEINFO * pDudeInfo = getDudeInfo ( actor - > spr . type ) ;
int center = ( actor - > spr . yrepeat * pDudeInfo - > aimHeight ) < < 2 ;
int dzCenter = ( z2 - center ) - z ;
2021-12-30 15:51:56 +00:00
if ( cansee ( x , y , z , plActor - > sector ( ) , x2 , y2 , z2 , actor - > sector ( ) ) )
2021-12-29 21:56:21 +00:00
{
nClosest = nDist2 ;
aim . dx = bcos ( angle ) ;
aim . dy = bsin ( angle ) ;
aim . dz = DivScale ( dzCenter , nDist , 10 ) ;
targetactor = actor ;
}
}
if ( pWeaponTrack - > thingAngle > 0 )
{
BloodStatIterator itr ( kStatThing ) ;
while ( auto actor = itr . Next ( ) )
{
if ( ! gGameOptions . bFriendlyFire & & IsTargetTeammate ( pPlayer , actor ) )
continue ;
if ( ! ( actor - > spr . flags & 8 ) )
continue ;
2022-01-30 17:09:26 +00:00
int x2 = actor - > int_pos ( ) . X ;
int y2 = actor - > int_pos ( ) . Y ;
int z2 = actor - > int_pos ( ) . Z ;
2021-12-29 21:56:21 +00:00
int dx = x2 - x ;
int dy = y2 - y ;
int dz = z2 - z ;
int nDist = approxDist ( dx , dy ) ;
if ( nDist = = 0 | | nDist > 51200 )
continue ;
2022-08-16 21:17:01 +00:00
int lx = x + MulScale ( Cos ( plActor - > int_ang ( ) ) , nDist , 30 ) ;
int ly = y + MulScale ( Sin ( plActor - > int_ang ( ) ) , nDist , 30 ) ;
2021-12-29 21:56:21 +00:00
int lz = z + MulScale ( pPlayer - > slope , nDist , 10 ) ;
int zRange = MulScale ( 9460 , nDist , 10 ) ;
int top , bottom ;
GetActorExtents ( actor , & top , & bottom ) ;
if ( lz - zRange > bottom | | lz + zRange < top )
continue ;
int angle = getangle ( dx , dy ) ;
2022-08-16 21:15:49 +00:00
if ( abs ( ( ( angle - plActor - > int_ang ( ) + 1024 ) & 2047 ) - 1024 ) > pWeaponTrack - > thingAngle )
2021-12-29 21:56:21 +00:00
continue ;
2022-01-30 17:09:26 +00:00
if ( pPlayer - > aimTargetsCount < 16 & & cansee ( x , y , z , plActor - > sector ( ) , actor - > int_pos ( ) . X , actor - > int_pos ( ) . Y , actor - > int_pos ( ) . Z , actor - > sector ( ) ) )
2021-12-29 21:56:21 +00:00
pPlayer - > aimTargets [ pPlayer - > aimTargetsCount + + ] = actor ;
// Inlined?
int dz2 = ( lz - z2 ) > > 8 ;
int dy2 = ( ly - y2 ) > > 4 ;
int dx2 = ( lx - x2 ) > > 4 ;
int nDist2 = ksqrt ( dx2 * dx2 + dy2 * dy2 + dz2 * dz2 ) ;
if ( nDist2 > = nClosest )
continue ;
2022-01-30 17:09:26 +00:00
if ( cansee ( x , y , z , plActor - > sector ( ) , actor - > int_pos ( ) . X , actor - > int_pos ( ) . Y , actor - > int_pos ( ) . Z , actor - > sector ( ) ) )
2021-12-29 21:56:21 +00:00
{
nClosest = nDist2 ;
aim . dx = bcos ( angle ) ;
aim . dy = bsin ( angle ) ;
aim . dz = DivScale ( dz , nDist , 10 ) ;
targetactor = actor ;
}
}
}
}
Aim aim2 ;
aim2 = aim ;
2022-08-16 21:15:49 +00:00
RotateVector ( ( int * ) & aim2 . dx , ( int * ) & aim2 . dy , - plActor - > int_ang ( ) ) ;
2021-12-29 21:56:21 +00:00
aim2 . dz - = pPlayer - > slope ;
2022-09-07 03:52:32 +00:00
pPlayer - > relAim . dx = __interpvalue ( pPlayer - > relAim . dx , aim2 . dx , pWeaponTrack - > aimSpeedHorz ) ;
pPlayer - > relAim . dy = __interpvalue ( pPlayer - > relAim . dy , aim2 . dy , pWeaponTrack - > aimSpeedHorz ) ;
pPlayer - > relAim . dz = __interpvalue ( pPlayer - > relAim . dz , aim2 . dz , pWeaponTrack - > aimSpeedVert ) ;
2021-12-29 21:56:21 +00:00
pPlayer - > aim = pPlayer - > relAim ;
2022-08-16 21:15:49 +00:00
RotateVector ( ( int * ) & pPlayer - > aim . dx , ( int * ) & pPlayer - > aim . dy , plActor - > int_ang ( ) ) ;
2021-12-29 21:56:21 +00:00
pPlayer - > aim . dz + = pPlayer - > slope ;
pPlayer - > aimTarget = targetactor ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2019-09-19 22:42:45 +00:00
struct t_WeaponModes
{
2021-12-29 21:56:21 +00:00
int update ;
int ammoType ;
2019-09-19 22:42:45 +00:00
} ;
t_WeaponModes weaponModes [ ] = {
2021-12-29 21:56:21 +00:00
{ 0 , - 1 } ,
{ 1 , - 1 } ,
{ 1 , 1 } ,
{ 1 , 2 } ,
{ 1 , 3 } ,
{ 1 , 4 } ,
{ 1 , 5 } ,
{ 1 , 6 } ,
{ 1 , 7 } ,
{ 1 , 8 } ,
{ 1 , 9 } ,
{ 1 , 10 } ,
{ 1 , 11 } ,
{ 0 , - 1 } ,
2019-09-19 22:42:45 +00:00
} ;
2021-12-29 21:56:21 +00:00
void WeaponRaise ( PLAYER * pPlayer )
{
assert ( pPlayer ! = NULL ) ;
int prevWeapon = pPlayer - > curWeapon ;
pPlayer - > curWeapon = pPlayer - > newWeapon ;
pPlayer - > newWeapon = kWeapNone ;
pPlayer - > weaponAmmo = weaponModes [ pPlayer - > curWeapon ] . ammoType ;
switch ( pPlayer - > curWeapon )
{
case kWeapPitchFork :
pPlayer - > weaponState = 0 ;
StartQAV ( pPlayer , kQAVFORKUP ) ;
break ;
case kWeapSpraycan :
if ( pPlayer - > weaponState = = 2 )
{
pPlayer - > weaponState = 3 ;
StartQAV ( pPlayer , kQAVCANPREF ) ;
}
else
{
pPlayer - > weaponState = 0 ;
StartQAV ( pPlayer , kQAVLITEOPEN ) ;
}
break ;
case kWeapDynamite :
if ( gInfiniteAmmo | | checkAmmo2 ( pPlayer , 5 , 1 ) )
{
pPlayer - > weaponState = 3 ;
if ( prevWeapon = = kWeapSpraycan )
StartQAV ( pPlayer , kQAVBUNUP ) ;
else
StartQAV ( pPlayer , kQAVBUNUP2 ) ;
}
break ;
case kWeapProximity :
if ( gInfiniteAmmo | | checkAmmo2 ( pPlayer , 10 , 1 ) )
{
pPlayer - > weaponState = 7 ;
StartQAV ( pPlayer , kQAVPROXUP ) ;
}
break ;
case kWeapRemote :
if ( gInfiniteAmmo | | checkAmmo2 ( pPlayer , 11 , 1 ) )
{
pPlayer - > weaponState = 10 ;
StartQAV ( pPlayer , kQAVREMUP2 ) ;
}
else
{
StartQAV ( pPlayer , kQAVREMUP3 ) ;
pPlayer - > weaponState = 11 ;
}
break ;
case kWeapShotgun :
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) )
{
if ( gInfiniteAmmo | | pPlayer - > ammoCount [ 2 ] > = 4 )
StartQAV ( pPlayer , kQAV2SHOTUP ) ;
else
StartQAV ( pPlayer , kQAVSHOTUP ) ;
if ( gInfiniteAmmo | | pPlayer - > ammoCount [ 2 ] > = 4 )
pPlayer - > weaponState = 7 ;
else if ( pPlayer - > ammoCount [ 2 ] > 1 )
pPlayer - > weaponState = 3 ;
else if ( pPlayer - > ammoCount [ 2 ] > 0 )
pPlayer - > weaponState = 2 ;
else
pPlayer - > weaponState = 1 ;
}
else
{
if ( gInfiniteAmmo | | pPlayer - > ammoCount [ 2 ] > 1 )
pPlayer - > weaponState = 3 ;
else if ( pPlayer - > ammoCount [ 2 ] > 0 )
pPlayer - > weaponState = 2 ;
else
pPlayer - > weaponState = 1 ;
StartQAV ( pPlayer , kQAVSHOTUP ) ;
}
break ;
case kWeapTommyGun :
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 3 , 2 ) )
{
pPlayer - > weaponState = 1 ;
StartQAV ( pPlayer , kQAV2TOMUP ) ;
}
else
{
pPlayer - > weaponState = 0 ;
StartQAV ( pPlayer , kQAVTOMUP ) ;
}
break ;
case kWeapVoodooDoll :
if ( gInfiniteAmmo | | checkAmmo2 ( pPlayer , 9 , 1 ) )
{
pPlayer - > weaponState = 2 ;
StartQAV ( pPlayer , kQAVVDUP ) ;
}
break ;
case kWeapFlareGun :
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 1 , 2 ) )
{
StartQAV ( pPlayer , kQAVFLAR2UP ) ;
pPlayer - > weaponState = 3 ;
}
else
{
StartQAV ( pPlayer , kQAVFLARUP ) ;
pPlayer - > weaponState = 2 ;
}
break ;
case kWeapTeslaCannon :
if ( checkAmmo2 ( pPlayer , 7 , 1 ) )
{
pPlayer - > weaponState = 2 ;
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) )
StartQAV ( pPlayer , kQAV2SGUNUP ) ;
else
StartQAV ( pPlayer , kQAVSGUNUP ) ;
}
else
{
pPlayer - > weaponState = 3 ;
StartQAV ( pPlayer , kQAVSGUNUP ) ;
}
break ;
case kWeapNapalm :
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) )
{
StartQAV ( pPlayer , kQAV2NAPUP ) ;
pPlayer - > weaponState = 3 ;
}
else
{
StartQAV ( pPlayer , kQAVNAPUP ) ;
pPlayer - > weaponState = 2 ;
}
break ;
case kWeapLifeLeech :
pPlayer - > weaponState = 2 ;
StartQAV ( pPlayer , kQAVSTAFUP ) ;
break ;
case kWeapBeast :
pPlayer - > weaponState = 2 ;
StartQAV ( pPlayer , kQAVBSTUP ) ;
break ;
}
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void WeaponLower ( PLAYER * pPlayer )
{
assert ( pPlayer ! = NULL ) ;
2022-05-05 23:16:10 +00:00
if ( checkLitSprayOrTNT ( pPlayer ) )
2021-12-29 21:56:21 +00:00
return ;
pPlayer - > throwPower = 0 ;
int prevState = pPlayer - > weaponState ;
switch ( pPlayer - > curWeapon )
{
case kWeapPitchFork :
StartQAV ( pPlayer , kQAVFORKDOWN ) ;
break ;
case kWeapSpraycan :
sfxKill3DSound ( pPlayer - > actor , - 1 , 441 ) ;
switch ( prevState )
{
case 1 :
if ( VanillaMode ( ) )
{
StartQAV ( pPlayer , kQAVLITECLO2 ) ;
}
else
{
if ( pPlayer - > newWeapon = = kWeapDynamite ) // do not put away lighter if TNT was selected while throwing a spray can
{
pPlayer - > weaponState = 2 ;
StartQAV ( pPlayer , kQAVCANDOWN ) ;
WeaponRaise ( pPlayer ) ;
return ;
}
}
break ;
case 2 :
pPlayer - > weaponState = 1 ;
WeaponRaise ( pPlayer ) ;
return ;
case 4 :
pPlayer - > weaponState = 1 ;
StartQAV ( pPlayer , kQAVCANDOWN ) ;
if ( VanillaMode ( ) )
{
pPlayer - > newWeapon = kWeapNone ;
WeaponLower ( pPlayer ) ;
}
else
{
if ( pPlayer - > newWeapon = = kWeapDynamite )
{
pPlayer - > weaponState = 2 ;
StartQAV ( pPlayer , kQAVCANDOWN ) ;
return ;
}
else
{
WeaponLower ( pPlayer ) ;
}
}
break ;
case 3 :
if ( pPlayer - > newWeapon = = kWeapDynamite )
{
pPlayer - > weaponState = 2 ;
StartQAV ( pPlayer , kQAVCANDOWN ) ;
return ;
}
else if ( pPlayer - > newWeapon = = kWeapSpraycan )
{
pPlayer - > weaponState = 1 ;
StartQAV ( pPlayer , kQAVCANDOWN ) ;
pPlayer - > newWeapon = kWeapNone ;
WeaponLower ( pPlayer ) ;
}
else
{
pPlayer - > weaponState = 1 ;
StartQAV ( pPlayer , kQAVCANDOWN ) ;
}
break ;
case 7 : // throwing ignited alt fire spray
if ( VanillaMode ( ) | | ( pPlayer - > newWeapon ! = 0 ) )
break ;
pPlayer - > weaponState = 1 ;
StartQAV ( pPlayer , kQAVCANDOWN ) ;
break ;
}
break ;
case kWeapDynamite :
switch ( prevState )
{
case 1 :
if ( VanillaMode ( ) )
{
StartQAV ( pPlayer , kQAVLITECLO2 ) ;
}
else
{
if ( pPlayer - > newWeapon = = kWeapSpraycan ) // do not put away lighter if TNT was selected while throwing a spray can
{
pPlayer - > weaponState = 2 ;
StartQAV ( pPlayer , kQAVCANDOWN ) ;
WeaponRaise ( pPlayer ) ;
return ;
}
}
break ;
case 2 :
WeaponRaise ( pPlayer ) ;
break ;
case 3 :
if ( pPlayer - > newWeapon = = kWeapSpraycan )
{
pPlayer - > weaponState = 2 ;
StartQAV ( pPlayer , kQAVBUNDOWN ) ;
}
else
{
StartQAV ( pPlayer , kQAVBUNDOWN2 ) ;
}
break ;
default :
break ;
}
break ;
case kWeapProximity :
switch ( prevState )
{
case 7 :
StartQAV ( pPlayer , kQAVPROXDOWN ) ;
break ;
}
break ;
case kWeapRemote :
switch ( prevState )
{
case 10 :
StartQAV ( pPlayer , kQAVREMDOWN2 ) ;
break ;
case 11 :
StartQAV ( pPlayer , kQAVREMDOWN3 ) ;
break ;
}
break ;
case kWeapShotgun :
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) )
StartQAV ( pPlayer , kQAV2SHOTDWN ) ;
else
StartQAV ( pPlayer , kQAVSHOTDOWN ) ;
break ;
case kWeapTommyGun :
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & pPlayer - > weaponState = = 1 )
StartQAV ( pPlayer , kQAV2TOMDOWN ) ;
else
StartQAV ( pPlayer , kQAVTOMDOWN ) ;
break ;
case kWeapFlareGun :
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & pPlayer - > weaponState = = 3 )
StartQAV ( pPlayer , kQAVFLAR2DWN ) ;
else
StartQAV ( pPlayer , kQAVFLARDOWN ) ;
break ;
case kWeapVoodooDoll :
StartQAV ( pPlayer , kQAVVDDOWN ) ;
break ;
case kWeapTeslaCannon :
if ( checkAmmo2 ( pPlayer , 7 , 10 ) & & powerupCheck ( pPlayer , kPwUpTwoGuns ) )
StartQAV ( pPlayer , kQAV2SGUNDWN ) ;
else
StartQAV ( pPlayer , kQAVSGUNDOWN ) ;
break ;
case kWeapNapalm :
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) )
StartQAV ( pPlayer , kQAV2NAPDOWN ) ;
else
StartQAV ( pPlayer , kQAVNAPDOWN ) ;
break ;
case kWeapLifeLeech :
StartQAV ( pPlayer , kQAVSTAFDOWN ) ;
break ;
case kWeapBeast :
StartQAV ( pPlayer , kQAVBSTDOWN ) ;
break ;
}
pPlayer - > curWeapon = kWeapNone ;
pPlayer - > qavLoop = 0 ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void WeaponUpdateState ( PLAYER * pPlayer )
{
static int lastWeapon = 0 ;
static int lastState = 0 ;
int va = pPlayer - > curWeapon ;
int vb = pPlayer - > weaponState ;
if ( va ! = lastWeapon | | vb ! = lastState )
{
lastWeapon = va ;
lastState = vb ;
}
switch ( lastWeapon )
{
case kWeapPitchFork :
SetQAV ( pPlayer , kQAVFORKIDLE ) ;
break ;
case kWeapSpraycan :
switch ( vb )
{
case 0 :
pPlayer - > weaponState = 1 ;
StartQAV ( pPlayer , kQAVLITEFLAM ) ;
break ;
case 1 :
if ( CheckAmmo ( pPlayer , 6 , 1 ) )
{
pPlayer - > weaponState = 3 ;
StartQAV ( pPlayer , kQAVCANPREF ) ;
}
else
SetQAV ( pPlayer , kQAVLITEIDLE ) ;
break ;
case 3 :
SetQAV ( pPlayer , kQAVCANIDLE ) ;
break ;
case 4 :
if ( CheckAmmo ( pPlayer , 6 , 1 ) )
{
SetQAV ( pPlayer , kQAVCANIDLE ) ;
pPlayer - > weaponState = 3 ;
}
else
{
pPlayer - > weaponState = 1 ;
StartQAV ( pPlayer , kQAVCANDOWN ) ;
}
sfxKill3DSound ( pPlayer - > actor , - 1 , 441 ) ;
break ;
}
break ;
case kWeapDynamite :
switch ( vb )
{
case 1 :
if ( pPlayer - > weaponAmmo = = 5 & & CheckAmmo ( pPlayer , 5 , 1 ) )
{
pPlayer - > weaponState = 3 ;
StartQAV ( pPlayer , kQAVBUNUP ) ;
}
break ;
case 0 :
pPlayer - > weaponState = 1 ;
StartQAV ( pPlayer , kQAVLITEFLAM ) ;
break ;
case 2 :
if ( pPlayer - > ammoCount [ 5 ] > 0 )
{
pPlayer - > weaponState = 3 ;
StartQAV ( pPlayer , kQAVBUNUP ) ;
}
else
SetQAV ( pPlayer , kQAVLITEIDLE ) ;
break ;
case 3 :
SetQAV ( pPlayer , kQAVBUNIDLE ) ;
break ;
}
break ;
case kWeapProximity :
switch ( vb )
{
case 7 :
SetQAV ( pPlayer , kQAVPROXIDLE ) ;
break ;
case 8 :
pPlayer - > weaponState = 7 ;
StartQAV ( pPlayer , kQAVPROXUP ) ;
break ;
}
break ;
case kWeapRemote :
switch ( vb )
{
case 10 :
SetQAV ( pPlayer , kQAVREMIDLE1 ) ;
break ;
case 11 :
SetQAV ( pPlayer , kQAVREMIDLE2 ) ;
break ;
case 12 :
if ( pPlayer - > ammoCount [ 11 ] > 0 )
{
pPlayer - > weaponState = 10 ;
StartQAV ( pPlayer , kQAVREMUP2 ) ;
}
else
pPlayer - > weaponState = - 1 ;
break ;
}
break ;
case kWeapShotgun :
switch ( vb )
{
case 6 :
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & ( gInfiniteAmmo | | CheckAmmo ( pPlayer , 2 , 4 ) ) )
pPlayer - > weaponState = 7 ;
else
pPlayer - > weaponState = 1 ;
break ;
case 7 :
SetQAV ( pPlayer , kQAV2SHOTI ) ;
break ;
case 1 :
if ( CheckAmmo ( pPlayer , 2 , 1 ) )
{
sfxPlay3DSound ( pPlayer - > actor , 410 , 3 , 2 ) ;
StartQAV ( pPlayer , kQAVSHOTL1 , nClientEjectShell ) ;
if ( gInfiniteAmmo | | pPlayer - > ammoCount [ 2 ] > 1 )
pPlayer - > weaponState = 3 ;
else
pPlayer - > weaponState = 2 ;
}
else
SetQAV ( pPlayer , kQAVSHOTI3 ) ;
break ;
case 2 :
SetQAV ( pPlayer , kQAVSHOTI2 ) ;
break ;
case 3 :
SetQAV ( pPlayer , kQAVSHOTI1 ) ;
break ;
}
break ;
case kWeapTommyGun :
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 3 , 2 ) )
{
SetQAV ( pPlayer , kQAV2TOMIDLE ) ;
pPlayer - > weaponState = 1 ;
}
else
{
SetQAV ( pPlayer , kQAVTOMIDLE ) ;
pPlayer - > weaponState = 0 ;
}
break ;
case kWeapFlareGun :
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) )
{
if ( vb = = 3 & & checkAmmo2 ( pPlayer , 1 , 2 ) )
SetQAV ( pPlayer , kQAVFLAR2I ) ;
else
{
SetQAV ( pPlayer , kQAVFLARIDLE ) ;
pPlayer - > weaponState = 2 ;
}
}
else
SetQAV ( pPlayer , kQAVFLARIDLE ) ;
break ;
case kWeapVoodooDoll :
if ( pPlayer - > actor - > xspr . height < 256 & & pPlayer - > swayHeight ! = 0 )
StartQAV ( pPlayer , kQAVVDIDLE2 ) ;
else
SetQAV ( pPlayer , kQAVVDIDLE1 ) ;
break ;
case kWeapTeslaCannon :
switch ( vb )
{
case 2 :
if ( checkAmmo2 ( pPlayer , 7 , 10 ) & & powerupCheck ( pPlayer , kPwUpTwoGuns ) )
SetQAV ( pPlayer , kQAV2SGUNIDL ) ;
else
SetQAV ( pPlayer , kQAVSGUNIDL1 ) ;
break ;
case 3 :
SetQAV ( pPlayer , kQAVSGUNIDL2 ) ;
break ;
}
break ;
case kWeapNapalm :
switch ( vb )
{
case 3 :
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & ( gInfiniteAmmo | | CheckAmmo ( pPlayer , 4 , 4 ) ) )
SetQAV ( pPlayer , kQAV2NAPIDLE ) ;
else
SetQAV ( pPlayer , kQAVNAPIDLE ) ;
break ;
case 2 :
SetQAV ( pPlayer , kQAVNAPIDLE ) ;
break ;
}
break ;
case kWeapLifeLeech :
switch ( vb )
{
case 2 :
SetQAV ( pPlayer , kQAVSTAFIDL1 ) ;
break ;
}
break ;
case kWeapBeast :
SetQAV ( pPlayer , kQAVBSTIDLE ) ;
break ;
}
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void FirePitchfork ( int , PLAYER * pPlayer )
{
DBloodActor * actor = pPlayer - > actor ;
Aim * aim = & pPlayer - > aim ;
int r1 = Random2 ( 2000 ) ;
int r2 = Random2 ( 2000 ) ;
int r3 = Random2 ( 2000 ) ;
for ( int i = 0 ; i < 4 ; i + + )
2022-01-30 17:09:26 +00:00
actFireVector ( actor , ( 2 * i - 3 ) * 40 , pPlayer - > zWeapon - pPlayer - > actor - > int_pos ( ) . Z , aim - > dx + r1 , aim - > dy + r2 , aim - > dz + r3 , kVectorTine ) ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void FireSpray ( int , PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
2021-12-29 21:56:21 +00:00
playerFireMissile ( pPlayer , 0 , pPlayer - > aim . dx , pPlayer - > aim . dy , pPlayer - > aim . dz , kMissileFlameSpray ) ;
UseAmmo ( pPlayer , 6 , 4 ) ;
if ( CheckAmmo ( pPlayer , 6 , 1 ) )
sfxPlay3DSound ( pPlayer - > actor , 441 , 1 , 2 ) ;
else
sfxKill3DSound ( pPlayer - > actor , - 1 , 441 ) ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void ThrowCan ( int , PLAYER * pPlayer )
{
sfxKill3DSound ( pPlayer - > actor , - 1 , 441 ) ;
int nSpeed = MulScale ( pPlayer - > throwPower , 0x177777 , 16 ) + 0x66666 ;
sfxPlay3DSound ( pPlayer - > actor , 455 , 1 , 0 ) ;
auto spawned = playerFireThing ( pPlayer , 0 , - 9460 , kThingArmedSpray , nSpeed ) ;
if ( spawned )
{
sfxPlay3DSound ( spawned , 441 , 0 , 0 ) ;
2022-05-05 23:40:27 +00:00
spawned - > spr . shade = - 128 ;
2022-08-10 21:45:29 +00:00
evPostActor ( spawned , pPlayer - > fuseTime , kCmdOn , pPlayer - > actor ) ;
2021-12-29 21:56:21 +00:00
spawned - > xspr . Impact = 1 ;
UseAmmo ( pPlayer , 6 , gAmmoItemData [ 0 ] . count ) ;
pPlayer - > throwPower = 0 ;
}
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DropCan ( int , PLAYER * pPlayer )
{
sfxKill3DSound ( pPlayer - > actor , - 1 , 441 ) ;
auto spawned = playerFireThing ( pPlayer , 0 , 0 , kThingArmedSpray , 0 ) ;
if ( spawned )
{
2022-08-10 21:45:29 +00:00
evPostActor ( spawned , pPlayer - > fuseTime , kCmdOn , pPlayer - > actor ) ;
2021-12-29 21:56:21 +00:00
UseAmmo ( pPlayer , 6 , gAmmoItemData [ 0 ] . count ) ;
}
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void ExplodeCan ( int , PLAYER * pPlayer )
{
sfxKill3DSound ( pPlayer - > actor , - 1 , 441 ) ;
auto spawned = playerFireThing ( pPlayer , 0 , 0 , kThingArmedSpray , 0 ) ;
if ( spawned )
{
2022-08-10 21:45:29 +00:00
evPostActor ( spawned , 0 , kCmdOn , pPlayer - > actor ) ;
2021-12-29 21:56:21 +00:00
UseAmmo ( pPlayer , 6 , gAmmoItemData [ 0 ] . count ) ;
StartQAV ( pPlayer , kQAVCANBOOM ) ;
pPlayer - > curWeapon = kWeapNone ;
pPlayer - > throwPower = 0 ;
}
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void ThrowBundle ( int , PLAYER * pPlayer )
{
sfxKill3DSound ( pPlayer - > actor , 16 , - 1 ) ;
int nSpeed = MulScale ( pPlayer - > throwPower , 0x177777 , 16 ) + 0x66666 ;
sfxPlay3DSound ( pPlayer - > actor , 455 , 1 , 0 ) ;
auto spawned = playerFireThing ( pPlayer , 0 , - 9460 , kThingArmedTNTBundle , nSpeed ) ;
if ( spawned )
{
if ( pPlayer - > fuseTime < 0 )
spawned - > xspr . Impact = 1 ;
else
2022-08-10 21:45:29 +00:00
evPostActor ( spawned , pPlayer - > fuseTime , kCmdOn , pPlayer - > actor ) ;
2021-12-29 21:56:21 +00:00
UseAmmo ( pPlayer , 5 , 1 ) ;
pPlayer - > throwPower = 0 ;
}
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DropBundle ( int , PLAYER * pPlayer )
{
sfxKill3DSound ( pPlayer - > actor , 16 , - 1 ) ;
auto spawned = playerFireThing ( pPlayer , 0 , 0 , kThingArmedTNTBundle , 0 ) ;
if ( spawned )
{
2022-08-10 21:45:29 +00:00
evPostActor ( spawned , pPlayer - > fuseTime , kCmdOn , pPlayer - > actor ) ;
2021-12-29 21:56:21 +00:00
UseAmmo ( pPlayer , 5 , 1 ) ;
}
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void ExplodeBundle ( int , PLAYER * pPlayer )
{
sfxKill3DSound ( pPlayer - > actor , 16 , - 1 ) ;
auto spawned = playerFireThing ( pPlayer , 0 , 0 , kThingArmedTNTBundle , 0 ) ;
if ( spawned )
{
2022-08-10 21:45:29 +00:00
evPostActor ( spawned , 0 , kCmdOn , pPlayer - > actor ) ;
2021-12-29 21:56:21 +00:00
UseAmmo ( pPlayer , 5 , 1 ) ;
StartQAV ( pPlayer , kQAVDYNEXPLO ) ;
pPlayer - > curWeapon = kWeapNone ;
pPlayer - > throwPower = 0 ;
}
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void ThrowProx ( int , PLAYER * pPlayer )
{
int nSpeed = MulScale ( pPlayer - > throwPower , 0x177777 , 16 ) + 0x66666 ;
sfxPlay3DSound ( pPlayer - > actor , 455 , 1 , 0 ) ;
auto spawned = playerFireThing ( pPlayer , 0 , - 9460 , kThingArmedProxBomb , nSpeed ) ;
if ( spawned )
{
2022-08-10 21:45:29 +00:00
evPostActor ( spawned , 240 , kCmdOn , pPlayer - > actor ) ;
2021-12-29 21:56:21 +00:00
UseAmmo ( pPlayer , 10 , 1 ) ;
pPlayer - > throwPower = 0 ;
}
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DropProx ( int , PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
2021-12-29 21:56:21 +00:00
auto spawned = playerFireThing ( pPlayer , 0 , 0 , kThingArmedProxBomb , 0 ) ;
if ( spawned )
{
2022-08-10 21:45:29 +00:00
evPostActor ( spawned , 240 , kCmdOn , pPlayer - > actor ) ;
2021-12-29 21:56:21 +00:00
UseAmmo ( pPlayer , 10 , 1 ) ;
}
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void ThrowRemote ( int , PLAYER * pPlayer )
{
int nSpeed = MulScale ( pPlayer - > throwPower , 0x177777 , 16 ) + 0x66666 ;
sfxPlay3DSound ( pPlayer - > actor , 455 , 1 , 0 ) ;
auto spawned = playerFireThing ( pPlayer , 0 , - 9460 , kThingArmedRemoteBomb , nSpeed ) ;
if ( spawned )
{
spawned - > xspr . rxID = 90 + ( pPlayer - > actor - > spr . type - kDudePlayer1 ) ;
UseAmmo ( pPlayer , 11 , 1 ) ;
pPlayer - > throwPower = 0 ;
}
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DropRemote ( int , PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
2021-12-29 21:56:21 +00:00
auto spawned = playerFireThing ( pPlayer , 0 , 0 , kThingArmedRemoteBomb , 0 ) ;
if ( spawned )
{
spawned - > xspr . rxID = 90 + ( pPlayer - > actor - > spr . type - kDudePlayer1 ) ;
UseAmmo ( pPlayer , 11 , 1 ) ;
}
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
void FireRemote ( int , PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
2021-12-29 21:56:21 +00:00
evSendGame ( 90 + ( pPlayer - > actor - > spr . type - kDudePlayer1 ) , kCmdOn ) ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-10-11 10:18:25 +00:00
enum { kMaxShotgunBarrels = 4 } ;
2019-09-19 22:42:45 +00:00
2021-12-29 21:56:21 +00:00
void FireShotgun ( int nTrigger , PLAYER * pPlayer )
{
DBloodActor * actor = pPlayer - > actor ;
assert ( nTrigger > 0 & & nTrigger < = kMaxShotgunBarrels ) ;
if ( nTrigger = = 1 )
{
sfxPlay3DSound ( pPlayer - > actor , 411 , 2 , 0 ) ;
pPlayer - > tiltEffect = 30 ;
pPlayer - > visibility = 20 ;
}
else
{
sfxPlay3DSound ( pPlayer - > actor , 412 , 2 , 0 ) ;
pPlayer - > tiltEffect = 50 ;
pPlayer - > visibility = 40 ;
}
int n = nTrigger < < 4 ;
for ( int i = 0 ; i < n ; i + + )
{
int r1 , r2 , r3 ;
VECTOR_TYPE nType ;
if ( nTrigger = = 1 )
{
r1 = Random3 ( 1500 ) ;
r2 = Random3 ( 1500 ) ;
r3 = Random3 ( 500 ) ;
nType = kVectorShell ;
}
else
{
r1 = Random3 ( 2500 ) ;
r2 = Random3 ( 2500 ) ;
r3 = Random3 ( 1500 ) ;
nType = kVectorShellAP ;
}
2022-01-30 17:09:26 +00:00
actFireVector ( actor , 0 , pPlayer - > zWeapon - pPlayer - > actor - > int_pos ( ) . Z , pPlayer - > aim . dx + r1 , pPlayer - > aim . dy + r2 , pPlayer - > aim . dz + r3 , nType ) ;
2021-12-29 21:56:21 +00:00
}
UseAmmo ( pPlayer , pPlayer - > weaponAmmo , nTrigger ) ;
pPlayer - > flashEffect = 1 ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void EjectShell ( int , PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
2021-12-29 21:56:21 +00:00
SpawnShellEject ( pPlayer , 25 , 35 ) ;
SpawnShellEject ( pPlayer , 48 , 35 ) ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
void FireTommy ( int nTrigger , PLAYER * pPlayer )
{
DBloodActor * actor = pPlayer - > actor ;
Aim * aim = & pPlayer - > aim ;
sfxPlay3DSound ( pPlayer - > actor , 431 , - 1 , 0 ) ;
switch ( nTrigger )
{
case 1 :
{
int r1 = Random3 ( 400 ) ;
int r2 = Random3 ( 1200 ) ;
int r3 = Random3 ( 1200 ) ;
2022-01-30 17:09:26 +00:00
actFireVector ( actor , 0 , pPlayer - > zWeapon - pPlayer - > actor - > int_pos ( ) . Z , aim - > dx + r3 , aim - > dy + r2 , aim - > dz + r1 , kVectorTommyRegular ) ;
2021-12-29 21:56:21 +00:00
SpawnBulletEject ( pPlayer , - 15 , - 45 ) ;
pPlayer - > visibility = 20 ;
break ;
}
case 2 :
{
int r1 = Random3 ( 400 ) ;
int r2 = Random3 ( 1200 ) ;
int r3 = Random3 ( 1200 ) ;
2022-01-30 17:09:26 +00:00
actFireVector ( actor , - 120 , pPlayer - > zWeapon - pPlayer - > actor - > int_pos ( ) . Z , aim - > dx + r3 , aim - > dy + r2 , aim - > dz + r1 , kVectorTommyRegular ) ;
2021-12-29 21:56:21 +00:00
SpawnBulletEject ( pPlayer , - 140 , - 45 ) ;
r1 = Random3 ( 400 ) ;
r2 = Random3 ( 1200 ) ;
r3 = Random3 ( 1200 ) ;
2022-01-30 17:09:26 +00:00
actFireVector ( actor , 120 , pPlayer - > zWeapon - pPlayer - > actor - > int_pos ( ) . Z , aim - > dx + r3 , aim - > dy + r2 , aim - > dz + r1 , kVectorTommyRegular ) ;
2021-12-29 21:56:21 +00:00
SpawnBulletEject ( pPlayer , 140 , 45 ) ;
pPlayer - > visibility = 30 ;
break ;
}
}
UseAmmo ( pPlayer , pPlayer - > weaponAmmo , nTrigger ) ;
pPlayer - > flashEffect = 1 ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-10-11 10:18:25 +00:00
enum { kMaxSpread = 14 } ;
2019-09-19 22:42:45 +00:00
2021-12-29 21:56:21 +00:00
void FireSpread ( int nTrigger , PLAYER * pPlayer )
{
DBloodActor * actor = pPlayer - > actor ;
assert ( nTrigger > 0 & & nTrigger < = kMaxSpread ) ;
Aim * aim = & pPlayer - > aim ;
int angle = ( getangle ( aim - > dx , aim - > dy ) + ( ( 112 * ( nTrigger - 1 ) ) / 14 - 56 ) ) & 2047 ;
int dx = bcos ( angle ) ;
int dy = bsin ( angle ) ;
sfxPlay3DSound ( pPlayer - > actor , 431 , - 1 , 0 ) ;
int r1 , r2 , r3 ;
r1 = Random3 ( 300 ) ;
r2 = Random3 ( 600 ) ;
r3 = Random3 ( 600 ) ;
2022-01-30 17:09:26 +00:00
actFireVector ( actor , 0 , pPlayer - > zWeapon - pPlayer - > actor - > int_pos ( ) . Z , dx + r3 , dy + r2 , aim - > dz + r1 , kVectorTommyAP ) ;
2021-12-29 21:56:21 +00:00
r1 = Random2 ( 90 ) ;
r2 = Random2 ( 30 ) ;
SpawnBulletEject ( pPlayer , r2 , r1 ) ;
pPlayer - > visibility = 20 ;
UseAmmo ( pPlayer , pPlayer - > weaponAmmo , 1 ) ;
pPlayer - > flashEffect = 1 ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void AltFireSpread ( int nTrigger , PLAYER * pPlayer )
{
DBloodActor * actor = pPlayer - > actor ;
assert ( nTrigger > 0 & & nTrigger < = kMaxSpread ) ;
Aim * aim = & pPlayer - > aim ;
int angle = ( getangle ( aim - > dx , aim - > dy ) + ( ( 112 * ( nTrigger - 1 ) ) / 14 - 56 ) ) & 2047 ;
int dx = bcos ( angle ) ;
int dy = bsin ( angle ) ;
sfxPlay3DSound ( pPlayer - > actor , 431 , - 1 , 0 ) ;
int r1 , r2 , r3 ;
r1 = Random3 ( 300 ) ;
r2 = Random3 ( 600 ) ;
r3 = Random3 ( 600 ) ;
2022-01-30 17:09:26 +00:00
actFireVector ( actor , - 120 , pPlayer - > zWeapon - pPlayer - > actor - > int_pos ( ) . Z , dx + r3 , dy + r2 , aim - > dz + r1 , kVectorTommyAP ) ;
2021-12-29 21:56:21 +00:00
r1 = Random2 ( 45 ) ;
r2 = Random2 ( 120 ) ;
SpawnBulletEject ( pPlayer , r2 , r1 ) ;
r1 = Random3 ( 300 ) ;
r2 = Random3 ( 600 ) ;
r3 = Random3 ( 600 ) ;
2022-01-30 17:09:26 +00:00
actFireVector ( actor , 120 , pPlayer - > zWeapon - pPlayer - > actor - > int_pos ( ) . Z , dx + r3 , dy + r2 , aim - > dz + r1 , kVectorTommyAP ) ;
2021-12-29 21:56:21 +00:00
r1 = Random2 ( - 45 ) ;
r2 = Random2 ( - 120 ) ;
SpawnBulletEject ( pPlayer , r2 , r1 ) ;
pPlayer - > tiltEffect = 20 ;
pPlayer - > visibility = 30 ;
UseAmmo ( pPlayer , pPlayer - > weaponAmmo , 2 ) ;
pPlayer - > flashEffect = 1 ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void AltFireSpread2 ( int nTrigger , PLAYER * pPlayer )
{
DBloodActor * actor = pPlayer - > actor ;
assert ( nTrigger > 0 & & nTrigger < = kMaxSpread ) ;
Aim * aim = & pPlayer - > aim ;
int angle = ( getangle ( aim - > dx , aim - > dy ) + ( ( 112 * ( nTrigger - 1 ) ) / 14 - 56 ) ) & 2047 ;
int dx = bcos ( angle ) ;
int dy = bsin ( angle ) ;
sfxPlay3DSound ( pPlayer - > actor , 431 , - 1 , 0 ) ;
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 3 , 2 ) )
{
int r1 , r2 , r3 ;
r1 = Random3 ( 300 ) ;
r2 = Random3 ( 600 ) ;
r3 = Random3 ( 600 ) ;
2022-01-30 17:09:26 +00:00
actFireVector ( actor , - 120 , pPlayer - > zWeapon - pPlayer - > actor - > int_pos ( ) . Z , dx + r3 , dy + r2 , aim - > dz + r1 , kVectorTommyAP ) ;
2021-12-29 21:56:21 +00:00
r1 = Random2 ( 45 ) ;
r2 = Random2 ( 120 ) ;
SpawnBulletEject ( pPlayer , r2 , r1 ) ;
r1 = Random3 ( 300 ) ;
r2 = Random3 ( 600 ) ;
r3 = Random3 ( 600 ) ;
2022-01-30 17:09:26 +00:00
actFireVector ( actor , 120 , pPlayer - > zWeapon - pPlayer - > actor - > int_pos ( ) . Z , dx + r3 , dy + r2 , aim - > dz + r1 , kVectorTommyAP ) ;
2021-12-29 21:56:21 +00:00
r1 = Random2 ( - 45 ) ;
r2 = Random2 ( - 120 ) ;
SpawnBulletEject ( pPlayer , r2 , r1 ) ;
pPlayer - > tiltEffect = 30 ;
pPlayer - > visibility = 45 ;
UseAmmo ( pPlayer , pPlayer - > weaponAmmo , 2 ) ;
}
else
{
int r1 , r2 , r3 ;
r1 = Random3 ( 300 ) ;
r2 = Random3 ( 600 ) ;
r3 = Random3 ( 600 ) ;
2022-01-30 17:09:26 +00:00
actFireVector ( actor , 0 , pPlayer - > zWeapon - pPlayer - > actor - > int_pos ( ) . Z , dx + r3 , dy + r2 , aim - > dz + r1 , kVectorTommyAP ) ;
2021-12-29 21:56:21 +00:00
r1 = Random2 ( 90 ) ;
r2 = Random2 ( 30 ) ;
SpawnBulletEject ( pPlayer , r2 , r1 ) ;
pPlayer - > tiltEffect = 20 ;
pPlayer - > visibility = 30 ;
UseAmmo ( pPlayer , pPlayer - > weaponAmmo , 1 ) ;
}
pPlayer - > flashEffect = 1 ;
if ( ! checkAmmo2 ( pPlayer , 3 , 1 ) )
{
WeaponLower ( pPlayer ) ;
pPlayer - > weaponState = - 1 ;
}
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void FireFlare ( int nTrigger , PLAYER * pPlayer )
{
auto plActor = pPlayer - > actor ;
int offset = 0 ;
switch ( nTrigger )
{
case 2 :
offset = - 120 ;
break ;
case 3 :
offset = 120 ;
break ;
}
playerFireMissile ( pPlayer , offset , pPlayer - > aim . dx , pPlayer - > aim . dy , pPlayer - > aim . dz , kMissileFlareRegular ) ;
UseAmmo ( pPlayer , 1 , 1 ) ;
sfxPlay3DSound ( pPlayer - > actor , 420 , 2 , 0 ) ;
pPlayer - > visibility = 30 ;
pPlayer - > flashEffect = 1 ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void AltFireFlare ( int nTrigger , PLAYER * pPlayer )
{
auto plActor = pPlayer - > actor ;
int offset = 0 ;
switch ( nTrigger )
{
case 2 :
offset = - 120 ;
break ;
case 3 :
offset = 120 ;
break ;
}
playerFireMissile ( pPlayer , offset , pPlayer - > aim . dx , pPlayer - > aim . dy , pPlayer - > aim . dz , kMissileFlareAlt ) ;
UseAmmo ( pPlayer , 1 , 8 ) ;
sfxPlay3DSound ( pPlayer - > actor , 420 , 2 , 0 ) ;
pPlayer - > visibility = 45 ;
pPlayer - > flashEffect = 1 ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void FireVoodoo ( int nTrigger , PLAYER * pPlayer )
{
nTrigger - - ;
DBloodActor * actor = pPlayer - > actor ;
auto plActor = pPlayer - > actor ;
if ( nTrigger = = 4 )
{
actDamageSprite ( actor , actor , kDamageBullet , 1 < < 4 ) ;
return ;
}
DBloodActor * targetactor = pPlayer - > voodooTarget ;
if ( ! targetactor ) return ;
if ( ! gGameOptions . bFriendlyFire & & IsTargetTeammate ( pPlayer , targetactor ) )
return ;
switch ( nTrigger )
{
case 0 :
{
sfxPlay3DSound ( actor , 460 , 2 , 0 ) ;
fxSpawnBlood ( targetactor , 17 < < 4 ) ;
int nDamage = actDamageSprite ( actor , targetactor , kDamageSpirit , 17 < < 4 ) ;
UseAmmo ( pPlayer , 9 , nDamage / 4 ) ;
break ;
}
case 1 :
{
sfxPlay3DSound ( actor , 460 , 2 , 0 ) ;
fxSpawnBlood ( targetactor , 17 < < 4 ) ;
int nDamage = actDamageSprite ( actor , targetactor , kDamageSpirit , 9 < < 4 ) ;
if ( targetactor - > IsPlayerActor ( ) )
WeaponLower ( & gPlayer [ targetactor - > spr . type - kDudePlayer1 ] ) ;
UseAmmo ( pPlayer , 9 , nDamage / 4 ) ;
break ;
}
case 3 :
{
sfxPlay3DSound ( actor , 463 , 2 , 0 ) ;
fxSpawnBlood ( targetactor , 17 < < 4 ) ;
int nDamage = actDamageSprite ( actor , targetactor , kDamageSpirit , 49 < < 4 ) ;
UseAmmo ( pPlayer , 9 , nDamage / 4 ) ;
break ;
}
case 2 :
{
sfxPlay3DSound ( actor , 460 , 2 , 0 ) ;
fxSpawnBlood ( targetactor , 17 < < 4 ) ;
int nDamage = actDamageSprite ( actor , targetactor , kDamageSpirit , 11 < < 4 ) ;
if ( targetactor - > IsPlayerActor ( ) )
{
PLAYER * pOtherPlayer = & gPlayer [ targetactor - > spr . type - kDudePlayer1 ] ;
pOtherPlayer - > blindEffect = 128 ;
}
UseAmmo ( pPlayer , 9 , nDamage / 4 ) ;
break ;
}
}
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void AltFireVoodoo ( int nTrigger , PLAYER * pPlayer )
{
DBloodActor * actor = pPlayer - > actor ;
if ( nTrigger = = 2 ) {
// by NoOne: trying to simulate v1.0x voodoo here.
// dunno how exactly it works, but at least it not spend all the ammo on alt fire
if ( gGameOptions . weaponsV10x & & ! VanillaMode ( ) ) {
int nCount = ClipHigh ( pPlayer - > ammoCount [ 9 ] , pPlayer - > aimTargetsCount ) ;
if ( nCount > 0 )
{
for ( int i = 0 ; i < pPlayer - > aimTargetsCount ; i + + )
{
DBloodActor * targetactor = pPlayer - > aimTargets [ i ] ;
if ( ! targetactor ) continue ;
if ( ! gGameOptions . bFriendlyFire & & IsTargetTeammate ( pPlayer , targetactor ) )
continue ;
2022-08-23 20:32:14 +00:00
int nDist = approxDist ( targetactor - > spr . pos . XY ( ) - pPlayer - > actor - > spr . pos . XY ( ) ) ;
2021-12-29 21:56:21 +00:00
if ( nDist > 0 & & nDist < 51200 )
{
int vc = pPlayer - > ammoCount [ 9 ] > > 3 ;
int v8 = pPlayer - > ammoCount [ 9 ] < < 1 ;
int nDamage = ( v8 + Random ( vc ) ) < < 4 ;
nDamage = ( nDamage * ( ( 51200 - nDist ) + 1 ) ) / 51200 ;
nDamage = actDamageSprite ( actor , targetactor , kDamageSpirit , nDamage ) ;
if ( targetactor - > IsPlayerActor ( ) )
{
PLAYER * pOtherPlayer = & gPlayer [ targetactor - > spr . type - kDudePlayer1 ] ;
if ( ! pOtherPlayer - > godMode | | ! powerupCheck ( pOtherPlayer , kPwUpDeathMask ) )
powerupActivate ( pOtherPlayer , kPwUpDeliriumShroom ) ;
}
fxSpawnBlood ( targetactor , 0 ) ;
}
}
}
UseAmmo ( pPlayer , 9 , 20 ) ;
pPlayer - > weaponState = 0 ;
return ;
}
//int nAmmo = pPlayer->ammCount[9];
int nCount = ClipHigh ( pPlayer - > ammoCount [ 9 ] , pPlayer - > aimTargetsCount ) ;
if ( nCount > 0 )
{
int v4 = pPlayer - > ammoCount [ 9 ] - ( pPlayer - > ammoCount [ 9 ] / nCount ) * nCount ;
for ( int i = 0 ; i < pPlayer - > aimTargetsCount ; i + + )
{
DBloodActor * targetactor = pPlayer - > aimTargets [ i ] ;
if ( ! targetactor ) continue ;
if ( ! gGameOptions . bFriendlyFire & & IsTargetTeammate ( pPlayer , targetactor ) )
continue ;
if ( v4 > 0 )
v4 - - ;
2022-08-23 20:32:14 +00:00
int nDist = approxDist ( targetactor - > spr . pos . XY ( ) - pPlayer - > actor - > spr . pos . XY ( ) ) ;
2021-12-29 21:56:21 +00:00
if ( nDist > 0 & & nDist < 51200 )
{
int vc = pPlayer - > ammoCount [ 9 ] > > 3 ;
int v8 = pPlayer - > ammoCount [ 9 ] < < 1 ;
int nDamage = ( v8 + Random2 ( vc ) ) < < 4 ;
nDamage = ( nDamage * ( ( 51200 - nDist ) + 1 ) ) / 51200 ;
nDamage = actDamageSprite ( actor , targetactor , kDamageSpirit , nDamage ) ;
UseAmmo ( pPlayer , 9 , nDamage ) ;
if ( targetactor - > IsPlayerActor ( ) )
{
PLAYER * pOtherPlayer = & gPlayer [ targetactor - > spr . type - kDudePlayer1 ] ;
if ( ! pOtherPlayer - > godMode | | ! powerupCheck ( pOtherPlayer , kPwUpDeathMask ) )
powerupActivate ( pOtherPlayer , kPwUpDeliriumShroom ) ;
}
fxSpawnBlood ( targetactor , 0 ) ;
}
}
}
UseAmmo ( pPlayer , 9 , pPlayer - > ammoCount [ 9 ] ) ;
2022-01-12 11:22:48 +00:00
pPlayer - > hasWeapon [ kWeapVoodooDoll ] = 0 ;
2021-12-29 21:56:21 +00:00
pPlayer - > weaponState = - 1 ;
}
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DropVoodoo ( int , PLAYER * pPlayer )
{
sfxPlay3DSound ( pPlayer - > actor , 455 , 2 , 0 ) ;
auto spawned = playerFireThing ( pPlayer , 0 , - 4730 , kThingVoodooHead , 0xccccc ) ;
if ( spawned )
{
spawned - > xspr . data1 = pPlayer - > ammoCount [ 9 ] ;
evPostActor ( spawned , 90 , kCallbackDropVoodoo ) ;
UseAmmo ( pPlayer , 6 , gAmmoItemData [ 0 ] . count ) ;
UseAmmo ( pPlayer , 9 , pPlayer - > ammoCount [ 9 ] ) ;
2022-01-12 11:22:48 +00:00
pPlayer - > hasWeapon [ kWeapVoodooDoll ] = 0 ;
2021-12-29 21:56:21 +00:00
}
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2019-09-19 22:42:45 +00:00
struct TeslaMissile
{
2021-12-29 21:56:21 +00:00
int offset ; // offset
int id ; // id
int ammouse ; // ammo use
int sound ; // sound
int light ; // light
int flash ; // weapon flash
2019-09-19 22:42:45 +00:00
} ;
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void FireTesla ( int nTrigger , PLAYER * pPlayer )
{
TeslaMissile teslaMissile [ 6 ] =
{
{ 0 , 306 , 1 , 470 , 20 , 1 } ,
{ - 140 , 306 , 1 , 470 , 30 , 1 } ,
{ 140 , 306 , 1 , 470 , 30 , 1 } ,
{ 0 , 302 , 35 , 471 , 40 , 1 } ,
{ - 140 , 302 , 35 , 471 , 50 , 1 } ,
{ 140 , 302 , 35 , 471 , 50 , 1 } ,
} ;
if ( nTrigger > 0 & & nTrigger < = 6 )
{
nTrigger - - ;
auto plActor = pPlayer - > actor ;
TeslaMissile * pMissile = & teslaMissile [ nTrigger ] ;
if ( ! checkAmmo2 ( pPlayer , 7 , pMissile - > ammouse ) )
{
pMissile = & teslaMissile [ 0 ] ;
if ( ! checkAmmo2 ( pPlayer , 7 , pMissile - > ammouse ) )
{
pPlayer - > weaponState = - 1 ;
SetQAV ( pPlayer , kQAVSGUNIDL2 ) ;
pPlayer - > flashEffect = 0 ;
return ;
}
}
playerFireMissile ( pPlayer , pMissile - > offset , pPlayer - > aim . dx , pPlayer - > aim . dy , pPlayer - > aim . dz , pMissile - > id ) ;
2022-05-05 23:40:27 +00:00
UseAmmo ( pPlayer , pPlayer - > weaponAmmo , pMissile - > ammouse ) ;
2021-12-29 21:56:21 +00:00
sfxPlay3DSound ( pPlayer - > actor , pMissile - > sound , 1 , 0 ) ;
pPlayer - > visibility = pMissile - > light ;
pPlayer - > flashEffect = pMissile - > flash ;
}
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void AltFireTesla ( int , PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
2021-12-29 21:56:21 +00:00
auto plActor = pPlayer - > actor ;
playerFireMissile ( pPlayer , 0 , pPlayer - > aim . dx , pPlayer - > aim . dy , pPlayer - > aim . dz , kMissileTeslaAlt ) ;
UseAmmo ( pPlayer , pPlayer - > weaponAmmo , 35 ) ;
sfxPlay3DSound ( pPlayer - > actor , 471 , 2 , 0 ) ;
pPlayer - > visibility = 40 ;
pPlayer - > flashEffect = 1 ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void FireNapalm ( int nTrigger , PLAYER * pPlayer )
{
auto plActor = pPlayer - > actor ;
int offset = 0 ;
switch ( nTrigger )
{
case 2 :
offset = - 50 ;
break ;
case 3 :
offset = 50 ;
break ;
}
playerFireMissile ( pPlayer , offset , pPlayer - > aim . dx , pPlayer - > aim . dy , pPlayer - > aim . dz , kMissileFireballNapalm ) ;
sfxPlay3DSound ( pPlayer - > actor , 480 , 2 , 0 ) ;
UseAmmo ( pPlayer , 4 , 1 ) ;
pPlayer - > flashEffect = 1 ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
void FireNapalm2 ( int , PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
2021-12-29 21:56:21 +00:00
auto plActor = pPlayer - > actor ;
playerFireMissile ( pPlayer , - 120 , pPlayer - > aim . dx , pPlayer - > aim . dy , pPlayer - > aim . dz , kMissileFireballNapalm ) ;
playerFireMissile ( pPlayer , 120 , pPlayer - > aim . dx , pPlayer - > aim . dy , pPlayer - > aim . dz , kMissileFireballNapalm ) ;
sfxPlay3DSound ( pPlayer - > actor , 480 , 2 , 0 ) ;
UseAmmo ( pPlayer , 4 , 2 ) ;
pPlayer - > flashEffect = 1 ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void AltFireNapalm ( int , PLAYER * pPlayer )
{
int nSpeed = MulScale ( 0x8000 , 0x177777 , 16 ) + 0x66666 ;
auto missile = playerFireThing ( pPlayer , 0 , - 4730 , kThingNapalmBall , nSpeed ) ;
if ( missile )
{
missile - > xspr . data4 = ClipHigh ( pPlayer - > ammoCount [ 4 ] , 12 ) ;
UseAmmo ( pPlayer , 4 , missile - > xspr . data4 ) ;
seqSpawn ( 22 , missile , - 1 ) ;
actBurnSprite ( pPlayer - > actor , missile , 600 ) ;
evPostActor ( missile , 0 , kCallbackFXFlameLick ) ;
sfxPlay3DSound ( missile , 480 , 2 , 0 ) ;
pPlayer - > visibility = 30 ;
pPlayer - > flashEffect = 1 ;
}
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void FireLifeLeech ( int nTrigger , PLAYER * pPlayer )
{
if ( ! CheckAmmo ( pPlayer , 8 , 1 ) )
return ;
int r1 = Random2 ( 2000 ) ;
int r2 = Random2 ( 2000 ) ;
int r3 = Random2 ( 1000 ) ;
DBloodActor * actor = pPlayer - > actor ;
auto missileActor = playerFireMissile ( pPlayer , 0 , pPlayer - > aim . dx + r1 , pPlayer - > aim . dy + r2 , pPlayer - > aim . dz + r3 , 315 ) ;
if ( missileActor )
{
missileActor - > SetTarget ( pPlayer - > aimTarget ) ;
2022-08-16 21:20:03 +00:00
missileActor - > set_int_ang ( ( nTrigger = = 2 ) ? 1024 : 0 ) ;
2021-12-29 21:56:21 +00:00
}
if ( checkAmmo2 ( pPlayer , 8 , 1 ) )
UseAmmo ( pPlayer , 8 , 1 ) ;
else
actDamageSprite ( actor , actor , kDamageSpirit , 16 ) ;
pPlayer - > visibility = ClipHigh ( pPlayer - > visibility + 5 , 50 ) ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void AltFireLifeLeech ( int , PLAYER * pPlayer )
{
DBloodActor * actor = pPlayer - > actor ;
sfxPlay3DSound ( pPlayer - > actor , 455 , 2 , 0 ) ;
auto missile = playerFireThing ( pPlayer , 0 , - 4730 , kThingDroppedLifeLeech , 0x19999 ) ;
if ( missile )
{
missile - > spr . cstat | = CSTAT_SPRITE_BLOOD_BIT1 ;
missile - > xspr . Push = 1 ;
missile - > xspr . Proximity = 1 ;
missile - > xspr . DudeLockout = 1 ;
missile - > xspr . stateTimer = 1 ;
evPostActor ( missile , 120 , kCallbackLeechStateTimer ) ;
if ( gGameOptions . nGameType < = 1 )
{
int nAmmo = pPlayer - > ammoCount [ 8 ] ;
if ( nAmmo < 25 & & pPlayer - > actor - > xspr . health > unsigned ( ( 25 - nAmmo ) < < 4 ) )
{
actDamageSprite ( actor , actor , kDamageSpirit , ( ( 25 - nAmmo ) < < 4 ) ) ;
nAmmo = 25 ;
}
missile - > xspr . data3 = nAmmo ;
UseAmmo ( pPlayer , 8 , nAmmo ) ;
}
else
{
missile - > xspr . data3 = pPlayer - > ammoCount [ 8 ] ;
pPlayer - > ammoCount [ 8 ] = 0 ;
}
2022-01-12 11:22:48 +00:00
pPlayer - > hasWeapon [ kWeapLifeLeech ] = 0 ;
2021-12-29 21:56:21 +00:00
}
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void FireBeast ( int , PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
2021-12-29 21:56:21 +00:00
DBloodActor * actor = pPlayer - > actor ;
int r1 = Random2 ( 2000 ) ;
int r2 = Random2 ( 2000 ) ;
int r3 = Random2 ( 2000 ) ;
2022-01-30 17:09:26 +00:00
actFireVector ( actor , 0 , pPlayer - > zWeapon - pPlayer - > actor - > int_pos ( ) . Z , pPlayer - > aim . dx + r1 , pPlayer - > aim . dy + r2 , pPlayer - > aim . dz + r3 , kVectorBeastSlash ) ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static const uint8_t gWeaponUpgrade [ ] [ 13 ] = {
{ 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 } ,
{ 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 } ,
{ 0 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 } ,
2019-09-19 22:42:45 +00:00
} ;
2021-12-29 21:56:21 +00:00
int WeaponUpgrade ( PLAYER * pPlayer , int newWeapon )
2019-09-19 22:42:45 +00:00
{
2021-12-29 21:56:21 +00:00
int weapon = pPlayer - > curWeapon ;
2022-05-05 23:16:10 +00:00
if ( ! checkLitSprayOrTNT ( pPlayer ) & & ( cl_weaponswitch & 1 ) & & ( gWeaponUpgrade [ pPlayer - > curWeapon ] [ newWeapon ] | | ( cl_weaponswitch & 2 ) ) )
2021-12-29 21:56:21 +00:00
weapon = newWeapon ;
return weapon ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static const int OrderNext [ ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 1 , 1 } ;
static const int OrderPrev [ ] = { 12 , 12 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 1 } ;
static int WeaponFindNext ( PLAYER * pPlayer , int * a2 , int bDir )
{
int weapon = pPlayer - > curWeapon ;
do
{
if ( bDir )
weapon = OrderNext [ weapon ] ;
else
weapon = OrderPrev [ weapon ] ;
if ( weaponModes [ weapon ] . update & & pPlayer - > hasWeapon [ weapon ] )
{
if ( weapon = = kWeapLifeLeech )
{
if ( CheckAmmo ( pPlayer , weaponModes [ weapon ] . ammoType , 1 ) )
break ;
}
else
{
if ( checkAmmo2 ( pPlayer , weaponModes [ weapon ] . ammoType , 1 ) )
break ;
}
}
} while ( weapon ! = pPlayer - > curWeapon ) ;
if ( weapon = = pPlayer - > curWeapon )
{
if ( ! weaponModes [ weapon ] . update | | ! CheckAmmo ( pPlayer , weaponModes [ weapon ] . ammoType , 1 ) )
weapon = kWeapPitchFork ;
}
if ( a2 )
* a2 = 0 ;
return weapon ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static int WeaponFindLoaded ( PLAYER * pPlayer , int * a2 )
{
int v4 = 1 ;
int v14 = 0 ;
if ( weaponModes [ pPlayer - > curWeapon ] . update > 1 )
{
for ( int i = 0 ; i < weaponModes [ pPlayer - > curWeapon ] . update ; i + + )
{
if ( CheckAmmo ( pPlayer , weaponModes [ pPlayer - > curWeapon ] . ammoType , 1 ) )
{
v14 = i ;
v4 = pPlayer - > curWeapon ;
break ;
}
}
}
if ( v4 = = kWeapPitchFork )
{
int vc = 0 ;
for ( int i = 0 ; i < 14 ; i + + )
{
int weapon = pPlayer - > weaponOrder [ vc ] [ i ] ;
if ( pPlayer - > hasWeapon [ weapon ] )
{
for ( int j = 0 ; j < weaponModes [ weapon ] . update ; j + + )
{
if ( CheckWeaponAmmo ( pPlayer , weapon , weaponModes [ weapon ] . ammoType , 1 ) )
{
if ( a2 )
* a2 = j ;
return weapon ;
}
}
}
}
}
2022-05-05 23:40:27 +00:00
if ( a2 )
2021-12-29 21:56:21 +00:00
* a2 = v14 ;
return v4 ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
int processSprayCan ( PLAYER * pPlayer )
{
switch ( pPlayer - > weaponState )
{
case 5 :
if ( ! ( pPlayer - > input . actions & SB_ALTFIRE ) )
pPlayer - > weaponState = 6 ;
return 1 ;
case 6 :
if ( pPlayer - > input . actions & SB_ALTFIRE )
{
pPlayer - > weaponState = 3 ;
pPlayer - > fuseTime = pPlayer - > weaponTimer ;
StartQAV ( pPlayer , kQAVCANDROP , nClientDropCan ) ;
}
else if ( pPlayer - > input . actions & SB_FIRE )
{
pPlayer - > weaponState = 7 ;
pPlayer - > fuseTime = 0 ;
pPlayer - > throwTime = PlayClock ;
}
return 1 ;
case 7 :
{
pPlayer - > throwPower = ClipHigh ( DivScale ( PlayClock - pPlayer - > throwTime , 240 , 16 ) , 65536 ) ;
if ( ! ( pPlayer - > input . actions & SB_FIRE ) )
{
if ( ! pPlayer - > fuseTime )
pPlayer - > fuseTime = pPlayer - > weaponTimer ;
pPlayer - > weaponState = 1 ;
StartQAV ( pPlayer , kQAVCANTHRO , nClientThrowCan ) ;
}
return 1 ;
}
}
return 0 ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static bool processTNT ( PLAYER * pPlayer )
{
switch ( pPlayer - > weaponState )
{
case 4 :
if ( ! ( pPlayer - > input . actions & SB_ALTFIRE ) )
pPlayer - > weaponState = 5 ;
return 1 ;
case 5 :
if ( pPlayer - > input . actions & SB_ALTFIRE )
{
pPlayer - > weaponState = 1 ;
pPlayer - > fuseTime = pPlayer - > weaponTimer ;
StartQAV ( pPlayer , kQAVBUNDROP , nClientDropBundle ) ;
}
else if ( pPlayer - > input . actions & SB_FIRE )
{
pPlayer - > weaponState = 6 ;
pPlayer - > fuseTime = 0 ;
pPlayer - > throwTime = PlayClock ;
}
return 1 ;
case 6 :
{
pPlayer - > throwPower = ClipHigh ( DivScale ( PlayClock - pPlayer - > throwTime , 240 , 16 ) , 65536 ) ;
if ( ! ( pPlayer - > input . actions & SB_FIRE ) )
{
if ( ! pPlayer - > fuseTime )
pPlayer - > fuseTime = pPlayer - > weaponTimer ;
pPlayer - > weaponState = 1 ;
StartQAV ( pPlayer , kQAVBUNTHRO , nClientThrowBundle ) ;
}
return 1 ;
}
}
return 0 ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static bool processProxy ( PLAYER * pPlayer )
{
switch ( pPlayer - > weaponState )
{
case 9 :
pPlayer - > throwPower = ClipHigh ( DivScale ( PlayClock - pPlayer - > throwTime , 240 , 16 ) , 65536 ) ;
pPlayer - > weaponTimer = 0 ;
pPlayer - > qavTimer = 0 ;
if ( ! ( pPlayer - > input . actions & SB_FIRE ) )
{
pPlayer - > weaponState = 8 ;
StartQAV ( pPlayer , kQAVPROXTHRO , nClientThrowProx ) ;
}
2022-05-05 23:40:27 +00:00
return true ;
2021-12-29 21:56:21 +00:00
}
2022-05-05 23:40:27 +00:00
return false ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static bool processRemote ( PLAYER * pPlayer )
{
switch ( pPlayer - > weaponState )
{
case 13 :
pPlayer - > throwPower = ClipHigh ( DivScale ( PlayClock - pPlayer - > throwTime , 240 , 16 ) , 65536 ) ;
if ( ! ( pPlayer - > input . actions & SB_FIRE ) )
{
pPlayer - > weaponState = 11 ;
StartQAV ( pPlayer , kQAVREMTHRO , nClientThrowRemote ) ;
}
2022-05-05 23:40:27 +00:00
return true ;
2021-12-29 21:56:21 +00:00
}
2022-05-05 23:40:27 +00:00
return false ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static bool processLeech ( PLAYER * pPlayer )
{
switch ( pPlayer - > weaponState )
{
case 4 :
pPlayer - > weaponState = 6 ;
StartQAV ( pPlayer , kQAVSTAFIRE1 , nClientFireLifeLeech , 1 ) ;
return 1 ;
case 6 :
if ( ! ( pPlayer - > input . actions & SB_ALTFIRE ) )
{
pPlayer - > weaponState = 2 ;
StartQAV ( pPlayer , kQAVSTAFPOST ) ;
return 1 ;
}
break ;
case 8 :
pPlayer - > weaponState = 2 ;
StartQAV ( pPlayer , kQAVSTAFPOST ) ;
return 1 ;
}
return 0 ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static bool processTesla ( PLAYER * pPlayer )
{
switch ( pPlayer - > weaponState )
{
case 4 :
pPlayer - > weaponState = 5 ;
if ( checkAmmo2 ( pPlayer , 7 , 10 ) & & powerupCheck ( pPlayer , kPwUpTwoGuns ) )
StartQAV ( pPlayer , kQAV2SGUNFIR , nClientFireTesla , 1 ) ;
else
StartQAV ( pPlayer , kQAVSGUNFIR1 , nClientFireTesla , 1 ) ;
return 1 ;
case 5 :
if ( ! ( pPlayer - > input . actions & SB_FIRE ) )
{
pPlayer - > weaponState = 2 ;
if ( checkAmmo2 ( pPlayer , 7 , 10 ) & & powerupCheck ( pPlayer , kPwUpTwoGuns ) )
StartQAV ( pPlayer , kQAV2SGUNPST ) ;
else
StartQAV ( pPlayer , kQAVSGUNPOST ) ;
return 1 ;
}
break ;
case 7 :
pPlayer - > weaponState = 2 ;
if ( checkAmmo2 ( pPlayer , 7 , 10 ) & & powerupCheck ( pPlayer , kPwUpTwoGuns ) )
StartQAV ( pPlayer , kQAV2SGUNPST ) ;
else
StartQAV ( pPlayer , kQAVSGUNPOST ) ;
return 1 ;
}
return 0 ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void WeaponProcess ( PLAYER * pPlayer ) {
pPlayer - > flashEffect = ClipLow ( pPlayer - > flashEffect - 1 , 0 ) ;
# ifdef NOONE_EXTENSIONS
if ( gPlayerCtrl [ pPlayer - > nPlayer ] . qavScene . initiator ! = nullptr & & pPlayer - > actor - > xspr . health > 0 ) {
playerQavSceneProcess ( pPlayer , & gPlayerCtrl [ pPlayer - > nPlayer ] . qavScene ) ;
UpdateAimVector ( pPlayer ) ;
return ;
}
# endif
if ( pPlayer - > actor - > xspr . health = = 0 )
{
pPlayer - > qavLoop = 0 ;
sfxKill3DSound ( pPlayer - > actor , 1 , - 1 ) ;
}
if ( pPlayer - > isUnderwater & & BannedUnderwater ( pPlayer - > curWeapon ) )
{
2022-05-05 23:16:10 +00:00
if ( checkLitSprayOrTNT ( pPlayer ) )
2021-12-29 21:56:21 +00:00
{
if ( pPlayer - > curWeapon = = kWeapSpraycan )
{
pPlayer - > fuseTime = pPlayer - > weaponTimer ;
DropCan ( 1 , pPlayer ) ;
pPlayer - > weaponState = 3 ;
}
else if ( pPlayer - > curWeapon = = kWeapDynamite )
{
pPlayer - > fuseTime = pPlayer - > weaponTimer ;
DropBundle ( 1 , pPlayer ) ;
pPlayer - > weaponState = 1 ;
}
}
WeaponLower ( pPlayer ) ;
pPlayer - > throwPower = 0 ;
}
WeaponPlay ( pPlayer ) ;
UpdateAimVector ( pPlayer ) ;
pPlayer - > weaponTimer - = 4 ;
bool bShoot = pPlayer - > input . actions & SB_FIRE ;
bool bShoot2 = pPlayer - > input . actions & SB_ALTFIRE ;
const int prevNewWeaponVal = pPlayer - > input . getNewWeapon ( ) ; // used to fix scroll issue for banned weapons
if ( ( bShoot | | bShoot2 | | prevNewWeaponVal ) & & pPlayer - > weaponQav = = qavGetCorrectID ( kQAVVDIDLE2 ) ) pPlayer - > weaponTimer = 0 ;
if ( pPlayer - > qavLoop & & pPlayer - > actor - > xspr . health > 0 )
{
if ( bShoot & & CheckAmmo ( pPlayer , pPlayer - > weaponAmmo , 1 ) )
{
auto pQAV = getQAV ( pPlayer - > weaponQav ) ;
while ( pPlayer - > weaponTimer < = 0 )
{
pPlayer - > weaponTimer + = pQAV - > duration ;
pPlayer - > qavTimer + = pQAV - > duration ;
}
}
else
{
pPlayer - > weaponTimer = 0 ;
pPlayer - > qavTimer = 0 ;
pPlayer - > qavLoop = 0 ;
}
return ;
}
pPlayer - > weaponTimer = ClipLow ( pPlayer - > weaponTimer , 0 ) ;
switch ( pPlayer - > curWeapon )
{
case kWeapSpraycan :
if ( processSprayCan ( pPlayer ) )
return ;
break ;
case kWeapDynamite :
if ( processTNT ( pPlayer ) )
return ;
break ;
case kWeapProximity :
if ( processProxy ( pPlayer ) )
return ;
break ;
case kWeapRemote :
if ( processRemote ( pPlayer ) )
return ;
break ;
}
if ( pPlayer - > weaponTimer > 0 )
return ;
if ( pPlayer - > actor - > xspr . health = = 0 | | pPlayer - > curWeapon = = kWeapNone )
pPlayer - > weaponQav = kQAVNone ;
switch ( pPlayer - > curWeapon )
{
case kWeapLifeLeech :
if ( processLeech ( pPlayer ) )
return ;
break ;
case kWeapTeslaCannon :
if ( processTesla ( pPlayer ) )
return ;
break ;
}
if ( VanillaMode ( ) )
{
if ( pPlayer - > nextWeapon )
{
sfxKill3DSound ( pPlayer - > actor , - 1 , 441 ) ;
pPlayer - > weaponState = 0 ;
pPlayer - > newWeapon = pPlayer - > nextWeapon ;
pPlayer - > nextWeapon = kWeapNone ;
}
}
if ( pPlayer - > input . getNewWeapon ( ) = = WeaponSel_Next )
{
pPlayer - > input . setNewWeapon ( kWeapNone ) ;
if ( VanillaMode ( ) )
{
pPlayer - > weaponState = 0 ;
}
pPlayer - > nextWeapon = kWeapNone ;
int t ;
int weapon = WeaponFindNext ( pPlayer , & t , 1 ) ;
pPlayer - > weaponMode [ weapon ] = t ;
if ( VanillaMode ( ) )
{
if ( pPlayer - > curWeapon )
{
WeaponLower ( pPlayer ) ;
pPlayer - > nextWeapon = weapon ;
return ;
}
}
pPlayer - > newWeapon = weapon ;
}
else if ( pPlayer - > input . getNewWeapon ( ) = = WeaponSel_Prev )
{
pPlayer - > input . setNewWeapon ( kWeapNone ) ;
if ( VanillaMode ( ) )
{
pPlayer - > weaponState = 0 ;
}
pPlayer - > nextWeapon = kWeapNone ;
int t ;
int weapon = WeaponFindNext ( pPlayer , & t , 0 ) ;
pPlayer - > weaponMode [ weapon ] = t ;
if ( VanillaMode ( ) )
{
if ( pPlayer - > curWeapon )
{
WeaponLower ( pPlayer ) ;
pPlayer - > nextWeapon = weapon ;
return ;
}
}
pPlayer - > newWeapon = weapon ;
}
else if ( pPlayer - > input . getNewWeapon ( ) = = WeaponSel_Alt )
{
int weapon ;
switch ( pPlayer - > curWeapon )
{
case kWeapDynamite :
weapon = kWeapProximity ;
break ;
case kWeapProximity :
weapon = kWeapRemote ;
break ;
case kWeapRemote :
weapon = kWeapDynamite ;
break ;
default :
return ;
}
pPlayer - > input . setNewWeapon ( kWeapNone ) ;
pPlayer - > weaponState = 0 ;
pPlayer - > nextWeapon = kWeapNone ;
int t = 0 ;
pPlayer - > weaponMode [ weapon ] = t ;
if ( pPlayer - > curWeapon )
{
WeaponLower ( pPlayer ) ;
pPlayer - > nextWeapon = weapon ;
return ;
}
pPlayer - > newWeapon = weapon ;
}
if ( ! VanillaMode ( ) )
{
if ( pPlayer - > nextWeapon )
{
sfxKill3DSound ( pPlayer - > actor , - 1 , 441 ) ;
pPlayer - > newWeapon = pPlayer - > nextWeapon ;
pPlayer - > nextWeapon = kWeapNone ;
}
}
if ( pPlayer - > weaponState = = - 1 )
{
pPlayer - > weaponState = 0 ;
int t ;
int weapon = WeaponFindLoaded ( pPlayer , & t ) ;
pPlayer - > weaponMode [ weapon ] = t ;
if ( pPlayer - > curWeapon )
{
WeaponLower ( pPlayer ) ;
pPlayer - > nextWeapon = weapon ;
return ;
}
pPlayer - > newWeapon = weapon ;
}
if ( pPlayer - > newWeapon )
{
2022-05-05 23:16:10 +00:00
if ( pPlayer - > isUnderwater & & BannedUnderwater ( pPlayer - > newWeapon ) & & ! checkLitSprayOrTNT ( pPlayer ) & & ! VanillaMode ( ) ) // skip banned weapons when underwater and using next/prev weapon key inputs
2021-12-29 21:56:21 +00:00
{
if ( prevNewWeaponVal = = WeaponSel_Next | | prevNewWeaponVal = = WeaponSel_Prev ) // if player switched weapons
{
int saveweapon = pPlayer - > curWeapon ;
pPlayer - > curWeapon = pPlayer - > newWeapon ; // set current banned weapon to curweapon so WeaponFindNext() can find the next weapon
for ( int i = 0 ; i < 3 ; i + + ) // attempt twice to find a new weapon
{
pPlayer - > curWeapon = WeaponFindNext ( pPlayer , NULL , ( char ) ( prevNewWeaponVal = = WeaponSel_Next ) ) ;
if ( ! BannedUnderwater ( pPlayer - > curWeapon ) ) // if new weapon is not a banned weapon, set to new current weapon
{
pPlayer - > newWeapon = pPlayer - > curWeapon ;
pPlayer - > weaponMode [ pPlayer - > newWeapon ] = 0 ;
break ;
}
}
pPlayer - > curWeapon = saveweapon ;
}
}
if ( pPlayer - > newWeapon = = kWeapDynamite )
{
if ( pPlayer - > curWeapon = = kWeapDynamite )
{
if ( checkAmmo2 ( pPlayer , 10 , 1 ) )
pPlayer - > newWeapon = kWeapProximity ;
else if ( checkAmmo2 ( pPlayer , 11 , 1 ) )
pPlayer - > newWeapon = kWeapRemote ;
}
else if ( pPlayer - > curWeapon = = kWeapProximity )
{
if ( checkAmmo2 ( pPlayer , 11 , 1 ) )
pPlayer - > newWeapon = kWeapRemote ;
else if ( checkAmmo2 ( pPlayer , 5 , 1 ) & & pPlayer - > isUnderwater = = 0 )
pPlayer - > newWeapon = kWeapDynamite ;
}
else if ( pPlayer - > curWeapon = = kWeapRemote )
{
if ( checkAmmo2 ( pPlayer , 5 , 1 ) & & pPlayer - > isUnderwater = = 0 )
pPlayer - > newWeapon = kWeapDynamite ;
else if ( checkAmmo2 ( pPlayer , 10 , 1 ) )
pPlayer - > newWeapon = kWeapProximity ;
}
else
{
if ( checkAmmo2 ( pPlayer , 5 , 1 ) & & pPlayer - > isUnderwater = = 0 )
pPlayer - > newWeapon = kWeapDynamite ;
else if ( checkAmmo2 ( pPlayer , 10 , 1 ) )
pPlayer - > newWeapon = kWeapProximity ;
else if ( checkAmmo2 ( pPlayer , 11 , 1 ) )
pPlayer - > newWeapon = kWeapRemote ;
}
}
else if ( ( pPlayer - > newWeapon = = kWeapSpraycan ) & & ! VanillaMode ( ) )
{
if ( ( pPlayer - > curWeapon = = kWeapSpraycan ) & & ( pPlayer - > weaponState = = 2 ) ) // fix spray can state glitch when switching from spray to tnt and back quickly
{
pPlayer - > weaponState = 1 ;
pPlayer - > newWeapon = kWeapNone ;
return ;
}
}
if ( pPlayer - > actor - > xspr . health = = 0 | | pPlayer - > hasWeapon [ pPlayer - > newWeapon ] = = 0 )
{
pPlayer - > newWeapon = kWeapNone ;
return ;
}
2022-05-05 23:16:10 +00:00
if ( pPlayer - > isUnderwater & & BannedUnderwater ( pPlayer - > newWeapon ) & & ! checkLitSprayOrTNT ( pPlayer ) )
2021-12-29 21:56:21 +00:00
{
pPlayer - > newWeapon = kWeapNone ;
return ;
}
int nWeapon = pPlayer - > newWeapon ;
int v4c = weaponModes [ nWeapon ] . update ;
if ( ! pPlayer - > curWeapon )
{
int nAmmoType = weaponModes [ nWeapon ] . ammoType ;
if ( v4c > 1 )
{
if ( CheckAmmo ( pPlayer , nAmmoType , 1 ) | | nAmmoType = = 11 )
WeaponRaise ( pPlayer ) ;
pPlayer - > newWeapon = kWeapNone ;
}
else
{
if ( CheckWeaponAmmo ( pPlayer , nWeapon , nAmmoType , 1 ) )
WeaponRaise ( pPlayer ) ;
else
{
pPlayer - > weaponState = 0 ;
int t ;
int weapon = WeaponFindLoaded ( pPlayer , & t ) ;
pPlayer - > weaponMode [ weapon ] = t ;
if ( pPlayer - > curWeapon )
{
WeaponLower ( pPlayer ) ;
pPlayer - > nextWeapon = weapon ;
return ;
}
pPlayer - > newWeapon = weapon ;
}
}
return ;
}
if ( nWeapon = = pPlayer - > curWeapon & & v4c < = 1 )
{
pPlayer - > newWeapon = kWeapNone ;
return ;
}
int i = 0 ;
if ( nWeapon = = pPlayer - > curWeapon )
i = 1 ;
for ( ; i < = v4c ; i + + )
{
int v6c = ( pPlayer - > weaponMode [ nWeapon ] + i ) % v4c ;
if ( CheckWeaponAmmo ( pPlayer , nWeapon , weaponModes [ nWeapon ] . ammoType , 1 ) )
{
WeaponLower ( pPlayer ) ;
pPlayer - > weaponMode [ nWeapon ] = v6c ;
return ;
}
}
pPlayer - > newWeapon = kWeapNone ;
return ;
}
if ( pPlayer - > curWeapon & & ! CheckAmmo ( pPlayer , pPlayer - > weaponAmmo , 1 ) & & pPlayer - > weaponAmmo ! = 11 )
{
pPlayer - > weaponState = - 1 ;
return ;
}
if ( bShoot )
{
switch ( pPlayer - > curWeapon )
{
case kWeapPitchFork :
StartQAV ( pPlayer , kQAVPFORK , nClientFirePitchfork ) ;
return ;
case kWeapSpraycan :
switch ( pPlayer - > weaponState )
{
case 3 :
pPlayer - > weaponState = 4 ;
StartQAV ( pPlayer , kQAVCANFIRE , nClientFireSpray , 1 ) ;
return ;
}
break ;
case kWeapDynamite :
switch ( pPlayer - > weaponState )
{
case 3 :
pPlayer - > weaponState = 6 ;
pPlayer - > fuseTime = - 1 ;
pPlayer - > throwTime = PlayClock ;
StartQAV ( pPlayer , kQAVBUNFUSE , nClientExplodeBundle ) ;
return ;
}
break ;
case kWeapProximity :
switch ( pPlayer - > weaponState )
{
case 7 :
SetQAV ( pPlayer , kQAVPROXIDLE ) ;
pPlayer - > weaponState = 9 ;
pPlayer - > throwTime = PlayClock ;
return ;
}
break ;
case kWeapRemote :
switch ( pPlayer - > weaponState )
{
case 10 :
SetQAV ( pPlayer , kQAVREMIDLE1 ) ;
pPlayer - > weaponState = 13 ;
pPlayer - > throwTime = PlayClock ;
return ;
case 11 :
pPlayer - > weaponState = 12 ;
StartQAV ( pPlayer , kQAVREMFIRE , nClientFireRemote ) ;
return ;
}
break ;
case kWeapShotgun :
switch ( pPlayer - > weaponState )
{
case 7 :
pPlayer - > weaponState = 6 ;
StartQAV ( pPlayer , kQAV2SHOTF2 , nClientFireShotgun ) ;
return ;
case 3 :
pPlayer - > weaponState = 2 ;
StartQAV ( pPlayer , kQAVSHOTF1 , nClientFireShotgun ) ;
return ;
case 2 :
pPlayer - > weaponState = 1 ;
StartQAV ( pPlayer , kQAVSHOTF2 , nClientFireShotgun ) ;
return ;
}
break ;
case kWeapTommyGun :
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 3 , 2 ) )
StartQAV ( pPlayer , kQAV2TOMFIRE , nClientFireTommy , 1 ) ;
else
StartQAV ( pPlayer , kQAVTOMFIRE , nClientFireTommy , 1 ) ;
return ;
case kWeapFlareGun :
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 1 , 2 ) )
StartQAV ( pPlayer , kQAVFLAR2FIR , nClientFireFlare ) ;
else
StartQAV ( pPlayer , kQAVFLARFIR2 , nClientFireFlare ) ;
return ;
case kWeapVoodooDoll :
{
static int nChance [ ] = { 0xa000 , 0xc000 , 0xe000 , 0x10000 } ;
int nRand = wrand ( ) * 2 ;
int i ;
for ( i = 0 ; nChance [ i ] < nRand ; i + + )
{
}
pPlayer - > voodooTarget = pPlayer - > aimTarget ;
if ( pPlayer - > voodooTarget = = nullptr | | pPlayer - > voodooTarget - > spr . statnum ! = kStatDude )
i = 4 ;
StartQAV ( pPlayer , kQAVVDFIRE1 + i , nClientFireVoodoo ) ;
return ;
}
case kWeapTeslaCannon :
switch ( pPlayer - > weaponState )
{
case 2 :
pPlayer - > weaponState = 4 ;
if ( checkAmmo2 ( pPlayer , 7 , 10 ) & & powerupCheck ( pPlayer , kPwUpTwoGuns ) )
StartQAV ( pPlayer , kQAV2SGUNFIR , nClientFireTesla ) ;
else
StartQAV ( pPlayer , kQAVSGUNFIR1 , nClientFireTesla ) ;
return ;
case 5 :
if ( checkAmmo2 ( pPlayer , 7 , 10 ) & & powerupCheck ( pPlayer , kPwUpTwoGuns ) )
StartQAV ( pPlayer , kQAV2SGUNFIR , nClientFireTesla ) ;
else
StartQAV ( pPlayer , kQAVSGUNFIR1 , nClientFireTesla ) ;
return ;
}
break ;
case kWeapNapalm :
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) )
StartQAV ( pPlayer , kQAV2NAPFIRE , nClientFireNapalm ) ;
else
StartQAV ( pPlayer , kQAVNAPFIRE , nClientFireNapalm ) ;
return ;
case kWeapLifeLeech :
sfxPlay3DSound ( pPlayer - > actor , 494 , 2 , 0 ) ;
StartQAV ( pPlayer , kQAVSTAFIRE4 , nClientFireLifeLeech ) ;
return ;
case kWeapBeast :
StartQAV ( pPlayer , kQAVBSTATAK1 + Random ( 4 ) , nClientFireBeast ) ;
return ;
}
}
if ( bShoot2 )
{
switch ( pPlayer - > curWeapon )
{
case kWeapPitchFork :
StartQAV ( pPlayer , kQAVPFORK , nClientFirePitchfork ) ;
return ;
case kWeapSpraycan :
switch ( pPlayer - > weaponState )
{
case 3 :
pPlayer - > weaponState = 5 ;
StartQAV ( pPlayer , kQAVCANFIRE2 , nClientExplodeCan ) ;
return ;
}
break ;
case kWeapDynamite :
switch ( pPlayer - > weaponState )
{
case 3 :
pPlayer - > weaponState = 4 ;
StartQAV ( pPlayer , kQAVBUNFUSE , nClientExplodeBundle ) ;
return ;
case 7 :
pPlayer - > weaponState = 8 ;
StartQAV ( pPlayer , kQAVPROXDROP , nClientDropProx ) ;
return ;
case 10 :
pPlayer - > weaponState = 11 ;
StartQAV ( pPlayer , kQAVREMDROP , nClientDropRemote ) ;
return ;
case 11 :
if ( pPlayer - > ammoCount [ 11 ] > 0 )
{
pPlayer - > weaponState = 10 ;
StartQAV ( pPlayer , kQAVREMUP1 ) ;
}
return ;
}
break ;
case kWeapProximity :
switch ( pPlayer - > weaponState )
{
case 7 :
pPlayer - > weaponState = 8 ;
StartQAV ( pPlayer , kQAVPROXDROP , nClientDropProx ) ;
return ;
}
break ;
case kWeapRemote :
switch ( pPlayer - > weaponState )
{
case 10 :
pPlayer - > weaponState = 11 ;
StartQAV ( pPlayer , kQAVREMDROP , nClientDropRemote ) ;
return ;
case 11 :
if ( pPlayer - > ammoCount [ 11 ] > 0 )
{
pPlayer - > weaponState = 10 ;
StartQAV ( pPlayer , kQAVREMUP1 ) ;
}
return ;
}
break ;
case kWeapShotgun :
switch ( pPlayer - > weaponState )
{
case 7 :
pPlayer - > weaponState = 6 ;
StartQAV ( pPlayer , kQAV2SHOTFIR , nClientFireShotgun ) ;
return ;
case 3 :
pPlayer - > weaponState = 1 ;
StartQAV ( pPlayer , kQAVSHOTF3 , nClientFireShotgun ) ;
return ;
case 2 :
pPlayer - > weaponState = 1 ;
StartQAV ( pPlayer , kQAVSHOTF2 , nClientFireShotgun ) ;
return ;
}
break ;
case kWeapTommyGun :
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 3 , 2 ) )
StartQAV ( pPlayer , kQAV2TOMALT , nClientAltFireSpread2 ) ;
else
StartQAV ( pPlayer , kQAVTOMSPRED , nClientAltFireSpread2 ) ;
return ;
case kWeapVoodooDoll :
sfxPlay3DSound ( pPlayer - > actor , 461 , 2 , 0 ) ;
StartQAV ( pPlayer , kQAVVDSPEL1 , nClientAltFireVoodoo ) ;
return ;
2019-09-19 22:42:45 +00:00
#if 0
2021-12-29 21:56:21 +00:00
case kWeapFlareGun :
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 1 , 2 ) )
StartQAV ( pPlayer , kQAVFLAR2FIR , nClientFireFlare , 0 ) ;
else
StartQAV ( pPlayer , kQAVFLARFIR2 , nClientFireFlare , 0 ) ;
return ;
2019-09-19 22:42:45 +00:00
# endif
2021-12-29 21:56:21 +00:00
case kWeapTeslaCannon :
if ( checkAmmo2 ( pPlayer , 7 , 35 ) )
{
if ( checkAmmo2 ( pPlayer , 7 , 70 ) & & powerupCheck ( pPlayer , kPwUpTwoGuns ) )
StartQAV ( pPlayer , kQAV2SGUNALT , nClientFireTesla ) ;
else
StartQAV ( pPlayer , kQAVSGUNFIR4 , nClientFireTesla ) ;
}
else
{
if ( checkAmmo2 ( pPlayer , 7 , 10 ) & & powerupCheck ( pPlayer , kPwUpTwoGuns ) )
StartQAV ( pPlayer , kQAV2SGUNFIR , nClientFireTesla ) ;
else
StartQAV ( pPlayer , kQAVSGUNFIR1 , nClientFireTesla ) ;
}
return ;
case kWeapNapalm :
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) )
// by NoOne: allow napalm launcher alt fire act like in v1.0x versions
if ( gGameOptions . weaponsV10x & & ! VanillaMode ( ) ) StartQAV ( pPlayer , kQAV2NAPFIR2 , nClientFireNapalm2 ) ;
else StartQAV ( pPlayer , kQAV2NAPFIRE , nClientAltFireNapalm ) ;
else
StartQAV ( pPlayer , kQAVNAPFIRE , ( gGameOptions . weaponsV10x & & ! VanillaMode ( ) ) ? nClientFireNapalm : nClientAltFireNapalm ) ;
return ;
case kWeapFlareGun :
if ( CheckAmmo ( pPlayer , 1 , 8 ) )
{
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 1 , 16 ) )
StartQAV ( pPlayer , kQAVFLAR2FIR , nClientAltFireFlare ) ;
else
StartQAV ( pPlayer , kQAVFLARFIR2 , nClientAltFireFlare ) ;
}
else
{
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 1 , 2 ) )
StartQAV ( pPlayer , kQAVFLAR2FIR , nClientFireFlare ) ;
else
StartQAV ( pPlayer , kQAVFLARFIR2 , nClientFireFlare ) ;
}
return ;
case kWeapLifeLeech :
if ( gGameOptions . nGameType < = 1 & & ! checkAmmo2 ( pPlayer , 8 , 1 ) & & pPlayer - > actor - > xspr . health < ( 25 < < 4 ) )
{
sfxPlay3DSound ( pPlayer - > actor , 494 , 2 , 0 ) ;
StartQAV ( pPlayer , kQAVSTAFIRE4 , nClientFireLifeLeech ) ;
}
else
{
StartQAV ( pPlayer , kQAVSTAFDOWN ) ;
AltFireLifeLeech ( 1 , pPlayer ) ;
pPlayer - > weaponState = - 1 ;
}
return ;
}
}
WeaponUpdateState ( pPlayer ) ;
2019-09-19 22:42:45 +00:00
}
2021-12-29 21:56:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void teslaHit ( DBloodActor * missileactor , int a2 )
{
2022-08-22 16:20:16 +00:00
auto mpos = missileactor - > spr . pos ;
2021-12-29 21:56:21 +00:00
int nDist = 300 ;
2021-12-30 15:51:56 +00:00
auto pSector = missileactor - > sector ( ) ;
2021-12-29 21:56:21 +00:00
auto owneractor = missileactor - > GetOwner ( ) ;
const bool newSectCheckMethod = ! cl_bloodvanillaexplosions & & ! VanillaMode ( ) ; // use new sector checking logic
2022-08-22 16:20:16 +00:00
auto sectorMap = GetClosestSpriteSectors ( pSector , mpos . XY ( ) , nDist , nullptr , newSectCheckMethod ) ;
2021-12-29 21:56:21 +00:00
bool v4 = true ;
DBloodActor * actor = nullptr ;
actHitcodeToData ( a2 , & gHitInfo , & actor ) ;
if ( a2 = = 3 & & actor & & actor - > spr . statnum = = kStatDude )
v4 = false ;
BloodStatIterator it ( kStatDude ) ;
while ( auto hitactor = it . Next ( ) )
{
if ( hitactor ! = owneractor | | v4 )
{
if ( hitactor - > spr . flags & 32 )
continue ;
2022-08-22 16:23:36 +00:00
if ( CheckSector ( sectorMap , hitactor ) & & CheckProximity ( hitactor , mpos , pSector , nDist ) )
2021-12-29 21:56:21 +00:00
{
2022-01-30 17:09:26 +00:00
int dx = missileactor - > int_pos ( ) . X - hitactor - > int_pos ( ) . X ;
int dy = missileactor - > int_pos ( ) . Y - hitactor - > int_pos ( ) . Y ;
2021-12-29 21:56:21 +00:00
int nDamage = ClipLow ( ( nDist - ( ksqrt ( dx * dx + dy * dy ) > > 4 ) + 20 ) > > 1 , 10 ) ;
if ( hitactor = = owneractor )
nDamage / = 2 ;
actDamageSprite ( owneractor , hitactor , kDamageTesla , nDamage < < 4 ) ;
}
}
}
it . Reset ( kStatThing ) ;
while ( auto hitactor = it . Next ( ) )
{
if ( hitactor - > spr . flags & 32 )
continue ;
2022-08-22 16:23:36 +00:00
if ( CheckSector ( sectorMap , hitactor ) & & CheckProximity ( hitactor , mpos , pSector , nDist ) )
2021-12-29 21:56:21 +00:00
{
if ( ! hitactor - > xspr . locked )
{
2022-01-30 17:09:26 +00:00
int dx = missileactor - > int_pos ( ) . X - hitactor - > int_pos ( ) . X ;
int dy = missileactor - > int_pos ( ) . Y - hitactor - > int_pos ( ) . Y ;
2021-12-29 21:56:21 +00:00
int nDamage = ClipLow ( nDist - ( ksqrt ( dx * dx + dy * dy ) > > 4 ) + 20 , 20 ) ;
actDamageSprite ( owneractor , hitactor , kDamageTesla , nDamage < < 4 ) ;
}
}
}
2019-09-19 22:42:45 +00:00
}
2019-09-22 06:39:22 +00:00
END_BLD_NS