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 "compat.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
2019-09-19 22:42:45 +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 * ) ;
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
{
2020-11-17 08:03:10 +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 ,
} ;
2021-08-27 19:38:02 +00:00
bool checkFired6or7 ( PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > curWeapon )
2019-09-19 22:42:45 +00:00
{
2021-08-18 09:56:06 +00:00
case kWeapSpraycan :
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > weaponState )
2019-09-19 22:42:45 +00:00
{
case 5 :
case 6 :
return 1 ;
2021-08-12 09:19:07 +00:00
case 7 :
2021-08-21 10:16:48 +00:00
if ( VanillaMode ( ) )
2021-08-12 09:19:07 +00:00
return 0 ;
return 1 ;
2019-09-19 22:42:45 +00:00
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapDynamite :
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > weaponState )
2019-09-19 22:42:45 +00:00
{
case 4 :
case 5 :
case 6 :
return 1 ;
}
break ;
}
return 0 ;
}
2021-04-17 08:34:12 +00:00
static bool BannedUnderwater ( int nWeapon )
2019-09-19 22:42:45 +00:00
{
2021-08-18 09:57:31 +00:00
return nWeapon = = kWeapSpraycan | | nWeapon = = kWeapDynamite ;
2019-09-19 22:42:45 +00:00
}
2021-04-17 08:34:12 +00:00
static bool CheckWeaponAmmo ( PLAYER * pPlayer , int weapon , int ammotype , int count )
2019-09-19 22:42:45 +00:00
{
if ( gInfiniteAmmo )
return 1 ;
2020-11-21 18:30:00 +00:00
if ( ammotype = = - 1 )
2019-09-19 22:42:45 +00:00
return 1 ;
2021-08-18 09:57:31 +00:00
if ( weapon = = kWeapRemote & & pPlayer - > weaponAmmo = = 11 & & pPlayer - > weaponState = = 11 )
2019-09-19 22:42:45 +00:00
return 1 ;
2021-08-18 09:57:31 +00:00
if ( weapon = = kWeapLifeLeech & & pPlayer - > pXSprite - > health > 0 )
2019-09-19 22:42:45 +00:00
return 1 ;
2020-11-21 18:30:00 +00:00
return pPlayer - > ammoCount [ ammotype ] > = count ;
2019-09-19 22:42:45 +00:00
}
2021-04-17 08:34:12 +00:00
static bool CheckAmmo ( PLAYER * pPlayer , int ammotype , int count )
2019-09-19 22:42:45 +00:00
{
if ( gInfiniteAmmo )
return 1 ;
2020-11-21 18:30:00 +00:00
if ( ammotype = = - 1 )
2019-09-19 22:42:45 +00:00
return 1 ;
2021-08-18 09:56:06 +00:00
if ( pPlayer - > curWeapon = = kWeapRemote & & pPlayer - > weaponAmmo = = 11 & & pPlayer - > weaponState = = 11 )
2019-09-19 22:42:45 +00:00
return 1 ;
2021-08-18 09:56:06 +00:00
if ( pPlayer - > curWeapon = = kWeapLifeLeech & & pPlayer - > pXSprite - > health > = unsigned ( count < < 4 ) )
2019-09-19 22:42:45 +00:00
return 1 ;
2020-11-21 18:30:00 +00:00
return pPlayer - > ammoCount [ ammotype ] > = count ;
2019-09-19 22:42:45 +00:00
}
2021-04-17 08:34:12 +00:00
static bool checkAmmo2 ( PLAYER * pPlayer , int ammotype , int amount )
2019-09-19 22:42:45 +00:00
{
if ( gInfiniteAmmo )
return 1 ;
2020-11-21 18:30:00 +00:00
if ( ammotype = = - 1 )
2019-09-19 22:42:45 +00:00
return 1 ;
2020-11-21 18:30:00 +00:00
return pPlayer - > ammoCount [ ammotype ] > = amount ;
2019-09-19 22:42:45 +00:00
}
void SpawnBulletEject ( PLAYER * pPlayer , int a2 , int a3 )
{
2020-01-01 20:53:29 +00:00
POSTURE * pPosture = & pPlayer - > pPosture [ pPlayer - > lifeMode ] [ pPlayer - > posture ] ;
2019-10-21 19:46:41 +00:00
pPlayer - > zView = pPlayer - > pSprite - > z - pPosture - > eyeAboveZ ;
int dz = pPlayer - > zWeapon - ( pPlayer - > zWeapon - pPlayer - > zView ) / 2 ;
2019-10-26 07:08:45 +00:00
fxSpawnEjectingBrass ( pPlayer - > pSprite , dz , a2 , a3 ) ;
2019-09-19 22:42:45 +00:00
}
void SpawnShellEject ( PLAYER * pPlayer , int a2 , int a3 )
{
2020-01-01 20:53:29 +00:00
POSTURE * pPosture = & pPlayer - > pPosture [ pPlayer - > lifeMode ] [ pPlayer - > posture ] ;
2019-10-21 19:46:41 +00:00
pPlayer - > zView = pPlayer - > pSprite - > z - pPosture - > eyeAboveZ ;
int t = pPlayer - > zWeapon - pPlayer - > zView ;
int dz = pPlayer - > zWeapon - t + ( t > > 2 ) ;
2019-10-26 07:08:45 +00:00
fxSpawnEjectingShell ( pPlayer - > pSprite , dz , a2 , a3 ) ;
2019-09-19 22:42:45 +00:00
}
void WeaponInit ( void )
{
2021-08-28 06:41:51 +00:00
auto doInit = [ ] ( const int base )
2019-09-19 22:42:45 +00:00
{
2021-08-28 06:41:51 +00:00
for ( int i = base ; i < ( kQAVEnd + base ) ; i + + )
{
auto pQAV = getQAV ( i ) ;
if ( ! pQAV )
I_Error ( " Could not load QAV %d \n " , i ) ;
pQAV - > nSprite = - 1 ;
}
} ;
doInit ( 0 ) ;
doInit ( 10000 ) ;
2019-09-19 22:42:45 +00:00
}
2021-04-11 10:42:59 +00:00
void WeaponPrecache ( )
2020-01-02 11:01:18 +00:00
{
2021-08-28 06:41:51 +00:00
auto doPrecache = [ ] ( const int base )
2020-01-02 11:01:18 +00:00
{
2021-08-28 06:41:51 +00:00
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-08-05 02:38:26 +00:00
void WeaponDraw ( PLAYER * pPlayer , int shade , double xpos , double ypos , int palnum )
2019-09-19 22:42:45 +00:00
{
2020-10-11 10:38:17 +00:00
assert ( pPlayer ! = NULL ) ;
2021-08-03 10:34:08 +00:00
if ( pPlayer - > weaponQav = = kQAVNone )
2019-09-19 22:42:45 +00:00
return ;
2021-08-23 00:49:47 +00:00
auto pQAV = getQAV ( pPlayer - > weaponQav ) ;
2020-11-21 18:30:00 +00:00
int duration ;
2021-08-05 02:38:26 +00:00
double smoothratio ;
2020-11-22 19:09:09 +00:00
2021-08-27 12:18:57 +00:00
qavProcessTimer ( pPlayer , pQAV , & duration , & smoothratio , pPlayer - > weaponState = = - 1 , pPlayer - > curWeapon = = kWeapShotgun & & pPlayer - > weaponState = = 7 ) ;
2020-11-22 19:09:09 +00:00
2020-11-21 18:30:00 +00:00
pQAV - > x = int ( xpos ) ;
pQAV - > y = int ( ypos ) ;
2019-09-19 22:42:45 +00:00
int flags = 2 ;
2019-10-19 19:11:39 +00:00
int nInv = powerupCheck ( pPlayer , kPwUpShadowCloak ) ;
2021-02-18 10:46:36 +00:00
if ( nInv > = 120 * 8 | | ( nInv ! = 0 & & ( PlayClock & 32 ) ) )
2019-09-19 22:42:45 +00:00
{
2020-11-21 18:30:00 +00:00
shade = - 128 ;
2019-09-19 22:42:45 +00:00
flags | = 1 ;
}
2021-07-29 05:14:21 +00:00
pQAV - > Draw ( xpos , ypos , duration , flags , shade , palnum , true , smoothratio ) ;
2019-09-19 22:42:45 +00:00
}
void WeaponPlay ( PLAYER * pPlayer )
{
2020-10-11 10:38:17 +00:00
assert ( pPlayer ! = NULL ) ;
2021-08-03 10:34:08 +00:00
if ( pPlayer - > weaponQav = = kQAVNone )
2019-09-19 22:42:45 +00:00
return ;
2021-08-23 00:49:47 +00:00
auto pQAV = getQAV ( pPlayer - > weaponQav ) ;
2019-09-19 22:42:45 +00:00
pQAV - > nSprite = pPlayer - > pSprite - > index ;
2020-11-21 14:45:37 +00:00
int nTicks = pQAV - > duration - pPlayer - > weaponTimer ;
2019-10-21 19:46:41 +00:00
pQAV - > Play ( nTicks - 4 , nTicks , pPlayer - > qavCallback , pPlayer ) ;
2019-09-19 22:42:45 +00:00
}
2021-08-03 10:52:32 +00:00
static void StartQAV ( PLAYER * pPlayer , int nWeaponQAV , int callback = - 1 , bool looped = false )
2019-09-19 22:42:45 +00:00
{
2020-10-11 10:38:17 +00:00
assert ( nWeaponQAV < kQAVEnd ) ;
2021-08-23 00:55:00 +00:00
auto res_id = qavGetCorrectID ( nWeaponQAV ) ;
auto pQAV = getQAV ( res_id ) ;
pPlayer - > weaponQav = res_id ;
2021-08-23 00:49:47 +00:00
pPlayer - > weaponTimer = pQAV - > duration ;
2020-11-21 18:30:00 +00:00
pPlayer - > qavCallback = callback ;
pPlayer - > qavLoop = looped ;
2021-08-23 00:49:47 +00:00
pPlayer - > qavLastTick = I_GetTime ( pQAV - > ticrate ) ;
pPlayer - > qavTimer = pQAV - > duration ;
//pQAV->Preload();
2019-09-19 22:42:45 +00:00
WeaponPlay ( pPlayer ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponTimer - = 4 ;
2019-09-19 22:42:45 +00:00
}
2021-08-28 06:36:27 +00:00
static void SetQAV ( PLAYER * pPlayer , int nWeaponQAV )
{
assert ( nWeaponQAV < kQAVEnd ) ;
pPlayer - > weaponQav = qavGetCorrectID ( nWeaponQAV ) ;
pPlayer - > qavTimer = 0 ;
pPlayer - > qavLastTick = 0 ;
}
2019-09-19 22:42:45 +00:00
struct WEAPONTRACK
{
2020-11-21 17:14:24 +00:00
int aimSpeedHorz ;
int aimSpeedVert ;
int angleRange ;
int thingAngle ;
int seeker ;
2019-09-19 22:42:45 +00:00
bool bIsProjectile ;
} ;
WEAPONTRACK gWeaponTrack [ ] = {
{ 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 } ,
} ;
void UpdateAimVector ( PLAYER * pPlayer )
{
spritetype * pSprite ;
2020-10-11 10:38:17 +00:00
assert ( pPlayer ! = NULL ) ;
2019-09-19 22:42:45 +00:00
spritetype * pPSprite = pPlayer - > pSprite ;
int x = pPSprite - > x ;
int y = pPSprite - > y ;
2019-10-21 19:46:41 +00:00
int z = pPlayer - > zWeapon ;
2019-09-19 22:42:45 +00:00
Aim aim ;
2020-09-01 13:00:35 +00:00
aim . dx = CosScale16 ( pPSprite - > ang ) ;
aim . dy = SinScale16 ( pPSprite - > ang ) ;
2019-10-21 19:46:41 +00:00
aim . dz = pPlayer - > slope ;
WEAPONTRACK * pWeaponTrack = & gWeaponTrack [ pPlayer - > curWeapon ] ;
2019-09-19 22:42:45 +00:00
int nTarget = - 1 ;
2019-10-21 19:46:41 +00:00
pPlayer - > aimTargetsCount = 0 ;
2020-11-29 08:00:00 +00:00
int autoaim = Autoaim ( pPlayer - > nPlayer ) ;
2021-08-18 09:56:06 +00:00
if ( autoaim = = 1 | | ( autoaim = = 2 & & ! pWeaponTrack - > bIsProjectile ) | | pPlayer - > curWeapon = = kWeapVoodooDoll | | pPlayer - > curWeapon = = kWeapLifeLeech )
2019-09-19 22:42:45 +00:00
{
int nClosest = 0x7fffffff ;
2020-10-15 15:15:45 +00:00
int nSprite ;
StatIterator it ( kStatDude ) ;
while ( ( nSprite = it . NextIndex ( ) ) > = 0 )
2019-09-19 22:42:45 +00:00
{
pSprite = & sprite [ nSprite ] ;
if ( pSprite = = pPSprite )
continue ;
2019-09-22 16:17:06 +00:00
if ( ! gGameOptions . bFriendlyFire & & IsTargetTeammate ( pPlayer , pSprite ) )
continue ;
2019-09-30 07:18:01 +00:00
if ( pSprite - > flags & 32 )
2019-09-19 22:42:45 +00:00
continue ;
2019-09-30 07:18:01 +00:00
if ( ! ( pSprite - > flags & 8 ) )
2019-09-19 22:42:45 +00:00
continue ;
int x2 = pSprite - > x ;
int y2 = pSprite - > y ;
int z2 = pSprite - > z ;
int nDist = approxDist ( x2 - x , y2 - y ) ;
if ( nDist = = 0 | | nDist > 51200 )
continue ;
2020-11-21 17:14:24 +00:00
if ( pWeaponTrack - > seeker )
2019-09-19 22:42:45 +00:00
{
2021-01-04 11:59:00 +00:00
int t = DivScale ( nDist , pWeaponTrack - > seeker , 12 ) ;
2019-09-19 22:42:45 +00:00
x2 + = ( xvel [ nSprite ] * t ) > > 12 ;
y2 + = ( yvel [ nSprite ] * t ) > > 12 ;
z2 + = ( zvel [ nSprite ] * t ) > > 8 ;
}
2021-01-04 11:36:54 +00:00
int lx = x + MulScale ( Cos ( pPSprite - > ang ) , nDist , 30 ) ;
int ly = y + MulScale ( Sin ( pPSprite - > ang ) , nDist , 30 ) ;
2021-01-04 11:57:26 +00:00
int lz = z + MulScale ( pPlayer - > slope , nDist , 10 ) ;
int zRange = MulScale ( 9460 , nDist , 10 ) ;
2019-09-19 22:42:45 +00:00
int top , bottom ;
GetSpriteExtents ( pSprite , & top , & bottom ) ;
if ( lz - zRange > bottom | | lz + zRange < top )
continue ;
int angle = getangle ( x2 - x , y2 - y ) ;
2021-01-04 12:02:00 +00:00
if ( abs ( ( ( angle - pPSprite - > ang + 1024 ) & 2047 ) - 1024 ) > pWeaponTrack - > angleRange )
2019-09-19 22:42:45 +00:00
continue ;
2019-10-21 19:46:41 +00:00
if ( pPlayer - > aimTargetsCount < 16 & & cansee ( x , y , z , pPSprite - > sectnum , x2 , y2 , z2 , pSprite - > sectnum ) )
pPlayer - > aimTargets [ pPlayer - > aimTargetsCount + + ] = nSprite ;
2019-09-19 22:42:45 +00:00
// 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 ;
2020-02-05 21:17:05 +00:00
DUDEINFO * pDudeInfo = getDudeInfo ( pSprite - > type ) ;
2019-09-19 22:42:45 +00:00
int center = ( pSprite - > yrepeat * pDudeInfo - > aimHeight ) < < 2 ;
int dzCenter = ( z2 - center ) - z ;
if ( cansee ( x , y , z , pPSprite - > sectnum , x2 , y2 , z2 , pSprite - > sectnum ) )
{
nClosest = nDist2 ;
2020-09-01 13:00:35 +00:00
aim . dx = CosScale16 ( angle ) ;
aim . dy = SinScale16 ( angle ) ;
2021-01-04 11:59:00 +00:00
aim . dz = DivScale ( dzCenter , nDist , 10 ) ;
2019-09-19 22:42:45 +00:00
nTarget = nSprite ;
}
}
2020-11-21 17:14:24 +00:00
if ( pWeaponTrack - > thingAngle > 0 )
2019-09-19 22:42:45 +00:00
{
2020-10-15 15:15:45 +00:00
int nSprite ;
StatIterator it ( kStatThing ) ;
while ( ( nSprite = it . NextIndex ( ) ) > = 0 )
2019-09-19 22:42:45 +00:00
{
pSprite = & sprite [ nSprite ] ;
2019-09-22 16:17:06 +00:00
if ( ! gGameOptions . bFriendlyFire & & IsTargetTeammate ( pPlayer , pSprite ) )
continue ;
2019-09-30 07:18:01 +00:00
if ( ! ( pSprite - > flags & 8 ) )
2019-09-19 22:42:45 +00:00
continue ;
int x2 = pSprite - > x ;
int y2 = pSprite - > y ;
int z2 = pSprite - > z ;
int dx = x2 - x ;
int dy = y2 - y ;
int dz = z2 - z ;
int nDist = approxDist ( dx , dy ) ;
if ( nDist = = 0 | | nDist > 51200 )
continue ;
2021-01-04 11:36:54 +00:00
int lx = x + MulScale ( Cos ( pPSprite - > ang ) , nDist , 30 ) ;
int ly = y + MulScale ( Sin ( pPSprite - > ang ) , nDist , 30 ) ;
2021-01-04 11:57:26 +00:00
int lz = z + MulScale ( pPlayer - > slope , nDist , 10 ) ;
2021-01-04 11:36:54 +00:00
int zRange = MulScale ( 9460 , nDist , 10 ) ;
2019-09-19 22:42:45 +00:00
int top , bottom ;
GetSpriteExtents ( pSprite , & top , & bottom ) ;
if ( lz - zRange > bottom | | lz + zRange < top )
continue ;
int angle = getangle ( dx , dy ) ;
2021-01-04 12:02:00 +00:00
if ( abs ( ( ( angle - pPSprite - > ang + 1024 ) & 2047 ) - 1024 ) > pWeaponTrack - > thingAngle )
2019-09-19 22:42:45 +00:00
continue ;
2019-10-21 19:46:41 +00:00
if ( pPlayer - > aimTargetsCount < 16 & & cansee ( x , y , z , pPSprite - > sectnum , pSprite - > x , pSprite - > y , pSprite - > z , pSprite - > sectnum ) )
pPlayer - > aimTargets [ pPlayer - > aimTargetsCount + + ] = nSprite ;
2019-09-19 22:42:45 +00:00
// 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 ;
if ( cansee ( x , y , z , pPSprite - > sectnum , pSprite - > x , pSprite - > y , pSprite - > z , pSprite - > sectnum ) )
{
nClosest = nDist2 ;
2020-09-01 13:00:35 +00:00
aim . dx = CosScale16 ( angle ) ;
aim . dy = SinScale16 ( angle ) ;
2021-01-04 11:59:00 +00:00
aim . dz = DivScale ( dz , nDist , 10 ) ;
2019-09-19 22:42:45 +00:00
nTarget = nSprite ;
}
}
}
}
Aim aim2 ;
aim2 = aim ;
RotateVector ( ( int * ) & aim2 . dx , ( int * ) & aim2 . dy , - pPSprite - > ang ) ;
2019-10-21 19:46:41 +00:00
aim2 . dz - = pPlayer - > slope ;
2021-04-11 06:45:19 +00:00
pPlayer - > relAim . dx = interpolatedvalue ( pPlayer - > relAim . dx , aim2 . dx , pWeaponTrack - > aimSpeedHorz ) ;
pPlayer - > relAim . dy = interpolatedvalue ( pPlayer - > relAim . dy , aim2 . dy , pWeaponTrack - > aimSpeedHorz ) ;
pPlayer - > relAim . dz = interpolatedvalue ( pPlayer - > relAim . dz , aim2 . dz , pWeaponTrack - > aimSpeedVert ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > aim = pPlayer - > relAim ;
RotateVector ( ( int * ) & pPlayer - > aim . dx , ( int * ) & pPlayer - > aim . dy , pPSprite - > ang ) ;
pPlayer - > aim . dz + = pPlayer - > slope ;
pPlayer - > aimTarget = nTarget ;
2019-09-19 22:42:45 +00:00
}
struct t_WeaponModes
{
2020-11-21 18:30:00 +00:00
int update ;
int ammoType ;
2019-09-19 22:42:45 +00:00
} ;
t_WeaponModes weaponModes [ ] = {
{ 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 } ,
} ;
void WeaponRaise ( PLAYER * pPlayer )
{
2020-10-11 10:38:17 +00:00
assert ( pPlayer ! = NULL ) ;
2019-10-21 19:46:41 +00:00
int prevWeapon = pPlayer - > curWeapon ;
2020-08-26 14:48:33 +00:00
pPlayer - > curWeapon = pPlayer - > newWeapon ;
2021-08-03 10:23:39 +00:00
pPlayer - > newWeapon = kWeapNone ;
2020-11-21 18:30:00 +00:00
pPlayer - > weaponAmmo = weaponModes [ pPlayer - > curWeapon ] . ammoType ;
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > curWeapon )
2019-09-19 22:42:45 +00:00
{
2021-08-18 09:56:06 +00:00
case kWeapPitchFork :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 0 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVFORKUP ) ;
2019-09-19 22:42:45 +00:00
break ;
2021-08-18 09:56:06 +00:00
case kWeapSpraycan :
2019-10-21 19:46:41 +00:00
if ( pPlayer - > weaponState = = 2 )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 3 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVCANPREF ) ;
2019-09-19 22:42:45 +00:00
}
else
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 0 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVLITEOPEN ) ;
2019-09-19 22:42:45 +00:00
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapDynamite :
2020-11-21 17:14:24 +00:00
if ( gInfiniteAmmo | | checkAmmo2 ( pPlayer , 5 , 1 ) )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 3 ;
2021-08-18 09:57:31 +00:00
if ( prevWeapon = = kWeapSpraycan )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVBUNUP ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVBUNUP2 ) ;
2019-09-19 22:42:45 +00:00
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapProximity :
2020-11-21 17:14:24 +00:00
if ( gInfiniteAmmo | | checkAmmo2 ( pPlayer , 10 , 1 ) )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 7 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVPROXUP ) ;
2019-09-19 22:42:45 +00:00
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapRemote :
2020-11-21 17:14:24 +00:00
if ( gInfiniteAmmo | | checkAmmo2 ( pPlayer , 11 , 1 ) )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 10 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVREMUP2 ) ;
2019-09-19 22:42:45 +00:00
}
else
{
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVREMUP3 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 11 ;
2019-09-19 22:42:45 +00:00
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapShotgun :
2019-10-19 19:11:39 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) )
2019-09-19 22:42:45 +00:00
{
2019-10-25 20:53:41 +00:00
if ( gInfiniteAmmo | | pPlayer - > ammoCount [ 2 ] > = 4 )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2SHOTUP ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSHOTUP ) ;
2019-10-25 20:53:41 +00:00
if ( gInfiniteAmmo | | pPlayer - > ammoCount [ 2 ] > = 4 )
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 7 ;
2019-10-25 20:53:41 +00:00
else if ( pPlayer - > ammoCount [ 2 ] > 1 )
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 3 ;
2019-10-25 20:53:41 +00:00
else if ( pPlayer - > ammoCount [ 2 ] > 0 )
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 2 ;
2019-09-19 22:42:45 +00:00
else
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 1 ;
2019-09-19 22:42:45 +00:00
}
else
{
2019-10-25 20:53:41 +00:00
if ( gInfiniteAmmo | | pPlayer - > ammoCount [ 2 ] > 1 )
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 3 ;
2019-10-25 20:53:41 +00:00
else if ( pPlayer - > ammoCount [ 2 ] > 0 )
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 2 ;
2019-09-19 22:42:45 +00:00
else
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 1 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSHOTUP ) ;
2019-09-19 22:42:45 +00:00
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapTommyGun :
2020-11-21 17:14:24 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 3 , 2 ) )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 1 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2TOMUP ) ;
2019-09-19 22:42:45 +00:00
}
else
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 0 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVTOMUP ) ;
2019-09-19 22:42:45 +00:00
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapVoodooDoll :
2020-11-21 17:14:24 +00:00
if ( gInfiniteAmmo | | checkAmmo2 ( pPlayer , 9 , 1 ) )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 2 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVVDUP ) ;
2019-09-19 22:42:45 +00:00
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapFlareGun :
2020-11-21 17:14:24 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 1 , 2 ) )
2019-09-19 22:42:45 +00:00
{
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVFLAR2UP ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 3 ;
2019-09-19 22:42:45 +00:00
}
else
{
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVFLARUP ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 2 ;
2019-09-19 22:42:45 +00:00
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapTeslaCannon :
2020-11-21 17:14:24 +00:00
if ( checkAmmo2 ( pPlayer , 7 , 1 ) )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 2 ;
2019-10-19 19:11:39 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2SGUNUP ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSGUNUP ) ;
2019-09-19 22:42:45 +00:00
}
else
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 3 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSGUNUP ) ;
2019-09-19 22:42:45 +00:00
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapNapalm :
2019-10-19 19:11:39 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) )
2019-09-19 22:42:45 +00:00
{
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2NAPUP ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 3 ;
2019-09-19 22:42:45 +00:00
}
else
{
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVNAPUP ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 2 ;
2019-09-19 22:42:45 +00:00
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapLifeLeech :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 2 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSTAFUP ) ;
2019-09-19 22:42:45 +00:00
break ;
2021-08-18 09:56:06 +00:00
case kWeapBeast :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 2 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVBSTUP ) ;
2019-09-19 22:42:45 +00:00
break ;
}
}
void WeaponLower ( PLAYER * pPlayer )
{
2020-10-11 10:38:17 +00:00
assert ( pPlayer ! = NULL ) ;
2021-08-12 09:19:07 +00:00
if ( checkFired6or7 ( pPlayer ) )
2019-09-19 22:42:45 +00:00
return ;
2019-10-21 19:46:41 +00:00
pPlayer - > throwPower = 0 ;
int prevState = pPlayer - > weaponState ;
switch ( pPlayer - > curWeapon )
2019-09-19 22:42:45 +00:00
{
2021-08-18 09:56:06 +00:00
case kWeapPitchFork :
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVFORKDOWN ) ;
2019-09-19 22:42:45 +00:00
break ;
2021-08-18 09:56:06 +00:00
case kWeapSpraycan :
2019-09-19 22:42:45 +00:00
sfxKill3DSound ( pPlayer - > pSprite , - 1 , 441 ) ;
switch ( prevState )
{
case 1 :
2021-03-09 08:30:27 +00:00
if ( VanillaMode ( ) )
{
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVLITECLO2 ) ;
2021-03-09 08:30:27 +00:00
}
else
{
2021-08-23 01:02:09 +00:00
if ( pPlayer - > newWeapon = = kWeapDynamite ) // do not put away lighter if TNT was selected while throwing a spray can
2021-03-09 08:30:27 +00:00
{
pPlayer - > weaponState = 2 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVCANDOWN ) ;
2021-03-09 08:30:27 +00:00
WeaponRaise ( pPlayer ) ;
return ;
}
}
2019-09-19 22:42:45 +00:00
break ;
case 2 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 1 ;
2019-09-19 22:42:45 +00:00
WeaponRaise ( pPlayer ) ;
return ;
case 4 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 1 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVCANDOWN ) ;
2021-03-09 08:30:27 +00:00
if ( VanillaMode ( ) )
{
2021-08-03 10:23:39 +00:00
pPlayer - > newWeapon = kWeapNone ;
2021-03-09 08:30:27 +00:00
WeaponLower ( pPlayer ) ;
}
else
{
2021-08-03 10:23:39 +00:00
if ( pPlayer - > newWeapon = = kWeapDynamite )
2021-03-09 08:30:27 +00:00
{
pPlayer - > weaponState = 2 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVCANDOWN ) ;
2021-03-09 08:30:27 +00:00
return ;
}
else
{
WeaponLower ( pPlayer ) ;
}
}
2019-09-19 22:42:45 +00:00
break ;
case 3 :
2021-08-03 10:23:39 +00:00
if ( pPlayer - > newWeapon = = kWeapDynamite )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 2 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVCANDOWN ) ;
2019-09-19 22:42:45 +00:00
return ;
}
2021-08-03 10:23:39 +00:00
else if ( pPlayer - > newWeapon = = kWeapSpraycan )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 1 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVCANDOWN ) ;
2021-08-03 10:23:39 +00:00
pPlayer - > newWeapon = kWeapNone ;
2019-09-19 22:42:45 +00:00
WeaponLower ( pPlayer ) ;
}
else
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 1 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVCANDOWN ) ;
2019-09-19 22:42:45 +00:00
}
break ;
2021-08-12 09:19:07 +00:00
case 7 : // throwing ignited alt fire spray
2021-08-21 10:16:48 +00:00
if ( VanillaMode ( ) | | ( pPlayer - > newWeapon ! = 0 ) )
2021-08-12 09:19:07 +00:00
break ;
pPlayer - > weaponState = 1 ;
StartQAV ( pPlayer , 11 , - 1 , 0 ) ;
break ;
2019-09-19 22:42:45 +00:00
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapDynamite :
2019-09-19 22:42:45 +00:00
switch ( prevState )
{
case 1 :
2021-08-23 01:02:09 +00:00
if ( ! VanillaMode ( ) & & ( pPlayer - > newWeapon = = kWeapSpraycan ) ) // do not put away lighter after TNT is thrown if while throwing the weapon was switched already to spray
2021-03-09 08:30:27 +00:00
{
2021-08-12 09:19:07 +00:00
pPlayer - > weaponState = 2 ;
2021-08-23 01:02:09 +00:00
StartQAV ( pPlayer , kQAVBUNDOWN ) ;
2021-08-12 09:19:07 +00:00
WeaponRaise ( pPlayer ) ;
return ;
2021-03-09 08:30:27 +00:00
}
2021-08-23 01:02:09 +00:00
StartQAV ( pPlayer , kQAVLITECLO2 ) ;
2019-09-19 22:42:45 +00:00
break ;
case 2 :
WeaponRaise ( pPlayer ) ;
break ;
case 3 :
2021-08-03 10:23:39 +00:00
if ( pPlayer - > newWeapon = = kWeapSpraycan )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 2 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVBUNDOWN ) ;
2019-09-19 22:42:45 +00:00
}
else
{
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVBUNDOWN2 ) ;
2019-09-19 22:42:45 +00:00
}
break ;
default :
break ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapProximity :
2019-09-19 22:42:45 +00:00
switch ( prevState )
{
case 7 :
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVPROXDOWN ) ;
2019-09-19 22:42:45 +00:00
break ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapRemote :
2019-09-19 22:42:45 +00:00
switch ( prevState )
{
case 10 :
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVREMDOWN2 ) ;
2019-09-19 22:42:45 +00:00
break ;
case 11 :
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVREMDOWN3 ) ;
2019-09-19 22:42:45 +00:00
break ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapShotgun :
2019-10-19 19:11:39 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2SHOTDWN ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSHOTDOWN ) ;
2019-09-19 22:42:45 +00:00
break ;
2021-08-18 09:56:06 +00:00
case kWeapTommyGun :
2019-10-21 19:46:41 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & pPlayer - > weaponState = = 1 )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2TOMDOWN ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVTOMDOWN ) ;
2019-09-19 22:42:45 +00:00
break ;
2021-08-18 09:56:06 +00:00
case kWeapFlareGun :
2019-10-21 19:46:41 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & pPlayer - > weaponState = = 3 )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVFLAR2DWN ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVFLARDOWN ) ;
2019-09-19 22:42:45 +00:00
break ;
2021-08-18 09:56:06 +00:00
case kWeapVoodooDoll :
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVVDDOWN ) ;
2019-09-19 22:42:45 +00:00
break ;
2021-08-18 09:56:06 +00:00
case kWeapTeslaCannon :
2020-11-21 17:14:24 +00:00
if ( checkAmmo2 ( pPlayer , 7 , 10 ) & & powerupCheck ( pPlayer , kPwUpTwoGuns ) )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2SGUNDWN ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSGUNDOWN ) ;
2019-09-19 22:42:45 +00:00
break ;
2021-08-18 09:56:06 +00:00
case kWeapNapalm :
2019-10-19 19:11:39 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2NAPDOWN ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVNAPDOWN ) ;
2019-09-19 22:42:45 +00:00
break ;
2021-08-18 09:56:06 +00:00
case kWeapLifeLeech :
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSTAFDOWN ) ;
2019-09-19 22:42:45 +00:00
break ;
2021-08-18 09:56:06 +00:00
case kWeapBeast :
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVBSTDOWN ) ;
2019-09-19 22:42:45 +00:00
break ;
}
2021-08-18 09:56:06 +00:00
pPlayer - > curWeapon = kWeapNone ;
2019-10-21 19:46:41 +00:00
pPlayer - > qavLoop = 0 ;
2019-09-19 22:42:45 +00:00
}
void WeaponUpdateState ( PLAYER * pPlayer )
{
static int lastWeapon = 0 ;
static int lastState = 0 ;
XSPRITE * pXSprite = pPlayer - > pXSprite ;
2019-10-21 19:46:41 +00:00
int va = pPlayer - > curWeapon ;
int vb = pPlayer - > weaponState ;
2019-09-19 22:42:45 +00:00
if ( va ! = lastWeapon | | vb ! = lastState )
{
lastWeapon = va ;
lastState = vb ;
}
switch ( lastWeapon )
{
2021-08-18 09:56:06 +00:00
case kWeapPitchFork :
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVFORKIDLE ) ;
2019-09-19 22:42:45 +00:00
break ;
2021-08-18 09:56:06 +00:00
case kWeapSpraycan :
2019-09-19 22:42:45 +00:00
switch ( vb )
{
case 0 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 1 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVLITEFLAM ) ;
2019-09-19 22:42:45 +00:00
break ;
case 1 :
if ( CheckAmmo ( pPlayer , 6 , 1 ) )
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 3 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVCANPREF ) ;
2019-09-19 22:42:45 +00:00
}
else
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVLITEIDLE ) ;
2019-09-19 22:42:45 +00:00
break ;
case 3 :
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVCANIDLE ) ;
2019-09-19 22:42:45 +00:00
break ;
case 4 :
if ( CheckAmmo ( pPlayer , 6 , 1 ) )
{
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVCANIDLE ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 3 ;
2019-09-19 22:42:45 +00:00
}
else
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 1 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVCANDOWN ) ;
2019-09-19 22:42:45 +00:00
}
sfxKill3DSound ( pPlayer - > pSprite , - 1 , 441 ) ;
break ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapDynamite :
2019-09-19 22:42:45 +00:00
switch ( vb )
{
case 1 :
2019-10-21 19:46:41 +00:00
if ( pPlayer - > weaponAmmo = = 5 & & CheckAmmo ( pPlayer , 5 , 1 ) )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 3 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVBUNUP ) ;
2019-09-19 22:42:45 +00:00
}
break ;
case 0 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 1 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVLITEFLAM ) ;
2019-09-19 22:42:45 +00:00
break ;
case 2 :
2019-10-25 20:53:41 +00:00
if ( pPlayer - > ammoCount [ 5 ] > 0 )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 3 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVBUNUP ) ;
2019-09-19 22:42:45 +00:00
}
else
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVLITEIDLE ) ;
2019-09-19 22:42:45 +00:00
break ;
case 3 :
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVBUNIDLE ) ;
2019-09-19 22:42:45 +00:00
break ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapProximity :
2019-09-19 22:42:45 +00:00
switch ( vb )
{
case 7 :
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVPROXIDLE ) ;
2019-09-19 22:42:45 +00:00
break ;
case 8 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 7 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVPROXUP ) ;
2019-09-19 22:42:45 +00:00
break ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapRemote :
2019-09-19 22:42:45 +00:00
switch ( vb )
{
case 10 :
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVREMIDLE1 ) ;
2019-09-19 22:42:45 +00:00
break ;
case 11 :
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVREMIDLE2 ) ;
2019-09-19 22:42:45 +00:00
break ;
case 12 :
2019-10-25 20:53:41 +00:00
if ( pPlayer - > ammoCount [ 11 ] > 0 )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 10 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVREMUP2 ) ;
2019-09-19 22:42:45 +00:00
}
else
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = - 1 ;
2019-09-19 22:42:45 +00:00
break ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapShotgun :
2019-09-19 22:42:45 +00:00
switch ( vb )
{
case 6 :
2019-10-19 19:11:39 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & ( gInfiniteAmmo | | CheckAmmo ( pPlayer , 2 , 4 ) ) )
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 7 ;
2019-09-19 22:42:45 +00:00
else
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 1 ;
2019-09-19 22:42:45 +00:00
break ;
case 7 :
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAV2SHOTI ) ;
2019-09-19 22:42:45 +00:00
break ;
case 1 :
if ( CheckAmmo ( pPlayer , 2 , 1 ) )
{
sfxPlay3DSound ( pPlayer - > pSprite , 410 , 3 , 2 ) ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSHOTL1 , nClientEjectShell ) ;
2019-10-25 20:53:41 +00:00
if ( gInfiniteAmmo | | pPlayer - > ammoCount [ 2 ] > 1 )
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 3 ;
2019-09-19 22:42:45 +00:00
else
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 2 ;
2019-09-19 22:42:45 +00:00
}
else
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVSHOTI3 ) ;
2019-09-19 22:42:45 +00:00
break ;
case 2 :
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVSHOTI2 ) ;
2019-09-19 22:42:45 +00:00
break ;
case 3 :
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVSHOTI1 ) ;
2019-09-19 22:42:45 +00:00
break ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapTommyGun :
2020-11-21 17:14:24 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 3 , 2 ) )
2019-09-19 22:42:45 +00:00
{
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAV2TOMIDLE ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 1 ;
2019-09-19 22:42:45 +00:00
}
else
{
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVTOMIDLE ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 0 ;
2019-09-19 22:42:45 +00:00
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapFlareGun :
2019-10-19 19:11:39 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) )
2019-09-19 22:42:45 +00:00
{
2020-11-21 17:14:24 +00:00
if ( vb = = 3 & & checkAmmo2 ( pPlayer , 1 , 2 ) )
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVFLAR2I ) ;
2019-09-19 22:42:45 +00:00
else
{
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVFLARIDLE ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 2 ;
2019-09-19 22:42:45 +00:00
}
}
else
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVFLARIDLE ) ;
2019-09-19 22:42:45 +00:00
break ;
2021-08-18 09:56:06 +00:00
case kWeapVoodooDoll :
2021-08-13 05:18:02 +00:00
if ( pXSprite - > height < 256 & & pPlayer - > swayHeight ! = 0 )
StartQAV ( pPlayer , kQAVVDIDLE2 ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVVDIDLE1 ) ;
2019-09-19 22:42:45 +00:00
break ;
2021-08-18 09:56:06 +00:00
case kWeapTeslaCannon :
2019-09-19 22:42:45 +00:00
switch ( vb )
{
case 2 :
2020-11-21 17:14:24 +00:00
if ( checkAmmo2 ( pPlayer , 7 , 10 ) & & powerupCheck ( pPlayer , kPwUpTwoGuns ) )
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAV2SGUNIDL ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVSGUNIDL1 ) ;
2019-09-19 22:42:45 +00:00
break ;
case 3 :
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVSGUNIDL2 ) ;
2019-09-19 22:42:45 +00:00
break ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapNapalm :
2019-09-19 22:42:45 +00:00
switch ( vb )
{
case 3 :
2019-10-19 19:11:39 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & ( gInfiniteAmmo | | CheckAmmo ( pPlayer , 4 , 4 ) ) )
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAV2NAPIDLE ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVNAPIDLE ) ;
2019-09-19 22:42:45 +00:00
break ;
case 2 :
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVNAPIDLE ) ;
2019-09-19 22:42:45 +00:00
break ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapLifeLeech :
2019-09-19 22:42:45 +00:00
switch ( vb )
{
case 2 :
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVSTAFIDL1 ) ;
2019-09-19 22:42:45 +00:00
break ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapBeast :
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVBSTIDLE ) ;
2019-09-19 22:42:45 +00:00
break ;
}
}
void FirePitchfork ( int , PLAYER * pPlayer )
{
2021-08-30 18:28:24 +00:00
auto actor = & bloodActors [ pPlayer - > pSprite - > index ] ;
2019-10-21 19:46:41 +00:00
Aim * aim = & pPlayer - > aim ;
2019-09-19 22:42:45 +00:00
int r1 = Random2 ( 2000 ) ;
int r2 = Random2 ( 2000 ) ;
int r3 = Random2 ( 2000 ) ;
for ( int i = 0 ; i < 4 ; i + + )
2021-08-30 18:28:24 +00:00
actFireVector ( actor , ( 2 * i - 3 ) * 40 , pPlayer - > zWeapon - pPlayer - > pSprite - > z , aim - > dx + r1 , aim - > dy + r2 , aim - > dz + r3 , kVectorTine ) ;
2019-09-19 22:42:45 +00:00
}
void FireSpray ( int , PLAYER * pPlayer )
{
2019-10-21 19:46:41 +00:00
playerFireMissile ( pPlayer , 0 , pPlayer - > aim . dx , pPlayer - > aim . dy , pPlayer - > aim . dz , kMissileFlameSpray ) ;
2019-09-19 22:42:45 +00:00
UseAmmo ( pPlayer , 6 , 4 ) ;
if ( CheckAmmo ( pPlayer , 6 , 1 ) )
sfxPlay3DSound ( pPlayer - > pSprite , 441 , 1 , 2 ) ;
else
sfxKill3DSound ( pPlayer - > pSprite , - 1 , 441 ) ;
}
void ThrowCan ( int , PLAYER * pPlayer )
{
sfxKill3DSound ( pPlayer - > pSprite , - 1 , 441 ) ;
2021-01-04 11:36:54 +00:00
int nSpeed = MulScale ( pPlayer - > throwPower , 0x177777 , 16 ) + 0x66666 ;
2019-09-19 22:42:45 +00:00
sfxPlay3DSound ( pPlayer - > pSprite , 455 , 1 , 0 ) ;
2019-10-11 21:59:39 +00:00
spritetype * pSprite = playerFireThing ( pPlayer , 0 , - 9460 , kThingArmedSpray , nSpeed ) ;
2019-09-19 22:42:45 +00:00
if ( pSprite )
{
sfxPlay3DSound ( pSprite , 441 , 0 , 0 ) ;
2020-01-11 21:07:05 +00:00
evPost ( pSprite - > index , 3 , pPlayer - > fuseTime , kCmdOn ) ;
2019-09-19 22:42:45 +00:00
int nXSprite = pSprite - > extra ;
XSPRITE * pXSprite = & xsprite [ nXSprite ] ;
pXSprite - > Impact = 1 ;
2019-10-21 19:46:41 +00:00
UseAmmo ( pPlayer , 6 , gAmmoItemData [ 0 ] . count ) ;
pPlayer - > throwPower = 0 ;
2019-09-19 22:42:45 +00:00
}
}
void DropCan ( int , PLAYER * pPlayer )
{
sfxKill3DSound ( pPlayer - > pSprite , - 1 , 441 ) ;
2019-10-11 21:59:39 +00:00
spritetype * pSprite = playerFireThing ( pPlayer , 0 , 0 , kThingArmedSpray , 0 ) ;
2019-09-19 22:42:45 +00:00
if ( pSprite )
{
2020-01-11 21:07:05 +00:00
evPost ( pSprite - > index , 3 , pPlayer - > fuseTime , kCmdOn ) ;
2019-10-21 19:46:41 +00:00
UseAmmo ( pPlayer , 6 , gAmmoItemData [ 0 ] . count ) ;
2019-09-19 22:42:45 +00:00
}
}
void ExplodeCan ( int , PLAYER * pPlayer )
{
sfxKill3DSound ( pPlayer - > pSprite , - 1 , 441 ) ;
2019-10-11 21:59:39 +00:00
spritetype * pSprite = playerFireThing ( pPlayer , 0 , 0 , kThingArmedSpray , 0 ) ;
2020-01-11 21:07:05 +00:00
evPost ( pSprite - > index , 3 , 0 , kCmdOn ) ;
2019-10-21 19:46:41 +00:00
UseAmmo ( pPlayer , 6 , gAmmoItemData [ 0 ] . count ) ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVCANBOOM ) ;
2021-08-18 09:56:06 +00:00
pPlayer - > curWeapon = kWeapNone ;
2019-10-21 19:46:41 +00:00
pPlayer - > throwPower = 0 ;
2019-09-19 22:42:45 +00:00
}
void ThrowBundle ( int , PLAYER * pPlayer )
{
sfxKill3DSound ( pPlayer - > pSprite , 16 , - 1 ) ;
2021-01-04 11:36:54 +00:00
int nSpeed = MulScale ( pPlayer - > throwPower , 0x177777 , 16 ) + 0x66666 ;
2019-09-19 22:42:45 +00:00
sfxPlay3DSound ( pPlayer - > pSprite , 455 , 1 , 0 ) ;
2019-10-11 21:59:39 +00:00
spritetype * pSprite = playerFireThing ( pPlayer , 0 , - 9460 , kThingArmedTNTBundle , nSpeed ) ;
2019-09-19 22:42:45 +00:00
int nXSprite = pSprite - > extra ;
XSPRITE * pXSprite = & xsprite [ nXSprite ] ;
2019-10-21 19:46:41 +00:00
if ( pPlayer - > fuseTime < 0 )
2019-09-19 22:42:45 +00:00
pXSprite - > Impact = 1 ;
else
2020-01-11 21:07:05 +00:00
evPost ( pSprite - > index , 3 , pPlayer - > fuseTime , kCmdOn ) ;
2019-09-19 22:42:45 +00:00
UseAmmo ( pPlayer , 5 , 1 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > throwPower = 0 ;
2019-09-19 22:42:45 +00:00
}
void DropBundle ( int , PLAYER * pPlayer )
{
sfxKill3DSound ( pPlayer - > pSprite , 16 , - 1 ) ;
2019-10-11 21:59:39 +00:00
spritetype * pSprite = playerFireThing ( pPlayer , 0 , 0 , kThingArmedTNTBundle , 0 ) ;
2020-01-11 21:07:05 +00:00
evPost ( pSprite - > index , 3 , pPlayer - > fuseTime , kCmdOn ) ;
2019-09-19 22:42:45 +00:00
UseAmmo ( pPlayer , 5 , 1 ) ;
}
void ExplodeBundle ( int , PLAYER * pPlayer )
{
sfxKill3DSound ( pPlayer - > pSprite , 16 , - 1 ) ;
2019-10-11 21:59:39 +00:00
spritetype * pSprite = playerFireThing ( pPlayer , 0 , 0 , kThingArmedTNTBundle , 0 ) ;
2020-01-11 21:07:05 +00:00
evPost ( pSprite - > index , 3 , 0 , kCmdOn ) ;
2019-09-19 22:42:45 +00:00
UseAmmo ( pPlayer , 5 , 1 ) ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVDYNEXPLO ) ;
2021-08-18 09:56:06 +00:00
pPlayer - > curWeapon = kWeapNone ;
2019-10-21 19:46:41 +00:00
pPlayer - > throwPower = 0 ;
2019-09-19 22:42:45 +00:00
}
void ThrowProx ( int , PLAYER * pPlayer )
{
2021-01-04 11:36:54 +00:00
int nSpeed = MulScale ( pPlayer - > throwPower , 0x177777 , 16 ) + 0x66666 ;
2019-09-19 22:42:45 +00:00
sfxPlay3DSound ( pPlayer - > pSprite , 455 , 1 , 0 ) ;
2019-10-11 21:59:39 +00:00
spritetype * pSprite = playerFireThing ( pPlayer , 0 , - 9460 , kThingArmedProxBomb , nSpeed ) ;
2020-01-11 21:07:05 +00:00
evPost ( pSprite - > index , 3 , 240 , kCmdOn ) ;
2019-09-19 22:42:45 +00:00
UseAmmo ( pPlayer , 10 , 1 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > throwPower = 0 ;
2019-09-19 22:42:45 +00:00
}
void DropProx ( int , PLAYER * pPlayer )
{
2019-10-11 21:59:39 +00:00
spritetype * pSprite = playerFireThing ( pPlayer , 0 , 0 , kThingArmedProxBomb , 0 ) ;
2020-01-11 21:07:05 +00:00
evPost ( pSprite - > index , 3 , 240 , kCmdOn ) ;
2019-09-19 22:42:45 +00:00
UseAmmo ( pPlayer , 10 , 1 ) ;
}
void ThrowRemote ( int , PLAYER * pPlayer )
{
2021-01-04 11:36:54 +00:00
int nSpeed = MulScale ( pPlayer - > throwPower , 0x177777 , 16 ) + 0x66666 ;
2019-09-19 22:42:45 +00:00
sfxPlay3DSound ( pPlayer - > pSprite , 455 , 1 , 0 ) ;
2019-10-11 21:59:39 +00:00
spritetype * pSprite = playerFireThing ( pPlayer , 0 , - 9460 , kThingArmedRemoteBomb , nSpeed ) ;
2019-09-19 22:42:45 +00:00
int nXSprite = pSprite - > extra ;
XSPRITE * pXSprite = & xsprite [ nXSprite ] ;
pXSprite - > rxID = 90 + ( pPlayer - > pSprite - > type - kDudePlayer1 ) ;
UseAmmo ( pPlayer , 11 , 1 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > throwPower = 0 ;
2019-09-19 22:42:45 +00:00
}
void DropRemote ( int , PLAYER * pPlayer )
{
2019-10-11 21:59:39 +00:00
spritetype * pSprite = playerFireThing ( pPlayer , 0 , 0 , kThingArmedRemoteBomb , 0 ) ;
2019-09-19 22:42:45 +00:00
int nXSprite = pSprite - > extra ;
XSPRITE * pXSprite = & xsprite [ nXSprite ] ;
pXSprite - > rxID = 90 + ( pPlayer - > pSprite - > type - kDudePlayer1 ) ;
UseAmmo ( pPlayer , 11 , 1 ) ;
}
void FireRemote ( int , PLAYER * pPlayer )
{
2020-01-11 21:07:05 +00:00
evSend ( 0 , 0 , 90 + ( pPlayer - > pSprite - > type - kDudePlayer1 ) , kCmdOn ) ;
2019-09-19 22:42:45 +00:00
}
2020-10-11 10:18:25 +00:00
enum { kMaxShotgunBarrels = 4 } ;
2019-09-19 22:42:45 +00:00
void FireShotgun ( int nTrigger , PLAYER * pPlayer )
{
2021-08-30 18:28:24 +00:00
auto actor = & bloodActors [ pPlayer - > pSprite - > index ] ;
2020-10-11 10:38:17 +00:00
assert ( nTrigger > 0 & & nTrigger < = kMaxShotgunBarrels ) ;
2019-09-19 22:42:45 +00:00
if ( nTrigger = = 1 )
{
sfxPlay3DSound ( pPlayer - > pSprite , 411 , 2 , 0 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > tiltEffect = 30 ;
pPlayer - > visibility = 20 ;
2019-09-19 22:42:45 +00:00
}
else
{
sfxPlay3DSound ( pPlayer - > pSprite , 412 , 2 , 0 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > tiltEffect = 50 ;
pPlayer - > visibility = 40 ;
2019-09-19 22:42:45 +00:00
}
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 ) ;
2021-06-16 19:13:04 +00:00
nType = kVectorShell ;
2019-09-19 22:42:45 +00:00
}
else
{
r1 = Random3 ( 2500 ) ;
r2 = Random3 ( 2500 ) ;
r3 = Random3 ( 1500 ) ;
2021-06-16 19:13:04 +00:00
nType = kVectorShellAP ;
2019-09-19 22:42:45 +00:00
}
2021-08-30 18:28:24 +00:00
actFireVector ( actor , 0 , pPlayer - > zWeapon - pPlayer - > pSprite - > z , pPlayer - > aim . dx + r1 , pPlayer - > aim . dy + r2 , pPlayer - > aim . dz + r3 , nType ) ;
2019-09-19 22:42:45 +00:00
}
2019-10-21 19:46:41 +00:00
UseAmmo ( pPlayer , pPlayer - > weaponAmmo , nTrigger ) ;
pPlayer - > flashEffect = 1 ;
2019-09-19 22:42:45 +00:00
}
void EjectShell ( int , PLAYER * pPlayer )
{
SpawnShellEject ( pPlayer , 25 , 35 ) ;
SpawnShellEject ( pPlayer , 48 , 35 ) ;
}
void FireTommy ( int nTrigger , PLAYER * pPlayer )
{
2021-08-30 18:28:24 +00:00
auto actor = & bloodActors [ pPlayer - > pSprite - > index ] ;
2019-10-21 19:46:41 +00:00
Aim * aim = & pPlayer - > aim ;
2019-09-19 22:42:45 +00:00
sfxPlay3DSound ( pPlayer - > pSprite , 431 , - 1 , 0 ) ;
switch ( nTrigger )
{
case 1 :
{
int r1 = Random3 ( 400 ) ;
int r2 = Random3 ( 1200 ) ;
int r3 = Random3 ( 1200 ) ;
2021-08-30 18:28:24 +00:00
actFireVector ( actor , 0 , pPlayer - > zWeapon - pPlayer - > pSprite - > z , aim - > dx + r3 , aim - > dy + r2 , aim - > dz + r1 , kVectorTommyRegular ) ;
2019-09-19 22:42:45 +00:00
SpawnBulletEject ( pPlayer , - 15 , - 45 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > visibility = 20 ;
2019-09-19 22:42:45 +00:00
break ;
}
case 2 :
{
int r1 = Random3 ( 400 ) ;
int r2 = Random3 ( 1200 ) ;
int r3 = Random3 ( 1200 ) ;
2021-08-30 18:28:24 +00:00
actFireVector ( actor , - 120 , pPlayer - > zWeapon - pPlayer - > pSprite - > z , aim - > dx + r3 , aim - > dy + r2 , aim - > dz + r1 , kVectorTommyRegular ) ;
2019-09-19 22:42:45 +00:00
SpawnBulletEject ( pPlayer , - 140 , - 45 ) ;
r1 = Random3 ( 400 ) ;
r2 = Random3 ( 1200 ) ;
r3 = Random3 ( 1200 ) ;
2021-08-30 18:28:24 +00:00
actFireVector ( actor , 120 , pPlayer - > zWeapon - pPlayer - > pSprite - > z , aim - > dx + r3 , aim - > dy + r2 , aim - > dz + r1 , kVectorTommyRegular ) ;
2019-09-19 22:42:45 +00:00
SpawnBulletEject ( pPlayer , 140 , 45 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > visibility = 30 ;
2019-09-19 22:42:45 +00:00
break ;
}
}
2019-10-21 19:46:41 +00:00
UseAmmo ( pPlayer , pPlayer - > weaponAmmo , nTrigger ) ;
pPlayer - > flashEffect = 1 ;
2019-09-19 22:42:45 +00:00
}
2020-10-11 10:18:25 +00:00
enum { kMaxSpread = 14 } ;
2019-09-19 22:42:45 +00:00
void FireSpread ( int nTrigger , PLAYER * pPlayer )
{
2021-08-30 18:28:24 +00:00
auto actor = & bloodActors [ pPlayer - > pSprite - > index ] ;
2020-10-11 10:38:17 +00:00
assert ( nTrigger > 0 & & nTrigger < = kMaxSpread ) ;
2019-10-21 19:46:41 +00:00
Aim * aim = & pPlayer - > aim ;
2019-09-19 22:42:45 +00:00
int angle = ( getangle ( aim - > dx , aim - > dy ) + ( ( 112 * ( nTrigger - 1 ) ) / 14 - 56 ) ) & 2047 ;
2020-09-01 13:00:35 +00:00
int dx = CosScale16 ( angle ) ;
int dy = SinScale16 ( angle ) ;
2019-09-19 22:42:45 +00:00
sfxPlay3DSound ( pPlayer - > pSprite , 431 , - 1 , 0 ) ;
int r1 , r2 , r3 ;
r1 = Random3 ( 300 ) ;
r2 = Random3 ( 600 ) ;
r3 = Random3 ( 600 ) ;
2021-08-30 18:28:24 +00:00
actFireVector ( actor , 0 , pPlayer - > zWeapon - pPlayer - > pSprite - > z , dx + r3 , dy + r2 , aim - > dz + r1 , kVectorTommyAP ) ;
2019-09-19 22:42:45 +00:00
r1 = Random2 ( 90 ) ;
r2 = Random2 ( 30 ) ;
SpawnBulletEject ( pPlayer , r2 , r1 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > visibility = 20 ;
UseAmmo ( pPlayer , pPlayer - > weaponAmmo , 1 ) ;
pPlayer - > flashEffect = 1 ;
2019-09-19 22:42:45 +00:00
}
void AltFireSpread ( int nTrigger , PLAYER * pPlayer )
{
2021-08-30 18:28:24 +00:00
auto actor = & bloodActors [ pPlayer - > pSprite - > index ] ;
2020-10-11 10:38:17 +00:00
assert ( nTrigger > 0 & & nTrigger < = kMaxSpread ) ;
2019-10-21 19:46:41 +00:00
Aim * aim = & pPlayer - > aim ;
2019-09-19 22:42:45 +00:00
int angle = ( getangle ( aim - > dx , aim - > dy ) + ( ( 112 * ( nTrigger - 1 ) ) / 14 - 56 ) ) & 2047 ;
2020-09-01 13:00:35 +00:00
int dx = CosScale16 ( angle ) ;
int dy = SinScale16 ( angle ) ;
2019-09-19 22:42:45 +00:00
sfxPlay3DSound ( pPlayer - > pSprite , 431 , - 1 , 0 ) ;
int r1 , r2 , r3 ;
r1 = Random3 ( 300 ) ;
r2 = Random3 ( 600 ) ;
r3 = Random3 ( 600 ) ;
2021-08-30 18:28:24 +00:00
actFireVector ( actor , - 120 , pPlayer - > zWeapon - pPlayer - > pSprite - > z , dx + r3 , dy + r2 , aim - > dz + r1 , kVectorTommyAP ) ;
2019-09-19 22:42:45 +00:00
r1 = Random2 ( 45 ) ;
r2 = Random2 ( 120 ) ;
SpawnBulletEject ( pPlayer , r2 , r1 ) ;
r1 = Random3 ( 300 ) ;
r2 = Random3 ( 600 ) ;
r3 = Random3 ( 600 ) ;
2021-08-30 18:28:24 +00:00
actFireVector ( actor , 120 , pPlayer - > zWeapon - pPlayer - > pSprite - > z , dx + r3 , dy + r2 , aim - > dz + r1 , kVectorTommyAP ) ;
2019-09-19 22:42:45 +00:00
r1 = Random2 ( - 45 ) ;
r2 = Random2 ( - 120 ) ;
SpawnBulletEject ( pPlayer , r2 , r1 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > tiltEffect = 20 ;
pPlayer - > visibility = 30 ;
UseAmmo ( pPlayer , pPlayer - > weaponAmmo , 2 ) ;
pPlayer - > flashEffect = 1 ;
2019-09-19 22:42:45 +00:00
}
void AltFireSpread2 ( int nTrigger , PLAYER * pPlayer )
{
2021-08-30 18:28:24 +00:00
auto actor = & bloodActors [ pPlayer - > pSprite - > index ] ;
2020-10-11 10:38:17 +00:00
assert ( nTrigger > 0 & & nTrigger < = kMaxSpread ) ;
2019-10-21 19:46:41 +00:00
Aim * aim = & pPlayer - > aim ;
2019-09-19 22:42:45 +00:00
int angle = ( getangle ( aim - > dx , aim - > dy ) + ( ( 112 * ( nTrigger - 1 ) ) / 14 - 56 ) ) & 2047 ;
2020-09-01 13:00:35 +00:00
int dx = CosScale16 ( angle ) ;
int dy = SinScale16 ( angle ) ;
2019-09-19 22:42:45 +00:00
sfxPlay3DSound ( pPlayer - > pSprite , 431 , - 1 , 0 ) ;
2020-11-21 17:14:24 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 3 , 2 ) )
2019-09-19 22:42:45 +00:00
{
int r1 , r2 , r3 ;
r1 = Random3 ( 300 ) ;
r2 = Random3 ( 600 ) ;
r3 = Random3 ( 600 ) ;
2021-08-30 18:28:24 +00:00
actFireVector ( actor , - 120 , pPlayer - > zWeapon - pPlayer - > pSprite - > z , dx + r3 , dy + r2 , aim - > dz + r1 , kVectorTommyAP ) ;
2019-09-19 22:42:45 +00:00
r1 = Random2 ( 45 ) ;
r2 = Random2 ( 120 ) ;
SpawnBulletEject ( pPlayer , r2 , r1 ) ;
r1 = Random3 ( 300 ) ;
r2 = Random3 ( 600 ) ;
r3 = Random3 ( 600 ) ;
2021-08-30 18:28:24 +00:00
actFireVector ( actor , 120 , pPlayer - > zWeapon - pPlayer - > pSprite - > z , dx + r3 , dy + r2 , aim - > dz + r1 , kVectorTommyAP ) ;
2019-09-19 22:42:45 +00:00
r1 = Random2 ( - 45 ) ;
r2 = Random2 ( - 120 ) ;
SpawnBulletEject ( pPlayer , r2 , r1 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > tiltEffect = 30 ;
pPlayer - > visibility = 45 ;
UseAmmo ( pPlayer , pPlayer - > weaponAmmo , 2 ) ;
2019-09-19 22:42:45 +00:00
}
else
{
int r1 , r2 , r3 ;
r1 = Random3 ( 300 ) ;
r2 = Random3 ( 600 ) ;
r3 = Random3 ( 600 ) ;
2021-08-30 18:28:24 +00:00
actFireVector ( actor , 0 , pPlayer - > zWeapon - pPlayer - > pSprite - > z , dx + r3 , dy + r2 , aim - > dz + r1 , kVectorTommyAP ) ;
2019-09-19 22:42:45 +00:00
r1 = Random2 ( 90 ) ;
r2 = Random2 ( 30 ) ;
SpawnBulletEject ( pPlayer , r2 , r1 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > tiltEffect = 20 ;
pPlayer - > visibility = 30 ;
UseAmmo ( pPlayer , pPlayer - > weaponAmmo , 1 ) ;
2019-09-19 22:42:45 +00:00
}
2019-10-21 19:46:41 +00:00
pPlayer - > flashEffect = 1 ;
2020-11-21 17:14:24 +00:00
if ( ! checkAmmo2 ( pPlayer , 3 , 1 ) )
2019-09-19 22:42:45 +00:00
{
WeaponLower ( pPlayer ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = - 1 ;
2019-09-19 22:42:45 +00:00
}
}
void FireFlare ( int nTrigger , PLAYER * pPlayer )
{
spritetype * pSprite = pPlayer - > pSprite ;
int offset = 0 ;
switch ( nTrigger )
{
case 2 :
offset = - 120 ;
break ;
case 3 :
offset = 120 ;
break ;
}
2019-10-21 19:46:41 +00:00
playerFireMissile ( pPlayer , offset , pPlayer - > aim . dx , pPlayer - > aim . dy , pPlayer - > aim . dz , kMissileFlareRegular ) ;
2019-09-19 22:42:45 +00:00
UseAmmo ( pPlayer , 1 , 1 ) ;
sfxPlay3DSound ( pSprite , 420 , 2 , 0 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > visibility = 30 ;
pPlayer - > flashEffect = 1 ;
2019-09-19 22:42:45 +00:00
}
void AltFireFlare ( int nTrigger , PLAYER * pPlayer )
{
spritetype * pSprite = pPlayer - > pSprite ;
int offset = 0 ;
switch ( nTrigger )
{
case 2 :
offset = - 120 ;
break ;
case 3 :
offset = 120 ;
break ;
}
2019-10-21 19:46:41 +00:00
playerFireMissile ( pPlayer , offset , pPlayer - > aim . dx , pPlayer - > aim . dy , pPlayer - > aim . dz , kMissileFlareAlt ) ;
2019-09-19 22:42:45 +00:00
UseAmmo ( pPlayer , 1 , 8 ) ;
sfxPlay3DSound ( pSprite , 420 , 2 , 0 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > visibility = 45 ;
pPlayer - > flashEffect = 1 ;
2019-09-19 22:42:45 +00:00
}
void FireVoodoo ( int nTrigger , PLAYER * pPlayer )
{
nTrigger - - ;
2021-09-16 19:14:30 +00:00
auto actor = pPlayer - > actor ( ) ;
2019-09-19 22:42:45 +00:00
spritetype * pSprite = pPlayer - > pSprite ;
if ( nTrigger = = 4 )
{
2021-09-16 19:14:30 +00:00
actDamageSprite ( actor , actor , kDamageBullet , 1 < < 4 ) ;
2019-09-19 22:42:45 +00:00
return ;
}
2020-10-11 10:38:17 +00:00
assert ( pPlayer - > voodooTarget > = 0 ) ;
2021-09-16 19:14:30 +00:00
auto targetactor = & bloodActors [ pPlayer - > voodooTarget ] ;
spritetype * pTarget = & targetactor - > s ( ) ;
2019-09-22 07:53:42 +00:00
if ( ! gGameOptions . bFriendlyFire & & IsTargetTeammate ( pPlayer , pTarget ) )
return ;
2019-09-19 22:42:45 +00:00
switch ( nTrigger )
{
case 0 :
{
sfxPlay3DSound ( pSprite , 460 , 2 , 0 ) ;
fxSpawnBlood ( pTarget , 17 < < 4 ) ;
2021-09-16 19:14:30 +00:00
int nDamage = actDamageSprite ( actor , targetactor , kDamageSpirit , 17 < < 4 ) ;
2019-09-19 22:42:45 +00:00
UseAmmo ( pPlayer , 9 , nDamage / 4 ) ;
break ;
}
case 1 :
{
sfxPlay3DSound ( pSprite , 460 , 2 , 0 ) ;
fxSpawnBlood ( pTarget , 17 < < 4 ) ;
2021-09-16 19:14:30 +00:00
int nDamage = actDamageSprite ( actor , targetactor , kDamageSpirit , 9 < < 4 ) ;
2019-10-11 21:59:39 +00:00
if ( IsPlayerSprite ( pTarget ) )
2019-09-19 22:42:45 +00:00
WeaponLower ( & gPlayer [ pTarget - > type - kDudePlayer1 ] ) ;
UseAmmo ( pPlayer , 9 , nDamage / 4 ) ;
break ;
}
case 3 :
{
sfxPlay3DSound ( pSprite , 463 , 2 , 0 ) ;
fxSpawnBlood ( pTarget , 17 < < 4 ) ;
2021-09-16 19:14:30 +00:00
int nDamage = actDamageSprite ( actor , targetactor , kDamageSpirit , 49 < < 4 ) ;
2019-09-19 22:42:45 +00:00
UseAmmo ( pPlayer , 9 , nDamage / 4 ) ;
break ;
}
case 2 :
{
sfxPlay3DSound ( pSprite , 460 , 2 , 0 ) ;
fxSpawnBlood ( pTarget , 17 < < 4 ) ;
2021-09-16 19:14:30 +00:00
int nDamage = actDamageSprite ( actor , targetactor , kDamageSpirit , 11 < < 4 ) ;
2019-10-11 21:59:39 +00:00
if ( IsPlayerSprite ( pTarget ) )
2019-09-19 22:42:45 +00:00
{
2019-10-11 21:59:39 +00:00
PLAYER * pOtherPlayer = & gPlayer [ pTarget - > type - kDudePlayer1 ] ;
2019-10-21 19:46:41 +00:00
pOtherPlayer - > blindEffect = 128 ;
2019-09-19 22:42:45 +00:00
}
UseAmmo ( pPlayer , 9 , nDamage / 4 ) ;
break ;
}
}
}
void AltFireVoodoo ( int nTrigger , PLAYER * pPlayer )
{
2021-09-16 19:14:30 +00:00
auto actor = pPlayer - > actor ( ) ;
2019-09-21 11:02:17 +00:00
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
2021-08-21 10:16:48 +00:00
if ( gGameOptions . weaponsV10x & & ! VanillaMode ( ) ) {
2019-10-25 20:53:41 +00:00
int nCount = ClipHigh ( pPlayer - > ammoCount [ 9 ] , pPlayer - > aimTargetsCount ) ;
2019-09-21 11:02:17 +00:00
if ( nCount > 0 )
{
2019-10-21 19:46:41 +00:00
for ( int i = 0 ; i < pPlayer - > aimTargetsCount ; i + + )
2019-09-21 11:02:17 +00:00
{
2019-10-21 19:46:41 +00:00
int nTarget = pPlayer - > aimTargets [ i ] ;
2021-09-16 19:14:30 +00:00
auto targetactor = & bloodActors [ nTarget ] ;
spritetype * pTarget = & targetactor - > s ( ) ;
2019-09-22 07:53:42 +00:00
if ( ! gGameOptions . bFriendlyFire & & IsTargetTeammate ( pPlayer , pTarget ) )
continue ;
2019-09-21 11:02:17 +00:00
int nDist = approxDist ( pTarget - > x - pPlayer - > pSprite - > x , pTarget - > y - pPlayer - > pSprite - > y ) ;
if ( nDist > 0 & & nDist < 51200 )
{
2019-10-25 20:53:41 +00:00
int vc = pPlayer - > ammoCount [ 9 ] > > 3 ;
int v8 = pPlayer - > ammoCount [ 9 ] < < 1 ;
2019-09-21 11:02:17 +00:00
int nDamage = ( v8 + Random ( vc ) ) < < 4 ;
nDamage = ( nDamage * ( ( 51200 - nDist ) + 1 ) ) / 51200 ;
2021-09-16 19:14:30 +00:00
nDamage = actDamageSprite ( actor , targetactor , kDamageSpirit , nDamage ) ;
2019-09-21 11:02:17 +00:00
2019-10-11 21:59:39 +00:00
if ( IsPlayerSprite ( pTarget ) )
2019-09-21 11:02:17 +00:00
{
PLAYER * pOtherPlayer = & gPlayer [ pTarget - > type - kDudePlayer1 ] ;
2019-10-21 19:46:41 +00:00
if ( ! pOtherPlayer - > godMode | | ! powerupCheck ( pOtherPlayer , kPwUpDeathMask ) )
2019-10-19 19:11:39 +00:00
powerupActivate ( pOtherPlayer , kPwUpDeliriumShroom ) ;
2019-09-21 11:02:17 +00:00
}
fxSpawnBlood ( pTarget , 0 ) ;
}
}
}
UseAmmo ( pPlayer , 9 , 20 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 0 ;
2019-09-21 11:02:17 +00:00
return ;
}
2019-10-21 19:46:41 +00:00
//int nAmmo = pPlayer->ammCount[9];
2019-10-25 20:53:41 +00:00
int nCount = ClipHigh ( pPlayer - > ammoCount [ 9 ] , pPlayer - > aimTargetsCount ) ;
2019-09-21 11:02:17 +00:00
if ( nCount > 0 )
{
2019-10-25 20:53:41 +00:00
int v4 = pPlayer - > ammoCount [ 9 ] - ( pPlayer - > ammoCount [ 9 ] / nCount ) * nCount ;
2019-10-21 19:46:41 +00:00
for ( int i = 0 ; i < pPlayer - > aimTargetsCount ; i + + )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
int nTarget = pPlayer - > aimTargets [ i ] ;
2021-09-16 19:14:30 +00:00
auto targetactor = & bloodActors [ nTarget ] ;
spritetype * pTarget = & targetactor - > s ( ) ;
2019-09-22 07:53:42 +00:00
if ( ! gGameOptions . bFriendlyFire & & IsTargetTeammate ( pPlayer , pTarget ) )
continue ;
2019-09-21 11:02:17 +00:00
if ( v4 > 0 )
v4 - - ;
int nDist = approxDist ( pTarget - > x - pPlayer - > pSprite - > x , pTarget - > y - pPlayer - > pSprite - > y ) ;
if ( nDist > 0 & & nDist < 51200 )
2019-09-19 22:42:45 +00:00
{
2019-10-25 20:53:41 +00:00
int vc = pPlayer - > ammoCount [ 9 ] > > 3 ;
int v8 = pPlayer - > ammoCount [ 9 ] < < 1 ;
2019-09-21 11:02:17 +00:00
int nDamage = ( v8 + Random2 ( vc ) ) < < 4 ;
nDamage = ( nDamage * ( ( 51200 - nDist ) + 1 ) ) / 51200 ;
2021-09-16 19:14:30 +00:00
nDamage = actDamageSprite ( actor , targetactor , kDamageSpirit , nDamage ) ;
2019-09-21 11:02:17 +00:00
UseAmmo ( pPlayer , 9 , nDamage ) ;
2019-10-11 21:59:39 +00:00
if ( IsPlayerSprite ( pTarget ) )
2019-09-21 11:02:17 +00:00
{
PLAYER * pOtherPlayer = & gPlayer [ pTarget - > type - kDudePlayer1 ] ;
2019-10-21 19:46:41 +00:00
if ( ! pOtherPlayer - > godMode | | ! powerupCheck ( pOtherPlayer , kPwUpDeathMask ) )
2019-10-19 19:11:39 +00:00
powerupActivate ( pOtherPlayer , kPwUpDeliriumShroom ) ;
2019-09-21 11:02:17 +00:00
}
fxSpawnBlood ( pTarget , 0 ) ;
2019-09-19 22:42:45 +00:00
}
}
}
2019-10-25 20:53:41 +00:00
UseAmmo ( pPlayer , 9 , pPlayer - > ammoCount [ 9 ] ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > hasWeapon [ 10 ] = 0 ;
pPlayer - > weaponState = - 1 ;
2019-09-19 22:42:45 +00:00
}
}
2021-05-03 17:10:53 +00:00
void DropVoodoo ( int , PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
sfxPlay3DSound ( pPlayer - > pSprite , 455 , 2 , 0 ) ;
2019-10-11 21:59:39 +00:00
spritetype * pSprite = playerFireThing ( pPlayer , 0 , - 4730 , kThingVoodooHead , 0xccccc ) ;
2019-09-19 22:42:45 +00:00
if ( pSprite )
{
int nXSprite = pSprite - > extra ;
XSPRITE * pXSprite = & xsprite [ nXSprite ] ;
2019-10-25 20:53:41 +00:00
pXSprite - > data1 = pPlayer - > ammoCount [ 9 ] ;
2019-10-11 21:59:39 +00:00
evPost ( pSprite - > index , 3 , 90 , kCallbackDropVoodoo ) ;
2019-10-21 19:46:41 +00:00
UseAmmo ( pPlayer , 6 , gAmmoItemData [ 0 ] . count ) ;
2019-10-25 20:53:41 +00:00
UseAmmo ( pPlayer , 9 , pPlayer - > ammoCount [ 9 ] ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > hasWeapon [ 10 ] = 0 ;
2019-09-19 22:42:45 +00:00
}
}
struct TeslaMissile
{
2020-11-21 21:25:26 +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
} ;
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 - - ;
spritetype * pSprite = pPlayer - > pSprite ;
TeslaMissile * pMissile = & teslaMissile [ nTrigger ] ;
2020-11-21 21:25:26 +00:00
if ( ! checkAmmo2 ( pPlayer , 7 , pMissile - > ammouse ) )
2019-09-19 22:42:45 +00:00
{
pMissile = & teslaMissile [ 0 ] ;
2020-11-21 21:25:26 +00:00
if ( ! checkAmmo2 ( pPlayer , 7 , pMissile - > ammouse ) )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = - 1 ;
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVSGUNIDL2 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > flashEffect = 0 ;
2019-09-19 22:42:45 +00:00
return ;
}
}
2020-11-21 21:25:26 +00:00
playerFireMissile ( pPlayer , pMissile - > offset , pPlayer - > aim . dx , pPlayer - > aim . dy , pPlayer - > aim . dz , pMissile - > id ) ;
UseAmmo ( pPlayer , 7 , pMissile - > ammouse ) ;
sfxPlay3DSound ( pSprite , pMissile - > sound , 1 , 0 ) ;
pPlayer - > visibility = pMissile - > light ;
pPlayer - > flashEffect = pMissile - > flash ;
2019-09-19 22:42:45 +00:00
}
}
2021-05-03 17:10:53 +00:00
void AltFireTesla ( int , PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
spritetype * pSprite = pPlayer - > pSprite ;
2019-10-21 19:46:41 +00:00
playerFireMissile ( pPlayer , 0 , pPlayer - > aim . dx , pPlayer - > aim . dy , pPlayer - > aim . dz , kMissileTeslaAlt ) ;
UseAmmo ( pPlayer , pPlayer - > weaponAmmo , 35 ) ;
2019-09-19 22:42:45 +00:00
sfxPlay3DSound ( pSprite , 471 , 2 , 0 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > visibility = 40 ;
pPlayer - > flashEffect = 1 ;
2019-09-19 22:42:45 +00:00
}
void FireNapalm ( int nTrigger , PLAYER * pPlayer )
{
spritetype * pSprite = pPlayer - > pSprite ;
int offset = 0 ;
switch ( nTrigger )
{
case 2 :
offset = - 50 ;
break ;
case 3 :
offset = 50 ;
break ;
}
2021-08-22 07:49:02 +00:00
playerFireMissile ( pPlayer , offset , pPlayer - > aim . dx , pPlayer - > aim . dy , pPlayer - > aim . dz , kMissileFireballNapalm ) ;
2019-09-19 22:42:45 +00:00
sfxPlay3DSound ( pSprite , 480 , 2 , 0 ) ;
UseAmmo ( pPlayer , 4 , 1 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > flashEffect = 1 ;
2019-09-19 22:42:45 +00:00
}
2021-05-03 17:10:53 +00:00
void FireNapalm2 ( int , PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
spritetype * pSprite = pPlayer - > pSprite ;
2021-08-22 07:49:02 +00:00
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 ) ;
2019-09-19 22:42:45 +00:00
sfxPlay3DSound ( pSprite , 480 , 2 , 0 ) ;
UseAmmo ( pPlayer , 4 , 2 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > flashEffect = 1 ;
2019-09-19 22:42:45 +00:00
}
2021-05-03 17:10:53 +00:00
void AltFireNapalm ( int , PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
2021-01-04 11:36:54 +00:00
int nSpeed = MulScale ( 0x8000 , 0x177777 , 16 ) + 0x66666 ;
2019-10-11 21:59:39 +00:00
spritetype * pMissile = playerFireThing ( pPlayer , 0 , - 4730 , kThingNapalmBall , nSpeed ) ;
2019-09-19 22:42:45 +00:00
if ( pMissile )
{
XSPRITE * pXSprite = & xsprite [ pMissile - > extra ] ;
2019-10-25 20:53:41 +00:00
pXSprite - > data4 = ClipHigh ( pPlayer - > ammoCount [ 4 ] , 12 ) ;
2019-09-19 22:42:45 +00:00
UseAmmo ( pPlayer , 4 , pXSprite - > data4 ) ;
seqSpawn ( 22 , 3 , pMissile - > extra , - 1 ) ;
2020-12-02 18:56:32 +00:00
actBurnSprite ( pPlayer - > pSprite - > index , pXSprite , 600 ) ;
2019-10-11 21:59:39 +00:00
evPost ( pMissile - > index , 3 , 0 , kCallbackFXFlameLick ) ;
2019-09-19 22:42:45 +00:00
sfxPlay3DSound ( pMissile , 480 , 2 , 0 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > visibility = 30 ;
pPlayer - > flashEffect = 1 ;
2019-09-19 22:42:45 +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 ) ;
2021-09-16 19:14:30 +00:00
auto actor = pPlayer - > actor ( ) ;
2019-10-21 19:46:41 +00:00
spritetype * pMissile = playerFireMissile ( pPlayer , 0 , pPlayer - > aim . dx + r1 , pPlayer - > aim . dy + r2 , pPlayer - > aim . dz + r3 , 315 ) ;
2019-09-19 22:42:45 +00:00
if ( pMissile )
{
XSPRITE * pXSprite = & xsprite [ pMissile - > extra ] ;
2021-09-15 22:40:09 +00:00
pXSprite - > target_i = pPlayer - > aimTarget ;
2019-09-19 22:42:45 +00:00
pMissile - > ang = ( nTrigger = = 2 ) ? 1024 : 0 ;
}
2020-11-21 17:14:24 +00:00
if ( checkAmmo2 ( pPlayer , 8 , 1 ) )
2019-09-19 22:42:45 +00:00
UseAmmo ( pPlayer , 8 , 1 ) ;
else
2021-09-16 19:14:30 +00:00
actDamageSprite ( actor , actor , kDamageSpirit , 16 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > visibility = ClipHigh ( pPlayer - > visibility + 5 , 50 ) ;
2019-09-19 22:42:45 +00:00
}
2021-05-03 17:10:53 +00:00
void AltFireLifeLeech ( int , PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
2021-09-16 19:14:30 +00:00
auto actor = pPlayer - > actor ( ) ;
2019-09-19 22:42:45 +00:00
sfxPlay3DSound ( pPlayer - > pSprite , 455 , 2 , 0 ) ;
2019-10-11 21:59:39 +00:00
spritetype * pMissile = playerFireThing ( pPlayer , 0 , - 4730 , kThingDroppedLifeLeech , 0x19999 ) ;
2019-09-19 22:42:45 +00:00
if ( pMissile )
{
pMissile - > cstat | = 4096 ;
XSPRITE * pXSprite = & xsprite [ pMissile - > extra ] ;
pXSprite - > Push = 1 ;
pXSprite - > Proximity = 1 ;
pXSprite - > DudeLockout = 1 ;
2019-10-25 20:53:41 +00:00
pXSprite - > data4 = ClipHigh ( pPlayer - > ammoCount [ 4 ] , 12 ) ;
2019-09-19 22:42:45 +00:00
pXSprite - > stateTimer = 1 ;
2019-10-11 21:59:39 +00:00
evPost ( pMissile - > index , 3 , 120 , kCallbackLeechStateTimer ) ;
2019-09-19 22:42:45 +00:00
if ( gGameOptions . nGameType < = 1 )
{
2019-10-25 20:53:41 +00:00
int nAmmo = pPlayer - > ammoCount [ 8 ] ;
2021-05-12 00:00:06 +00:00
if ( nAmmo < 25 & & pPlayer - > pXSprite - > health > unsigned ( ( 25 - nAmmo ) < < 4 ) )
2019-09-19 22:42:45 +00:00
{
2021-09-16 19:36:34 +00:00
actDamageSprite ( actor , actor , kDamageSpirit , ( ( 25 - nAmmo ) < < 4 ) ) ;
2019-09-19 22:42:45 +00:00
nAmmo = 25 ;
}
pXSprite - > data3 = nAmmo ;
UseAmmo ( pPlayer , 8 , nAmmo ) ;
}
else
{
2019-10-25 20:53:41 +00:00
pXSprite - > data3 = pPlayer - > ammoCount [ 8 ] ;
pPlayer - > ammoCount [ 8 ] = 0 ;
2019-09-19 22:42:45 +00:00
}
2019-10-21 19:46:41 +00:00
pPlayer - > hasWeapon [ 9 ] = 0 ;
2019-09-19 22:42:45 +00:00
}
}
2021-05-03 17:10:53 +00:00
void FireBeast ( int , PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
2021-08-30 18:28:24 +00:00
auto actor = & bloodActors [ pPlayer - > pSprite - > index ] ;
2019-09-19 22:42:45 +00:00
int r1 = Random2 ( 2000 ) ;
int r2 = Random2 ( 2000 ) ;
int r3 = Random2 ( 2000 ) ;
2021-08-30 18:28:24 +00:00
actFireVector ( actor , 0 , pPlayer - > zWeapon - pPlayer - > pSprite - > z , pPlayer - > aim . dx + r1 , pPlayer - > aim . dy + r2 , pPlayer - > aim . dz + r3 , kVectorBeastSlash ) ;
2019-09-19 22:42:45 +00:00
}
2021-04-17 08:34:12 +00:00
uint8_t gWeaponUpgrade [ ] [ 13 ] = {
2019-09-19 22:42:45 +00:00
{ 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 } ,
} ;
2021-04-17 08:34:12 +00:00
int WeaponUpgrade ( PLAYER * pPlayer , int newWeapon )
2019-09-19 22:42:45 +00:00
{
2021-04-17 08:34:12 +00:00
int weapon = pPlayer - > curWeapon ;
2021-08-12 09:19:07 +00:00
if ( ! checkFired6or7 ( pPlayer ) & & ( cl_weaponswitch & 1 ) & & ( gWeaponUpgrade [ pPlayer - > curWeapon ] [ newWeapon ] | | ( cl_weaponswitch & 2 ) ) )
2019-09-19 22:42:45 +00:00
weapon = newWeapon ;
return weapon ;
}
int OrderNext [ ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 1 , 1 } ;
int OrderPrev [ ] = { 12 , 12 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 1 } ;
2021-04-17 08:34:12 +00:00
static int WeaponFindNext ( PLAYER * pPlayer , int * a2 , int bDir )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
int weapon = pPlayer - > curWeapon ;
2019-09-19 22:42:45 +00:00
do
{
if ( bDir )
weapon = OrderNext [ weapon ] ;
else
weapon = OrderPrev [ weapon ] ;
2020-11-21 18:30:00 +00:00
if ( weaponModes [ weapon ] . update & & pPlayer - > hasWeapon [ weapon ] )
2019-09-19 22:42:45 +00:00
{
2021-08-18 09:56:06 +00:00
if ( weapon = = kWeapLifeLeech )
2019-09-19 22:42:45 +00:00
{
2020-11-21 18:30:00 +00:00
if ( CheckAmmo ( pPlayer , weaponModes [ weapon ] . ammoType , 1 ) )
2019-09-19 22:42:45 +00:00
break ;
}
else
{
2020-11-21 18:30:00 +00:00
if ( checkAmmo2 ( pPlayer , weaponModes [ weapon ] . ammoType , 1 ) )
2019-09-19 22:42:45 +00:00
break ;
}
}
2019-10-21 19:46:41 +00:00
} while ( weapon ! = pPlayer - > curWeapon ) ;
if ( weapon = = pPlayer - > curWeapon )
2019-09-19 22:42:45 +00:00
{
2020-11-21 18:30:00 +00:00
if ( ! weaponModes [ weapon ] . update | | ! CheckAmmo ( pPlayer , weaponModes [ weapon ] . ammoType , 1 ) )
2021-08-18 09:56:06 +00:00
weapon = kWeapPitchFork ;
2019-09-19 22:42:45 +00:00
}
if ( a2 )
* a2 = 0 ;
return weapon ;
}
2021-04-17 08:34:12 +00:00
static int WeaponFindLoaded ( PLAYER * pPlayer , int * a2 )
2019-09-19 22:42:45 +00:00
{
2021-04-17 08:34:12 +00:00
int v4 = 1 ;
2019-09-19 22:42:45 +00:00
int v14 = 0 ;
2020-11-21 18:30:00 +00:00
if ( weaponModes [ pPlayer - > curWeapon ] . update > 1 )
2019-09-19 22:42:45 +00:00
{
2020-11-21 18:30:00 +00:00
for ( int i = 0 ; i < weaponModes [ pPlayer - > curWeapon ] . update ; i + + )
2019-09-19 22:42:45 +00:00
{
2020-11-21 18:30:00 +00:00
if ( CheckAmmo ( pPlayer , weaponModes [ pPlayer - > curWeapon ] . ammoType , 1 ) )
2019-09-19 22:42:45 +00:00
{
v14 = i ;
2019-10-21 19:46:41 +00:00
v4 = pPlayer - > curWeapon ;
2019-09-19 22:42:45 +00:00
break ;
}
}
}
2021-08-18 09:56:06 +00:00
if ( v4 = = kWeapPitchFork )
2019-09-19 22:42:45 +00:00
{
int vc = 0 ;
for ( int i = 0 ; i < 14 ; i + + )
{
2019-10-21 19:46:41 +00:00
int weapon = pPlayer - > weaponOrder [ vc ] [ i ] ;
if ( pPlayer - > hasWeapon [ weapon ] )
2019-09-19 22:42:45 +00:00
{
2020-11-21 18:30:00 +00:00
for ( int j = 0 ; j < weaponModes [ weapon ] . update ; j + + )
2019-09-19 22:42:45 +00:00
{
2020-11-21 18:30:00 +00:00
if ( CheckWeaponAmmo ( pPlayer , weapon , weaponModes [ weapon ] . ammoType , 1 ) )
2019-09-19 22:42:45 +00:00
{
if ( a2 )
* a2 = j ;
return weapon ;
}
}
}
}
}
else if ( a2 )
* a2 = v14 ;
return v4 ;
}
2020-11-21 17:33:31 +00:00
int processSprayCan ( PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > weaponState )
2019-09-19 22:42:45 +00:00
{
case 5 :
2020-08-28 20:51:05 +00:00
if ( ! ( pPlayer - > input . actions & SB_ALTFIRE ) )
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 6 ;
2019-09-19 22:42:45 +00:00
return 1 ;
case 6 :
2020-08-28 20:51:05 +00:00
if ( pPlayer - > input . actions & SB_ALTFIRE )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 3 ;
pPlayer - > fuseTime = pPlayer - > weaponTimer ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVCANDROP , nClientDropCan ) ;
2019-09-19 22:42:45 +00:00
}
2020-08-28 20:51:05 +00:00
else if ( pPlayer - > input . actions & SB_FIRE )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 7 ;
pPlayer - > fuseTime = 0 ;
2021-02-18 10:46:36 +00:00
pPlayer - > throwTime = PlayClock ;
2019-09-19 22:42:45 +00:00
}
return 1 ;
case 7 :
{
2021-02-18 10:46:36 +00:00
pPlayer - > throwPower = ClipHigh ( DivScale ( PlayClock - pPlayer - > throwTime , 240 , 16 ) , 65536 ) ;
2020-08-28 20:51:05 +00:00
if ( ! ( pPlayer - > input . actions & SB_FIRE ) )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
if ( ! pPlayer - > fuseTime )
pPlayer - > fuseTime = pPlayer - > weaponTimer ;
pPlayer - > weaponState = 1 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVCANTHRO , nClientThrowCan ) ;
2019-09-19 22:42:45 +00:00
}
return 1 ;
}
}
return 0 ;
}
2021-04-17 08:34:12 +00:00
static bool processTNT ( PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > weaponState )
2019-09-19 22:42:45 +00:00
{
case 4 :
2020-08-28 20:51:05 +00:00
if ( ! ( pPlayer - > input . actions & SB_ALTFIRE ) )
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 5 ;
2019-09-19 22:42:45 +00:00
return 1 ;
case 5 :
2020-08-28 20:51:05 +00:00
if ( pPlayer - > input . actions & SB_ALTFIRE )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 1 ;
pPlayer - > fuseTime = pPlayer - > weaponTimer ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVBUNDROP , nClientDropBundle ) ;
2019-09-19 22:42:45 +00:00
}
2020-08-28 20:51:05 +00:00
else if ( pPlayer - > input . actions & SB_FIRE )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 6 ;
pPlayer - > fuseTime = 0 ;
2021-02-18 10:46:36 +00:00
pPlayer - > throwTime = PlayClock ;
2019-09-19 22:42:45 +00:00
}
return 1 ;
case 6 :
{
2021-02-18 10:46:36 +00:00
pPlayer - > throwPower = ClipHigh ( DivScale ( PlayClock - pPlayer - > throwTime , 240 , 16 ) , 65536 ) ;
2020-08-28 20:51:05 +00:00
if ( ! ( pPlayer - > input . actions & SB_FIRE ) )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
if ( ! pPlayer - > fuseTime )
pPlayer - > fuseTime = pPlayer - > weaponTimer ;
pPlayer - > weaponState = 1 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVBUNTHRO , nClientThrowBundle ) ;
2019-09-19 22:42:45 +00:00
}
return 1 ;
}
}
return 0 ;
}
2021-04-17 08:34:12 +00:00
static bool processProxy ( PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > weaponState )
2019-09-19 22:42:45 +00:00
{
case 9 :
2021-02-18 10:46:36 +00:00
pPlayer - > throwPower = ClipHigh ( DivScale ( PlayClock - pPlayer - > throwTime , 240 , 16 ) , 65536 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponTimer = 0 ;
2021-08-05 02:38:26 +00:00
pPlayer - > qavTimer = 0 ;
2020-08-28 20:51:05 +00:00
if ( ! ( pPlayer - > input . actions & SB_FIRE ) )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 8 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVPROXTHRO , nClientThrowProx ) ;
2019-09-19 22:42:45 +00:00
}
break ;
}
return 0 ;
}
2021-04-17 08:34:12 +00:00
static bool processRemote ( PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > weaponState )
2019-09-19 22:42:45 +00:00
{
case 13 :
2021-02-18 10:46:36 +00:00
pPlayer - > throwPower = ClipHigh ( DivScale ( PlayClock - pPlayer - > throwTime , 240 , 16 ) , 65536 ) ;
2020-08-28 20:51:05 +00:00
if ( ! ( pPlayer - > input . actions & SB_FIRE ) )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 11 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVREMTHRO , nClientThrowRemote ) ;
2019-09-19 22:42:45 +00:00
}
break ;
}
return 0 ;
}
2021-04-17 08:34:12 +00:00
static bool processLeech ( PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > weaponState )
2019-09-19 22:42:45 +00:00
{
case 4 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 6 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSTAFIRE1 , nClientFireLifeLeech , 1 ) ;
2019-09-19 22:42:45 +00:00
return 1 ;
case 6 :
2020-08-28 20:51:05 +00:00
if ( ! ( pPlayer - > input . actions & SB_ALTFIRE ) )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 2 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSTAFPOST ) ;
2019-09-19 22:42:45 +00:00
return 1 ;
}
break ;
case 8 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 2 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSTAFPOST ) ;
2019-09-19 22:42:45 +00:00
return 1 ;
}
return 0 ;
}
2021-04-17 08:34:12 +00:00
static bool processTesla ( PLAYER * pPlayer )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > weaponState )
2019-09-19 22:42:45 +00:00
{
case 4 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 5 ;
2020-11-21 17:14:24 +00:00
if ( checkAmmo2 ( pPlayer , 7 , 10 ) & & powerupCheck ( pPlayer , kPwUpTwoGuns ) )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2SGUNFIR , nClientFireTesla , 1 ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSGUNFIR1 , nClientFireTesla , 1 ) ;
2019-09-19 22:42:45 +00:00
return 1 ;
case 5 :
2020-08-28 20:51:05 +00:00
if ( ! ( pPlayer - > input . actions & SB_FIRE ) )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 2 ;
2020-11-21 17:14:24 +00:00
if ( checkAmmo2 ( pPlayer , 7 , 10 ) & & powerupCheck ( pPlayer , kPwUpTwoGuns ) )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2SGUNPST ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSGUNPOST ) ;
2019-09-19 22:42:45 +00:00
return 1 ;
}
break ;
case 7 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 2 ;
2020-11-21 17:14:24 +00:00
if ( checkAmmo2 ( pPlayer , 7 , 10 ) & & powerupCheck ( pPlayer , kPwUpTwoGuns ) )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2SGUNPST ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSGUNPOST ) ;
2019-09-19 22:42:45 +00:00
return 1 ;
}
return 0 ;
}
2019-10-25 20:53:41 +00:00
void WeaponProcess ( PLAYER * pPlayer ) {
pPlayer - > flashEffect = ClipLow ( pPlayer - > flashEffect - 1 , 0 ) ;
2020-02-07 19:47:43 +00:00
2020-01-26 11:19:01 +00:00
# ifdef NOONE_EXTENSIONS
2019-11-08 19:57:01 +00:00
if ( gPlayerCtrl [ pPlayer - > nPlayer ] . qavScene . index > = 0 & & pPlayer - > pXSprite - > health > 0 ) {
2020-02-07 19:47:43 +00:00
playerQavSceneProcess ( pPlayer , & gPlayerCtrl [ pPlayer - > nPlayer ] . qavScene ) ;
2020-03-13 20:59:13 +00:00
UpdateAimVector ( pPlayer ) ;
2019-10-25 20:53:41 +00:00
return ;
}
2020-01-26 11:19:01 +00:00
# endif
2019-10-25 20:53:41 +00:00
2019-09-19 22:42:45 +00:00
if ( pPlayer - > pXSprite - > health = = 0 )
{
2019-10-21 19:46:41 +00:00
pPlayer - > qavLoop = 0 ;
2019-09-19 22:42:45 +00:00
sfxKill3DSound ( pPlayer - > pSprite , 1 , - 1 ) ;
}
2019-10-21 19:46:41 +00:00
if ( pPlayer - > isUnderwater & & BannedUnderwater ( pPlayer - > curWeapon ) )
2019-09-19 22:42:45 +00:00
{
2021-08-12 09:19:07 +00:00
if ( checkFired6or7 ( pPlayer ) )
2019-09-19 22:42:45 +00:00
{
2021-08-18 09:56:06 +00:00
if ( pPlayer - > curWeapon = = kWeapSpraycan )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > fuseTime = pPlayer - > weaponTimer ;
2019-09-19 22:42:45 +00:00
DropCan ( 1 , pPlayer ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 3 ;
2019-09-19 22:42:45 +00:00
}
2021-08-18 09:56:06 +00:00
else if ( pPlayer - > curWeapon = = kWeapDynamite )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > fuseTime = pPlayer - > weaponTimer ;
2019-09-19 22:42:45 +00:00
DropBundle ( 1 , pPlayer ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 1 ;
2019-09-19 22:42:45 +00:00
}
}
WeaponLower ( pPlayer ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > throwPower = 0 ;
2019-09-19 22:42:45 +00:00
}
WeaponPlay ( pPlayer ) ;
UpdateAimVector ( pPlayer ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponTimer - = 4 ;
2020-08-28 20:51:05 +00:00
bool bShoot = pPlayer - > input . actions & SB_FIRE ;
bool bShoot2 = pPlayer - > input . actions & SB_ALTFIRE ;
2021-08-23 21:25:52 +00:00
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 ;
2019-10-21 19:46:41 +00:00
if ( pPlayer - > qavLoop & & pPlayer - > pXSprite - > health > 0 )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
if ( bShoot & & CheckAmmo ( pPlayer , pPlayer - > weaponAmmo , 1 ) )
2019-09-19 22:42:45 +00:00
{
2021-08-23 00:49:47 +00:00
auto pQAV = getQAV ( pPlayer - > weaponQav ) ;
2019-10-21 19:46:41 +00:00
while ( pPlayer - > weaponTimer < = 0 )
2021-08-05 02:38:26 +00:00
{
2021-08-23 00:49:47 +00:00
pPlayer - > weaponTimer + = pQAV - > duration ;
pPlayer - > qavTimer + = pQAV - > duration ;
2021-08-05 02:38:26 +00:00
}
2019-09-19 22:42:45 +00:00
}
else
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponTimer = 0 ;
2021-08-05 02:38:26 +00:00
pPlayer - > qavTimer = 0 ;
2019-10-21 19:46:41 +00:00
pPlayer - > qavLoop = 0 ;
2019-09-19 22:42:45 +00:00
}
return ;
}
2019-10-21 19:46:41 +00:00
pPlayer - > weaponTimer = ClipLow ( pPlayer - > weaponTimer , 0 ) ;
switch ( pPlayer - > curWeapon )
2019-09-19 22:42:45 +00:00
{
2021-08-18 09:56:06 +00:00
case kWeapSpraycan :
2020-11-21 17:33:31 +00:00
if ( processSprayCan ( pPlayer ) )
2019-09-19 22:42:45 +00:00
return ;
break ;
2021-08-18 09:56:06 +00:00
case kWeapDynamite :
2020-11-21 17:33:31 +00:00
if ( processTNT ( pPlayer ) )
2019-09-19 22:42:45 +00:00
return ;
break ;
2021-08-18 09:56:06 +00:00
case kWeapProximity :
2020-11-21 17:33:31 +00:00
if ( processProxy ( pPlayer ) )
2019-09-19 22:42:45 +00:00
return ;
break ;
2021-08-18 09:56:06 +00:00
case kWeapRemote :
2020-11-21 17:33:31 +00:00
if ( processRemote ( pPlayer ) )
2019-09-19 22:42:45 +00:00
return ;
break ;
}
2019-10-21 19:46:41 +00:00
if ( pPlayer - > weaponTimer > 0 )
2019-09-19 22:42:45 +00:00
return ;
2021-08-18 09:56:06 +00:00
if ( pPlayer - > pXSprite - > health = = 0 | | pPlayer - > curWeapon = = kWeapNone )
2021-08-03 10:34:08 +00:00
pPlayer - > weaponQav = kQAVNone ;
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > curWeapon )
2019-09-19 22:42:45 +00:00
{
2021-08-18 09:56:06 +00:00
case kWeapLifeLeech :
2020-11-21 17:33:31 +00:00
if ( processLeech ( pPlayer ) )
2019-09-19 22:42:45 +00:00
return ;
break ;
2021-08-18 09:56:06 +00:00
case kWeapTeslaCannon :
2020-11-21 17:33:31 +00:00
if ( processTesla ( pPlayer ) )
2019-09-19 22:42:45 +00:00
return ;
break ;
}
2021-07-16 23:14:08 +00:00
if ( VanillaMode ( ) )
2019-09-19 22:42:45 +00:00
{
2021-07-16 23:14:08 +00:00
if ( pPlayer - > nextWeapon )
{
sfxKill3DSound ( pPlayer - > pSprite , - 1 , 441 ) ;
pPlayer - > weaponState = 0 ;
pPlayer - > newWeapon = pPlayer - > nextWeapon ;
2021-08-03 10:23:48 +00:00
pPlayer - > nextWeapon = kWeapNone ;
2021-07-16 23:14:08 +00:00
}
2019-09-19 22:42:45 +00:00
}
2020-08-26 22:53:35 +00:00
if ( pPlayer - > input . getNewWeapon ( ) = = WeaponSel_Next )
2019-09-19 22:42:45 +00:00
{
2021-08-18 09:57:31 +00:00
pPlayer - > input . setNewWeapon ( kWeapNone ) ;
2021-03-09 08:30:27 +00:00
if ( VanillaMode ( ) )
{
pPlayer - > weaponState = 0 ;
}
2021-08-03 10:23:48 +00:00
pPlayer - > nextWeapon = kWeapNone ;
2019-09-19 22:42:45 +00:00
int t ;
2021-04-17 08:34:12 +00:00
int weapon = WeaponFindNext ( pPlayer , & t , 1 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponMode [ weapon ] = t ;
2021-03-09 08:30:27 +00:00
if ( VanillaMode ( ) )
2019-09-19 22:42:45 +00:00
{
2021-03-09 08:30:27 +00:00
if ( pPlayer - > curWeapon )
{
WeaponLower ( pPlayer ) ;
pPlayer - > nextWeapon = weapon ;
return ;
}
2019-09-19 22:42:45 +00:00
}
2020-08-26 14:48:33 +00:00
pPlayer - > newWeapon = weapon ;
2019-09-19 22:42:45 +00:00
}
2020-08-26 22:53:35 +00:00
else if ( pPlayer - > input . getNewWeapon ( ) = = WeaponSel_Prev )
2019-09-19 22:42:45 +00:00
{
2021-08-18 09:57:31 +00:00
pPlayer - > input . setNewWeapon ( kWeapNone ) ;
2021-03-09 08:30:27 +00:00
if ( VanillaMode ( ) )
{
pPlayer - > weaponState = 0 ;
}
2021-08-03 10:23:48 +00:00
pPlayer - > nextWeapon = kWeapNone ;
2019-09-19 22:42:45 +00:00
int t ;
2021-04-17 08:34:12 +00:00
int weapon = WeaponFindNext ( pPlayer , & t , 0 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponMode [ weapon ] = t ;
2021-03-09 08:30:27 +00:00
if ( VanillaMode ( ) )
2019-09-19 22:42:45 +00:00
{
2021-03-09 08:30:27 +00:00
if ( pPlayer - > curWeapon )
{
WeaponLower ( pPlayer ) ;
pPlayer - > nextWeapon = weapon ;
return ;
}
2019-09-19 22:42:45 +00:00
}
2020-08-26 14:48:33 +00:00
pPlayer - > newWeapon = weapon ;
2019-09-19 22:42:45 +00:00
}
2020-08-26 22:53:35 +00:00
else if ( pPlayer - > input . getNewWeapon ( ) = = WeaponSel_Alt )
{
2021-04-17 08:34:12 +00:00
int weapon ;
2020-08-29 12:51:20 +00:00
switch ( pPlayer - > curWeapon )
{
2021-08-18 09:56:06 +00:00
case kWeapDynamite :
weapon = kWeapProximity ;
2020-08-29 12:51:20 +00:00
break ;
2021-08-18 09:56:06 +00:00
case kWeapProximity :
weapon = kWeapRemote ;
2020-08-29 12:51:20 +00:00
break ;
2021-08-18 09:56:06 +00:00
case kWeapRemote :
weapon = kWeapDynamite ;
2020-08-29 12:51:20 +00:00
break ;
default :
return ;
}
2021-08-18 09:57:31 +00:00
pPlayer - > input . setNewWeapon ( kWeapNone ) ;
2020-08-29 12:51:20 +00:00
pPlayer - > weaponState = 0 ;
2021-08-03 10:23:48 +00:00
pPlayer - > nextWeapon = kWeapNone ;
2020-08-29 12:51:20 +00:00
int t = 0 ;
pPlayer - > weaponMode [ weapon ] = t ;
if ( pPlayer - > curWeapon )
{
WeaponLower ( pPlayer ) ;
pPlayer - > nextWeapon = weapon ;
return ;
}
pPlayer - > newWeapon = weapon ;
2020-08-26 22:53:35 +00:00
}
2021-03-09 08:30:27 +00:00
if ( ! VanillaMode ( ) )
{
if ( pPlayer - > nextWeapon )
{
sfxKill3DSound ( pPlayer - > pSprite , - 1 , 441 ) ;
pPlayer - > newWeapon = pPlayer - > nextWeapon ;
2021-08-03 10:23:48 +00:00
pPlayer - > nextWeapon = kWeapNone ;
2021-03-09 08:30:27 +00:00
}
}
2019-10-21 19:46:41 +00:00
if ( pPlayer - > weaponState = = - 1 )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 0 ;
2019-09-19 22:42:45 +00:00
int t ;
2021-04-17 08:34:12 +00:00
int weapon = WeaponFindLoaded ( pPlayer , & t ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponMode [ weapon ] = t ;
if ( pPlayer - > curWeapon )
2019-09-19 22:42:45 +00:00
{
WeaponLower ( pPlayer ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > nextWeapon = weapon ;
2019-09-19 22:42:45 +00:00
return ;
}
2020-08-26 14:48:33 +00:00
pPlayer - > newWeapon = weapon ;
2019-09-19 22:42:45 +00:00
}
2020-08-26 14:48:33 +00:00
if ( pPlayer - > newWeapon )
2019-09-19 22:42:45 +00:00
{
2021-08-21 10:16:48 +00:00
if ( pPlayer - > isUnderwater & & BannedUnderwater ( pPlayer - > newWeapon ) & & ! checkFired6or7 ( pPlayer ) & & ! VanillaMode ( ) ) // skip banned weapons when underwater and using next/prev weapon key inputs
2021-08-13 12:39:16 +00:00
{
2021-08-13 15:55:24 +00:00
if ( prevNewWeaponVal = = WeaponSel_Next | | prevNewWeaponVal = = WeaponSel_Prev ) // if player switched weapons
2021-08-13 12:39:16 +00:00
{
PLAYER tmpPlayer = * pPlayer ;
tmpPlayer . 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
{
2021-08-13 15:55:24 +00:00
tmpPlayer . curWeapon = WeaponFindNext ( & tmpPlayer , NULL , ( char ) ( prevNewWeaponVal = = WeaponSel_Next ) ) ;
2021-08-13 12:39:16 +00:00
if ( ! BannedUnderwater ( tmpPlayer . curWeapon ) ) // if new weapon is not a banned weapon, set to new current weapon
{
pPlayer - > newWeapon = tmpPlayer . curWeapon ;
pPlayer - > weaponMode [ pPlayer - > newWeapon ] = 0 ;
break ;
}
}
}
}
2021-08-03 10:23:39 +00:00
if ( pPlayer - > newWeapon = = kWeapDynamite )
2019-09-19 22:42:45 +00:00
{
2021-08-18 09:56:06 +00:00
if ( pPlayer - > curWeapon = = kWeapDynamite )
2019-09-19 22:42:45 +00:00
{
2020-11-21 17:14:24 +00:00
if ( checkAmmo2 ( pPlayer , 10 , 1 ) )
2021-08-03 10:23:39 +00:00
pPlayer - > newWeapon = kWeapProximity ;
2020-11-21 17:14:24 +00:00
else if ( checkAmmo2 ( pPlayer , 11 , 1 ) )
2021-08-03 10:23:39 +00:00
pPlayer - > newWeapon = kWeapRemote ;
2019-09-19 22:42:45 +00:00
}
2021-08-18 09:56:06 +00:00
else if ( pPlayer - > curWeapon = = kWeapProximity )
2019-09-19 22:42:45 +00:00
{
2020-11-21 17:14:24 +00:00
if ( checkAmmo2 ( pPlayer , 11 , 1 ) )
2021-08-03 10:23:39 +00:00
pPlayer - > newWeapon = kWeapRemote ;
2020-11-21 17:14:24 +00:00
else if ( checkAmmo2 ( pPlayer , 5 , 1 ) & & pPlayer - > isUnderwater = = 0 )
2021-08-03 10:23:39 +00:00
pPlayer - > newWeapon = kWeapDynamite ;
2019-09-19 22:42:45 +00:00
}
2021-08-18 09:56:06 +00:00
else if ( pPlayer - > curWeapon = = kWeapRemote )
2019-09-19 22:42:45 +00:00
{
2020-11-21 17:14:24 +00:00
if ( checkAmmo2 ( pPlayer , 5 , 1 ) & & pPlayer - > isUnderwater = = 0 )
2021-08-03 10:23:39 +00:00
pPlayer - > newWeapon = kWeapDynamite ;
2020-11-21 17:14:24 +00:00
else if ( checkAmmo2 ( pPlayer , 10 , 1 ) )
2021-08-03 10:23:39 +00:00
pPlayer - > newWeapon = kWeapProximity ;
2019-09-19 22:42:45 +00:00
}
else
{
2020-11-21 17:14:24 +00:00
if ( checkAmmo2 ( pPlayer , 5 , 1 ) & & pPlayer - > isUnderwater = = 0 )
2021-08-03 10:23:39 +00:00
pPlayer - > newWeapon = kWeapDynamite ;
2020-11-21 17:14:24 +00:00
else if ( checkAmmo2 ( pPlayer , 10 , 1 ) )
2021-08-03 10:23:39 +00:00
pPlayer - > newWeapon = kWeapVoodooDoll ;
2020-11-21 17:14:24 +00:00
else if ( checkAmmo2 ( pPlayer , 11 , 1 ) )
2021-08-03 10:23:39 +00:00
pPlayer - > newWeapon = kWeapRemote ;
2019-09-19 22:42:45 +00:00
}
}
2021-08-23 01:40:05 +00:00
else if ( ( pPlayer - > newWeapon = = kWeapSpraycan ) & & ! VanillaMode ( ) )
2021-08-12 12:55:39 +00:00
{
2021-08-23 01:02:09 +00:00
if ( ( pPlayer - > curWeapon = = kWeapSpraycan ) & & ( pPlayer - > weaponState = = 2 ) ) // fix spray can state glitch when switching from spray to tnt and back quickly
2021-08-12 12:55:39 +00:00
{
pPlayer - > weaponState = 1 ;
2021-08-23 01:02:09 +00:00
pPlayer - > newWeapon = kWeapNone ;
2021-08-12 12:55:39 +00:00
return ;
}
}
2020-08-26 14:48:33 +00:00
if ( pPlayer - > pXSprite - > health = = 0 | | pPlayer - > hasWeapon [ pPlayer - > newWeapon ] = = 0 )
2019-09-19 22:42:45 +00:00
{
2021-08-23 01:02:09 +00:00
pPlayer - > newWeapon = kWeapNone ;
2019-09-19 22:42:45 +00:00
return ;
}
2021-08-12 09:19:07 +00:00
if ( pPlayer - > isUnderwater & & BannedUnderwater ( pPlayer - > newWeapon ) & & ! checkFired6or7 ( pPlayer ) )
2019-09-19 22:42:45 +00:00
{
2021-08-03 10:23:39 +00:00
pPlayer - > newWeapon = kWeapNone ;
2019-09-19 22:42:45 +00:00
return ;
}
2020-08-26 14:48:33 +00:00
int nWeapon = pPlayer - > newWeapon ;
2020-11-21 18:30:00 +00:00
int v4c = weaponModes [ nWeapon ] . update ;
2019-10-21 19:46:41 +00:00
if ( ! pPlayer - > curWeapon )
2019-09-19 22:42:45 +00:00
{
2020-11-21 18:30:00 +00:00
int nAmmoType = weaponModes [ nWeapon ] . ammoType ;
2019-09-19 22:42:45 +00:00
if ( v4c > 1 )
{
if ( CheckAmmo ( pPlayer , nAmmoType , 1 ) | | nAmmoType = = 11 )
WeaponRaise ( pPlayer ) ;
2021-08-03 10:23:39 +00:00
pPlayer - > newWeapon = kWeapNone ;
2019-09-19 22:42:45 +00:00
}
else
{
2020-11-21 18:30:00 +00:00
if ( CheckWeaponAmmo ( pPlayer , nWeapon , nAmmoType , 1 ) )
2019-09-19 22:42:45 +00:00
WeaponRaise ( pPlayer ) ;
else
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 0 ;
2019-09-19 22:42:45 +00:00
int t ;
2021-04-17 08:34:12 +00:00
int weapon = WeaponFindLoaded ( pPlayer , & t ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponMode [ weapon ] = t ;
if ( pPlayer - > curWeapon )
2019-09-19 22:42:45 +00:00
{
WeaponLower ( pPlayer ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > nextWeapon = weapon ;
2019-09-19 22:42:45 +00:00
return ;
}
2020-08-26 14:48:33 +00:00
pPlayer - > newWeapon = weapon ;
2019-09-19 22:42:45 +00:00
}
}
return ;
}
2019-10-21 19:46:41 +00:00
if ( nWeapon = = pPlayer - > curWeapon & & v4c < = 1 )
2019-09-19 22:42:45 +00:00
{
2021-08-03 10:23:39 +00:00
pPlayer - > newWeapon = kWeapNone ;
2019-09-19 22:42:45 +00:00
return ;
}
int i = 0 ;
2019-10-21 19:46:41 +00:00
if ( nWeapon = = pPlayer - > curWeapon )
2019-09-19 22:42:45 +00:00
i = 1 ;
for ( ; i < = v4c ; i + + )
{
2019-10-21 19:46:41 +00:00
int v6c = ( pPlayer - > weaponMode [ nWeapon ] + i ) % v4c ;
2020-11-21 18:30:00 +00:00
if ( CheckWeaponAmmo ( pPlayer , nWeapon , weaponModes [ nWeapon ] . ammoType , 1 ) )
2019-09-19 22:42:45 +00:00
{
WeaponLower ( pPlayer ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponMode [ nWeapon ] = v6c ;
2019-09-19 22:42:45 +00:00
return ;
}
}
2021-08-03 10:23:39 +00:00
pPlayer - > newWeapon = kWeapNone ;
2019-09-19 22:42:45 +00:00
return ;
}
2019-10-21 19:46:41 +00:00
if ( pPlayer - > curWeapon & & ! CheckAmmo ( pPlayer , pPlayer - > weaponAmmo , 1 ) & & pPlayer - > weaponAmmo ! = 11 )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = - 1 ;
2019-09-19 22:42:45 +00:00
return ;
}
if ( bShoot )
{
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > curWeapon )
2019-09-19 22:42:45 +00:00
{
2021-08-18 09:56:06 +00:00
case kWeapPitchFork :
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVPFORK , nClientFirePitchfork ) ;
2019-09-19 22:42:45 +00:00
return ;
2021-08-18 09:56:06 +00:00
case kWeapSpraycan :
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > weaponState )
2019-09-19 22:42:45 +00:00
{
case 3 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 4 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVCANFIRE , nClientFireSpray , 1 ) ;
2019-09-19 22:42:45 +00:00
return ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapDynamite :
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > weaponState )
2019-09-19 22:42:45 +00:00
{
case 3 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 6 ;
pPlayer - > fuseTime = - 1 ;
2021-02-18 10:46:36 +00:00
pPlayer - > throwTime = PlayClock ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVBUNFUSE , nClientExplodeBundle ) ;
2019-09-19 22:42:45 +00:00
return ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapProximity :
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > weaponState )
2019-09-19 22:42:45 +00:00
{
case 7 :
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVPROXIDLE ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 9 ;
2021-02-18 10:46:36 +00:00
pPlayer - > throwTime = PlayClock ;
2019-09-19 22:42:45 +00:00
return ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapRemote :
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > weaponState )
2019-09-19 22:42:45 +00:00
{
case 10 :
2021-08-28 06:36:27 +00:00
SetQAV ( pPlayer , kQAVREMIDLE1 ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 13 ;
2021-02-18 10:46:36 +00:00
pPlayer - > throwTime = PlayClock ;
2019-09-19 22:42:45 +00:00
return ;
case 11 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 12 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVREMFIRE , nClientFireRemote ) ;
2019-09-19 22:42:45 +00:00
return ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapShotgun :
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > weaponState )
2019-09-19 22:42:45 +00:00
{
case 7 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 6 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2SHOTF2 , nClientFireShotgun ) ;
2019-09-19 22:42:45 +00:00
return ;
case 3 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 2 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSHOTF1 , nClientFireShotgun ) ;
2019-09-19 22:42:45 +00:00
return ;
case 2 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 1 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSHOTF2 , nClientFireShotgun ) ;
2019-09-19 22:42:45 +00:00
return ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapTommyGun :
2020-11-21 17:14:24 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 3 , 2 ) )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2TOMFIRE , nClientFireTommy , 1 ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVTOMFIRE , nClientFireTommy , 1 ) ;
2019-09-19 22:42:45 +00:00
return ;
2021-08-18 09:56:06 +00:00
case kWeapFlareGun :
2020-11-21 17:14:24 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 1 , 2 ) )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVFLAR2FIR , nClientFireFlare ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVFLARFIR2 , nClientFireFlare ) ;
2019-09-19 22:42:45 +00:00
return ;
2021-08-18 09:56:06 +00:00
case kWeapVoodooDoll :
2019-09-19 22:42:45 +00:00
{
static int nChance [ ] = { 0xa000 , 0xc000 , 0xe000 , 0x10000 } ;
int nRand = wrand ( ) * 2 ;
int i ;
for ( i = 0 ; nChance [ i ] < nRand ; i + + )
{
}
2019-10-21 19:46:41 +00:00
pPlayer - > voodooTarget = pPlayer - > aimTarget ;
2019-10-07 19:29:52 +00:00
if ( pPlayer - > voodooTarget = = - 1 | | sprite [ pPlayer - > voodooTarget ] . statnum ! = kStatDude )
2019-09-19 22:42:45 +00:00
i = 4 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVVDFIRE1 + i , nClientFireVoodoo ) ;
2019-09-19 22:42:45 +00:00
return ;
}
2021-08-18 09:56:06 +00:00
case kWeapTeslaCannon :
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > weaponState )
2019-09-19 22:42:45 +00:00
{
case 2 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 4 ;
2020-11-21 17:14:24 +00:00
if ( checkAmmo2 ( pPlayer , 7 , 10 ) & & powerupCheck ( pPlayer , kPwUpTwoGuns ) )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2SGUNFIR , nClientFireTesla ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSGUNFIR1 , nClientFireTesla ) ;
2019-09-19 22:42:45 +00:00
return ;
case 5 :
2020-11-21 17:14:24 +00:00
if ( checkAmmo2 ( pPlayer , 7 , 10 ) & & powerupCheck ( pPlayer , kPwUpTwoGuns ) )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2SGUNFIR , nClientFireTesla ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSGUNFIR1 , nClientFireTesla ) ;
2019-09-19 22:42:45 +00:00
return ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapNapalm :
2019-10-19 19:11:39 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2NAPFIRE , nClientFireNapalm ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVNAPFIRE , nClientFireNapalm ) ;
2019-09-19 22:42:45 +00:00
return ;
2021-08-18 09:56:06 +00:00
case kWeapLifeLeech :
2019-09-19 22:42:45 +00:00
sfxPlay3DSound ( pPlayer - > pSprite , 494 , 2 , 0 ) ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSTAFIRE4 , nClientFireLifeLeech ) ;
2019-09-19 22:42:45 +00:00
return ;
2021-08-18 09:56:06 +00:00
case kWeapBeast :
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVBSTATAK1 + Random ( 4 ) , nClientFireBeast ) ;
2019-09-19 22:42:45 +00:00
return ;
}
}
if ( bShoot2 )
{
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > curWeapon )
2019-09-19 22:42:45 +00:00
{
2021-08-18 09:56:06 +00:00
case kWeapPitchFork :
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVPFORK , nClientFirePitchfork ) ;
2019-09-19 22:42:45 +00:00
return ;
2021-08-18 09:56:06 +00:00
case kWeapSpraycan :
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > weaponState )
2019-09-19 22:42:45 +00:00
{
case 3 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 5 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVCANFIRE2 , nClientExplodeCan ) ;
2019-09-19 22:42:45 +00:00
return ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapDynamite :
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > weaponState )
2019-09-19 22:42:45 +00:00
{
case 3 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 4 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVBUNFUSE , nClientExplodeBundle ) ;
2019-09-19 22:42:45 +00:00
return ;
case 7 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 8 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVPROXDROP , nClientDropProx ) ;
2019-09-19 22:42:45 +00:00
return ;
case 10 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 11 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVREMDROP , nClientDropRemote ) ;
2019-09-19 22:42:45 +00:00
return ;
case 11 :
2019-10-25 20:53:41 +00:00
if ( pPlayer - > ammoCount [ 11 ] > 0 )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 10 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVREMUP1 ) ;
2019-09-19 22:42:45 +00:00
}
return ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapProximity :
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > weaponState )
2019-09-19 22:42:45 +00:00
{
case 7 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 8 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVPROXDROP , nClientDropProx ) ;
2019-09-19 22:42:45 +00:00
return ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapRemote :
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > weaponState )
2019-09-19 22:42:45 +00:00
{
case 10 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 11 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVREMDROP , nClientDropRemote ) ;
2019-09-19 22:42:45 +00:00
return ;
case 11 :
2019-10-25 20:53:41 +00:00
if ( pPlayer - > ammoCount [ 11 ] > 0 )
2019-09-19 22:42:45 +00:00
{
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 10 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVREMUP1 ) ;
2019-09-19 22:42:45 +00:00
}
return ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapShotgun :
2019-10-21 19:46:41 +00:00
switch ( pPlayer - > weaponState )
2019-09-19 22:42:45 +00:00
{
case 7 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 6 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2SHOTFIR , nClientFireShotgun ) ;
2019-09-19 22:42:45 +00:00
return ;
case 3 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 1 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSHOTF3 , nClientFireShotgun ) ;
2019-09-19 22:42:45 +00:00
return ;
case 2 :
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = 1 ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSHOTF2 , nClientFireShotgun ) ;
2019-09-19 22:42:45 +00:00
return ;
}
break ;
2021-08-18 09:56:06 +00:00
case kWeapTommyGun :
2020-11-21 17:14:24 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 3 , 2 ) )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2TOMALT , nClientAltFireSpread2 ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVTOMSPRED , nClientAltFireSpread2 ) ;
2019-09-19 22:42:45 +00:00
return ;
2021-08-18 09:56:06 +00:00
case kWeapVoodooDoll :
2019-09-19 22:42:45 +00:00
sfxPlay3DSound ( pPlayer - > pSprite , 461 , 2 , 0 ) ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVVDSPEL1 , nClientAltFireVoodoo ) ;
2019-09-19 22:42:45 +00:00
return ;
#if 0
2021-08-18 09:56:06 +00:00
case kWeapFlareGun :
2020-11-21 17:14:24 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 1 , 2 ) )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVFLAR2FIR , nClientFireFlare , 0 ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVFLARFIR2 , nClientFireFlare , 0 ) ;
2019-09-19 22:42:45 +00:00
return ;
# endif
2021-08-18 09:56:06 +00:00
case kWeapTeslaCannon :
2020-11-21 17:14:24 +00:00
if ( checkAmmo2 ( pPlayer , 7 , 35 ) )
2019-09-19 22:42:45 +00:00
{
2020-11-21 17:14:24 +00:00
if ( checkAmmo2 ( pPlayer , 7 , 70 ) & & powerupCheck ( pPlayer , kPwUpTwoGuns ) )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2SGUNALT , nClientFireTesla ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSGUNFIR4 , nClientFireTesla ) ;
2019-09-19 22:42:45 +00:00
}
else
{
2020-11-21 17:14:24 +00:00
if ( checkAmmo2 ( pPlayer , 7 , 10 ) & & powerupCheck ( pPlayer , kPwUpTwoGuns ) )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAV2SGUNFIR , nClientFireTesla ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSGUNFIR1 , nClientFireTesla ) ;
2019-09-19 22:42:45 +00:00
}
return ;
2021-08-18 09:56:06 +00:00
case kWeapNapalm :
2019-10-19 19:11:39 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) )
2019-09-21 11:02:17 +00:00
// by NoOne: allow napalm launcher alt fire act like in v1.0x versions
2021-08-23 01:40:05 +00:00
if ( gGameOptions . weaponsV10x & & ! VanillaMode ( ) ) StartQAV ( pPlayer , kQAV2NAPFIR2 , nClientFireNapalm2 ) ;
else StartQAV ( pPlayer , kQAV2NAPFIRE , nClientAltFireNapalm ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-23 01:40:05 +00:00
StartQAV ( pPlayer , kQAVNAPFIRE , ( gGameOptions . weaponsV10x & & ! VanillaMode ( ) ) ? nClientFireNapalm : nClientAltFireNapalm ) ;
2019-09-19 22:42:45 +00:00
return ;
2021-08-18 09:56:06 +00:00
case kWeapFlareGun :
2019-09-19 22:42:45 +00:00
if ( CheckAmmo ( pPlayer , 1 , 8 ) )
{
2020-11-21 17:14:24 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 1 , 16 ) )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVFLAR2FIR , nClientAltFireFlare ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVFLARFIR2 , nClientAltFireFlare ) ;
2019-09-19 22:42:45 +00:00
}
else
{
2020-11-21 17:14:24 +00:00
if ( powerupCheck ( pPlayer , kPwUpTwoGuns ) & & checkAmmo2 ( pPlayer , 1 , 2 ) )
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVFLAR2FIR , nClientFireFlare ) ;
2019-09-19 22:42:45 +00:00
else
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVFLARFIR2 , nClientFireFlare ) ;
2019-09-19 22:42:45 +00:00
}
return ;
2021-08-18 09:56:06 +00:00
case kWeapLifeLeech :
2020-11-21 17:14:24 +00:00
if ( gGameOptions . nGameType < = 1 & & ! checkAmmo2 ( pPlayer , 8 , 1 ) & & pPlayer - > pXSprite - > health < ( 25 < < 4 ) )
2019-09-19 22:42:45 +00:00
{
sfxPlay3DSound ( pPlayer - > pSprite , 494 , 2 , 0 ) ;
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSTAFIRE4 , nClientFireLifeLeech ) ;
2019-09-19 22:42:45 +00:00
}
else
{
2021-08-03 10:52:32 +00:00
StartQAV ( pPlayer , kQAVSTAFDOWN ) ;
2019-09-19 22:42:45 +00:00
AltFireLifeLeech ( 1 , pPlayer ) ;
2019-10-21 19:46:41 +00:00
pPlayer - > weaponState = - 1 ;
2019-09-19 22:42:45 +00:00
}
return ;
}
}
WeaponUpdateState ( pPlayer ) ;
}
2020-11-21 18:30:00 +00:00
void teslaHit ( spritetype * pMissile , int a2 )
2019-09-19 22:42:45 +00:00
{
2021-09-16 19:18:26 +00:00
auto missileactor = & bloodActors [ pMissile - > index ] ;
2021-08-18 05:14:58 +00:00
uint8_t sectmap [ ( kMaxSectors + 7 ) > > 3 ] ;
2019-09-19 22:42:45 +00:00
int x = pMissile - > x ;
int y = pMissile - > y ;
int z = pMissile - > z ;
int nDist = 300 ;
int nSector = pMissile - > sectnum ;
2021-09-16 19:18:26 +00:00
auto owner = missileactor - > GetOwner ( ) ;
2021-08-21 10:16:48 +00:00
const bool newSectCheckMethod = ! cl_bloodvanillaexplosions & & ! VanillaMode ( ) ; // use new sector checking logic
2021-08-18 05:14:58 +00:00
GetClosestSpriteSectors ( nSector , x , y , nDist , sectmap , nullptr , newSectCheckMethod ) ;
2021-04-17 08:34:12 +00:00
bool v4 = true ;
2020-12-03 17:00:07 +00:00
DBloodActor * actor = nullptr ;
actHitcodeToData ( a2 , & gHitInfo , & actor ) ;
if ( a2 = = 3 & & actor & & actor - > s ( ) . statnum = = kStatDude )
2021-04-17 08:34:12 +00:00
v4 = false ;
2021-09-16 19:18:26 +00:00
BloodStatIterator it ( kStatDude ) ;
while ( auto hitactor = it . Next ( ) )
2019-09-19 22:42:45 +00:00
{
2021-09-16 19:18:26 +00:00
if ( hitactor ! = owner | | v4 )
2019-09-19 22:42:45 +00:00
{
2021-09-16 19:18:26 +00:00
spritetype * pHitSprite = & hitactor - > s ( ) ;
if ( pHitSprite - > flags & 32 )
2019-09-19 22:42:45 +00:00
continue ;
2021-09-16 19:18:26 +00:00
if ( TestBitString ( sectmap , pHitSprite - > sectnum ) & & CheckProximity ( pHitSprite , x , y , z , nSector , nDist ) )
2019-09-19 22:42:45 +00:00
{
2021-09-16 19:18:26 +00:00
int dx = pMissile - > x - pHitSprite - > x ;
int dy = pMissile - > y - pHitSprite - > y ;
2019-09-19 22:42:45 +00:00
int nDamage = ClipLow ( ( nDist - ( ksqrt ( dx * dx + dy * dy ) > > 4 ) + 20 ) > > 1 , 10 ) ;
2021-09-16 19:18:26 +00:00
if ( hitactor = = owner )
2019-09-19 22:42:45 +00:00
nDamage / = 2 ;
2021-09-16 19:18:26 +00:00
actDamageSprite ( owner , hitactor , kDamageTesla , nDamage < < 4 ) ;
2019-09-19 22:42:45 +00:00
}
}
}
2020-10-15 15:15:45 +00:00
it . Reset ( kStatThing ) ;
2021-09-16 19:18:26 +00:00
while ( auto hitactor = it . Next ( ) )
2019-09-19 22:42:45 +00:00
{
2021-09-16 19:18:26 +00:00
spritetype * pHitSprite = & hitactor - > s ( ) ;
if ( pHitSprite - > flags & 32 )
2019-09-19 22:42:45 +00:00
continue ;
2021-09-16 19:18:26 +00:00
if ( TestBitString ( sectmap , pHitSprite - > sectnum ) & & CheckProximity ( pHitSprite , x , y , z , nSector , nDist ) )
2019-09-19 22:42:45 +00:00
{
2021-09-16 19:18:26 +00:00
XSPRITE * pXSprite = & hitactor - > x ( ) ;
2019-09-19 22:42:45 +00:00
if ( ! pXSprite - > locked )
{
2021-09-16 19:18:26 +00:00
int dx = pMissile - > x - pHitSprite - > x ;
int dy = pMissile - > y - pHitSprite - > y ;
2019-09-19 22:42:45 +00:00
int nDamage = ClipLow ( nDist - ( ksqrt ( dx * dx + dy * dy ) > > 4 ) + 20 , 20 ) ;
2021-09-16 19:18:26 +00:00
actDamageSprite ( owner , hitactor , kDamageTesla , nDamage < < 4 ) ;
2019-09-19 22:42:45 +00:00
}
}
}
}
2019-09-22 06:39:22 +00:00
END_BLD_NS