2020-05-14 10:14:03 +00:00
//-------------------------------------------------------------------------
/*
Copyright ( C ) 1996 , 2003 - 3 D Realms Entertainment
Copyright ( C ) 2000 , 2003 - Matt Saettler ( EDuke Enhancements )
2020-06-28 07:03:31 +00:00
Copyright ( C ) 2020 - Christoph Oelckers
2020-05-14 10:14:03 +00:00
This file is part of Enhanced Duke Nukem 3 D version 1.5 - Atomic Edition
Duke Nukem 3 D is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
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 . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
Original Source : 1996 - Todd Replogle
Prepared for public release : 03 / 21 / 2003 - Charlie Wiederhold , 3 D Realms
EDuke enhancements integrated : 04 / 13 / 2003 - Matt Saettler
Note : EDuke source was in transition . Changes are in - progress in the
source as it is released .
*/
//-------------------------------------------------------------------------
# include "ns.h"
# include "global.h"
2020-05-16 21:55:21 +00:00
# include "gamevar.h"
2020-07-03 21:56:14 +00:00
# include "names_d.h"
2020-10-21 17:38:53 +00:00
# include "dukeactor.h"
2020-05-14 10:14:03 +00:00
BEGIN_DUKE_NS
2020-05-18 22:26:07 +00:00
void fireweapon_ww ( int snum ) ;
2021-11-21 07:48:36 +00:00
void operateweapon_ww ( int snum , ESyncBits actions ) ;
2020-05-18 22:26:07 +00:00
2020-05-16 21:55:21 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-02-07 10:04:19 +00:00
void incur_damage_d ( player_struct * p )
2020-05-16 21:55:21 +00:00
{
int damage = 0L , shield_damage = 0L ;
2021-12-21 17:19:45 +00:00
p - > GetActor ( ) - > spr . extra - = p - > extra_extra8 > > 8 ;
2020-05-16 21:55:21 +00:00
2021-12-21 17:19:45 +00:00
damage = p - > GetActor ( ) - > spr . extra - p - > last_extra ;
2020-05-16 21:55:21 +00:00
if ( damage < 0 )
{
p - > extra_extra8 = 0 ;
if ( p - > shield_amount > 0 )
{
shield_damage = damage * ( 20 + ( rand ( ) % 30 ) ) / 100 ;
damage - = shield_damage ;
p - > shield_amount + = shield_damage ;
if ( p - > shield_amount < 0 )
{
damage + = p - > shield_amount ;
p - > shield_amount = 0 ;
}
}
2021-12-21 17:19:45 +00:00
p - > GetActor ( ) - > spr . extra = p - > last_extra + damage ;
2020-05-16 21:55:21 +00:00
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-10-23 18:16:47 +00:00
static void shootfireball ( DDukeActor * actor , int p , int sx , int sy , int sz , int sa )
2020-05-16 21:55:21 +00:00
{
2020-10-20 22:17:09 +00:00
int vel , zvel ;
2021-12-21 19:40:35 +00:00
if ( actor - > spr . extra > = 0 )
actor - > spr . shade = - 96 ;
2020-10-20 22:17:09 +00:00
sz - = ( 4 < < 7 ) ;
2021-12-21 19:40:35 +00:00
if ( actor - > spr . picnum ! = BOSS5 )
2020-10-20 22:17:09 +00:00
vel = 840 ;
else {
vel = 968 ;
sz + = 6144 ;
}
if ( p < 0 )
2020-05-16 21:55:21 +00:00
{
2020-10-20 22:17:09 +00:00
sa + = 16 - ( krand ( ) & 31 ) ;
int scratch ;
2020-11-02 22:10:19 +00:00
int j = findplayer ( actor , & scratch ) ;
2022-02-04 17:11:44 +00:00
zvel = ( ( ( ps [ j ] . player_int_opos ( ) . Z - sz + ( 3 < < 8 ) ) ) * vel ) / ldist ( ps [ j ] . GetActor ( ) , actor ) ;
2020-05-16 21:55:21 +00:00
}
else
{
2021-01-04 11:36:54 +00:00
zvel = - MulScale ( ps [ p ] . horizon . sum ( ) . asq16 ( ) , 98 , 16 ) ;
2020-11-15 11:07:03 +00:00
sx + = bcos ( sa + 348 ) / 448 ;
sy + = bsin ( sa + 348 ) / 448 ;
2020-10-20 22:17:09 +00:00
sz + = ( 3 < < 8 ) ;
2020-05-16 21:55:21 +00:00
}
2020-10-20 22:17:09 +00:00
int sizx = 18 ;
int sizy = 18 ;
if ( p > = 0 )
2020-09-17 21:02:52 +00:00
{
2020-10-20 22:17:09 +00:00
sizx = 7 ;
sizy = 7 ;
}
2021-12-30 15:51:56 +00:00
auto spawned = EGS ( actor - > sector ( ) , sx , sy , sz , FIREBALL , - 127 , sizx , sizy , sa , vel , zvel , actor , ( short ) 4 ) ;
2021-11-19 08:47:17 +00:00
if ( spawned )
2020-10-20 22:17:09 +00:00
{
2021-12-21 19:33:39 +00:00
spawned - > spr . extra + = ( krand ( ) & 7 ) ;
2021-12-21 19:40:35 +00:00
if ( actor - > spr . picnum = = BOSS5 | | p > = 0 )
2021-11-19 08:47:17 +00:00
{
2021-12-21 19:33:39 +00:00
spawned - > spr . xrepeat = 40 ;
spawned - > spr . yrepeat = 40 ;
2021-11-19 08:47:17 +00:00
}
2021-12-21 19:33:39 +00:00
spawned - > spr . yvel = p ;
spawned - > spr . cstat = CSTAT_SPRITE_YCENTER ;
spawned - > spr . clipdist = 4 ;
2020-09-17 21:02:52 +00:00
}
2020-10-20 22:17:09 +00:00
}
2020-09-17 21:02:52 +00:00
2020-10-20 22:17:09 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-09-17 21:02:52 +00:00
2022-08-30 19:42:44 +00:00
static void shootflamethrowerflame ( DDukeActor * actor , int p , DVector3 spos , DAngle sang )
2020-10-20 22:17:09 +00:00
{
2022-08-30 19:42:44 +00:00
double vel , zvel = 0 ;
2020-05-16 21:55:21 +00:00
2021-12-21 19:40:35 +00:00
if ( actor - > spr . extra > = 0 )
actor - > spr . shade = - 96 ;
2022-08-30 19:42:44 +00:00
vel = 25 ;
2020-10-20 22:17:09 +00:00
2020-10-23 18:16:47 +00:00
DDukeActor * spawned = nullptr ;
2020-10-20 22:17:09 +00:00
if ( p < 0 )
2020-05-16 21:55:21 +00:00
{
2020-10-20 22:17:09 +00:00
int x ;
2020-10-23 18:16:47 +00:00
int j = findplayer ( actor , & x ) ;
2022-08-30 19:42:44 +00:00
sang = VecToAngle ( ps [ j ] . opos . XY ( ) - spos . XY ( ) ) ;
2020-05-16 21:55:21 +00:00
2021-12-21 19:40:35 +00:00
if ( actor - > spr . picnum = = BOSS5 )
2020-10-20 22:17:09 +00:00
{
2022-08-30 19:42:44 +00:00
vel = 33 ;
spos . Z + = 24 ;
2020-10-20 22:17:09 +00:00
}
2021-12-21 19:40:35 +00:00
else if ( actor - > spr . picnum = = BOSS3 )
2022-08-30 19:42:44 +00:00
spos . Z - = 32 ;
2020-05-16 21:55:21 +00:00
2022-08-30 19:42:44 +00:00
double l = ( ps [ j ] . GetActor ( ) - > spr . pos . XY ( ) - actor - > spr . pos . XY ( ) ) . Length ( ) ;
2020-10-20 22:17:09 +00:00
if ( l ! = 0 )
2022-08-30 19:42:44 +00:00
zvel = ( ( ps [ j ] . opos . Z - spos . Z ) * vel ) / l ;
2020-10-20 22:17:09 +00:00
2021-12-21 19:40:35 +00:00
if ( badguy ( actor ) & & ( actor - > spr . hitag & face_player_smart ) ! = 0 )
2022-08-30 19:42:44 +00:00
sang = actor - > spr . angle + DAngle : : fromBuild ( ( krand ( ) & 31 ) - 16 ) ;
2020-10-20 22:17:09 +00:00
2021-12-30 15:51:56 +00:00
if ( actor - > sector ( ) - > lotag = = 2 & & ( krand ( ) % 5 ) = = 0 )
2020-10-23 18:16:47 +00:00
spawned = spawn ( actor , WATERBUBBLE ) ;
2020-05-16 21:55:21 +00:00
}
else
{
2022-08-30 19:42:44 +00:00
zvel = - MulScale ( ps [ p ] . horizon . sum ( ) . asq16 ( ) , 81 , 16 ) * zinttoworld ;
// WTF???
DAngle myang = ( DAngle90 - ( DAngle180 - fabs ( fabs ( VecToAngle ( spos . XY ( ) - ps [ p ] . pos . XY ( ) ) - sang ) - DAngle180 ) ) ) ;
2021-12-21 17:19:45 +00:00
if ( ps [ p ] . GetActor ( ) - > spr . xvel ! = 0 )
2022-08-30 19:42:44 +00:00
vel = ( int ) ( ( myang . Buildang ( ) * 0.001953125f * ps [ p ] . GetActor ( ) - > spr . xvel ) + 400 ) ;
2021-12-30 15:51:56 +00:00
if ( actor - > sector ( ) - > lotag = = 2 & & ( krand ( ) % 5 ) = = 0 )
2020-10-23 18:16:47 +00:00
spawned = spawn ( actor , WATERBUBBLE ) ;
2020-05-16 21:55:21 +00:00
}
2020-10-23 18:16:47 +00:00
if ( spawned = = nullptr )
2020-10-20 22:17:09 +00:00
{
2020-10-23 18:16:47 +00:00
spawned = spawn ( actor , FLAMETHROWERFLAME ) ;
2021-11-19 11:32:12 +00:00
if ( ! spawned ) return ;
2022-08-30 19:42:44 +00:00
spawned - > spr . xvel = ( short ) ( vel * worldtoint ) ;
2022-08-31 22:28:40 +00:00
spawned - > set_int_zvel ( zvel * 256 ) ;
2021-12-21 17:19:45 +00:00
}
2022-08-30 19:42:44 +00:00
spawned - > spr . pos = spos + ( sang + DAngle : : fromBuild ( 112 ) ) . ToVector ( ) * 7 ;
spawned - > spr . pos . Z - - ;
2021-12-30 15:51:56 +00:00
spawned - > setsector ( actor - > sector ( ) ) ;
2021-12-21 17:19:45 +00:00
spawned - > spr . cstat = CSTAT_SPRITE_YCENTER ;
2022-08-30 19:42:44 +00:00
spawned - > spr . angle = sang ;
2021-12-21 17:19:45 +00:00
spawned - > spr . xrepeat = 2 ;
spawned - > spr . yrepeat = 2 ;
spawned - > spr . clipdist = 40 ;
spawned - > spr . yvel = p ;
2020-10-23 18:16:47 +00:00
spawned - > SetOwner ( actor ) ;
2020-10-20 22:17:09 +00:00
if ( p = = - 1 )
{
2021-12-21 19:40:35 +00:00
if ( actor - > spr . picnum = = BOSS5 )
2020-05-16 21:55:21 +00:00
{
2022-08-30 19:42:44 +00:00
spawned - > spr . pos + = sang . ToVector ( ) * ( 128. / 7 ) ;
2021-12-21 17:19:45 +00:00
spawned - > spr . xrepeat = 10 ;
spawned - > spr . yrepeat = 10 ;
2020-10-20 22:17:09 +00:00
}
}
}
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-05-16 21:55:21 +00:00
2020-10-23 18:16:47 +00:00
static void shootknee ( DDukeActor * actor , int p , int sx , int sy , int sz , int sa )
2020-10-20 22:17:09 +00:00
{
2021-12-30 15:51:56 +00:00
auto sectp = actor - > sector ( ) ;
2020-10-20 22:17:09 +00:00
int zvel ;
2021-12-06 11:24:22 +00:00
HitInfo hit { } ;
2020-10-20 22:17:09 +00:00
if ( p > = 0 )
{
zvel = - ps [ p ] . horizon . sum ( ) . asq16 ( ) > > 11 ;
sz + = ( 6 < < 8 ) ;
sa + = 15 ;
}
else
{
int x ;
2020-11-02 22:10:19 +00:00
auto pactor = ps [ findplayer ( actor , & x ) ] . GetActor ( ) ;
2022-01-31 18:21:49 +00:00
zvel = ( ( pactor - > int_pos ( ) . Z - sz ) < < 8 ) / ( x + 1 ) ;
sa = getangle ( pactor - > int_pos ( ) . X - sx , pactor - > int_pos ( ) . Y - sy ) ;
2020-10-20 22:17:09 +00:00
}
2022-08-20 13:47:52 +00:00
hitscan ( vec3_t ( sx , sy , sz ) , sectp , { bcos ( sa ) , bsin ( sa ) , zvel < < 6 } , hit , CLIPMASK1 ) ;
2020-10-20 22:17:09 +00:00
2021-11-25 23:08:59 +00:00
if ( hit . hitSector = = nullptr ) return ;
2020-10-20 22:17:09 +00:00
2022-08-16 22:59:32 +00:00
if ( ( abs ( sx - hit . int_hitpos ( ) . X ) + abs ( sy - hit . int_hitpos ( ) . Y ) ) < 1024 )
2020-10-20 22:17:09 +00:00
{
2021-11-25 23:08:59 +00:00
if ( hit . hitWall | | hit . actor ( ) )
2020-10-20 22:17:09 +00:00
{
2022-08-23 20:32:45 +00:00
auto knee = CreateActor ( hit . hitSector , hit . hitpos , KNEE , - 15 , 0 , 0 , sa , 32 , 0 , actor , 4 ) ;
2021-11-19 08:47:17 +00:00
if ( knee )
2020-05-16 21:55:21 +00:00
{
2021-12-21 17:19:45 +00:00
knee - > spr . extra + = ( krand ( ) & 7 ) ;
2021-11-19 08:47:17 +00:00
if ( p > = 0 )
{
auto k = spawn ( knee , SMALLSMOKE ) ;
2022-02-07 07:47:18 +00:00
if ( k ) k - > spr . pos . Z - = 8 ;
2021-11-19 08:47:17 +00:00
S_PlayActorSound ( KICK_HIT , knee ) ;
}
2020-10-20 22:17:09 +00:00
2021-11-19 08:47:17 +00:00
if ( p > = 0 & & ps [ p ] . steroids_amount > 0 & & ps [ p ] . steroids_amount < 400 )
2021-12-21 17:19:45 +00:00
knee - > spr . extra + = ( gs . max_player_health > > 2 ) ;
2021-11-19 08:47:17 +00:00
}
2021-12-21 17:19:45 +00:00
if ( hit . actor ( ) & & hit . actor ( ) - > spr . picnum ! = ACCESSSWITCH & & hit . actor ( ) - > spr . picnum ! = ACCESSSWITCH2 )
2020-05-16 21:55:21 +00:00
{
2021-11-25 23:08:59 +00:00
fi . checkhitsprite ( hit . actor ( ) , knee ) ;
if ( p > = 0 ) fi . checkhitswitch ( p , nullptr , hit . actor ( ) ) ;
2020-05-16 21:55:21 +00:00
}
2021-11-25 23:08:59 +00:00
else if ( hit . hitWall )
2020-05-16 21:55:21 +00:00
{
2021-12-18 14:11:21 +00:00
if ( hit . hitWall - > cstat & CSTAT_WALL_BOTTOM_SWAP )
2021-11-25 23:08:59 +00:00
if ( hit . hitWall - > twoSided ( ) )
2022-08-28 09:34:54 +00:00
if ( hit . hitpos . Z > = hit . hitWall - > nextSector ( ) - > floorz )
2021-11-25 23:08:59 +00:00
hit . hitWall = hit . hitWall - > nextWall ( ) ;
2020-05-16 21:55:21 +00:00
2021-11-25 23:08:59 +00:00
if ( hit . hitWall - > picnum ! = ACCESSSWITCH & & hit . hitWall - > picnum ! = ACCESSSWITCH2 )
2020-05-16 21:55:21 +00:00
{
2022-08-23 20:39:07 +00:00
fi . checkhitwall ( knee , hit . hitWall , hit . hitpos , KNEE ) ;
2021-11-25 23:08:59 +00:00
if ( p > = 0 ) fi . checkhitswitch ( p , hit . hitWall , nullptr ) ;
2020-05-16 21:55:21 +00:00
}
2020-10-20 22:17:09 +00:00
}
}
2021-11-25 23:08:59 +00:00
else if ( p > = 0 & & zvel > 0 & & hit . hitSector - > lotag = = 1 )
2020-10-20 22:17:09 +00:00
{
2020-10-23 20:06:02 +00:00
auto splash = spawn ( ps [ p ] . GetActor ( ) , WATERSPLASH2 ) ;
2021-11-19 11:32:12 +00:00
if ( splash )
{
2022-08-29 17:30:19 +00:00
splash - > spr . pos . XY ( ) = hit . hitpos . XY ( ) ;
splash - > spr . angle = ps [ p ] . angle . ang ; // Total tweek
2021-12-21 17:19:45 +00:00
splash - > spr . xvel = 32 ;
2021-11-19 11:32:12 +00:00
ssp ( actor , CLIPMASK0 ) ;
2021-12-21 17:19:45 +00:00
splash - > spr . xvel = 0 ;
2021-11-19 11:32:12 +00:00
}
2020-10-20 22:17:09 +00:00
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-05-16 21:55:21 +00:00
2020-10-24 04:33:31 +00:00
static void shootweapon ( DDukeActor * actor , int p , int sx , int sy , int sz , int sa , int atwith )
2020-10-20 22:17:09 +00:00
{
2021-12-30 15:51:56 +00:00
auto sectp = actor - > sector ( ) ;
2021-11-14 14:03:50 +00:00
int zvel = 0 ;
2021-12-06 11:24:22 +00:00
HitInfo hit { } ;
2020-05-16 21:55:21 +00:00
2021-12-21 19:40:35 +00:00
if ( actor - > spr . extra > = 0 ) actor - > spr . shade = - 96 ;
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
if ( p > = 0 )
{
2020-11-01 17:23:09 +00:00
SetGameVarID ( g_iAimAngleVarID , AUTO_AIM_ANGLE , actor , p ) ;
2020-11-01 16:57:40 +00:00
OnEvent ( EVENT_GETAUTOAIMANGLE , p , ps [ p ] . GetActor ( ) , - 1 ) ;
2021-12-05 16:36:57 +00:00
int varval = GetGameVarID ( g_iAimAngleVarID , actor , p ) . value ( ) ;
2020-11-01 19:57:02 +00:00
DDukeActor * aimed = nullptr ;
2020-11-01 17:23:09 +00:00
if ( varval > 0 )
2020-10-20 22:17:09 +00:00
{
2020-11-01 19:57:02 +00:00
aimed = aim ( actor , varval ) ;
2020-10-20 22:17:09 +00:00
}
2020-11-01 19:57:02 +00:00
if ( aimed )
2020-10-20 22:17:09 +00:00
{
2021-12-21 17:19:45 +00:00
int dal = ( ( aimed - > spr . xrepeat * tileHeight ( aimed - > spr . picnum ) ) < < 1 ) + ( 5 < < 8 ) ;
switch ( aimed - > spr . picnum )
2020-05-16 21:55:21 +00:00
{
2020-10-20 22:17:09 +00:00
case GREENSLIME :
case GREENSLIME + 1 :
case GREENSLIME + 2 :
case GREENSLIME + 3 :
case GREENSLIME + 4 :
case GREENSLIME + 5 :
case GREENSLIME + 6 :
case GREENSLIME + 7 :
case ROTATEGUN :
dal - = ( 8 < < 8 ) ;
break ;
2020-05-16 21:55:21 +00:00
}
2022-01-31 18:21:49 +00:00
zvel = ( ( aimed - > int_pos ( ) . Z - sz - dal ) < < 8 ) / ldist ( ps [ p ] . GetActor ( ) , aimed ) ;
sa = getangle ( aimed - > int_pos ( ) . X - sx , aimed - > int_pos ( ) . Y - sy ) ;
2020-10-20 22:17:09 +00:00
}
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
if ( isWW2GI ( ) )
{
int angRange = 32 ;
int zRange = 256 ;
2020-11-01 17:23:09 +00:00
SetGameVarID ( g_iAngRangeVarID , 32 , actor , p ) ;
SetGameVarID ( g_iZRangeVarID , 256 , actor , p ) ;
2020-11-01 16:57:40 +00:00
OnEvent ( EVENT_GETSHOTRANGE , p , ps [ p ] . GetActor ( ) , - 1 ) ;
2021-12-05 16:36:57 +00:00
angRange = GetGameVarID ( g_iAngRangeVarID , actor , p ) . value ( ) ;
zRange = GetGameVarID ( g_iZRangeVarID , actor , p ) . value ( ) ;
2020-10-20 22:17:09 +00:00
sa + = ( angRange / 2 ) - ( krand ( ) & ( angRange - 1 ) ) ;
2020-11-01 19:57:02 +00:00
if ( aimed = = nullptr )
2020-05-16 21:55:21 +00:00
{
2020-10-20 22:17:09 +00:00
// no target
zvel = - ps [ p ] . horizon . sum ( ) . asq16 ( ) > > 11 ;
2020-05-16 21:55:21 +00:00
}
2020-10-20 22:17:09 +00:00
zvel + = ( zRange / 2 ) - ( krand ( ) & ( zRange - 1 ) ) ;
}
2020-11-01 19:57:02 +00:00
else if ( aimed = = nullptr )
2020-10-20 22:17:09 +00:00
{
sa + = 16 - ( krand ( ) & 31 ) ;
zvel = - ps [ p ] . horizon . sum ( ) . asq16 ( ) > > 11 ;
zvel + = 128 - ( krand ( ) & 255 ) ;
}
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
sz - = ( 2 < < 8 ) ;
}
else
{
int x ;
2020-11-01 19:57:02 +00:00
int j = findplayer ( actor , & x ) ;
2020-10-20 22:17:09 +00:00
sz - = ( 4 < < 8 ) ;
2022-02-04 17:11:44 +00:00
zvel = ( ( ps [ j ] . player_int_pos ( ) . Z - sz ) < < 8 ) / ( ldist ( ps [ j ] . GetActor ( ) , actor ) ) ;
2021-12-21 19:40:35 +00:00
if ( actor - > spr . picnum ! = BOSS1 )
2020-10-20 22:17:09 +00:00
{
zvel + = 128 - ( krand ( ) & 255 ) ;
sa + = 32 - ( krand ( ) & 63 ) ;
}
else
{
zvel + = 128 - ( krand ( ) & 255 ) ;
2022-02-04 17:11:44 +00:00
sa = getangle ( ps [ j ] . player_int_pos ( ) . X - sx , ps [ j ] . player_int_pos ( ) . Y - sy ) + 64 - ( krand ( ) & 127 ) ;
2020-10-20 22:17:09 +00:00
}
}
2021-12-21 19:40:35 +00:00
actor - > spr . cstat & = ~ CSTAT_SPRITE_BLOCK_ALL ;
2022-08-20 13:47:52 +00:00
hitscan ( vec3_t ( sx , sy , sz ) , sectp , { bcos ( sa ) , bsin ( sa ) , zvel < < 6 } , hit , CLIPMASK1 ) ;
2021-12-21 19:40:35 +00:00
actor - > spr . cstat | = CSTAT_SPRITE_BLOCK_ALL ;
2020-10-20 22:17:09 +00:00
2020-10-23 20:06:02 +00:00
2021-11-25 23:08:59 +00:00
if ( hit . hitSector = = nullptr ) return ;
2020-10-20 22:17:09 +00:00
2021-11-25 23:08:59 +00:00
if ( ( krand ( ) & 15 ) = = 0 & & hit . hitSector - > lotag = = 2 )
2022-08-16 22:59:32 +00:00
tracers ( hit . int_hitpos ( ) . X , hit . int_hitpos ( ) . Y , hit . int_hitpos ( ) . Z , sx , sy , sz , 8 - ( ud . multimode > > 1 ) ) ;
2020-05-16 21:55:21 +00:00
2020-10-24 04:33:31 +00:00
DDukeActor * spark ;
2020-10-20 22:17:09 +00:00
if ( p > = 0 )
{
2022-08-23 20:32:45 +00:00
spark = CreateActor ( hit . hitSector , hit . hitpos , SHOTSPARK1 , - 15 , 10 , 10 , sa , 0 , 0 , actor , 4 ) ;
2021-11-19 08:47:17 +00:00
if ( ! spark ) return ;
2021-12-21 17:19:45 +00:00
spark - > spr . extra = ScriptCode [ gs . actorinfo [ atwith ] . scriptaddress ] ;
spark - > spr . extra + = ( krand ( ) % 6 ) ;
2020-10-20 22:17:09 +00:00
2021-11-25 23:08:59 +00:00
if ( hit . hitWall = = nullptr & & hit . actor ( ) = = nullptr )
2020-10-20 22:17:09 +00:00
{
if ( zvel < 0 )
2020-05-16 21:55:21 +00:00
{
2021-12-18 12:14:56 +00:00
if ( hit . hitSector - > ceilingstat & CSTAT_SECTOR_SKY )
2020-05-16 21:55:21 +00:00
{
2021-12-21 17:19:45 +00:00
spark - > spr . xrepeat = 0 ;
spark - > spr . yrepeat = 0 ;
2020-10-20 22:17:09 +00:00
return ;
2020-05-16 21:55:21 +00:00
}
2020-10-20 22:17:09 +00:00
else
2021-11-25 23:08:59 +00:00
fi . checkhitceiling ( hit . hitSector ) ;
2020-05-16 21:55:21 +00:00
}
2020-10-23 20:06:02 +00:00
spawn ( spark , SMALLSMOKE ) ;
2020-05-16 21:55:21 +00:00
}
2021-11-25 23:08:59 +00:00
if ( hit . actor ( ) )
2020-05-16 21:55:21 +00:00
{
2021-11-25 23:08:59 +00:00
fi . checkhitsprite ( hit . actor ( ) , spark ) ;
2021-12-31 17:47:00 +00:00
if ( hit . actor ( ) - > isPlayer ( ) & & ( ud . coop ! = 1 | | ud . ffire = = 1 ) )
2020-05-16 21:55:21 +00:00
{
2021-12-21 17:19:45 +00:00
spark - > spr . xrepeat = spark - > spr . yrepeat = 0 ;
2021-11-19 11:32:12 +00:00
auto jib = spawn ( spark , JIBS6 ) ;
if ( jib )
{
2022-02-07 07:47:18 +00:00
jib - > spr . pos . Z + = 4 ;
2021-12-21 17:19:45 +00:00
jib - > spr . xvel = 16 ;
jib - > spr . xrepeat = jib - > spr . yrepeat = 24 ;
2022-08-16 21:26:39 +00:00
jib - > add_int_ang ( 64 - ( krand ( ) & 127 ) ) ;
2021-11-19 11:32:12 +00:00
}
2020-05-16 21:55:21 +00:00
}
2020-10-23 20:06:02 +00:00
else spawn ( spark , SMALLSMOKE ) ;
2020-10-20 22:17:09 +00:00
if ( p > = 0 & & (
2021-12-21 17:19:45 +00:00
hit . actor ( ) - > spr . picnum = = DIPSWITCH | |
hit . actor ( ) - > spr . picnum = = DIPSWITCH + 1 | |
hit . actor ( ) - > spr . picnum = = DIPSWITCH2 | |
hit . actor ( ) - > spr . picnum = = DIPSWITCH2 + 1 | |
hit . actor ( ) - > spr . picnum = = DIPSWITCH3 | |
hit . actor ( ) - > spr . picnum = = DIPSWITCH3 + 1 | |
hit . actor ( ) - > spr . picnum = = HANDSWITCH | |
hit . actor ( ) - > spr . picnum = = HANDSWITCH + 1 ) )
2020-05-16 21:55:21 +00:00
{
2021-11-25 23:08:59 +00:00
fi . checkhitswitch ( p , nullptr , hit . actor ( ) ) ;
2020-10-20 22:17:09 +00:00
return ;
2020-05-16 21:55:21 +00:00
}
}
2021-11-25 23:08:59 +00:00
else if ( hit . hitWall )
2020-10-20 22:17:09 +00:00
{
2020-10-23 20:06:02 +00:00
spawn ( spark , SMALLSMOKE ) ;
2020-10-20 22:17:09 +00:00
2021-11-25 23:08:59 +00:00
if ( fi . isadoorwall ( hit . hitWall - > picnum ) = = 1 )
2020-10-20 22:17:09 +00:00
goto SKIPBULLETHOLE ;
if ( p > = 0 & & (
2021-11-25 23:08:59 +00:00
hit . hitWall - > picnum = = DIPSWITCH | |
hit . hitWall - > picnum = = DIPSWITCH + 1 | |
hit . hitWall - > picnum = = DIPSWITCH2 | |
hit . hitWall - > picnum = = DIPSWITCH2 + 1 | |
hit . hitWall - > picnum = = DIPSWITCH3 | |
hit . hitWall - > picnum = = DIPSWITCH3 + 1 | |
hit . hitWall - > picnum = = HANDSWITCH | |
hit . hitWall - > picnum = = HANDSWITCH + 1 ) )
2020-10-20 22:17:09 +00:00
{
2021-11-25 23:08:59 +00:00
fi . checkhitswitch ( p , hit . hitWall , nullptr ) ;
2020-10-20 22:17:09 +00:00
return ;
}
2020-05-16 21:55:21 +00:00
2021-11-25 23:08:59 +00:00
if ( hit . hitWall - > hitag ! = 0 | | ( hit . hitWall - > twoSided ( ) & & hit . hitWall - > nextWall ( ) - > hitag ! = 0 ) )
2020-10-20 22:17:09 +00:00
goto SKIPBULLETHOLE ;
2020-05-16 21:55:21 +00:00
2021-11-25 23:08:59 +00:00
if ( hit . hitSector & & hit . hitSector - > lotag = = 0 )
if ( hit . hitWall - > overpicnum ! = BIGFORCE )
if ( ( hit . hitWall - > twoSided ( ) & & hit . hitWall - > nextSector ( ) - > lotag = = 0 ) | |
( ! hit . hitWall - > twoSided ( ) & & hit . hitSector - > lotag = = 0 ) )
2021-12-18 14:11:21 +00:00
if ( ( hit . hitWall - > cstat & CSTAT_WALL_MASKED ) = = 0 )
2020-05-16 21:55:21 +00:00
{
2021-11-25 23:08:59 +00:00
if ( hit . hitWall - > twoSided ( ) )
2020-05-16 21:55:21 +00:00
{
2021-11-25 23:08:59 +00:00
DukeSectIterator it ( hit . hitWall - > nextSector ( ) ) ;
2020-10-24 04:33:31 +00:00
while ( auto l = it . Next ( ) )
2020-05-16 21:55:21 +00:00
{
2022-01-13 19:53:36 +00:00
if ( l - > spr . statnum = = STAT_EFFECTOR & & l - > spr . lotag = = SE_13_EXPLOSIVE )
2020-10-20 22:17:09 +00:00
goto SKIPBULLETHOLE ;
2020-05-16 21:55:21 +00:00
}
}
2020-10-24 04:33:31 +00:00
DukeStatIterator it ( STAT_MISC ) ;
while ( auto l = it . Next ( ) )
2020-05-16 21:55:21 +00:00
{
2021-12-21 17:19:45 +00:00
if ( l - > spr . picnum = = BULLETHOLE )
2020-10-24 04:33:31 +00:00
if ( dist ( l , spark ) < ( 12 + ( krand ( ) & 7 ) ) )
2020-10-20 22:17:09 +00:00
goto SKIPBULLETHOLE ;
2020-05-16 21:55:21 +00:00
}
2020-10-23 20:06:02 +00:00
auto hole = spawn ( spark , BULLETHOLE ) ;
2021-11-19 11:32:12 +00:00
if ( hole )
{
2021-12-21 17:19:45 +00:00
hole - > spr . xvel = - 1 ;
2022-08-30 21:05:54 +00:00
hole - > set_int_ang ( getangle ( - hit . hitWall - > delta ( ) ) + 512 ) ;
2021-11-19 11:32:12 +00:00
ssp ( hole , CLIPMASK0 ) ;
2022-01-13 19:53:36 +00:00
hole - > spr . cstat2 | = CSTAT2_SPRITE_DECAL ;
2021-11-19 11:32:12 +00:00
}
2020-05-16 21:55:21 +00:00
}
2020-10-20 22:17:09 +00:00
SKIPBULLETHOLE :
2020-05-16 21:55:21 +00:00
2021-12-18 14:11:21 +00:00
if ( hit . hitWall - > cstat & CSTAT_WALL_BOTTOM_SWAP )
2021-11-25 23:08:59 +00:00
if ( hit . hitWall - > twoSided ( ) )
2022-08-28 09:34:54 +00:00
if ( hit . hitpos . Z > = hit . hitWall - > nextSector ( ) - > floorz )
2021-11-25 23:08:59 +00:00
hit . hitWall = hit . hitWall - > nextWall ( ) ;
2020-05-16 21:55:21 +00:00
2022-08-23 20:39:07 +00:00
fi . checkhitwall ( spark , hit . hitWall , hit . hitpos , SHOTSPARK1 ) ;
2020-10-20 22:17:09 +00:00
}
}
else
{
2022-08-23 20:32:45 +00:00
spark = CreateActor ( hit . hitSector , hit . hitpos , SHOTSPARK1 , - 15 , 24 , 24 , sa , 0 , 0 , actor , 4 ) ;
2021-11-19 08:47:17 +00:00
if ( spark )
2020-10-20 22:17:09 +00:00
{
2021-12-21 17:19:45 +00:00
spark - > spr . extra = ScriptCode [ gs . actorinfo [ atwith ] . scriptaddress ] ;
2021-11-19 08:47:17 +00:00
2021-11-25 23:08:59 +00:00
if ( hit . actor ( ) )
2021-11-19 08:47:17 +00:00
{
2021-11-25 23:08:59 +00:00
fi . checkhitsprite ( hit . actor ( ) , spark ) ;
2021-12-31 17:47:00 +00:00
if ( ! hit . actor ( ) - > isPlayer ( ) )
2021-11-19 08:47:17 +00:00
spawn ( spark , SMALLSMOKE ) ;
2021-12-21 17:19:45 +00:00
else spark - > spr . xrepeat = spark - > spr . yrepeat = 0 ;
2021-11-19 08:47:17 +00:00
}
2021-11-25 23:08:59 +00:00
else if ( hit . hitWall )
2022-08-23 20:39:07 +00:00
fi . checkhitwall ( spark , hit . hitWall , hit . hitpos , SHOTSPARK1 ) ;
2020-10-20 22:17:09 +00:00
}
}
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
if ( ( krand ( ) & 255 ) < 4 )
{
2022-08-16 22:59:32 +00:00
S_PlaySound3D ( PISTOL_RICOCHET , spark , hit . int_hitpos ( ) ) ;
2020-10-20 22:17:09 +00:00
}
}
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-05-16 21:55:21 +00:00
2020-10-24 04:40:41 +00:00
static void shootstuff ( DDukeActor * actor , int p , int sx , int sy , int sz , int sa , int atwith )
2020-10-20 22:17:09 +00:00
{
2021-12-30 15:51:56 +00:00
sectortype * sect = actor - > sector ( ) ;
2020-10-20 22:17:09 +00:00
int vel , zvel ;
2021-11-07 13:36:39 +00:00
int l , scount ;
2020-05-16 21:55:21 +00:00
2021-12-21 19:40:35 +00:00
if ( actor - > spr . extra > = 0 ) actor - > spr . shade = - 96 ;
2020-10-20 22:17:09 +00:00
scount = 1 ;
if ( atwith = = SPIT ) vel = 292 ;
else
{
if ( atwith = = COOLEXPLOSION1 )
2020-05-16 21:55:21 +00:00
{
2021-12-21 19:40:35 +00:00
if ( actor - > spr . picnum = = BOSS2 ) vel = 644 ;
2020-10-20 22:17:09 +00:00
else vel = 348 ;
sz - = ( 4 < < 7 ) ;
}
else
{
vel = 840 ;
sz - = ( 4 < < 7 ) ;
}
}
2020-09-17 20:36:09 +00:00
2020-10-20 22:17:09 +00:00
if ( p > = 0 )
{
2020-11-01 19:57:02 +00:00
auto aimed = aim ( actor , AUTO_AIM_ANGLE ) ;
2020-05-16 21:55:21 +00:00
2020-11-01 19:57:02 +00:00
if ( aimed )
2020-10-20 22:17:09 +00:00
{
2021-12-21 17:19:45 +00:00
int dal = ( ( aimed - > spr . xrepeat * tileHeight ( aimed - > spr . picnum ) ) < < 1 ) - ( 12 < < 8 ) ;
2022-01-31 18:21:49 +00:00
zvel = ( ( aimed - > int_pos ( ) . Z - sz - dal ) * vel ) / ldist ( ps [ p ] . GetActor ( ) , aimed ) ;
sa = getangle ( aimed - > int_pos ( ) . X - sx , aimed - > int_pos ( ) . Y - sy ) ;
2020-05-16 21:55:21 +00:00
}
else
2021-01-04 11:36:54 +00:00
zvel = - MulScale ( ps [ p ] . horizon . sum ( ) . asq16 ( ) , 98 , 16 ) ;
2020-10-20 22:17:09 +00:00
}
else
{
int x ;
2020-11-01 19:57:02 +00:00
int j = findplayer ( actor , & x ) ;
2021-11-09 23:05:42 +00:00
// sa = getangle(ps[j].oposx-sx,ps[j].oposy-sy);
2020-10-20 22:17:09 +00:00
sa + = 16 - ( krand ( ) & 31 ) ;
2022-02-04 17:11:44 +00:00
zvel = ( ( ( ps [ j ] . player_int_opos ( ) . Z - sz + ( 3 < < 8 ) ) ) * vel ) / ldist ( ps [ j ] . GetActor ( ) , actor ) ;
2020-10-20 22:17:09 +00:00
}
int oldzvel = zvel ;
int sizx , sizy ;
if ( atwith = = SPIT ) { sizx = 18 ; sizy = 18 , sz - = ( 10 < < 8 ) ; }
else
{
if ( atwith = = FIRELASER )
2020-05-16 21:55:21 +00:00
{
2020-10-20 22:17:09 +00:00
if ( p > = 0 )
2020-05-16 21:55:21 +00:00
{
2020-10-20 22:17:09 +00:00
sizx = 34 ;
sizy = 34 ;
2020-05-16 21:55:21 +00:00
}
else
{
2020-10-20 22:17:09 +00:00
sizx = 18 ;
sizy = 18 ;
2020-05-16 21:55:21 +00:00
}
}
2020-10-20 22:17:09 +00:00
else
{
sizx = 18 ;
sizy = 18 ;
}
}
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
if ( p > = 0 ) sizx = 7 , sizy = 7 ;
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
while ( scount > 0 )
{
2020-10-24 04:40:41 +00:00
auto spawned = EGS ( sect , sx , sy , sz , atwith , - 127 , sizx , sizy , sa , vel , zvel , actor , 4 ) ;
2021-11-19 08:47:17 +00:00
if ( ! spawned ) return ;
2021-12-21 17:19:45 +00:00
spawned - > spr . extra + = ( krand ( ) & 7 ) ;
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
if ( atwith = = COOLEXPLOSION1 )
2020-05-16 21:55:21 +00:00
{
2021-12-21 17:19:45 +00:00
spawned - > spr . shade = 0 ;
2021-12-21 19:40:35 +00:00
if ( actor - > spr . picnum = = BOSS2 )
2020-05-16 21:55:21 +00:00
{
2021-12-21 17:19:45 +00:00
l = spawned - > spr . xvel ;
spawned - > spr . xvel = 1024 ;
2020-10-24 04:40:41 +00:00
ssp ( spawned , CLIPMASK0 ) ;
2021-12-21 17:19:45 +00:00
spawned - > spr . xvel = l ;
2022-08-16 21:26:39 +00:00
spawned - > add_int_ang ( 128 - ( krand ( ) & 255 ) ) ;
2020-05-16 21:55:21 +00:00
}
2020-10-20 22:17:09 +00:00
}
2020-05-16 21:55:21 +00:00
2021-12-21 17:19:45 +00:00
spawned - > spr . cstat = CSTAT_SPRITE_YCENTER ;
spawned - > spr . clipdist = 4 ;
2020-05-16 21:55:21 +00:00
2022-08-16 21:15:49 +00:00
sa = actor - > int_ang ( ) + 32 - ( krand ( ) & 63 ) ;
2020-10-20 22:17:09 +00:00
zvel = oldzvel + 512 - ( krand ( ) & 1023 ) ;
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
scount - - ;
}
}
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-05-16 21:55:21 +00:00
2020-10-24 04:40:41 +00:00
static void shootrpg ( DDukeActor * actor , int p , int sx , int sy , int sz , int sa , int atwith )
2020-10-20 22:17:09 +00:00
{
2021-12-30 15:51:56 +00:00
auto sect = actor - > sector ( ) ;
2020-10-20 22:17:09 +00:00
int vel , zvel ;
2021-11-07 13:36:39 +00:00
int l , scount ;
2020-05-16 21:55:21 +00:00
2021-12-21 19:40:35 +00:00
if ( actor - > spr . extra > = 0 ) actor - > spr . shade = - 96 ;
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
scount = 1 ;
vel = 644 ;
2020-05-16 21:55:21 +00:00
2020-11-01 19:57:02 +00:00
DDukeActor * aimed = nullptr ;
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
if ( p > = 0 )
{
2020-11-01 19:57:02 +00:00
aimed = aim ( actor , 48 ) ;
if ( aimed )
2020-10-20 22:17:09 +00:00
{
2021-12-21 17:19:45 +00:00
int dal = ( ( aimed - > spr . xrepeat * tileHeight ( aimed - > spr . picnum ) ) < < 1 ) + ( 8 < < 8 ) ;
2022-01-31 18:21:49 +00:00
zvel = ( ( aimed - > int_pos ( ) . Z - sz - dal ) * vel ) / ldist ( ps [ p ] . GetActor ( ) , aimed ) ;
2021-12-21 17:19:45 +00:00
if ( aimed - > spr . picnum ! = RECON )
2022-01-31 18:21:49 +00:00
sa = getangle ( aimed - > int_pos ( ) . X - sx , aimed - > int_pos ( ) . Y - sy ) ;
2020-05-16 21:55:21 +00:00
}
2021-01-04 11:36:54 +00:00
else zvel = - MulScale ( ps [ p ] . horizon . sum ( ) . asq16 ( ) , 81 , 16 ) ;
2020-10-20 22:17:09 +00:00
if ( atwith = = RPG )
2020-10-24 04:40:41 +00:00
S_PlayActorSound ( RPG_SHOOT , actor ) ;
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
}
else
{
int x ;
2020-11-01 19:57:02 +00:00
int j = findplayer ( actor , & x ) ;
2022-02-04 17:11:44 +00:00
sa = getangle ( ps [ j ] . player_int_opos ( ) . X - sx , ps [ j ] . player_int_opos ( ) . Y - sy ) ;
2021-12-21 19:40:35 +00:00
if ( actor - > spr . picnum = = BOSS3 )
2020-05-16 21:55:21 +00:00
{
2020-10-20 22:17:09 +00:00
int zoffs = ( 32 < < 8 ) ;
if ( isWorldTour ( ) ) // Twentieth Anniversary World Tour
2021-12-21 17:19:45 +00:00
zoffs = ( int ) ( ( actor - > spr . yrepeat / 80.0f ) * zoffs ) ;
2020-10-20 22:17:09 +00:00
sz - = zoffs ;
}
2021-12-21 19:40:35 +00:00
else if ( actor - > spr . picnum = = BOSS2 )
2020-10-20 22:17:09 +00:00
{
vel + = 128 ;
int zoffs = 24 < < 8 ;
if ( isWorldTour ( ) ) // Twentieth Anniversary World Tour
2021-12-21 17:19:45 +00:00
zoffs = ( int ) ( ( actor - > spr . yrepeat / 80.0f ) * zoffs ) ;
2020-10-20 22:17:09 +00:00
sz + = zoffs ;
2020-05-16 21:55:21 +00:00
}
2020-10-24 04:40:41 +00:00
l = ldist ( ps [ j ] . GetActor ( ) , actor ) ;
2022-02-04 17:11:44 +00:00
zvel = ( ( ps [ j ] . player_int_opos ( ) . Z - sz ) * vel ) / l ;
2020-05-16 21:55:21 +00:00
2021-12-21 19:40:35 +00:00
if ( badguy ( actor ) & & ( actor - > spr . hitag & face_player_smart ) )
2022-08-16 21:15:49 +00:00
sa = actor - > int_ang ( ) + ( krand ( ) & 31 ) - 16 ;
2020-10-20 22:17:09 +00:00
}
2020-11-01 19:57:02 +00:00
if ( p < 0 ) aimed = nullptr ;
2020-05-16 21:55:21 +00:00
2020-10-23 19:37:40 +00:00
auto spawned = EGS ( sect ,
2020-11-15 11:07:03 +00:00
sx + ( bcos ( sa + 348 ) / 448 ) ,
sy + ( bsin ( sa + 348 ) / 448 ) ,
2020-10-24 04:40:41 +00:00
sz - ( 1 < < 8 ) , atwith , 0 , 14 , 14 , sa , vel , zvel , actor , 4 ) ;
2020-10-20 22:17:09 +00:00
2021-11-19 08:47:17 +00:00
if ( ! spawned ) return ;
2021-12-30 09:30:21 +00:00
2021-12-21 19:33:39 +00:00
spawned - > spr . extra + = ( krand ( ) & 7 ) ;
2020-10-20 22:17:09 +00:00
if ( atwith ! = FREEZEBLAST )
2020-11-01 19:57:02 +00:00
spawned - > temp_actor = aimed ;
2020-10-20 22:17:09 +00:00
else
{
2021-12-21 19:33:39 +00:00
spawned - > spr . yvel = gs . numfreezebounces ;
spawned - > spr . xrepeat > > = 1 ;
spawned - > spr . yrepeat > > = 1 ;
spawned - > spr . zvel - = ( 2 < < 4 ) ;
2020-10-20 22:17:09 +00:00
}
if ( p = = - 1 )
{
2021-12-21 19:40:35 +00:00
if ( actor - > spr . picnum = = BOSS3 )
2020-05-16 21:55:21 +00:00
{
2020-11-15 11:07:03 +00:00
int xoffs = bsin ( sa , - 6 ) ;
int yoffs = - bcos ( sa , - 6 ) ;
2020-10-20 22:17:09 +00:00
int aoffs = 4 ;
if ( ( krand ( ) & 1 ) ! = 0 )
2020-05-16 21:55:21 +00:00
{
2020-10-20 22:17:09 +00:00
xoffs = - xoffs ;
yoffs = - yoffs ;
aoffs = - 8 ;
2020-05-16 21:55:21 +00:00
}
2020-10-20 22:17:09 +00:00
if ( isWorldTour ( ) ) // Twentieth Anniversary World Tour
2020-05-16 21:55:21 +00:00
{
2021-12-21 17:19:45 +00:00
float siz = actor - > spr . yrepeat / 80.0f ;
2021-05-12 15:33:33 +00:00
xoffs = int ( xoffs * siz ) ;
yoffs = int ( yoffs * siz ) ;
aoffs = int ( aoffs * siz ) ;
2020-05-16 21:55:21 +00:00
}
2022-01-30 17:33:11 +00:00
spawned - > add_int_pos ( { xoffs , yoffs , 0 } ) ;
2022-08-16 21:26:39 +00:00
spawned - > add_int_ang ( aoffs ) ;
2020-05-16 21:55:21 +00:00
2021-12-21 19:33:39 +00:00
spawned - > spr . xrepeat = 42 ;
spawned - > spr . yrepeat = 42 ;
2020-05-16 21:55:21 +00:00
}
2021-12-21 19:40:35 +00:00
else if ( actor - > spr . picnum = = BOSS2 )
2020-05-16 21:55:21 +00:00
{
2020-11-15 11:07:03 +00:00
int xoffs = bsin ( sa ) / 56 ;
int yoffs = - bcos ( sa ) / 56 ;
2020-10-20 22:17:09 +00:00
int aoffs = 8 + ( krand ( ) & 255 ) - 128 ;
if ( isWorldTour ( ) ) { // Twentieth Anniversary World Tour
2021-12-21 17:19:45 +00:00
int siz = actor - > spr . yrepeat ;
2020-10-20 22:17:09 +00:00
xoffs = Scale ( xoffs , siz , 80 ) ;
yoffs = Scale ( yoffs , siz , 80 ) ;
aoffs = Scale ( aoffs , siz , 80 ) ;
}
2020-05-16 21:55:21 +00:00
2022-01-30 17:33:11 +00:00
spawned - > add_int_pos ( { - xoffs , - yoffs , 0 } ) ;
2022-08-16 21:27:44 +00:00
spawned - > add_int_ang ( - aoffs ) ;
2020-05-16 21:55:21 +00:00
2021-12-21 19:33:39 +00:00
spawned - > spr . xrepeat = 24 ;
spawned - > spr . yrepeat = 24 ;
2020-10-20 22:17:09 +00:00
}
else if ( atwith ! = FREEZEBLAST )
2020-05-16 21:55:21 +00:00
{
2021-12-21 19:33:39 +00:00
spawned - > spr . xrepeat = 30 ;
spawned - > spr . yrepeat = 30 ;
spawned - > spr . extra > > = 2 ;
2020-10-20 22:17:09 +00:00
}
}
2021-12-05 12:43:31 +00:00
else if ( ( isWW2GI ( ) & & aplWeaponWorksLike ( ps [ p ] . curr_weapon , p ) = = DEVISTATOR_WEAPON ) | | ( ! isWW2GI ( ) & & ps [ p ] . curr_weapon = = DEVISTATOR_WEAPON ) )
2020-10-20 22:17:09 +00:00
{
2021-12-21 19:33:39 +00:00
spawned - > spr . extra > > = 2 ;
2022-08-16 21:26:39 +00:00
spawned - > add_int_ang ( 16 - ( krand ( ) & 31 ) ) ;
2022-08-31 22:30:16 +00:00
spawned - > add_int_zvel ( 256 - ( krand ( ) & 511 ) ) ;
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
if ( ps [ p ] . hbomb_hold_delay )
{
2022-01-30 17:33:11 +00:00
spawned - > add_int_pos ( { - bsin ( sa ) / 644 , bcos ( sa ) / 644 , 0 } ) ;
2020-10-20 22:17:09 +00:00
}
else
{
2022-01-30 17:33:11 +00:00
spawned - > add_int_pos ( { bsin ( sa , - 8 ) , - bcos ( sa , - 8 ) , 0 } ) ;
2020-10-20 22:17:09 +00:00
}
2021-12-21 19:33:39 +00:00
spawned - > spr . xrepeat > > = 1 ;
spawned - > spr . yrepeat > > = 1 ;
2020-10-20 22:17:09 +00:00
}
2020-05-16 21:55:21 +00:00
2021-12-21 19:33:39 +00:00
spawned - > spr . cstat = CSTAT_SPRITE_YCENTER ;
2020-10-20 22:17:09 +00:00
if ( atwith = = RPG )
2021-12-21 19:33:39 +00:00
spawned - > spr . clipdist = 4 ;
2020-10-20 22:17:09 +00:00
else
2021-12-21 19:33:39 +00:00
spawned - > spr . clipdist = 40 ;
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
}
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-05-16 21:55:21 +00:00
2020-10-24 04:46:34 +00:00
static void shootlaser ( DDukeActor * actor , int p , int sx , int sy , int sz , int sa )
2020-10-20 22:17:09 +00:00
{
2021-12-30 15:51:56 +00:00
auto sectp = actor - > sector ( ) ;
2020-10-20 22:17:09 +00:00
int zvel ;
2021-11-17 22:57:17 +00:00
int j ;
2021-12-06 11:24:22 +00:00
HitInfo hit { } ;
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
if ( p > = 0 )
zvel = - ps [ p ] . horizon . sum ( ) . asq16 ( ) > > 11 ;
else zvel = 0 ;
2020-05-16 21:55:21 +00:00
2022-08-30 20:25:07 +00:00
hitscan ( vec3_t ( sx , sy , sz - ps [ p ] . pyoff * zworldtoint ) , sectp , { bcos ( sa ) , bsin ( sa ) , zvel < < 6 } , hit , CLIPMASK1 ) ;
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
j = 0 ;
2021-11-25 23:08:59 +00:00
if ( hit . actor ( ) ) return ;
2020-05-16 21:55:21 +00:00
2021-11-25 23:08:59 +00:00
if ( hit . hitWall & & hit . hitSector )
2021-11-17 21:46:50 +00:00
{
2022-08-16 22:59:32 +00:00
if ( ( ( hit . int_hitpos ( ) . X - sx ) * ( hit . int_hitpos ( ) . X - sx ) + ( hit . int_hitpos ( ) . Y - sy ) * ( hit . int_hitpos ( ) . Y - sy ) ) < ( 290 * 290 ) )
2020-05-16 21:55:21 +00:00
{
2021-11-25 23:08:59 +00:00
if ( hit . hitWall - > twoSided ( ) )
2020-05-16 21:55:21 +00:00
{
2021-11-25 23:08:59 +00:00
if ( hit . hitWall - > nextSector ( ) - > lotag < = 2 & & hit . hitSector - > lotag < = 2 )
2020-10-20 22:17:09 +00:00
j = 1 ;
2020-05-16 21:55:21 +00:00
}
2021-11-25 23:08:59 +00:00
else if ( hit . hitSector - > lotag < = 2 )
2020-10-20 22:17:09 +00:00
j = 1 ;
2020-05-16 21:55:21 +00:00
}
2020-10-20 22:17:09 +00:00
2021-11-17 21:46:50 +00:00
if ( j = = 1 )
2020-05-16 21:55:21 +00:00
{
2022-08-23 20:32:45 +00:00
auto bomb = CreateActor ( hit . hitSector , hit . hitpos , TRIPBOMB , - 16 , 4 , 5 , sa , 0 , 0 , actor , STAT_STANDABLE ) ;
2021-11-19 08:47:17 +00:00
if ( ! bomb ) return ;
2021-11-17 21:46:50 +00:00
if ( isWW2GI ( ) )
2020-05-16 21:55:21 +00:00
{
2021-12-05 16:36:57 +00:00
int lTripBombControl = GetGameVar ( " TRIPBOMB_CONTROL " , TRIPBOMB_TRIPWIRE , nullptr , - 1 ) . value ( ) ;
2021-11-17 21:46:50 +00:00
if ( lTripBombControl & TRIPBOMB_TIMER )
{
2021-12-05 16:36:57 +00:00
int lLifetime = GetGameVar ( " STICKYBOMB_LIFETIME " , NAM_GRENADE_LIFETIME , nullptr , p ) . value ( ) ;
int lLifetimeVar = GetGameVar ( " STICKYBOMB_LIFETIME_VAR " , NAM_GRENADE_LIFETIME_VAR , nullptr , p ) . value ( ) ;
2021-11-17 21:46:50 +00:00
// set timer. blows up when at zero....
2021-12-21 17:19:45 +00:00
bomb - > spr . extra = lLifetime
2021-01-04 11:57:26 +00:00
+ MulScale ( krand ( ) , lLifetimeVar , 14 )
2020-10-20 22:17:09 +00:00
- lLifetimeVar ;
2021-11-17 21:46:50 +00:00
}
2020-05-16 21:55:21 +00:00
}
2021-12-30 09:30:21 +00:00
2021-11-17 21:46:50 +00:00
// this originally used the sprite index as tag to link the laser segments.
// This value is never used again to reference an actor by index. Decouple this for robustness.
ud . bomb_tag = ( ud . bomb_tag + 1 ) & 32767 ;
2021-12-21 17:19:45 +00:00
bomb - > spr . hitag = ud . bomb_tag ;
2021-11-17 21:46:50 +00:00
S_PlayActorSound ( LASERTRIP_ONWALL , bomb ) ;
2021-12-21 17:19:45 +00:00
bomb - > spr . xvel = - 20 ;
2021-11-17 21:46:50 +00:00
ssp ( bomb , CLIPMASK0 ) ;
2021-12-21 17:19:45 +00:00
bomb - > spr . cstat = CSTAT_SPRITE_ALIGNMENT_WALL ;
2022-08-30 21:05:03 +00:00
auto delta = hit . hitWall - > delta ( ) ;
2022-08-29 21:12:39 +00:00
bomb - > spr . angle = VecToAngle ( - delta . X , - delta . Y ) - DAngle90 ;
bomb - > temp_angle = bomb - > spr . angle ;
2021-12-30 09:30:21 +00:00
2021-11-17 21:46:50 +00:00
if ( p > = 0 )
ps [ p ] . ammo_amount [ TRIPBOMB_WEAPON ] - - ;
2020-10-20 22:17:09 +00:00
}
}
}
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-05-16 21:55:21 +00:00
2020-10-24 04:46:34 +00:00
static void shootgrowspark ( DDukeActor * actor , int p , int sx , int sy , int sz , int sa )
2020-10-20 22:17:09 +00:00
{
2021-12-30 15:51:56 +00:00
auto sect = actor - > sector ( ) ;
2020-10-20 22:17:09 +00:00
int zvel ;
2021-11-17 22:57:17 +00:00
int k ;
2021-12-06 11:24:22 +00:00
HitInfo hit { } ;
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
if ( p > = 0 )
{
2020-11-01 19:57:02 +00:00
auto aimed = aim ( actor , AUTO_AIM_ANGLE ) ;
if ( aimed )
2020-10-20 22:17:09 +00:00
{
2021-12-21 17:19:45 +00:00
int dal = ( ( aimed - > spr . xrepeat * tileHeight ( aimed - > spr . picnum ) ) < < 1 ) + ( 5 < < 8 ) ;
switch ( aimed - > spr . picnum )
2020-10-20 22:17:09 +00:00
{
case GREENSLIME :
case GREENSLIME + 1 :
case GREENSLIME + 2 :
case GREENSLIME + 3 :
case GREENSLIME + 4 :
case GREENSLIME + 5 :
case GREENSLIME + 6 :
case GREENSLIME + 7 :
case ROTATEGUN :
dal - = ( 8 < < 8 ) ;
break ;
}
2022-01-31 18:21:49 +00:00
zvel = ( ( aimed - > int_pos ( ) . Z - sz - dal ) < < 8 ) / ( ldist ( ps [ p ] . GetActor ( ) , aimed ) ) ;
sa = getangle ( aimed - > int_pos ( ) . X - sx , aimed - > int_pos ( ) . Y - sy ) ;
2020-10-20 22:17:09 +00:00
}
2020-05-16 21:55:21 +00:00
else
{
2020-10-20 22:17:09 +00:00
sa + = 16 - ( krand ( ) & 31 ) ;
zvel = - ps [ p ] . horizon . sum ( ) . asq16 ( ) > > 11 ;
zvel + = 128 - ( krand ( ) & 255 ) ;
2020-05-16 21:55:21 +00:00
}
2020-10-20 22:17:09 +00:00
sz - = ( 2 < < 8 ) ;
}
else
{
int x ;
2020-11-02 22:10:19 +00:00
int j = findplayer ( actor , & x ) ;
2020-10-20 22:17:09 +00:00
sz - = ( 4 < < 8 ) ;
2022-02-04 17:11:44 +00:00
zvel = ( ( ps [ j ] . player_int_pos ( ) . Z - sz ) < < 8 ) / ( ldist ( ps [ j ] . GetActor ( ) , actor ) ) ;
2020-10-20 22:17:09 +00:00
zvel + = 128 - ( krand ( ) & 255 ) ;
sa + = 32 - ( krand ( ) & 63 ) ;
}
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
k = 0 ;
2020-05-16 21:55:21 +00:00
2021-11-09 23:05:42 +00:00
//RESHOOTGROW:
2020-05-16 21:55:21 +00:00
2021-12-21 19:40:35 +00:00
actor - > spr . cstat & = ~ CSTAT_SPRITE_BLOCK_ALL ;
2022-08-20 13:47:52 +00:00
hitscan ( vec3_t ( sx , sy , sz ) , sect , { bcos ( sa ) , bsin ( sa ) , zvel < < 6 } , hit , CLIPMASK1 ) ;
2020-05-16 21:55:21 +00:00
2021-12-21 19:40:35 +00:00
actor - > spr . cstat | = CSTAT_SPRITE_BLOCK_ALL ;
2020-09-07 19:38:17 +00:00
2022-08-16 22:59:32 +00:00
auto spark = EGS ( sect , hit . int_hitpos ( ) . X , hit . int_hitpos ( ) . Y , hit . int_hitpos ( ) . Z , GROWSPARK , - 16 , 28 , 28 , sa , 0 , 0 , actor , 1 ) ;
2021-11-19 08:47:17 +00:00
if ( ! spark ) return ;
2020-05-16 21:55:21 +00:00
2021-12-21 17:19:45 +00:00
spark - > spr . pal = 2 ;
spark - > spr . cstat | = CSTAT_SPRITE_YCENTER | CSTAT_SPRITE_TRANSLUCENT ;
spark - > spr . xrepeat = spark - > spr . yrepeat = 1 ;
2020-05-16 21:55:21 +00:00
2021-11-25 23:08:59 +00:00
if ( hit . hitWall = = nullptr & & hit . actor ( ) = = nullptr & & hit . hitSector ! = nullptr )
2020-10-20 22:17:09 +00:00
{
2021-12-18 12:14:56 +00:00
if ( zvel < 0 & & ( hit . hitSector - > ceilingstat & CSTAT_SECTOR_SKY ) = = 0 )
2021-11-25 23:08:59 +00:00
fi . checkhitceiling ( hit . hitSector ) ;
2020-10-20 22:17:09 +00:00
}
2021-11-25 23:08:59 +00:00
else if ( hit . actor ( ) ! = nullptr ) fi . checkhitsprite ( hit . actor ( ) , spark ) ;
else if ( hit . hitWall ! = nullptr )
2020-10-20 22:17:09 +00:00
{
2021-11-25 23:08:59 +00:00
if ( hit . hitWall - > picnum ! = ACCESSSWITCH & & hit . hitWall - > picnum ! = ACCESSSWITCH2 )
2021-11-17 22:49:49 +00:00
{
2022-08-23 20:39:07 +00:00
fi . checkhitwall ( spark , hit . hitWall , hit . hitpos , GROWSPARK ) ;
2021-11-17 22:49:49 +00:00
}
2020-10-20 22:17:09 +00:00
}
}
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-05-16 21:55:21 +00:00
2020-10-24 05:34:39 +00:00
void shoot_d ( DDukeActor * actor , int atwith )
2020-10-20 22:17:09 +00:00
{
2021-11-18 18:04:00 +00:00
int l , j ;
2020-10-20 22:17:09 +00:00
int sx , sy , sz , sa , p , vel , zvel , x , dal ;
2021-12-31 17:47:00 +00:00
if ( actor - > isPlayer ( ) )
2020-10-20 22:17:09 +00:00
{
2021-12-21 19:40:35 +00:00
p = actor - > spr . yvel ;
2020-10-20 22:17:09 +00:00
}
else
{
p = - 1 ;
}
2020-05-16 21:55:21 +00:00
2020-10-24 05:28:07 +00:00
SetGameVarID ( g_iAtWithVarID , atwith , actor , p ) ;
2020-11-01 17:23:09 +00:00
SetGameVarID ( g_iReturnVarID , 0 , actor , p ) ;
2020-11-01 16:57:40 +00:00
OnEvent ( EVENT_SHOOT , p , ps [ p ] . GetActor ( ) , - 1 ) ;
2021-12-05 16:36:57 +00:00
if ( GetGameVarID ( g_iReturnVarID , actor , p ) . safeValue ( ) ! = 0 )
2020-10-20 22:17:09 +00:00
{
return ;
}
2020-05-16 21:55:21 +00:00
2021-12-30 15:51:56 +00:00
auto sect = actor - > sector ( ) ;
2020-10-20 22:17:09 +00:00
zvel = 0 ;
2020-05-16 21:55:21 +00:00
2021-12-31 17:47:00 +00:00
if ( actor - > isPlayer ( ) )
2020-10-20 22:17:09 +00:00
{
2022-02-04 17:11:44 +00:00
sx = ps [ p ] . player_int_pos ( ) . X ;
sy = ps [ p ] . player_int_pos ( ) . Y ;
2022-08-30 20:25:07 +00:00
sz = ps [ p ] . player_int_pos ( ) . Z + ps [ p ] . pyoff * zworldtoint + ( 4 < < 8 ) ;
2022-08-27 13:09:22 +00:00
sa = ps [ p ] . angle . ang . Buildang ( ) ;
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
ps [ p ] . crack_time = CRACK_TIME ;
}
else
{
2022-08-16 21:17:01 +00:00
sa = actor - > int_ang ( ) ;
2022-01-31 18:21:49 +00:00
sx = actor - > int_pos ( ) . X ;
sy = actor - > int_pos ( ) . Y ;
sz = actor - > int_pos ( ) . Z - ( actor - > spr . yrepeat * tileHeight ( actor - > spr . picnum ) < < 1 ) + ( 4 < < 8 ) ;
2021-12-21 19:40:35 +00:00
if ( actor - > spr . picnum ! = ROTATEGUN )
2020-05-16 21:55:21 +00:00
{
2020-10-20 22:17:09 +00:00
sz - = ( 7 < < 8 ) ;
2021-12-21 19:40:35 +00:00
if ( badguy ( actor ) & & actor - > spr . picnum ! = COMMANDER )
2020-05-16 21:55:21 +00:00
{
2020-11-15 11:07:03 +00:00
sx - = bsin ( sa + 96 , - 7 ) ;
sy + = bcos ( sa + 96 , - 7 ) ;
2020-05-16 21:55:21 +00:00
}
2020-10-20 22:17:09 +00:00
}
}
2022-08-30 19:42:44 +00:00
DVector3 spos ( sx * inttoworld , sy * inttoworld , sz * zinttoworld ) ;
DAngle sang = DAngle : : fromBuild ( sa ) ;
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
if ( isWorldTour ( ) )
{ // Twentieth Anniversary World Tour
switch ( atwith )
{
case FIREBALL :
2020-10-23 18:16:47 +00:00
shootfireball ( actor , p , sx , sy , sz , sa ) ;
2020-10-20 22:17:09 +00:00
return ;
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
case FLAMETHROWERFLAME :
2022-08-30 19:42:44 +00:00
shootflamethrowerflame ( actor , p , spos , sang ) ;
2020-10-20 22:17:09 +00:00
return ;
2020-05-16 21:55:21 +00:00
2020-10-20 22:17:09 +00:00
case FIREFLY : // BOSS5 shot
2020-10-23 18:16:47 +00:00
{
auto k = spawn ( actor , atwith ) ;
2021-11-19 11:32:12 +00:00
if ( k )
{
2021-12-30 15:36:04 +00:00
k - > setsector ( sect ) ;
2022-08-30 19:43:34 +00:00
k - > spr . pos = spos ;
k - > spr . angle = sang ;
2021-12-21 17:19:45 +00:00
k - > spr . xvel = 500 ;
2022-08-31 21:57:15 +00:00
k - > set_int_zvel ( 0 ) ;
2021-11-19 11:32:12 +00:00
}
2020-10-20 22:17:09 +00:00
return ;
2020-05-16 21:55:21 +00:00
}
2020-10-23 18:16:47 +00:00
}
2020-10-20 22:17:09 +00:00
}
switch ( atwith )
{
case BLOODSPLAT1 :
case BLOODSPLAT2 :
case BLOODSPLAT3 :
case BLOODSPLAT4 :
2020-10-23 17:50:18 +00:00
shootbloodsplat ( actor , p , sx , sy , sz , sa , atwith , BIGFORCE , OOZFILTER , NEWBEAST ) ;
2020-10-20 22:17:09 +00:00
break ;
case KNEE :
2020-10-23 18:16:47 +00:00
shootknee ( actor , p , sx , sy , sz , sa ) ;
2020-10-20 22:17:09 +00:00
break ;
case SHOTSPARK1 :
case SHOTGUN :
case CHAINGUN :
2020-10-24 04:33:31 +00:00
shootweapon ( actor , p , sx , sy , sz , sa , atwith ) ;
2020-10-20 22:17:09 +00:00
return ;
case FIRELASER :
case SPIT :
case COOLEXPLOSION1 :
2020-10-24 04:40:41 +00:00
shootstuff ( actor , p , sx , sy , sz , sa , atwith ) ;
2020-10-20 22:17:09 +00:00
return ;
case FREEZEBLAST :
sz + = ( 3 < < 8 ) ;
2021-11-14 11:25:25 +00:00
[[fallthrough]] ;
2020-10-20 22:17:09 +00:00
case RPG :
2020-10-24 04:40:41 +00:00
shootrpg ( actor , p , sx , sy , sz , sa , atwith ) ;
2020-10-20 22:17:09 +00:00
break ;
case HANDHOLDINGLASER :
2020-10-24 04:46:34 +00:00
shootlaser ( actor , p , sx , sy , sz , sa ) ;
2020-05-16 21:55:21 +00:00
return ;
case BOUNCEMINE :
case MORTER :
2020-10-25 05:15:21 +00:00
{
2021-12-21 19:40:35 +00:00
if ( actor - > spr . extra > = 0 ) actor - > spr . shade = - 96 ;
2020-05-16 21:55:21 +00:00
2021-12-24 09:53:27 +00:00
auto plActor = ps [ findplayer ( actor , & x ) ] . GetActor ( ) ;
x = ldist ( plActor , actor ) ;
2020-05-16 21:55:21 +00:00
zvel = - x > > 1 ;
if ( zvel < - 4096 )
zvel = - 2048 ;
vel = x > > 4 ;
EGS ( sect ,
2020-11-15 11:07:03 +00:00
sx - bsin ( sa , - 8 ) ,
sy + bcos ( sa , - 8 ) ,
2020-10-24 05:34:39 +00:00
sz + ( 6 < < 8 ) , atwith , - 64 , 32 , 32 , sa , vel , zvel , actor , 1 ) ;
2020-05-16 21:55:21 +00:00
break ;
2020-10-25 05:15:21 +00:00
}
2020-05-16 21:55:21 +00:00
case GROWSPARK :
2020-10-24 04:46:34 +00:00
shootgrowspark ( actor , p , sx , sy , sz , sa ) ;
2020-05-16 21:55:21 +00:00
break ;
case SHRINKER :
2020-10-24 05:34:39 +00:00
{
2021-12-21 19:40:35 +00:00
if ( actor - > spr . extra > = 0 ) actor - > spr . shade = - 96 ;
2020-05-16 21:55:21 +00:00
if ( p > = 0 )
{
2020-10-24 05:34:39 +00:00
auto aimed = isNamWW2GI ( ) ? nullptr : aim ( actor , AUTO_AIM_ANGLE ) ;
2020-11-01 19:57:02 +00:00
if ( aimed )
2020-05-16 21:55:21 +00:00
{
2021-12-21 17:19:45 +00:00
dal = ( ( aimed - > spr . xrepeat * tileHeight ( aimed - > spr . picnum ) ) < < 1 ) ;
2022-01-31 18:21:49 +00:00
zvel = ( ( aimed - > int_pos ( ) . Z - sz - dal - ( 4 < < 8 ) ) * 768 ) / ( ldist ( ps [ p ] . GetActor ( ) , aimed ) ) ;
sa = getangle ( aimed - > int_pos ( ) . X - sx , aimed - > int_pos ( ) . Y - sy ) ;
2020-05-16 21:55:21 +00:00
}
2021-01-04 11:36:54 +00:00
else zvel = - MulScale ( ps [ p ] . horizon . sum ( ) . asq16 ( ) , 98 , 16 ) ;
2020-05-16 21:55:21 +00:00
}
2021-12-21 19:40:35 +00:00
else if ( actor - > spr . statnum ! = 3 )
2020-05-16 21:55:21 +00:00
{
2020-11-01 19:57:02 +00:00
j = findplayer ( actor , & x ) ;
l = ldist ( ps [ j ] . GetActor ( ) , actor ) ;
2022-02-04 17:11:44 +00:00
zvel = ( ( ps [ j ] . player_int_opos ( ) . Z - sz ) * 512 ) / l ;
2020-05-16 21:55:21 +00:00
}
else zvel = 0 ;
2021-12-24 09:53:27 +00:00
auto spawned = EGS ( sect ,
2020-11-15 11:07:03 +00:00
sx - bsin ( sa , - 12 ) ,
sy + bcos ( sa , - 12 ) ,
2020-10-24 05:34:39 +00:00
sz + ( 2 < < 8 ) , SHRINKSPARK , - 16 , 28 , 28 , sa , 768 , zvel , actor , 4 ) ;
2020-05-16 21:55:21 +00:00
2021-12-24 09:53:27 +00:00
if ( spawned )
2021-11-19 08:47:17 +00:00
{
2021-12-24 09:53:27 +00:00
spawned - > spr . cstat = CSTAT_SPRITE_YCENTER ;
spawned - > spr . clipdist = 32 ;
2021-11-19 08:47:17 +00:00
}
2020-05-16 21:55:21 +00:00
return ;
}
2020-10-24 05:34:39 +00:00
}
2020-05-16 21:55:21 +00:00
return ;
}
2020-05-17 11:25:39 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-08-26 22:53:35 +00:00
void selectweapon_d ( int snum , int weap ) // playernum, weaponnum
2020-05-17 11:25:39 +00:00
{
2020-08-26 22:53:35 +00:00
int i , j , k ;
2020-05-17 11:25:39 +00:00
auto p = & ps [ snum ] ;
2021-12-21 17:19:45 +00:00
if ( p - > last_pissed_time < = ( 26 * 218 ) & & p - > show_empty_weapon = = 0 & & p - > kickback_pic = = 0 & & p - > quick_kick = = 0 & & p - > GetActor ( ) - > spr . xrepeat > 32 & & p - > access_incs = = 0 & & p - > knee_incs = = 0 )
2020-05-17 11:25:39 +00:00
{
if ( ( p - > weapon_pos = = 0 | | ( p - > holster_weapon & & p - > weapon_pos = = - 9 ) ) )
{
2020-08-26 22:53:35 +00:00
if ( weap = = WeaponSel_Alt )
{
2020-12-01 20:07:38 +00:00
j = p - > curr_weapon ;
2020-08-29 11:27:58 +00:00
switch ( p - > curr_weapon )
{
case SHRINKER_WEAPON :
2020-12-01 20:07:38 +00:00
if ( p - > ammo_amount [ GROW_WEAPON ] > 0 & & p - > gotweapon [ GROW_WEAPON ] & & isPlutoPak ( ) )
{
j = GROW_WEAPON ;
p - > subweapon | = ( 1 < < GROW_WEAPON ) ;
}
2020-08-29 11:27:58 +00:00
break ;
case GROW_WEAPON :
2020-12-01 20:07:38 +00:00
if ( p - > ammo_amount [ SHRINKER_WEAPON ] > 0 & & p - > gotweapon [ SHRINKER_WEAPON ] )
{
j = SHRINKER_WEAPON ;
p - > subweapon & = ~ ( 1 < < GROW_WEAPON ) ;
}
2020-08-29 11:27:58 +00:00
break ;
2020-08-29 12:30:45 +00:00
case FREEZE_WEAPON :
2020-12-01 20:07:38 +00:00
if ( p - > ammo_amount [ FLAMETHROWER_WEAPON ] > 0 & & p - > gotweapon [ FLAMETHROWER_WEAPON ] & & isWorldTour ( ) )
{
j = FLAMETHROWER_WEAPON ;
p - > subweapon | = ( 1 < < FLAMETHROWER_WEAPON ) ;
}
2020-08-29 12:30:45 +00:00
break ;
case FLAMETHROWER_WEAPON :
2020-12-01 20:07:38 +00:00
if ( p - > ammo_amount [ FREEZE_WEAPON ] > 0 & & p - > gotweapon [ FREEZE_WEAPON ] )
{
j = FREEZE_WEAPON ;
p - > subweapon & = ~ ( 1 < < FLAMETHROWER_WEAPON ) ;
}
2020-08-29 12:30:45 +00:00
break ;
2020-08-29 11:27:58 +00:00
default :
break ;
}
2020-08-26 22:53:35 +00:00
}
else if ( weap = = WeaponSel_Next | | weap = = WeaponSel_Prev )
2020-05-17 11:25:39 +00:00
{
k = p - > curr_weapon ;
2020-08-26 22:53:35 +00:00
j = ( weap = = WeaponSel_Prev ? - 1 : 1 ) ; // JBF: prev (-1) or next (1) weapon choice
2020-05-17 11:25:39 +00:00
i = 0 ;
2020-10-11 09:39:51 +00:00
while ( ( k > = 0 & & k < 10 ) | | ( isPlutoPak ( ) & & k = = GROW_WEAPON & & ( p - > subweapon & ( 1 < < GROW_WEAPON ) ) ! = 0 )
2020-05-17 12:20:49 +00:00
| | ( isWorldTour ( ) & & k = = FLAMETHROWER_WEAPON & & ( p - > subweapon & ( 1 < < FLAMETHROWER_WEAPON ) ) ! = 0 ) )
2020-05-17 11:25:39 +00:00
{
2020-05-17 12:20:49 +00:00
if ( k = = FLAMETHROWER_WEAPON ) //Twentieth Anniversary World Tour
{
if ( j = = - 1 ) k = TRIPBOMB_WEAPON ;
else k = PISTOL_WEAPON ;
}
else if ( k = = GROW_WEAPON ) // JBF: this is handling next/previous with the grower selected
2020-05-17 11:25:39 +00:00
{
2021-10-08 17:21:29 +00:00
if ( j = = - 1 )
2020-05-17 11:25:39 +00:00
k = 5 ;
else k = 7 ;
}
else
{
k + = j ;
2020-05-17 12:20:49 +00:00
// JBF 20040116: so we don't select grower with v1.3d
2020-10-11 09:39:51 +00:00
if ( isPlutoPak ( ) & & k = = SHRINKER_WEAPON & & ( p - > subweapon & ( 1 < < GROW_WEAPON ) ) ) // JBF: activates grower
2020-05-17 12:20:49 +00:00
k = GROW_WEAPON ; // if enabled
if ( isWorldTour ( ) & & k = = FREEZE_WEAPON & & ( p - > subweapon & ( 1 < < FLAMETHROWER_WEAPON ) ) ! = 0 )
k = FLAMETHROWER_WEAPON ;
2020-05-17 11:25:39 +00:00
}
if ( k = = - 1 ) k = 9 ;
else if ( k = = 10 ) k = 0 ;
if ( p - > gotweapon [ k ] & & p - > ammo_amount [ k ] > 0 )
{
2020-10-11 09:39:51 +00:00
if ( isPlutoPak ( ) ) // JBF 20040116: so we don't select grower with v1.3d
2021-11-14 11:25:25 +00:00
{
2020-05-17 11:25:39 +00:00
if ( k = = SHRINKER_WEAPON & & ( p - > subweapon & ( 1 < < GROW_WEAPON ) ) )
k = GROW_WEAPON ;
2020-05-17 12:20:49 +00:00
if ( isWorldTour ( ) & & k = = FREEZE_WEAPON & & ( p - > subweapon & ( 1 < < FLAMETHROWER_WEAPON ) ) ! = 0 )
k = FLAMETHROWER_WEAPON ;
2021-11-14 11:25:25 +00:00
}
2020-05-17 11:25:39 +00:00
j = k ;
break ;
}
2020-10-11 09:39:51 +00:00
else if ( isPlutoPak ( ) & & k = = GROW_WEAPON & & p - > ammo_amount [ GROW_WEAPON ] = = 0 & & p - > gotweapon [ SHRINKER_WEAPON ] & & p - > ammo_amount [ SHRINKER_WEAPON ] > 0 ) // JBF 20040116: added isPlutoPak() so we don't select grower with v1.3d
2020-05-17 12:20:49 +00:00
{
j = SHRINKER_WEAPON ;
p - > subweapon & = ~ ( 1 < < GROW_WEAPON ) ;
break ;
}
2020-10-11 09:39:51 +00:00
else if ( isPlutoPak ( ) & & k = = SHRINKER_WEAPON & & p - > ammo_amount [ SHRINKER_WEAPON ] = = 0 & & p - > gotweapon [ SHRINKER_WEAPON ] & & p - > ammo_amount [ GROW_WEAPON ] > 0 ) // JBF 20040116: added isPlutoPak() so we don't select grower with v1.3d
2020-05-17 12:20:49 +00:00
{
j = GROW_WEAPON ;
p - > subweapon | = ( 1 < < GROW_WEAPON ) ;
break ;
}
//Twentieth Anniversary World Tour
else if ( isWorldTour ( ) & & k = = FLAMETHROWER_WEAPON & & p - > ammo_amount [ FLAMETHROWER_WEAPON ] = = 0 & & p - > gotweapon [ FREEZE_WEAPON ] & & p - > ammo_amount [ FREEZE_WEAPON ] > 0 )
{
j = FREEZE_WEAPON ;
p - > subweapon & = ~ ( 1 < < FLAMETHROWER_WEAPON ) ;
break ;
}
else if ( isWorldTour ( ) & & k = = FREEZE_WEAPON & & p - > ammo_amount [ FREEZE_WEAPON ] = = 0 & & p - > gotweapon [ FLAMETHROWER_WEAPON ] & & p - > ammo_amount [ FLAMETHROWER_WEAPON ] > 0 )
{
j = FLAMETHROWER_WEAPON ;
p - > subweapon | = ( 1 < < FLAMETHROWER_WEAPON ) ;
break ;
}
2020-05-17 11:25:39 +00:00
i + + ; // absolutely no weapons, so use foot
if ( i = = 10 )
{
fi . addweapon ( p , KNEE_WEAPON ) ;
break ;
}
}
}
2021-07-17 12:42:58 +00:00
else j = weap - 1 ;
2020-05-17 11:25:39 +00:00
k = - 1 ;
if ( j = = HANDBOMB_WEAPON & & p - > ammo_amount [ HANDBOMB_WEAPON ] = = 0 )
{
2020-10-25 05:34:25 +00:00
DukeStatIterator it ( STAT_ACTOR ) ;
while ( auto act = it . Next ( ) )
2020-05-17 11:25:39 +00:00
{
2021-12-21 17:19:45 +00:00
if ( act - > spr . picnum = = HEAVYHBOMB & & act - > GetOwner ( ) = = p - > GetActor ( ) )
2020-05-17 11:25:39 +00:00
{
2021-05-15 08:23:50 +00:00
p - > gotweapon [ HANDBOMB_WEAPON ] = true ;
2020-05-17 11:25:39 +00:00
j = HANDREMOTE_WEAPON ;
break ;
}
}
}
2020-05-17 12:20:49 +00:00
//Twentieth Anniversary World Tour
if ( j = = FREEZE_WEAPON & & isWorldTour ( ) )
{
if ( p - > curr_weapon ! = FLAMETHROWER_WEAPON & & p - > curr_weapon ! = FREEZE_WEAPON )
{
if ( p - > ammo_amount [ FLAMETHROWER_WEAPON ] > 0 )
{
if ( ( p - > subweapon & ( 1 < < FLAMETHROWER_WEAPON ) ) = = ( 1 < < FLAMETHROWER_WEAPON ) )
j = FLAMETHROWER_WEAPON ;
else if ( p - > ammo_amount [ FREEZE_WEAPON ] = = 0 )
{
j = FLAMETHROWER_WEAPON ;
p - > subweapon | = ( 1 < < FLAMETHROWER_WEAPON ) ;
}
}
else if ( p - > ammo_amount [ FREEZE_WEAPON ] > 0 )
p - > subweapon & = ~ ( 1 < < FLAMETHROWER_WEAPON ) ;
}
else if ( p - > curr_weapon = = FREEZE_WEAPON )
{
p - > subweapon | = ( 1 < < FLAMETHROWER_WEAPON ) ;
j = FLAMETHROWER_WEAPON ;
}
else
p - > subweapon & = ~ ( 1 < < FLAMETHROWER_WEAPON ) ;
}
2020-10-11 09:39:51 +00:00
if ( j = = SHRINKER_WEAPON & & isPlutoPak ( ) ) // JBF 20040116: so we don't select the grower with v1.3d
2020-05-17 11:25:39 +00:00
{
if ( p - > curr_weapon ! = GROW_WEAPON & & p - > curr_weapon ! = SHRINKER_WEAPON )
{
if ( p - > ammo_amount [ GROW_WEAPON ] > 0 )
{
if ( ( p - > subweapon & ( 1 < < GROW_WEAPON ) ) = = ( 1 < < GROW_WEAPON ) )
j = GROW_WEAPON ;
else if ( p - > ammo_amount [ SHRINKER_WEAPON ] = = 0 )
{
j = GROW_WEAPON ;
p - > subweapon | = ( 1 < < GROW_WEAPON ) ;
}
}
else if ( p - > ammo_amount [ SHRINKER_WEAPON ] > 0 )
p - > subweapon & = ~ ( 1 < < GROW_WEAPON ) ;
}
else if ( p - > curr_weapon = = SHRINKER_WEAPON )
{
p - > subweapon | = ( 1 < < GROW_WEAPON ) ;
j = GROW_WEAPON ;
}
else
p - > subweapon & = ~ ( 1 < < GROW_WEAPON ) ;
}
if ( p - > holster_weapon )
{
2020-08-27 22:03:35 +00:00
PlayerSetInput ( snum , SB_HOLSTER ) ;
2020-09-16 11:01:09 +00:00
p - > oweapon_pos = p - > weapon_pos = - 9 ;
2020-05-17 11:25:39 +00:00
}
2021-10-08 17:21:29 +00:00
else if ( j > = MIN_WEAPON & & p - > gotweapon [ j ] & & p - > curr_weapon ! = j ) switch ( j )
2020-05-17 11:25:39 +00:00
{
case KNEE_WEAPON :
fi . addweapon ( p , KNEE_WEAPON ) ;
break ;
case PISTOL_WEAPON :
case SHOTGUN_WEAPON :
case CHAINGUN_WEAPON :
case RPG_WEAPON :
case DEVISTATOR_WEAPON :
case FREEZE_WEAPON :
2020-05-17 12:20:49 +00:00
case FLAMETHROWER_WEAPON :
2020-05-17 11:25:39 +00:00
case GROW_WEAPON :
case SHRINKER_WEAPON :
if ( p - > ammo_amount [ j ] = = 0 & & p - > show_empty_weapon = = 0 )
{
p - > show_empty_weapon = 32 ;
p - > last_full_weapon = p - > curr_weapon ;
}
fi . addweapon ( p , j ) ;
break ;
case HANDREMOTE_WEAPON :
if ( k > = 0 ) // Found in list of [1]'s
{
p - > curr_weapon = HANDREMOTE_WEAPON ;
p - > last_weapon = - 1 ;
2020-09-16 11:01:09 +00:00
p - > oweapon_pos = p - > weapon_pos = 10 ;
2020-05-17 11:25:39 +00:00
}
break ;
case HANDBOMB_WEAPON :
if ( p - > ammo_amount [ HANDBOMB_WEAPON ] > 0 & & p - > gotweapon [ HANDBOMB_WEAPON ] )
fi . addweapon ( p , HANDBOMB_WEAPON ) ;
break ;
case TRIPBOMB_WEAPON :
if ( p - > ammo_amount [ TRIPBOMB_WEAPON ] > 0 & & p - > gotweapon [ TRIPBOMB_WEAPON ] )
fi . addweapon ( p , TRIPBOMB_WEAPON ) ;
break ;
}
}
}
}
2020-05-16 21:55:21 +00:00
2020-05-17 16:04:45 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-02-07 10:04:19 +00:00
int doincrements_d ( player_struct * p )
2020-05-17 16:04:45 +00:00
{
int snum ;
2020-11-02 19:24:07 +00:00
auto pact = p - > GetActor ( ) ;
2021-12-21 17:19:45 +00:00
snum = pact - > spr . yvel ;
2020-05-17 16:04:45 +00:00
p - > player_par + + ;
if ( p - > invdisptime > 0 )
p - > invdisptime - - ;
2022-06-05 23:40:47 +00:00
if ( p - > tipincs > 0 )
{
p - > otipincs = p - > tipincs ;
p - > tipincs - - ;
}
2020-05-17 16:04:45 +00:00
if ( p - > last_pissed_time > 0 )
{
p - > last_pissed_time - - ;
if ( p - > last_pissed_time = = ( 26 * 219 ) )
{
2020-11-02 19:24:07 +00:00
S_PlayActorSound ( FLUSH_TOILET , pact ) ;
2020-05-17 16:04:45 +00:00
if ( snum = = screenpeek | | ud . coop = = 1 )
2020-11-02 19:24:07 +00:00
S_PlayActorSound ( DUKE_PISSRELIEF , pact ) ;
2020-05-17 16:04:45 +00:00
}
if ( p - > last_pissed_time = = ( 26 * 218 ) )
{
p - > holster_weapon = 0 ;
2020-09-16 11:01:09 +00:00
p - > oweapon_pos = p - > weapon_pos = 10 ;
2020-05-17 16:04:45 +00:00
}
}
if ( p - > crack_time > 0 )
{
p - > crack_time - - ;
if ( p - > crack_time = = 0 )
{
p - > knuckle_incs = 1 ;
2020-08-27 05:54:49 +00:00
p - > crack_time = CRACK_TIME ;
2020-05-17 16:04:45 +00:00
}
}
if ( p - > steroids_amount > 0 & & p - > steroids_amount < 400 )
{
p - > steroids_amount - - ;
if ( p - > steroids_amount = = 0 )
checkavailinven ( p ) ;
if ( ! ( p - > steroids_amount & 7 ) )
if ( snum = = screenpeek | | ud . coop = = 1 )
2020-11-02 19:24:07 +00:00
S_PlayActorSound ( DUKE_HARTBEAT , pact ) ;
2020-05-17 16:04:45 +00:00
}
if ( p - > heat_on & & p - > heat_amount > 0 )
{
p - > heat_amount - - ;
if ( p - > heat_amount = = 0 )
{
p - > heat_on = 0 ;
checkavailinven ( p ) ;
2020-11-02 19:24:07 +00:00
S_PlayActorSound ( NITEVISION_ONOFF , pact ) ;
2020-05-17 16:04:45 +00:00
}
}
2020-10-21 08:48:38 +00:00
if ( p - > holoduke_on ! = nullptr )
2020-05-17 16:04:45 +00:00
{
p - > holoduke_amount - - ;
if ( p - > holoduke_amount < = 0 )
{
2020-11-02 19:24:07 +00:00
S_PlayActorSound ( TELEPORTER , pact ) ;
2020-10-21 08:48:38 +00:00
p - > holoduke_on = nullptr ;
2020-05-17 16:04:45 +00:00
checkavailinven ( p ) ;
}
}
if ( p - > jetpack_on & & p - > jetpack_amount > 0 )
{
p - > jetpack_amount - - ;
if ( p - > jetpack_amount < = 0 )
{
p - > jetpack_on = 0 ;
checkavailinven ( p ) ;
2020-11-02 19:24:07 +00:00
S_PlayActorSound ( DUKE_JETPACK_OFF , pact ) ;
S_StopSound ( DUKE_JETPACK_IDLE , pact ) ;
S_StopSound ( DUKE_JETPACK_ON , pact ) ;
2020-05-17 16:04:45 +00:00
}
}
2021-12-21 17:19:45 +00:00
if ( p - > quick_kick > 0 & & p - > GetActor ( ) - > spr . pal ! = 1 )
2020-05-17 16:04:45 +00:00
{
2020-07-26 08:18:55 +00:00
p - > last_quick_kick = p - > quick_kick + 1 ;
2020-05-17 16:04:45 +00:00
p - > quick_kick - - ;
if ( p - > quick_kick = = 8 )
2020-10-24 05:34:39 +00:00
fi . shoot ( p - > GetActor ( ) , KNEE ) ;
2020-05-17 16:04:45 +00:00
}
2020-07-26 08:18:55 +00:00
else if ( p - > last_quick_kick > 0 )
p - > last_quick_kick - - ;
2020-05-17 16:04:45 +00:00
2021-12-21 17:19:45 +00:00
if ( p - > access_incs & & p - > GetActor ( ) - > spr . pal ! = 1 )
2020-05-17 16:04:45 +00:00
{
2022-06-05 23:47:30 +00:00
p - > oaccess_incs = p - > access_incs ;
2020-05-17 16:04:45 +00:00
p - > access_incs + + ;
2021-12-21 17:19:45 +00:00
if ( p - > GetActor ( ) - > spr . extra < = 0 )
2020-05-17 16:04:45 +00:00
p - > access_incs = 12 ;
if ( p - > access_incs = = 12 )
{
2020-10-25 05:34:25 +00:00
if ( p - > access_spritenum ! = nullptr )
2020-05-17 16:04:45 +00:00
{
2021-11-17 23:16:53 +00:00
fi . checkhitswitch ( snum , nullptr , p - > access_spritenum ) ;
2021-12-21 17:19:45 +00:00
switch ( p - > access_spritenum - > spr . pal )
2020-05-17 16:04:45 +00:00
{
case 0 : p - > got_access & = ( 0xffff - 0x1 ) ; break ;
case 21 : p - > got_access & = ( 0xffff - 0x2 ) ; break ;
case 23 : p - > got_access & = ( 0xffff - 0x4 ) ; break ;
}
2020-10-25 05:34:25 +00:00
p - > access_spritenum = nullptr ;
2020-05-17 16:04:45 +00:00
}
else
{
2021-11-17 23:20:39 +00:00
fi . checkhitswitch ( snum , p - > access_wall , nullptr ) ;
switch ( p - > access_wall - > pal )
2020-05-17 16:04:45 +00:00
{
case 0 : p - > got_access & = ( 0xffff - 0x1 ) ; break ;
case 21 : p - > got_access & = ( 0xffff - 0x2 ) ; break ;
case 23 : p - > got_access & = ( 0xffff - 0x4 ) ; break ;
}
}
}
if ( p - > access_incs > 20 )
{
2022-06-05 23:47:30 +00:00
p - > oaccess_incs = p - > access_incs = 0 ;
2020-09-16 11:01:09 +00:00
p - > oweapon_pos = p - > weapon_pos = 10 ;
p - > okickback_pic = p - > kickback_pic = 0 ;
2020-05-17 16:04:45 +00:00
}
}
2021-11-21 07:56:39 +00:00
if ( p - > scuba_on = = 0 & & p - > insector ( ) & & p - > cursector - > lotag = = 2 )
2020-05-17 16:04:45 +00:00
{
if ( p - > scuba_amount > 0 )
{
p - > scuba_on = 1 ;
p - > inven_icon = 6 ;
FTA ( 76 , p ) ;
}
else
{
if ( p - > airleft > 0 )
p - > airleft - - ;
else
{
p - > extra_extra8 + = 32 ;
2020-11-29 12:54:58 +00:00
if ( p - > last_extra < ( gs . max_player_health > > 1 ) & & ( p - > last_extra & 3 ) = = 0 )
2020-11-02 19:24:07 +00:00
S_PlayActorSound ( DUKE_LONGTERM_PAIN , pact ) ;
2020-05-17 16:04:45 +00:00
}
}
}
else if ( p - > scuba_amount > 0 & & p - > scuba_on )
{
p - > scuba_amount - - ;
if ( p - > scuba_amount = = 0 )
{
p - > scuba_on = 0 ;
checkavailinven ( p ) ;
}
}
if ( p - > knuckle_incs )
{
p - > knuckle_incs + + ;
if ( p - > knuckle_incs = = 10 & & ! isWW2GI ( ) )
{
2021-02-18 10:46:36 +00:00
if ( PlayClock > 1024 )
2020-05-17 16:04:45 +00:00
if ( snum = = screenpeek | | ud . coop = = 1 )
{
if ( rand ( ) & 1 )
2020-11-02 19:24:07 +00:00
S_PlayActorSound ( DUKE_CRACK , pact ) ;
else S_PlayActorSound ( DUKE_CRACK2 , pact ) ;
2020-05-17 16:04:45 +00:00
}
2020-11-02 19:24:07 +00:00
S_PlayActorSound ( DUKE_CRACK_FIRST , pact ) ;
2020-05-17 16:04:45 +00:00
}
2020-08-28 20:51:05 +00:00
else if ( p - > knuckle_incs = = 22 | | PlayerInput ( snum , SB_FIRE ) )
2020-05-17 16:04:45 +00:00
p - > knuckle_incs = 0 ;
return 1 ;
}
return 0 ;
}
2020-05-17 21:44:53 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-02-07 10:04:19 +00:00
void checkweapons_d ( player_struct * p )
2020-05-17 21:44:53 +00:00
{
2021-11-07 13:36:39 +00:00
static const uint16_t weapon_sprites [ MAX_WEAPONS ] = { KNEE , FIRSTGUNSPRITE , SHOTGUNSPRITE ,
2020-05-17 21:44:53 +00:00
CHAINGUNSPRITE , RPGSPRITE , HEAVYHBOMB , SHRINKERSPRITE , DEVISTATORSPRITE ,
TRIPBOMBSPRITE , FREEZESPRITE , HEAVYHBOMB , SHRINKERSPRITE } ;
int cw ;
if ( isWW2GI ( ) )
{
2021-12-21 17:19:45 +00:00
int snum = p - > GetActor ( ) - > spr . yvel ;
2021-12-05 12:43:31 +00:00
cw = aplWeaponWorksLike ( p - > curr_weapon , snum ) ;
2020-05-17 21:44:53 +00:00
}
else
cw = p - > curr_weapon ;
if ( cw < 1 | | cw > = MAX_WEAPONS ) return ;
if ( cw )
{
if ( krand ( ) & 1 )
2020-11-02 19:24:07 +00:00
spawn ( p - > GetActor ( ) , weapon_sprites [ cw ] ) ;
2020-05-17 21:44:53 +00:00
else switch ( cw )
{
case RPG_WEAPON :
case HANDBOMB_WEAPON :
2020-11-02 19:24:07 +00:00
spawn ( p - > GetActor ( ) , EXPLOSION2 ) ;
2020-05-17 21:44:53 +00:00
break ;
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-08-28 20:51:05 +00:00
static void operateJetpack ( int snum , ESyncBits actions , int psectlotag , int fz , int cz , int shrunk )
2020-05-17 21:44:53 +00:00
{
auto p = & ps [ snum ] ;
2020-10-25 05:50:31 +00:00
auto pact = p - > GetActor ( ) ;
2020-05-17 21:44:53 +00:00
p - > on_ground = 0 ;
p - > jumping_counter = 0 ;
p - > hard_landing = 0 ;
p - > falling_counter = 0 ;
p - > pycount + = 32 ;
p - > pycount & = 2047 ;
2022-08-30 20:25:07 +00:00
p - > pyoff = DAngle : : fromBuild ( p - > pycount ) . Sin ( ) ;
2020-05-17 21:44:53 +00:00
2020-10-25 05:50:31 +00:00
if ( p - > jetpack_on & & S_CheckActorSoundPlaying ( pact , DUKE_SCREAM ) )
2020-08-11 03:48:16 +00:00
{
2020-10-25 05:50:31 +00:00
S_StopSound ( DUKE_SCREAM , pact ) ;
2020-08-11 03:48:16 +00:00
}
2020-05-17 21:44:53 +00:00
if ( p - > jetpack_on < 11 )
{
p - > jetpack_on + + ;
2022-02-05 12:40:30 +00:00
p - > pos . Z - = ( p - > jetpack_on * 0.5 ) ; //Goin up
2020-05-17 21:44:53 +00:00
}
2020-10-25 05:50:31 +00:00
else if ( p - > jetpack_on = = 11 & & ! S_CheckActorSoundPlaying ( pact , DUKE_JETPACK_IDLE ) )
S_PlayActorSound ( DUKE_JETPACK_IDLE , pact ) ;
2020-05-17 21:44:53 +00:00
2022-02-05 12:40:30 +00:00
double dist ;
if ( shrunk ) dist = 2 ;
else dist = 8 ;
2020-05-17 21:44:53 +00:00
2020-08-28 20:51:05 +00:00
if ( actions & SB_JUMP ) //A (soar high)
2020-05-17 21:44:53 +00:00
{
// jump
2020-11-01 17:23:09 +00:00
SetGameVarID ( g_iReturnVarID , 0 , p - > GetActor ( ) , snum ) ;
2020-11-01 16:57:40 +00:00
OnEvent ( EVENT_SOARUP , snum , p - > GetActor ( ) , - 1 ) ;
2021-12-05 16:36:57 +00:00
if ( GetGameVarID ( g_iReturnVarID , p - > GetActor ( ) , snum ) . value ( ) = = 0 )
2020-05-17 21:44:53 +00:00
{
2022-02-05 12:40:30 +00:00
p - > pos . Z - = dist ;
2020-08-27 05:54:49 +00:00
p - > crack_time = CRACK_TIME ;
2020-05-17 21:44:53 +00:00
}
}
2020-08-28 20:51:05 +00:00
if ( actions & SB_CROUCH ) //Z (soar low)
2020-05-17 21:44:53 +00:00
{
// crouch
2020-11-01 17:23:09 +00:00
SetGameVarID ( g_iReturnVarID , 0 , p - > GetActor ( ) , snum ) ;
2020-11-01 16:57:40 +00:00
OnEvent ( EVENT_SOARDOWN , snum , p - > GetActor ( ) , - 1 ) ;
2021-12-05 16:36:57 +00:00
if ( GetGameVarID ( g_iReturnVarID , p - > GetActor ( ) , snum ) . value ( ) = = 0 )
2020-05-17 21:44:53 +00:00
{
2022-02-05 12:40:30 +00:00
p - > pos . Z + = dist ;
2020-08-27 05:54:49 +00:00
p - > crack_time = CRACK_TIME ;
2020-05-17 21:44:53 +00:00
}
}
int k ;
if ( shrunk = = 0 & & ( psectlotag = = 0 | | psectlotag = = 2 ) ) k = 32 ;
else k = 16 ;
if ( psectlotag ! = 2 & & p - > scuba_on = = 1 )
p - > scuba_on = 0 ;
2022-02-04 17:11:44 +00:00
if ( p - > player_int_pos ( ) . Z > ( fz - ( k < < 8 ) ) )
2022-02-05 12:40:30 +00:00
p - > pos . Z + = ( ( ( fz - ( k < < 8 ) ) - p - > player_int_pos ( ) . Z ) > > 1 ) * zinttoworld ;
2022-08-20 18:57:54 +00:00
if ( p - > pos . Z < pact - > ceilingz + 18 )
2022-02-05 12:40:30 +00:00
p - > pos . Z = pact - > ceilingz + 18 ;
2020-05-17 21:44:53 +00:00
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-08-30 22:03:40 +00:00
static void movement ( int snum , ESyncBits actions , sectortype * psect , int fz_ , int cz_ , int shrunk , int truefdist , int psectlotag )
2020-05-17 21:44:53 +00:00
{
int j ;
auto p = & ps [ snum ] ;
2020-10-25 05:50:31 +00:00
auto pact = p - > GetActor ( ) ;
2022-08-30 22:03:40 +00:00
double floorz = fz_ * zinttoworld ;
double ceilingz = cz_ * zinttoworld ;
2020-05-17 21:44:53 +00:00
if ( p - > airleft ! = 15 * 26 )
p - > airleft = 15 * 26 ; //Aprox twenty seconds.
if ( p - > scuba_on = = 1 )
p - > scuba_on = 0 ;
2022-08-30 22:03:40 +00:00
double i = 40 ;
2020-08-07 19:59:11 +00:00
if ( psectlotag = = ST_1_ABOVE_WATER & & p - > spritebridge = = 0 )
2020-05-17 21:44:53 +00:00
{
if ( shrunk = = 0 )
{
i = 34 ;
p - > pycount + = 32 ;
p - > pycount & = 2047 ;
2022-08-30 20:25:07 +00:00
p - > pyoff = DAngle : : fromBuild ( p - > pycount ) . Sin ( ) * 2 ;
2020-05-17 21:44:53 +00:00
}
else i = 12 ;
2022-02-04 17:06:08 +00:00
if ( shrunk = = 0 & & truefdist < = gs . int_playerheight )
2020-05-17 21:44:53 +00:00
{
if ( p - > on_ground = = 1 )
{
2020-10-25 06:21:33 +00:00
if ( p - > dummyplayersprite = = nullptr )
p - > dummyplayersprite = spawn ( pact , PLAYERONWATER ) ;
2020-05-17 21:44:53 +00:00
p - > footprintcount = 6 ;
2021-11-21 07:56:39 +00:00
if ( p - > cursector - > floorpicnum = = FLOORSLIME )
2020-05-17 21:44:53 +00:00
p - > footprintpal = 8 ;
else p - > footprintpal = 0 ;
p - > footprintshade = 0 ;
}
}
}
else
{
footprints ( snum ) ;
}
2022-08-30 22:03:40 +00:00
if ( p - > pos . Z < floorz - i ) //falling
2020-05-17 21:44:53 +00:00
{
// not jumping or crouching
2022-08-30 22:03:40 +00:00
if ( ( actions & ( SB_JUMP | SB_CROUCH ) ) = = 0 & & p - > on_ground & & ( psect - > floorstat & CSTAT_SECTOR_SLOPE ) & & p - > pos . Z > = ( floorz - i - 16 ) )
p - > pos . Z = floorz - i ;
2020-05-17 21:44:53 +00:00
else
{
p - > on_ground = 0 ;
2021-12-30 11:14:04 +00:00
p - > vel . Z + = ( gs . gravity + 80 ) ; // (TICSPERFRAME<<6);
if ( p - > vel . Z > = ( 4096 + 2048 ) ) p - > vel . Z = ( 4096 + 2048 ) ;
if ( p - > vel . Z > 2400 & & p - > falling_counter < 255 )
2020-05-17 21:44:53 +00:00
{
p - > falling_counter + + ;
2020-10-25 05:50:31 +00:00
if ( p - > falling_counter = = 38 & & ! S_CheckActorSoundPlaying ( pact , DUKE_SCREAM ) )
S_PlayActorSound ( DUKE_SCREAM , pact ) ;
2020-05-17 21:44:53 +00:00
}
2022-08-30 22:03:40 +00:00
if ( p - > pos . Z + p - > vel . Z * zinttoworld > = floorz - i ) // hit the ground
2020-08-07 20:20:29 +00:00
{
2020-10-25 05:50:31 +00:00
S_StopSound ( DUKE_SCREAM , pact ) ;
2021-11-21 07:56:39 +00:00
if ( ! p - > insector ( ) | | p - > cursector - > lotag ! = 1 )
2020-05-17 21:44:53 +00:00
{
if ( p - > falling_counter > 62 ) quickkill ( p ) ;
else if ( p - > falling_counter > 9 )
{
j = p - > falling_counter ;
2021-12-21 17:19:45 +00:00
pact - > spr . extra - = j - ( krand ( ) & 3 ) ;
if ( pact - > spr . extra < = 0 )
2020-05-17 21:44:53 +00:00
{
2020-10-25 05:50:31 +00:00
S_PlayActorSound ( SQUISHED , pact ) ;
2020-05-17 21:44:53 +00:00
SetPlayerPal ( p , PalEntry ( 63 , 63 , 0 , 0 ) ) ;
}
else
{
2020-10-25 05:50:31 +00:00
S_PlayActorSound ( DUKE_LAND , pact ) ;
S_PlayActorSound ( DUKE_LAND_HURT , pact ) ;
2020-05-17 21:44:53 +00:00
}
SetPlayerPal ( p , PalEntry ( 32 , 16 , 0 , 0 ) ) ;
}
2021-12-30 11:14:04 +00:00
else if ( p - > vel . Z > 2048 ) S_PlayActorSound ( DUKE_LAND , pact ) ;
2020-05-17 21:44:53 +00:00
}
2020-08-07 20:20:29 +00:00
}
2020-05-17 21:44:53 +00:00
}
}
else
{
p - > falling_counter = 0 ;
2020-10-25 05:50:31 +00:00
S_StopSound ( - 1 , pact , CHAN_VOICE ) ;
2020-05-17 21:44:53 +00:00
2021-12-30 11:14:04 +00:00
if ( psectlotag ! = ST_1_ABOVE_WATER & & psectlotag ! = ST_2_UNDERWATER & & p - > on_ground = = 0 & & p - > vel . Z > ( 6144 > > 1 ) )
p - > hard_landing = p - > vel . Z > > 10 ;
2020-05-17 21:44:53 +00:00
p - > on_ground = 1 ;
if ( i = = 40 )
{
//Smooth on the ground
2022-08-30 22:03:40 +00:00
double k = ( floorz - i - p - > pos . Z ) * 0.5 ;
if ( abs ( k ) < 1 ) k = 0 ;
p - > pos . Z + = k ;
2021-12-30 11:14:04 +00:00
p - > vel . Z - = 768 ;
if ( p - > vel . Z < 0 ) p - > vel . Z = 0 ;
2020-05-17 21:44:53 +00:00
}
else if ( p - > jumping_counter = = 0 )
{
2022-08-30 22:03:40 +00:00
p - > pos . Z + = ( ( floorz - i * 0.5 ) - p - > pos . Z ) * 0.5 ; //Smooth on the water
if ( p - > on_warping_sector = = 0 & & p - > pos . Z > floorz - 16 )
2020-05-17 21:44:53 +00:00
{
2022-08-30 22:03:40 +00:00
p - > pos . Z = floorz - 16 ;
2021-12-30 11:14:04 +00:00
p - > vel . Z > > = 1 ;
2020-05-17 21:44:53 +00:00
}
}
p - > on_warping_sector = 0 ;
2022-01-13 11:42:48 +00:00
if ( ( actions & SB_CROUCH ) | | crouch_toggle ) // FIXME: The crouch_toggle check here is not network safe and needs revision when multiplayer is going.
2020-05-17 21:44:53 +00:00
{
playerCrouch ( snum ) ;
}
// jumping
2020-08-28 20:51:05 +00:00
if ( ( actions & SB_JUMP ) = = 0 & & p - > jumping_toggle = = 1 )
2020-05-17 21:44:53 +00:00
p - > jumping_toggle = 0 ;
2020-08-28 20:51:05 +00:00
else if ( ( actions & SB_JUMP ) )
2020-05-17 21:44:53 +00:00
{
2022-08-30 22:03:40 +00:00
playerJump ( snum , fz_ , cz_ ) ;
2020-05-17 21:44:53 +00:00
}
2020-08-28 20:51:05 +00:00
if ( p - > jumping_counter & & ( actions & SB_JUMP ) = = 0 )
2020-05-17 21:44:53 +00:00
p - > jumping_toggle = 0 ;
}
if ( p - > jumping_counter )
{
2020-08-28 20:51:05 +00:00
if ( ( actions & SB_JUMP ) = = 0 & & p - > jumping_toggle = = 1 )
2020-05-17 21:44:53 +00:00
p - > jumping_toggle = 0 ;
if ( p - > jumping_counter < ( 1024 + 256 ) )
{
if ( psectlotag = = 1 & & p - > jumping_counter > 768 )
{
p - > jumping_counter = 0 ;
2021-12-30 11:14:04 +00:00
p - > vel . Z = - 512 ;
2020-05-17 21:44:53 +00:00
}
else
{
2021-12-30 11:14:04 +00:00
p - > vel . Z - = bsin ( 2048 - 128 + p - > jumping_counter ) / 12 ;
2020-05-17 21:44:53 +00:00
p - > jumping_counter + = 180 ;
p - > on_ground = 0 ;
}
}
else
{
p - > jumping_counter = 0 ;
2021-12-30 11:14:04 +00:00
p - > vel . Z = 0 ;
2020-05-17 21:44:53 +00:00
}
}
2022-08-30 22:03:40 +00:00
p - > pos . Z + = p - > vel . Z * zinttoworld ;
2020-05-17 21:44:53 +00:00
2022-08-30 22:03:40 +00:00
if ( p - > pos . Z < ceilingz + 4 )
2020-05-17 21:44:53 +00:00
{
p - > jumping_counter = 0 ;
2021-12-30 11:14:04 +00:00
if ( p - > vel . Z < 0 )
2021-12-30 11:18:56 +00:00
p - > vel . X = p - > vel . Y = 0 ;
2021-12-30 11:14:04 +00:00
p - > vel . Z = 128 ;
2022-08-30 22:03:40 +00:00
p - > pos . Z = ceilingz + 4 ;
2020-05-17 21:44:53 +00:00
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-08-30 22:10:49 +00:00
static void underwater ( int snum , ESyncBits actions , int fz_ , int cz_ )
2020-05-17 21:44:53 +00:00
{
auto p = & ps [ snum ] ;
2020-10-25 06:01:58 +00:00
auto pact = p - > GetActor ( ) ;
2022-08-30 22:10:49 +00:00
double floorz = fz_ * zinttoworld ;
double ceilingz = cz_ * zinttoworld ;
2020-05-17 21:44:53 +00:00
// under water
p - > jumping_counter = 0 ;
p - > pycount + = 32 ;
p - > pycount & = 2047 ;
2022-08-30 20:25:07 +00:00
p - > pyoff = DAngle : : fromBuild ( p - > pycount ) . Sin ( ) ;
2020-05-17 21:44:53 +00:00
2020-10-25 06:01:58 +00:00
if ( ! S_CheckActorSoundPlaying ( pact , DUKE_UNDERWATER ) )
S_PlayActorSound ( DUKE_UNDERWATER , pact ) ;
2020-05-17 21:44:53 +00:00
2020-08-28 20:51:05 +00:00
if ( actions & SB_JUMP )
2020-05-17 21:44:53 +00:00
{
// jump
2021-12-30 11:14:04 +00:00
if ( p - > vel . Z > 0 ) p - > vel . Z = 0 ;
p - > vel . Z - = 348 ;
if ( p - > vel . Z < - ( 256 * 6 ) ) p - > vel . Z = - ( 256 * 6 ) ;
2020-05-17 21:44:53 +00:00
}
2020-08-28 20:51:05 +00:00
else if ( actions & SB_CROUCH )
2020-05-17 21:44:53 +00:00
{
// crouch
2021-12-30 11:14:04 +00:00
if ( p - > vel . Z < 0 ) p - > vel . Z = 0 ;
p - > vel . Z + = 348 ;
if ( p - > vel . Z > ( 256 * 6 ) ) p - > vel . Z = ( 256 * 6 ) ;
2020-05-17 21:44:53 +00:00
}
else
{
// normal view
2021-12-30 11:14:04 +00:00
if ( p - > vel . Z < 0 )
2020-05-17 21:44:53 +00:00
{
2021-12-30 11:14:04 +00:00
p - > vel . Z + = 256 ;
if ( p - > vel . Z > 0 )
p - > vel . Z = 0 ;
2020-05-17 21:44:53 +00:00
}
2021-12-30 11:14:04 +00:00
if ( p - > vel . Z > 0 )
2020-05-17 21:44:53 +00:00
{
2021-12-30 11:14:04 +00:00
p - > vel . Z - = 256 ;
if ( p - > vel . Z < 0 )
p - > vel . Z = 0 ;
2020-05-17 21:44:53 +00:00
}
}
2021-12-30 11:14:04 +00:00
if ( p - > vel . Z > 2048 )
p - > vel . Z > > = 1 ;
2020-05-17 21:44:53 +00:00
2022-08-30 22:10:49 +00:00
p - > pos . Z + = p - > vel . Z * zinttoworld ;
2020-05-17 21:44:53 +00:00
2022-08-30 22:10:49 +00:00
if ( p - > pos . Z > floorz - 15 )
p - > pos . Z + = ( ( ( floorz - 15 ) - p - > pos . Z ) * 0.5 ) ;
2020-05-17 21:44:53 +00:00
2022-08-30 22:10:49 +00:00
if ( p - > pos . Z < ceilingz + 4 )
2020-05-17 21:44:53 +00:00
{
2022-08-30 22:10:49 +00:00
p - > pos . Z = ceilingz + 4 ;
2021-12-30 11:14:04 +00:00
p - > vel . Z = 0 ;
2020-05-17 21:44:53 +00:00
}
if ( p - > scuba_on & & ( krand ( ) & 255 ) < 8 )
{
2020-10-25 06:01:58 +00:00
auto j = spawn ( pact , WATERBUBBLE ) ;
2021-11-19 11:32:12 +00:00
if ( j )
{
2022-08-27 13:09:22 +00:00
j - > add_int_pos ( { bcos ( p - > angle . ang . Buildang ( ) + 64 - ( global_random & 128 ) , - 6 ) , bsin ( p - > angle . ang . Buildang ( ) + 64 - ( global_random & 128 ) , - 6 ) , 0 } ) ;
2021-12-21 17:19:45 +00:00
j - > spr . xrepeat = 3 ;
j - > spr . yrepeat = 2 ;
2022-08-30 22:10:49 +00:00
j - > spr . pos . Z = p - > pos . Z + 8 ;
2021-11-19 11:32:12 +00:00
}
2020-05-17 21:44:53 +00:00
}
}
2020-05-18 06:26:09 +00:00
2020-05-18 20:28:12 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
int operateTripbomb ( int snum )
2020-05-18 06:26:09 +00:00
{
auto p = & ps [ snum ] ;
2021-12-06 11:24:22 +00:00
HitInfo hit { } ;
2020-05-18 06:26:09 +00:00
2022-08-27 13:09:51 +00:00
hitscan ( p - > player_int_pos ( ) , p - > cursector , { int ( p - > angle . ang . Cos ( ) * ( 1 < < 14 ) ) , int ( p - > angle . ang . Sin ( ) * ( 1 < < 14 ) ) , - p - > horizon . sum ( ) . asq16 ( ) > > 11 } , hit , CLIPMASK1 ) ;
2020-05-18 06:26:09 +00:00
2021-11-25 23:08:59 +00:00
if ( hit . hitSector = = nullptr | | hit . actor ( ) )
2020-05-18 06:26:09 +00:00
return 0 ;
2021-11-25 23:08:59 +00:00
if ( hit . hitWall ! = nullptr & & hit . hitSector - > lotag > 2 )
2020-05-18 06:26:09 +00:00
return 0 ;
2021-11-25 23:08:59 +00:00
if ( hit . hitWall ! = nullptr & & hit . hitWall - > overpicnum > = 0 )
if ( hit . hitWall - > overpicnum = = BIGFORCE )
2020-05-18 06:26:09 +00:00
return 0 ;
2021-12-21 19:33:39 +00:00
DDukeActor * act ;
2021-11-25 23:08:59 +00:00
DukeSectIterator it ( hit . hitSector ) ;
2021-12-21 19:33:39 +00:00
while ( ( act = it . Next ( ) ) )
2020-05-18 06:26:09 +00:00
{
2022-01-19 08:02:20 +00:00
if ( ! actorflag ( act , SFLAG_BLOCK_TRIPBOMB ) & &
2022-08-16 22:59:32 +00:00
abs ( act - > int_pos ( ) . Z - hit . int_hitpos ( ) . Z ) < ( 12 < < 8 ) & & ( ( act - > int_pos ( ) . X - hit . int_hitpos ( ) . X ) * ( act - > int_pos ( ) . X - hit . int_hitpos ( ) . X ) + ( act - > int_pos ( ) . Y - hit . int_hitpos ( ) . Y ) * ( act - > int_pos ( ) . Y - hit . int_hitpos ( ) . Y ) ) < ( 290 * 290 ) )
2020-05-18 06:26:09 +00:00
return 0 ;
}
2021-12-21 19:33:39 +00:00
if ( act = = nullptr & & hit . hitWall ! = nullptr & & ( hit . hitWall - > cstat & CSTAT_WALL_MASKED ) = = 0 )
2021-11-25 23:08:59 +00:00
if ( ( hit . hitWall - > twoSided ( ) & & hit . hitWall - > nextSector ( ) - > lotag < = 2 ) | | ( ! hit . hitWall - > twoSided ( ) & & hit . hitSector - > lotag < = 2 ) )
2022-08-16 22:59:32 +00:00
if ( ( ( hit . int_hitpos ( ) . X - p - > player_int_pos ( ) . X ) * ( hit . int_hitpos ( ) . X - p - > player_int_pos ( ) . X ) + ( hit . int_hitpos ( ) . Y - p - > player_int_pos ( ) . Y ) * ( hit . int_hitpos ( ) . Y - p - > player_int_pos ( ) . Y ) ) < ( 290 * 290 ) )
2020-05-18 06:26:09 +00:00
{
2022-02-05 12:40:30 +00:00
p - > pos . Z = p - > opos . Z ;
2021-12-30 11:14:04 +00:00
p - > vel . Z = 0 ;
2020-05-18 06:26:09 +00:00
return 1 ;
}
return 0 ;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-05-18 22:26:07 +00:00
static void fireweapon ( int snum )
2020-05-18 06:26:09 +00:00
{
auto p = & ps [ snum ] ;
2020-11-02 19:24:07 +00:00
auto pact = p - > GetActor ( ) ;
2020-05-18 06:26:09 +00:00
2020-08-27 05:54:49 +00:00
p - > crack_time = CRACK_TIME ;
2020-05-18 06:26:09 +00:00
if ( p - > holster_weapon = = 1 )
{
if ( p - > last_pissed_time < = ( 26 * 218 ) & & p - > weapon_pos = = - 9 )
{
p - > holster_weapon = 0 ;
2020-09-16 11:01:09 +00:00
p - > oweapon_pos = p - > weapon_pos = 10 ;
2020-05-18 06:26:09 +00:00
FTA ( 74 , p ) ;
}
}
else switch ( p - > curr_weapon )
{
case HANDBOMB_WEAPON :
p - > hbomb_hold_delay = 0 ;
if ( p - > ammo_amount [ HANDBOMB_WEAPON ] > 0 )
2020-05-18 22:26:07 +00:00
p - > kickback_pic = 1 ;
2020-05-18 06:26:09 +00:00
break ;
case HANDREMOTE_WEAPON :
p - > hbomb_hold_delay = 0 ;
2020-05-18 22:26:07 +00:00
p - > kickback_pic = 1 ;
2020-05-18 06:26:09 +00:00
break ;
case PISTOL_WEAPON :
if ( p - > ammo_amount [ PISTOL_WEAPON ] > 0 )
{
p - > ammo_amount [ PISTOL_WEAPON ] - - ;
2020-05-18 22:26:07 +00:00
p - > kickback_pic = 1 ;
2020-05-18 06:26:09 +00:00
}
break ;
case CHAINGUN_WEAPON :
if ( p - > ammo_amount [ CHAINGUN_WEAPON ] > 0 ) // && p->random_club_frame == 0)
2020-05-18 22:26:07 +00:00
p - > kickback_pic = 1 ;
2020-05-18 06:26:09 +00:00
break ;
case SHOTGUN_WEAPON :
if ( p - > ammo_amount [ SHOTGUN_WEAPON ] > 0 & & p - > random_club_frame = = 0 )
2020-05-18 22:26:07 +00:00
p - > kickback_pic = 1 ;
2020-05-18 06:26:09 +00:00
break ;
case TRIPBOMB_WEAPON :
if ( p - > ammo_amount [ TRIPBOMB_WEAPON ] > 0 )
{
if ( operateTripbomb ( snum ) )
2020-05-18 22:26:07 +00:00
p - > kickback_pic = 1 ;
2020-05-18 06:26:09 +00:00
}
break ;
case SHRINKER_WEAPON :
case GROW_WEAPON :
if ( p - > curr_weapon = = GROW_WEAPON )
{
if ( p - > ammo_amount [ GROW_WEAPON ] > 0 )
{
2020-05-18 22:26:07 +00:00
p - > kickback_pic = 1 ;
2020-11-02 19:24:07 +00:00
S_PlayActorSound ( EXPANDERSHOOT , pact ) ;
2020-05-18 06:26:09 +00:00
}
}
else if ( p - > ammo_amount [ SHRINKER_WEAPON ] > 0 )
{
2020-05-18 22:26:07 +00:00
p - > kickback_pic = 1 ;
2020-11-02 19:24:07 +00:00
S_PlayActorSound ( SHRINKER_FIRE , pact ) ;
2020-05-18 06:26:09 +00:00
}
break ;
case FREEZE_WEAPON :
if ( p - > ammo_amount [ FREEZE_WEAPON ] > 0 )
{
2020-05-18 22:26:07 +00:00
p - > kickback_pic = 1 ;
2020-11-02 19:24:07 +00:00
S_PlayActorSound ( CAT_FIRE , pact ) ;
2020-05-18 06:26:09 +00:00
}
break ;
case DEVISTATOR_WEAPON :
if ( p - > ammo_amount [ DEVISTATOR_WEAPON ] > 0 )
{
2020-05-18 22:26:07 +00:00
p - > kickback_pic = 1 ;
2020-05-18 06:26:09 +00:00
p - > hbomb_hold_delay = ! p - > hbomb_hold_delay ;
2020-11-02 19:24:07 +00:00
S_PlayActorSound ( CAT_FIRE , pact ) ;
2020-05-18 06:26:09 +00:00
}
break ;
case RPG_WEAPON :
if ( p - > ammo_amount [ RPG_WEAPON ] > 0 )
{
2020-05-18 22:26:07 +00:00
p - > kickback_pic = 1 ;
2020-05-18 06:26:09 +00:00
}
break ;
2020-05-18 20:28:12 +00:00
case FLAMETHROWER_WEAPON : // Twentieth Anniversary World Tour
if ( isWorldTour ( ) & & p - > ammo_amount [ FLAMETHROWER_WEAPON ] > 0 )
{
2020-05-18 22:26:07 +00:00
p - > kickback_pic = 1 ;
2021-11-21 07:56:39 +00:00
if ( p - > cursector - > lotag ! = 2 )
2020-11-02 19:24:07 +00:00
S_PlayActorSound ( FLAMETHROWER_INTRO , pact ) ;
2020-05-18 20:28:12 +00:00
}
break ;
2020-05-18 06:26:09 +00:00
case KNEE_WEAPON :
if ( p - > quick_kick = = 0 )
{
2020-05-18 22:26:07 +00:00
p - > kickback_pic = 1 ;
2020-05-18 06:26:09 +00:00
}
break ;
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-11-21 07:48:36 +00:00
static void operateweapon ( int snum , ESyncBits actions )
2020-05-18 06:26:09 +00:00
{
auto p = & ps [ snum ] ;
2020-10-24 05:34:39 +00:00
auto pact = p - > GetActor ( ) ;
int i , k ;
2020-05-18 06:26:09 +00:00
// already firing...
2020-05-18 20:28:12 +00:00
switch ( p - > curr_weapon )
2020-05-18 06:26:09 +00:00
{
2020-05-18 20:28:12 +00:00
case HANDBOMB_WEAPON : // grenade in NAM
2020-08-28 20:51:05 +00:00
if ( p - > kickback_pic = = 6 & & ( actions & SB_FIRE ) )
2020-05-18 06:26:09 +00:00
{
p - > rapid_fire_hold = 1 ;
2020-05-18 20:28:12 +00:00
break ;
2020-05-18 06:26:09 +00:00
}
2020-05-18 22:26:07 +00:00
p - > kickback_pic + + ;
if ( p - > kickback_pic = = 12 )
2020-05-18 06:26:09 +00:00
{
2020-05-18 20:28:12 +00:00
p - > ammo_amount [ HANDBOMB_WEAPON ] - - ;
2020-05-18 06:26:09 +00:00
2020-08-28 20:51:05 +00:00
if ( p - > on_ground & & ( actions & SB_CROUCH ) )
2020-05-18 06:26:09 +00:00
{
k = 15 ;
2021-01-04 11:36:54 +00:00
i = MulScale ( p - > horizon . sum ( ) . asq16 ( ) , 20 , 16 ) ;
2020-05-18 06:26:09 +00:00
}
else
{
k = 140 ;
2021-01-04 11:36:54 +00:00
i = - 512 - MulScale ( p - > horizon . sum ( ) . asq16 ( ) , 20 , 16 ) ;
2020-05-18 06:26:09 +00:00
}
2021-11-21 07:56:39 +00:00
auto spawned = EGS ( p - > cursector ,
2022-08-27 13:09:51 +00:00
p - > player_int_pos ( ) . X + p - > angle . ang . Cos ( ) * ( 1 < < 8 ) ,
p - > player_int_pos ( ) . Y + p - > angle . ang . Sin ( ) * ( 1 < < 8 ) ,
2022-02-04 17:11:44 +00:00
p - > player_int_pos ( ) . Z , HEAVYHBOMB , - 16 , 9 , 9 ,
2022-08-27 13:09:22 +00:00
p - > angle . ang . Buildang ( ) , ( k + ( p - > hbomb_hold_delay < < 5 ) ) , i , pact , 1 ) ;
2020-05-18 06:26:09 +00:00
2020-05-18 20:28:12 +00:00
if ( isNam ( ) )
2020-05-18 06:26:09 +00:00
{
2021-12-21 17:19:45 +00:00
spawned - > spr . extra = MulScale ( krand ( ) , NAM_GRENADE_LIFETIME_VAR , 14 ) ;
2020-05-18 06:26:09 +00:00
}
if ( k = = 15 )
{
2021-12-21 17:19:45 +00:00
spawned - > spr . yvel = 3 ;
2022-02-07 07:47:18 +00:00
spawned - > spr . pos . Z + = 8 ;
2020-05-18 06:26:09 +00:00
}
2020-10-24 05:34:39 +00:00
k = hits ( pact ) ;
2020-05-18 06:26:09 +00:00
if ( k < 512 )
{
2022-08-16 21:26:39 +00:00
spawned - > add_int_ang ( 1024 ) ;
2021-12-21 17:19:45 +00:00
spawned - > spr . zvel / = 3 ;
spawned - > spr . xvel / = 3 ;
2020-05-18 06:26:09 +00:00
}
p - > hbomb_on = 1 ;
}
2020-08-28 20:51:05 +00:00
else if ( p - > kickback_pic < 12 & & ( actions & SB_FIRE ) )
2020-05-18 06:26:09 +00:00
p - > hbomb_hold_delay + + ;
2020-05-18 22:26:07 +00:00
else if ( p - > kickback_pic > 19 )
2020-05-18 06:26:09 +00:00
{
2020-08-03 05:02:30 +00:00
p - > okickback_pic = p - > kickback_pic = 0 ;
2020-05-18 06:26:09 +00:00
// don't change to remote when in NAM: grenades are timed
2020-05-18 20:28:12 +00:00
if ( isNam ( ) ) checkavailweapon ( p ) ;
else
{
p - > curr_weapon = HANDREMOTE_WEAPON ;
p - > last_weapon = - 1 ;
2020-08-03 05:05:38 +00:00
p - > oweapon_pos = p - > weapon_pos = 10 ;
2020-05-18 20:28:12 +00:00
}
2020-05-18 06:26:09 +00:00
}
2020-05-18 20:28:12 +00:00
break ;
case HANDREMOTE_WEAPON : // knife in NAM
2020-05-18 22:26:07 +00:00
p - > kickback_pic + + ;
2020-05-18 06:26:09 +00:00
2020-05-18 22:26:07 +00:00
if ( p - > kickback_pic = = 2 )
2020-05-18 06:26:09 +00:00
{
2020-05-18 20:28:12 +00:00
p - > hbomb_on = 0 ;
2020-05-18 06:26:09 +00:00
}
2020-05-18 22:26:07 +00:00
if ( p - > kickback_pic = = 10 )
2020-05-18 06:26:09 +00:00
{
2020-08-03 05:02:30 +00:00
p - > okickback_pic = p - > kickback_pic = 0 ;
2020-05-18 20:28:12 +00:00
int weapon = isNam ( ) ? TRIPBOMB_WEAPON : HANDBOMB_WEAPON ;
if ( p - > ammo_amount [ weapon ] > 0 )
fi . addweapon ( p , weapon ) ;
2020-05-18 06:26:09 +00:00
else
checkavailweapon ( p ) ;
}
2020-05-18 20:28:12 +00:00
break ;
2020-05-18 06:26:09 +00:00
2020-05-18 20:28:12 +00:00
case PISTOL_WEAPON : // m-16 in NAM
2020-05-18 22:26:07 +00:00
if ( p - > kickback_pic = = 1 )
2020-05-18 06:26:09 +00:00
{
2020-10-24 05:34:39 +00:00
fi . shoot ( pact , SHOTSPARK1 ) ;
S_PlayActorSound ( PISTOL_FIRE , pact ) ;
2021-02-18 10:46:36 +00:00
lastvisinc = PlayClock + 32 ;
2020-05-18 20:28:12 +00:00
p - > visibility = 0 ;
2020-05-18 06:26:09 +00:00
}
2020-05-18 22:26:07 +00:00
else if ( p - > kickback_pic = = 2 )
2020-10-24 05:34:39 +00:00
spawn ( pact , SHELL ) ;
2020-05-18 20:28:12 +00:00
2020-05-18 22:26:07 +00:00
p - > kickback_pic + + ;
2020-05-18 20:28:12 +00:00
2020-05-18 22:26:07 +00:00
if ( p - > kickback_pic > = 5 )
2020-05-18 20:28:12 +00:00
{
if ( p - > ammo_amount [ PISTOL_WEAPON ] < = 0 | | ( p - > ammo_amount [ PISTOL_WEAPON ] % ( isNam ( ) ? 20 : 12 ) ) )
2020-05-18 06:26:09 +00:00
{
2020-08-03 05:02:30 +00:00
p - > okickback_pic = p - > kickback_pic = 0 ;
2020-05-18 20:28:12 +00:00
checkavailweapon ( p ) ;
2020-05-18 06:26:09 +00:00
}
2020-05-18 20:28:12 +00:00
else
2020-05-18 06:26:09 +00:00
{
2020-05-18 22:26:07 +00:00
switch ( p - > kickback_pic )
2020-05-18 06:26:09 +00:00
{
2020-05-18 20:28:12 +00:00
case 5 :
2020-10-24 05:34:39 +00:00
S_PlayActorSound ( EJECT_CLIP , pact ) ;
2020-05-18 20:28:12 +00:00
break ;
//#ifdef NAM
2021-11-09 23:05:42 +00:00
// case WEAPON2_RELOAD_TIME - 15:
2020-05-18 20:28:12 +00:00
//#else
case 8 :
//#endif
2020-10-24 05:34:39 +00:00
S_PlayActorSound ( INSERT_CLIP , pact ) ;
2020-05-18 20:28:12 +00:00
break ;
2020-05-18 06:26:09 +00:00
}
}
2020-05-18 20:28:12 +00:00
}
2020-05-18 06:26:09 +00:00
2020-05-18 20:28:12 +00:00
// 3 second re-load time
2020-05-18 22:26:07 +00:00
if ( p - > kickback_pic = = ( isNam ( ) ? 50 : 27 ) )
2020-05-18 20:28:12 +00:00
{
2020-08-03 05:02:30 +00:00
p - > okickback_pic = p - > kickback_pic = 0 ;
2020-05-18 20:28:12 +00:00
checkavailweapon ( p ) ;
}
break ;
2020-05-18 06:26:09 +00:00
2020-05-18 20:28:12 +00:00
case SHOTGUN_WEAPON :
2020-05-18 06:26:09 +00:00
2020-05-18 22:26:07 +00:00
p - > kickback_pic + + ;
2020-05-18 06:26:09 +00:00
2020-05-18 22:26:07 +00:00
if ( p - > kickback_pic = = 4 )
2020-05-18 20:28:12 +00:00
{
2021-12-24 09:53:27 +00:00
for ( int ii = 0 ; ii < 7 ; ii + + )
2020-10-24 05:34:39 +00:00
fi . shoot ( pact , SHOTGUN ) ;
2020-05-18 20:28:12 +00:00
p - > ammo_amount [ SHOTGUN_WEAPON ] - - ;
2020-05-18 06:26:09 +00:00
2020-10-24 05:34:39 +00:00
S_PlayActorSound ( SHOTGUN_FIRE , pact ) ;
2020-05-18 06:26:09 +00:00
2021-02-18 10:46:36 +00:00
lastvisinc = PlayClock + 32 ;
2020-05-18 20:28:12 +00:00
p - > visibility = 0 ;
2020-05-18 06:26:09 +00:00
}
2020-05-18 22:26:07 +00:00
switch ( p - > kickback_pic )
2020-05-18 06:26:09 +00:00
{
case 13 :
checkavailweapon ( p ) ;
break ;
case 15 :
2020-10-24 05:34:39 +00:00
S_PlayActorSound ( SHOTGUN_COCK , pact ) ;
2020-05-18 06:26:09 +00:00
break ;
case 17 :
case 20 :
p - > kickback_pic + + ;
break ;
case 24 :
2020-10-24 05:34:39 +00:00
{
auto j = spawn ( pact , SHOTGUNSHELL ) ;
2021-11-19 11:32:12 +00:00
if ( j )
{
2022-08-16 21:26:39 +00:00
j - > add_int_ang ( 1024 ) ;
2021-11-19 11:32:12 +00:00
ssp ( j , CLIPMASK0 ) ;
2022-08-16 21:26:39 +00:00
j - > add_int_ang ( 1024 ) ;
2021-11-19 11:32:12 +00:00
}
2020-05-18 06:26:09 +00:00
p - > kickback_pic + + ;
break ;
2020-10-24 05:34:39 +00:00
}
2020-05-18 06:26:09 +00:00
case 31 :
2020-08-03 05:02:30 +00:00
p - > okickback_pic = p - > kickback_pic = 0 ;
2020-05-18 06:26:09 +00:00
return ;
}
break ;
case CHAINGUN_WEAPON : // m-60 in NAM
2020-05-18 22:26:07 +00:00
p - > kickback_pic + + ;
2020-05-18 06:26:09 +00:00
2020-05-18 22:26:07 +00:00
if ( p - > kickback_pic < = 12 )
2020-05-18 06:26:09 +00:00
{
2020-05-18 22:26:07 +00:00
if ( ( ( p - > kickback_pic ) % 3 ) = = 0 )
2020-05-18 06:26:09 +00:00
{
p - > ammo_amount [ CHAINGUN_WEAPON ] - - ;
2020-05-18 22:26:07 +00:00
if ( ( p - > kickback_pic % 3 ) = = 0 )
2020-05-18 06:26:09 +00:00
{
2020-10-24 05:34:39 +00:00
auto j = spawn ( pact , SHELL ) ;
2021-11-19 11:32:12 +00:00
if ( j )
{
2022-08-16 21:27:44 +00:00
j - > set_int_ang ( ( j - > int_ang ( ) + 1024 ) & 2047 ) ;
2021-12-21 17:19:45 +00:00
j - > spr . xvel + = 32 ;
2022-02-07 07:47:18 +00:00
j - > spr . pos . Z + = 3 ;
2021-11-19 11:32:12 +00:00
ssp ( j , CLIPMASK0 ) ;
}
2020-05-18 06:26:09 +00:00
}
2020-10-24 05:34:39 +00:00
S_PlayActorSound ( CHAINGUN_FIRE , pact ) ;
fi . shoot ( pact , CHAINGUN ) ;
2021-02-18 10:46:36 +00:00
lastvisinc = PlayClock + 32 ;
2020-05-18 06:26:09 +00:00
p - > visibility = 0 ;
checkavailweapon ( p ) ;
2020-08-28 20:51:05 +00:00
if ( ( actions & SB_FIRE ) = = 0 )
2020-05-18 06:26:09 +00:00
{
2020-08-03 05:02:30 +00:00
p - > okickback_pic = p - > kickback_pic = 0 ;
2020-05-18 06:26:09 +00:00
break ;
}
}
}
2020-05-18 22:26:07 +00:00
else if ( p - > kickback_pic > 10 )
2020-05-18 06:26:09 +00:00
{
2020-08-28 20:51:05 +00:00
if ( actions & SB_FIRE ) p - > okickback_pic = p - > kickback_pic = 1 ;
2020-08-03 05:02:30 +00:00
else p - > okickback_pic = p - > kickback_pic = 0 ;
2020-05-18 06:26:09 +00:00
}
break ;
case GROW_WEAPON : // m-14 with scope (sniper rifle)
2020-05-18 20:28:12 +00:00
bool check ;
if ( isNam ( ) )
2020-05-18 06:26:09 +00:00
{
2020-05-18 22:26:07 +00:00
p - > kickback_pic + + ;
check = ( p - > kickback_pic = = 3 ) ;
2020-05-18 06:26:09 +00:00
}
else
{
2020-05-18 22:26:07 +00:00
check = ( p - > kickback_pic > 3 ) ;
2020-05-18 06:26:09 +00:00
}
2020-05-18 20:28:12 +00:00
if ( check )
2020-05-18 06:26:09 +00:00
{
2020-05-18 20:28:12 +00:00
// fire now, but don't reload right away...
if ( isNam ( ) )
{
2020-05-18 22:26:07 +00:00
p - > kickback_pic + + ;
2020-05-18 06:26:09 +00:00
if ( p - > ammo_amount [ p - > curr_weapon ] < = 1 )
2020-08-03 05:02:30 +00:00
p - > okickback_pic = p - > kickback_pic = 0 ;
2020-05-18 06:26:09 +00:00
}
2020-05-18 20:28:12 +00:00
else
2020-08-03 05:02:30 +00:00
p - > okickback_pic = p - > kickback_pic = 0 ;
2020-05-18 20:28:12 +00:00
p - > ammo_amount [ p - > curr_weapon ] - - ;
2020-10-24 05:34:39 +00:00
fi . shoot ( pact , GROWSPARK ) ;
2020-05-18 20:28:12 +00:00
//#ifdef NAM
//#else
2021-12-05 12:43:31 +00:00
if ( ! ( aplWeaponFlags ( p - > curr_weapon , snum ) & WEAPON_FLAG_NOVISIBLE ) )
2020-05-18 20:28:12 +00:00
{
// make them visible if not set...
p - > visibility = 0 ;
2021-02-18 10:46:36 +00:00
lastvisinc = PlayClock + 32 ;
2020-05-18 06:26:09 +00:00
}
2020-05-18 20:28:12 +00:00
checkavailweapon ( p ) ;
//#endif
2020-05-18 06:26:09 +00:00
}
2020-05-18 22:26:07 +00:00
else if ( ! isNam ( ) ) p - > kickback_pic + + ;
2022-01-08 20:42:44 +00:00
if ( isNam ( ) & & p - > kickback_pic > 30 )
2020-05-18 06:26:09 +00:00
{
2020-05-18 20:28:12 +00:00
// reload now...
2020-08-03 05:02:30 +00:00
p - > okickback_pic = p - > kickback_pic = 0 ;
2021-12-05 12:43:31 +00:00
if ( ! ( aplWeaponFlags ( p - > curr_weapon , snum ) & WEAPON_FLAG_NOVISIBLE ) )
2020-05-18 06:26:09 +00:00
{
2020-05-18 20:28:12 +00:00
// make them visible if not set...
2020-05-18 06:26:09 +00:00
p - > visibility = 0 ;
2021-02-18 10:46:36 +00:00
lastvisinc = PlayClock + 32 ;
2020-05-18 06:26:09 +00:00
}
2020-05-18 20:28:12 +00:00
checkavailweapon ( p ) ;
}
break ;
case SHRINKER_WEAPON : // m-79 in NAM (Grenade launcher)
2020-05-18 22:26:07 +00:00
if ( ( ! isNam ( ) & & p - > kickback_pic > 10 ) | | ( isNam ( ) & & p - > kickback_pic = = 10 ) )
2020-05-18 20:28:12 +00:00
{
2020-05-18 22:26:07 +00:00
if ( isNam ( ) ) p - > kickback_pic + + ; // fire now, but wait for reload...
2020-08-03 05:02:30 +00:00
else p - > okickback_pic = p - > kickback_pic = 0 ;
2020-05-18 20:28:12 +00:00
p - > ammo_amount [ SHRINKER_WEAPON ] - - ;
2020-10-24 05:34:39 +00:00
fi . shoot ( pact , SHRINKER ) ;
2020-05-18 20:28:12 +00:00
if ( ! isNam ( ) )
2020-05-18 06:26:09 +00:00
{
p - > visibility = 0 ;
2020-05-18 20:28:12 +00:00
//flashColor = 176 + (252 << 8) + (120 << 16);
2021-02-18 10:46:36 +00:00
lastvisinc = PlayClock + 32 ;
2020-05-18 06:26:09 +00:00
checkavailweapon ( p ) ;
}
}
2020-05-18 22:26:07 +00:00
else if ( isNam ( ) & & p - > kickback_pic > 30 )
2020-05-18 20:28:12 +00:00
{
2020-08-03 05:02:30 +00:00
p - > okickback_pic = p - > kickback_pic = 0 ;
2020-05-18 20:28:12 +00:00
p - > visibility = 0 ;
2021-02-18 10:46:36 +00:00
lastvisinc = PlayClock + 32 ;
2020-05-18 20:28:12 +00:00
checkavailweapon ( p ) ;
}
2020-05-18 22:26:07 +00:00
else p - > kickback_pic + + ;
2020-05-18 06:26:09 +00:00
break ;
case DEVISTATOR_WEAPON :
2020-05-18 22:26:07 +00:00
if ( p - > kickback_pic )
2020-05-18 06:26:09 +00:00
{
2020-05-18 22:26:07 +00:00
p - > kickback_pic + + ;
2020-05-18 06:26:09 +00:00
2020-08-05 19:48:16 +00:00
if ( isNam ( ) )
{
if ( ( p - > kickback_pic > = 2 ) & &
p - > kickback_pic < 5 & &
2020-05-18 22:26:07 +00:00
( p - > kickback_pic & 1 ) )
2020-05-18 06:26:09 +00:00
{
2020-08-05 19:48:16 +00:00
p - > visibility = 0 ;
2021-02-18 10:46:36 +00:00
lastvisinc = PlayClock + 32 ;
2020-10-24 05:34:39 +00:00
fi . shoot ( pact , RPG ) ;
2020-05-18 06:26:09 +00:00
p - > ammo_amount [ DEVISTATOR_WEAPON ] - - ;
checkavailweapon ( p ) ;
}
2020-09-16 11:01:09 +00:00
if ( p - > kickback_pic > 5 ) p - > okickback_pic = p - > kickback_pic = 0 ;
2020-08-05 19:48:16 +00:00
}
else if ( p - > kickback_pic & 1 )
{
p - > visibility = 0 ;
2021-02-18 10:46:36 +00:00
lastvisinc = PlayClock + 32 ;
2020-10-24 05:34:39 +00:00
fi . shoot ( pact , RPG ) ;
2020-08-05 19:48:16 +00:00
p - > ammo_amount [ DEVISTATOR_WEAPON ] - - ;
checkavailweapon ( p ) ;
2020-09-16 11:01:09 +00:00
if ( p - > ammo_amount [ DEVISTATOR_WEAPON ] < = 0 ) p - > okickback_pic = p - > kickback_pic = 0 ;
2020-08-05 19:48:16 +00:00
}
2020-09-16 11:01:09 +00:00
if ( p - > kickback_pic > 5 ) p - > okickback_pic = p - > kickback_pic = 0 ;
2020-05-18 06:26:09 +00:00
}
break ;
case FREEZE_WEAPON :
// flame thrower in NAM
2020-05-18 22:26:07 +00:00
if ( p - > kickback_pic < 4 )
2020-05-18 06:26:09 +00:00
{
2020-05-18 22:26:07 +00:00
p - > kickback_pic + + ;
if ( p - > kickback_pic = = 3 )
2020-05-18 06:26:09 +00:00
{
p - > ammo_amount [ p - > curr_weapon ] - - ;
p - > visibility = 0 ;
2021-02-18 10:46:36 +00:00
lastvisinc = PlayClock + 32 ;
2020-10-24 05:34:39 +00:00
fi . shoot ( pact , FREEZEBLAST ) ;
2020-05-18 06:26:09 +00:00
checkavailweapon ( p ) ;
}
2021-12-21 17:19:45 +00:00
if ( pact - > spr . xrepeat < 32 )
2020-05-18 06:26:09 +00:00
{
2020-08-03 05:02:30 +00:00
p - > okickback_pic = p - > kickback_pic = 0 ; break ;
2020-05-18 06:26:09 +00:00
}
}
else
{
2020-08-28 20:51:05 +00:00
if ( actions & SB_FIRE )
2020-05-18 06:26:09 +00:00
{
2020-08-03 05:02:30 +00:00
p - > okickback_pic = p - > kickback_pic = 1 ;
2020-10-24 05:34:39 +00:00
S_PlayActorSound ( CAT_FIRE , pact ) ;
2020-05-18 06:26:09 +00:00
}
2020-09-16 11:01:09 +00:00
else p - > okickback_pic = p - > kickback_pic = 0 ;
2020-05-18 06:26:09 +00:00
}
break ;
2020-05-18 20:28:12 +00:00
case FLAMETHROWER_WEAPON :
if ( ! isWorldTour ( ) ) // Twentieth Anniversary World Tour
break ;
2020-05-18 22:26:07 +00:00
p - > kickback_pic + + ;
if ( p - > kickback_pic = = 2 )
2020-05-18 20:28:12 +00:00
{
2021-11-21 07:56:39 +00:00
if ( p - > cursector - > lotag ! = 2 )
2020-05-18 20:28:12 +00:00
{
p - > ammo_amount [ FLAMETHROWER_WEAPON ] - - ;
2020-10-24 05:34:39 +00:00
fi . shoot ( pact , FIREBALL ) ;
2020-05-18 20:28:12 +00:00
}
checkavailweapon ( p ) ;
}
2020-05-18 22:26:07 +00:00
else if ( p - > kickback_pic = = 16 )
2020-05-18 20:28:12 +00:00
{
2020-08-28 20:51:05 +00:00
if ( ( actions & SB_FIRE ) ! = 0 )
2020-05-18 20:28:12 +00:00
{
2020-08-03 05:02:30 +00:00
p - > okickback_pic = p - > kickback_pic = 1 ;
2020-10-24 05:34:39 +00:00
S_PlayActorSound ( FLAMETHROWER_INTRO , pact ) ;
2020-05-18 20:28:12 +00:00
}
else
2020-08-03 05:02:30 +00:00
p - > okickback_pic = p - > kickback_pic = 0 ;
2020-05-18 20:28:12 +00:00
}
break ;
2020-05-18 06:26:09 +00:00
case TRIPBOMB_WEAPON : // Claymore in NAM
2020-05-18 22:26:07 +00:00
if ( p - > kickback_pic < 4 )
2020-05-18 06:26:09 +00:00
{
2022-02-05 12:40:30 +00:00
p - > pos . Z = p - > opos . Z ;
2021-12-30 11:14:04 +00:00
p - > vel . Z = 0 ;
2020-05-18 22:26:07 +00:00
if ( p - > kickback_pic = = 3 )
2020-10-24 05:34:39 +00:00
fi . shoot ( pact , HANDHOLDINGLASER ) ;
2020-05-18 06:26:09 +00:00
}
2020-05-18 22:26:07 +00:00
if ( p - > kickback_pic = = 16 )
2020-05-18 06:26:09 +00:00
{
2020-08-03 05:02:30 +00:00
p - > okickback_pic = p - > kickback_pic = 0 ;
2020-05-18 06:26:09 +00:00
checkavailweapon ( p ) ;
2020-08-03 05:05:38 +00:00
p - > oweapon_pos = p - > weapon_pos = - 9 ;
2020-05-18 06:26:09 +00:00
}
2020-05-18 22:26:07 +00:00
else p - > kickback_pic + + ;
2020-05-18 06:26:09 +00:00
break ;
case KNEE_WEAPON :
2020-05-18 22:26:07 +00:00
p - > kickback_pic + + ;
2020-05-18 06:26:09 +00:00
2020-10-24 05:34:39 +00:00
if ( p - > kickback_pic = = 7 ) fi . shoot ( pact , KNEE ) ;
2020-05-18 22:26:07 +00:00
else if ( p - > kickback_pic = = 14 )
2020-05-18 06:26:09 +00:00
{
2020-08-28 20:51:05 +00:00
if ( actions & SB_FIRE )
2020-08-03 05:02:30 +00:00
p - > okickback_pic = p - > kickback_pic = 1 + ( krand ( ) & 3 ) ;
else p - > okickback_pic = p - > kickback_pic = 0 ;
2020-05-18 06:26:09 +00:00
}
if ( p - > wantweaponfire > = 0 )
checkavailweapon ( p ) ;
break ;
case RPG_WEAPON : // m-72 in NAM (LAW)
2020-05-18 22:26:07 +00:00
p - > kickback_pic + + ;
if ( p - > kickback_pic = = 4 )
2020-05-18 06:26:09 +00:00
{
p - > ammo_amount [ RPG_WEAPON ] - - ;
2021-02-18 10:46:36 +00:00
lastvisinc = PlayClock + 32 ;
2020-05-18 06:26:09 +00:00
p - > visibility = 0 ;
2020-10-24 05:34:39 +00:00
fi . shoot ( pact , RPG ) ;
2020-05-18 06:26:09 +00:00
checkavailweapon ( p ) ;
}
2021-03-31 09:35:10 +00:00
else if ( p - > kickback_pic = = 20 )
2020-08-03 05:02:30 +00:00
p - > okickback_pic = p - > kickback_pic = 0 ;
2020-05-18 06:26:09 +00:00
break ;
}
}
2020-05-18 20:28:12 +00:00
2020-05-19 07:54:52 +00:00
//---------------------------------------------------------------------------
//
// this function exists because gotos suck. :P
//
//---------------------------------------------------------------------------
2021-11-21 07:48:36 +00:00
static void processweapon ( int snum , ESyncBits actions )
2020-05-19 07:54:52 +00:00
{
auto p = & ps [ snum ] ;
2020-10-25 05:34:25 +00:00
auto pact = p - > GetActor ( ) ;
2021-12-21 19:33:39 +00:00
int shrunk = ( pact - > spr . yrepeat < 32 ) ;
2020-05-19 07:54:52 +00:00
2020-08-27 22:03:35 +00:00
if ( isNamWW2GI ( ) & & ( actions & SB_HOLSTER ) ) // 'Holster Weapon
2020-05-19 07:54:52 +00:00
{
if ( isWW2GI ( ) )
{
2020-11-01 17:23:09 +00:00
SetGameVarID ( g_iReturnVarID , 0 , p - > GetActor ( ) , snum ) ;
SetGameVarID ( g_iWeaponVarID , p - > curr_weapon , p - > GetActor ( ) , snum ) ;
2021-12-05 12:43:31 +00:00
SetGameVarID ( g_iWorksLikeVarID , aplWeaponWorksLike ( p - > curr_weapon , snum ) , p - > GetActor ( ) , snum ) ;
2020-11-01 16:57:40 +00:00
OnEvent ( EVENT_HOLSTER , snum , p - > GetActor ( ) , - 1 ) ;
2021-12-05 16:36:57 +00:00
if ( GetGameVarID ( g_iReturnVarID , p - > GetActor ( ) , snum ) . value ( ) = = 0 )
2020-05-19 07:54:52 +00:00
{
// now it uses the game definitions...
2021-12-05 12:43:31 +00:00
if ( aplWeaponFlags ( p - > curr_weapon , snum ) & WEAPON_FLAG_HOLSTER_CLEARS_CLIP )
2020-05-19 07:54:52 +00:00
{
2021-12-05 12:43:31 +00:00
if ( p - > ammo_amount [ p - > curr_weapon ] > aplWeaponClip ( p - > curr_weapon , snum )
& & ( p - > ammo_amount [ p - > curr_weapon ] % aplWeaponClip ( p - > curr_weapon , snum ) ) ! = 0 )
2020-05-19 07:54:52 +00:00
{
// throw away the remaining clip
p - > ammo_amount [ p - > curr_weapon ] - =
2021-12-05 12:43:31 +00:00
p - > ammo_amount [ p - > curr_weapon ] % aplWeaponClip ( p - > curr_weapon , snum ) ;
// p->kickback_pic = aplWeaponFireDelay(p->curr_weapon, snum)+1; // animate, but don't shoot...
p - > kickback_pic = aplWeaponTotalTime ( p - > curr_weapon , snum ) + 1 ; // animate, but don't shoot...
2020-08-28 20:51:05 +00:00
actions & = ~ SB_FIRE ; // not firing...
2020-05-19 07:54:52 +00:00
}
return ;
}
}
}
else if ( p - > curr_weapon = = PISTOL_WEAPON )
{
if ( p - > ammo_amount [ PISTOL_WEAPON ] > 20 )
{
// throw away the remaining clip
p - > ammo_amount [ PISTOL_WEAPON ] - = p - > ammo_amount [ PISTOL_WEAPON ] % 20 ;
p - > kickback_pic = 3 ; // animate, but don't shoot...
2020-08-28 20:51:05 +00:00
actions & = ~ SB_FIRE ; // not firing...
2020-05-19 07:54:52 +00:00
}
return ;
}
}
2021-12-05 12:43:31 +00:00
if ( isWW2GI ( ) & & ( aplWeaponFlags ( p - > curr_weapon , snum ) & WEAPON_FLAG_GLOWS ) )
2020-05-19 07:54:52 +00:00
p - > random_club_frame + = 64 ; // Glowing
if ( ! isWW2GI ( ) & & ( p - > curr_weapon = = SHRINKER_WEAPON | | p - > curr_weapon = = GROW_WEAPON ) )
p - > random_club_frame + = 64 ; // Glowing
if ( p - > rapid_fire_hold = = 1 )
{
2020-08-28 20:51:05 +00:00
if ( actions & SB_FIRE ) return ;
2020-05-19 07:54:52 +00:00
p - > rapid_fire_hold = 0 ;
}
if ( shrunk | | p - > tipincs | | p - > access_incs )
2020-08-28 20:51:05 +00:00
actions & = ~ SB_FIRE ;
else if ( shrunk = = 0 & & ( actions & SB_FIRE ) & & p - > kickback_pic = = 0 & & p - > fist_incs = = 0 & &
2020-05-19 07:54:52 +00:00
p - > last_weapon = = - 1 & & ( p - > weapon_pos = = 0 | | p - > holster_weapon = = 1 ) )
{
if ( ! isWW2GI ( ) ) fireweapon ( snum ) ;
else fireweapon_ww ( snum ) ;
}
else if ( p - > kickback_pic )
{
2021-11-21 07:48:36 +00:00
if ( ! isWW2GI ( ) ) operateweapon ( snum , actions ) ;
else operateweapon_ww ( snum , actions ) ;
2020-05-19 07:54:52 +00:00
}
}
2020-05-18 22:26:07 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2020-05-19 07:03:07 +00:00
void processinput_d ( int snum )
2020-05-18 22:26:07 +00:00
{
2020-11-02 23:20:51 +00:00
int j , k , doubvel , fz , cz , truefdist ;
2020-10-25 06:12:04 +00:00
Collision chz , clz ;
bool shrunk ;
2021-11-21 07:48:36 +00:00
int psectlotag ;
2022-02-07 10:04:19 +00:00
player_struct * p ;
2020-05-18 22:26:07 +00:00
p = & ps [ snum ] ;
2020-10-25 05:34:25 +00:00
auto pact = p - > GetActor ( ) ;
2020-05-18 22:26:07 +00:00
2020-10-12 03:42:43 +00:00
p - > horizon . resetadjustment ( ) ;
p - > angle . resetadjustment ( ) ;
2020-05-19 17:50:31 +00:00
2021-04-21 10:41:04 +00:00
ESyncBits & actions = p - > sync . actions ;
2020-05-18 22:26:07 +00:00
2020-07-03 19:44:57 +00:00
auto sb_fvel = PlayerInputForwardVel ( snum ) ;
auto sb_svel = PlayerInputSideVel ( snum ) ;
auto sb_avel = PlayerInputAngVel ( snum ) ;
2020-05-18 22:26:07 +00:00
2021-11-21 07:56:39 +00:00
auto psectp = p - > cursector ;
2021-11-21 07:48:36 +00:00
if ( psectp = = nullptr )
2020-05-18 22:26:07 +00:00
{
2021-12-21 19:33:39 +00:00
if ( pact - > spr . extra > 0 & & ud . clipping = = 0 )
2020-05-18 22:26:07 +00:00
{
quickkill ( p ) ;
2020-11-02 19:24:07 +00:00
S_PlayActorSound ( SQUISHED , pact ) ;
2020-05-18 22:26:07 +00:00
}
2021-11-21 07:48:36 +00:00
psectp = & sector [ 0 ] ;
2020-05-18 22:26:07 +00:00
}
2021-11-18 16:34:31 +00:00
psectlotag = psectp - > lotag ;
2020-05-18 22:26:07 +00:00
p - > spritebridge = 0 ;
2021-12-21 19:33:39 +00:00
shrunk = ( pact - > spr . yrepeat < 32 ) ;
2022-02-05 11:05:29 +00:00
getzrange ( p - > player_int_pos ( ) , psectp , & cz , chz , & fz , clz , 163 , CLIPMASK0 ) ;
2020-05-18 22:26:07 +00:00
2022-02-04 17:11:44 +00:00
j = getflorzofslopeptr ( psectp , p - > player_int_pos ( ) . X , p - > player_int_pos ( ) . Y ) ;
2020-05-18 22:26:07 +00:00
2022-02-04 16:49:48 +00:00
p - > truefz = j * zinttoworld ;
2022-02-04 17:11:44 +00:00
p - > truecz = getceilzofslopeptr ( psectp , p - > player_int_pos ( ) . X , p - > player_int_pos ( ) . Y ) * zinttoworld ;
2020-05-18 22:26:07 +00:00
2022-02-04 17:11:44 +00:00
truefdist = abs ( p - > player_int_pos ( ) . Z - j ) ;
2022-02-04 17:06:08 +00:00
if ( clz . type = = kHitSector & & psectlotag = = 1 & & truefdist > gs . int_playerheight + ( 16 < < 8 ) )
2020-05-18 22:26:07 +00:00
psectlotag = 0 ;
2022-02-03 23:44:13 +00:00
pact - > floorz = fz * zinttoworld ;
pact - > ceilingz = cz * zinttoworld ;
2020-05-18 22:26:07 +00:00
2020-11-30 22:40:16 +00:00
if ( SyncInput ( ) )
2020-05-18 22:26:07 +00:00
{
2020-10-07 06:12:37 +00:00
p - > horizon . backup ( ) ;
2021-01-01 22:32:19 +00:00
doslopetilting ( p ) ;
2020-05-18 22:26:07 +00:00
}
2020-10-25 06:12:04 +00:00
if ( chz . type = = kHitSprite )
2020-05-18 22:26:07 +00:00
{
2021-12-21 17:19:45 +00:00
if ( chz . actor ( ) - > spr . statnum = = 1 & & chz . actor ( ) - > spr . extra > = 0 )
2020-05-18 22:26:07 +00:00
{
2021-11-26 12:41:15 +00:00
chz . setNone ( ) ;
2022-02-04 16:49:48 +00:00
cz = p - > truecz * zworldtoint ;
2020-05-18 22:26:07 +00:00
}
}
2020-10-25 06:12:04 +00:00
if ( clz . type = = kHitSprite )
2020-05-18 22:26:07 +00:00
{
2021-12-21 17:19:45 +00:00
if ( ( clz . actor ( ) - > spr . cstat & ( CSTAT_SPRITE_ALIGNMENT_FLOOR | CSTAT_SPRITE_BLOCK ) ) = = ( CSTAT_SPRITE_ALIGNMENT_FLOOR | CSTAT_SPRITE_BLOCK ) )
2020-05-18 22:26:07 +00:00
{
psectlotag = 0 ;
p - > footprintcount = 0 ;
p - > spritebridge = 1 ;
}
2022-01-31 18:21:49 +00:00
else if ( badguy ( clz . actor ( ) ) & & clz . actor ( ) - > spr . xrepeat > 24 & & abs ( pact - > int_pos ( ) . Z - clz . actor ( ) - > int_pos ( ) . Z ) < ( 84 < < 8 ) )
2020-05-18 22:26:07 +00:00
{
2022-02-04 17:11:44 +00:00
j = getangle ( clz . actor ( ) - > int_pos ( ) . X - p - > player_int_pos ( ) . X , clz . actor ( ) - > int_pos ( ) . Y - p - > player_int_pos ( ) . Y ) ;
2021-12-30 11:14:55 +00:00
p - > vel . X - = bcos ( j , 4 ) ;
2021-12-30 11:18:56 +00:00
p - > vel . Y - = bsin ( j , 4 ) ;
2020-05-18 22:26:07 +00:00
}
}
2021-12-21 19:33:39 +00:00
if ( pact - > spr . extra > 0 ) fi . incur_damage ( p ) ;
2020-05-18 22:26:07 +00:00
else
{
2021-12-21 19:33:39 +00:00
pact - > spr . extra = 0 ;
2020-05-18 22:26:07 +00:00
p - > shield_amount = 0 ;
}
2021-12-21 19:33:39 +00:00
p - > last_extra = pact - > spr . extra ;
2020-05-18 22:26:07 +00:00
2022-06-06 01:24:38 +00:00
if ( p - > loogcnt > 0 )
{
p - > oloogcnt = p - > loogcnt ;
p - > loogcnt - - ;
}
else
{
p - > oloogcnt = p - > loogcnt = 0 ;
}
2020-05-18 22:26:07 +00:00
if ( p - > fist_incs )
{
if ( endoflevel ( snum ) ) return ;
}
if ( p - > timebeforeexit > 1 & & p - > last_extra > 0 )
{
if ( timedexit ( snum ) )
return ;
}
2021-12-21 19:33:39 +00:00
if ( pact - > spr . extra < = 0 & & ! ud . god )
2020-05-18 22:26:07 +00:00
{
playerisdead ( snum , psectlotag , fz , cz ) ;
2020-07-16 13:03:09 +00:00
return ;
2020-05-18 22:26:07 +00:00
}
2022-01-15 14:48:50 +00:00
if ( p - > GetActor ( ) - > spr . xrepeat < 40 & & p - > jetpack_on = = 0 )
{
2022-06-06 00:51:57 +00:00
p - > ofistsign = p - > fistsign ;
2022-01-15 14:48:50 +00:00
p - > fistsign + = p - > GetActor ( ) - > spr . xvel ;
}
2020-05-18 22:26:07 +00:00
if ( p - > transporter_hold > 0 )
{
p - > transporter_hold - - ;
if ( p - > transporter_hold = = 0 & & p - > on_warping_sector )
p - > transporter_hold = 2 ;
}
if ( p - > transporter_hold < 0 )
p - > transporter_hold + + ;
2020-11-02 23:20:51 +00:00
if ( p - > newOwner ! = nullptr )
2020-05-18 22:26:07 +00:00
{
2021-12-30 11:18:56 +00:00
p - > vel . X = p - > vel . Y = pact - > spr . xvel = 0 ;
2020-05-18 22:26:07 +00:00
fi . doincrements ( p ) ;
2021-12-05 12:43:31 +00:00
if ( isWW2GI ( ) & & aplWeaponWorksLike ( p - > curr_weapon , snum ) = = HANDREMOTE_WEAPON ) processweapon ( snum , actions ) ;
2021-11-21 07:48:36 +00:00
if ( ! isWW2GI ( ) & & p - > curr_weapon = = HANDREMOTE_WEAPON ) processweapon ( snum , actions ) ;
2020-05-18 22:26:07 +00:00
return ;
}
doubvel = TICSPERFRAME ;
2020-08-29 11:32:14 +00:00
checklook ( snum , actions ) ;
2020-11-02 23:20:51 +00:00
int ii = 40 ;
2022-02-05 11:30:00 +00:00
auto oldpos = p - > opos ;
2020-05-18 22:26:07 +00:00
2020-10-17 08:44:00 +00:00
if ( p - > on_crane ! = nullptr )
2020-05-18 22:26:07 +00:00
goto HORIZONLY ;
2021-12-21 19:33:39 +00:00
p - > playerweaponsway ( pact - > spr . xvel ) ;
2020-05-18 22:26:07 +00:00
2022-02-05 12:58:12 +00:00
pact - > spr . xvel = int ( clamp ( ( p - > pos . XY ( ) - p - > bobpos ) . Length ( ) , 0. , 32. ) * worldtoint ) ;
2021-12-21 17:19:45 +00:00
if ( p - > on_ground ) p - > bobcounter + = p - > GetActor ( ) - > spr . xvel > > 1 ;
2020-05-18 22:26:07 +00:00
2022-01-04 03:00:18 +00:00
p - > backuppos ( ud . clipping = = 0 & & ( ( p - > insector ( ) & & p - > cursector - > floorpicnum = = MIRROR ) | | ! p - > insector ( ) ) ) ;
2020-05-18 22:26:07 +00:00
// Shrinking code
2020-07-16 13:03:09 +00:00
if ( psectlotag = = ST_2_UNDERWATER )
2020-05-18 22:26:07 +00:00
{
2021-11-18 16:34:31 +00:00
underwater ( snum , actions , fz , cz ) ;
2020-05-18 22:26:07 +00:00
}
else if ( p - > jetpack_on )
{
2020-08-28 20:51:05 +00:00
operateJetpack ( snum , actions , psectlotag , fz , cz , shrunk ) ;
2020-05-18 22:26:07 +00:00
}
2020-07-16 13:03:09 +00:00
else if ( psectlotag ! = ST_2_UNDERWATER )
2020-05-18 22:26:07 +00:00
{
2021-11-18 16:34:31 +00:00
movement ( snum , actions , psectp , fz , cz , shrunk , truefdist , psectlotag ) ;
2020-05-18 22:26:07 +00:00
}
2020-08-05 12:57:47 +00:00
p - > psectlotag = psectlotag ;
2020-05-18 22:26:07 +00:00
//Do the quick lefts and rights
2021-01-02 00:04:03 +00:00
if ( movementBlocked ( p ) )
2020-05-18 22:26:07 +00:00
{
doubvel = 0 ;
2021-12-30 11:14:55 +00:00
p - > vel . X = 0 ;
2021-12-30 11:18:56 +00:00
p - > vel . Y = 0 ;
2020-05-18 22:26:07 +00:00
}
2020-11-30 22:40:16 +00:00
else if ( SyncInput ( ) )
2020-07-28 12:12:09 +00:00
{
//p->ang += syncangvel * constant
//ENGINE calculates angvel for you
// may still be needed later for demo recording
2020-05-18 22:26:07 +00:00
2020-11-29 08:00:00 +00:00
sb_avel = p - > adjustavel ( sb_avel ) ;
2021-04-21 10:41:04 +00:00
p - > angle . applyinput ( sb_avel , & actions ) ;
2020-05-18 22:26:07 +00:00
}
2021-12-30 15:24:51 +00:00
if ( p - > spritebridge = = 0 & & pact - > insector ( ) )
2020-05-18 22:26:07 +00:00
{
2021-12-30 15:51:56 +00:00
j = pact - > sector ( ) - > floorpicnum ;
2020-05-18 22:26:07 +00:00
2021-12-30 15:51:56 +00:00
if ( j = = PURPLELAVA | | pact - > sector ( ) - > ceilingpicnum = = PURPLELAVA )
2020-05-18 22:26:07 +00:00
{
if ( p - > boot_amount > 0 )
{
p - > boot_amount - - ;
p - > inven_icon = 7 ;
if ( p - > boot_amount < = 0 )
checkavailinven ( p ) ;
}
else
{
2020-11-02 19:24:07 +00:00
if ( ! S_CheckActorSoundPlaying ( pact , DUKE_LONGTERM_PAIN ) )
S_PlayActorSound ( DUKE_LONGTERM_PAIN , pact ) ;
2020-05-18 22:26:07 +00:00
SetPlayerPal ( p , PalEntry ( 32 , 0 , 8 , 0 ) ) ;
2021-12-21 19:33:39 +00:00
pact - > spr . extra - - ;
2020-05-18 22:26:07 +00:00
}
}
k = 0 ;
2022-02-04 17:06:08 +00:00
if ( p - > on_ground & & truefdist < = gs . int_playerheight + ( 16 < < 8 ) )
2020-05-18 22:26:07 +00:00
{
2022-01-21 13:02:59 +00:00
int whichsound = ( gs . tileinfo [ j ] . flags & TFLAG_ELECTRIC ) ? 0 : j = = FLOORSLIME ? 1 : j = = FLOORPLASMA ? 2 : - 1 ;
2020-05-18 22:26:07 +00:00
if ( j > = 0 ) k = makepainsounds ( snum , whichsound ) ;
}
if ( k )
{
FTA ( 75 , p ) ;
p - > boot_amount - = 2 ;
if ( p - > boot_amount < = 0 )
checkavailinven ( p ) ;
}
}
2021-12-30 11:18:56 +00:00
if ( p - > vel . X | | p - > vel . Y | | sb_fvel | | sb_svel )
2020-05-18 22:26:07 +00:00
{
2020-08-27 05:54:49 +00:00
p - > crack_time = CRACK_TIME ;
2020-05-18 22:26:07 +00:00
2020-11-15 11:07:03 +00:00
k = bsin ( p - > bobcounter , - 12 ) ;
2020-05-18 22:26:07 +00:00
2022-02-04 17:06:08 +00:00
if ( truefdist < gs . int_playerheight + ( 8 < < 8 ) & & ( k = = 1 | | k = = 3 ) )
2020-05-18 22:26:07 +00:00
{
if ( p - > spritebridge = = 0 & & p - > walking_snd_toggle = = 0 & & p - > on_ground )
{
switch ( psectlotag )
{
case 0 :
2020-10-25 06:12:04 +00:00
if ( clz . type = = kHitSprite )
2021-12-21 17:19:45 +00:00
j = clz . actor ( ) - > spr . picnum ;
2020-10-25 06:12:04 +00:00
else
2021-11-18 16:34:31 +00:00
j = psectp - > floorpicnum ;
2020-05-18 22:26:07 +00:00
switch ( j )
{
case PANNEL1 :
case PANNEL2 :
2020-11-02 19:24:07 +00:00
S_PlayActorSound ( DUKE_WALKINDUCTS , pact ) ;
2020-05-18 22:26:07 +00:00
p - > walking_snd_toggle = 1 ;
break ;
}
break ;
case 1 :
if ( ( krand ( ) & 1 ) = = 0 )
2020-11-02 19:24:07 +00:00
S_PlayActorSound ( DUKE_ONWATER , pact ) ;
2020-05-18 22:26:07 +00:00
p - > walking_snd_toggle = 1 ;
break ;
}
}
}
else if ( p - > walking_snd_toggle > 0 )
p - > walking_snd_toggle - - ;
if ( p - > jetpack_on = = 0 & & p - > steroids_amount > 0 & & p - > steroids_amount < 400 )
doubvel < < = 1 ;
2021-12-30 11:14:55 +00:00
p - > vel . X + = ( ( sb_fvel * doubvel ) < < 6 ) ;
2021-12-30 11:18:56 +00:00
p - > vel . Y + = ( ( sb_svel * doubvel ) < < 6 ) ;
2020-05-18 22:26:07 +00:00
bool check ;
2020-08-28 20:51:05 +00:00
if ( ! isWW2GI ( ) ) check = ( ( p - > curr_weapon = = KNEE_WEAPON & & p - > kickback_pic > 10 & & p - > on_ground ) | | ( p - > on_ground & & ( actions & SB_CROUCH ) ) ) ;
2021-12-05 12:43:31 +00:00
else check = ( ( aplWeaponWorksLike ( p - > curr_weapon , snum ) = = KNEE_WEAPON & & p - > kickback_pic > 10 & & p - > on_ground ) | | ( p - > on_ground & & ( actions & SB_CROUCH ) ) ) ;
2020-05-18 22:26:07 +00:00
if ( check )
{
2021-12-30 11:14:55 +00:00
p - > vel . X = MulScale ( p - > vel . X , gs . playerfriction - 0x2000 , 16 ) ;
2021-12-30 11:18:56 +00:00
p - > vel . Y = MulScale ( p - > vel . Y , gs . playerfriction - 0x2000 , 16 ) ;
2020-05-18 22:26:07 +00:00
}
else
{
if ( psectlotag = = 2 )
{
2021-12-30 11:14:55 +00:00
p - > vel . X = MulScale ( p - > vel . X , gs . playerfriction - 0x1400 , 16 ) ;
2021-12-30 11:18:56 +00:00
p - > vel . Y = MulScale ( p - > vel . Y , gs . playerfriction - 0x1400 , 16 ) ;
2020-05-18 22:26:07 +00:00
}
else
{
2021-12-30 11:14:55 +00:00
p - > vel . X = MulScale ( p - > vel . X , gs . playerfriction , 16 ) ;
2021-12-30 11:18:56 +00:00
p - > vel . Y = MulScale ( p - > vel . Y , gs . playerfriction , 16 ) ;
2020-05-18 22:26:07 +00:00
}
}
2021-12-30 11:18:56 +00:00
if ( abs ( p - > vel . X ) < 2048 & & abs ( p - > vel . Y ) < 2048 )
p - > vel . X = p - > vel . Y = 0 ;
2020-05-18 22:26:07 +00:00
if ( shrunk )
{
2021-12-30 11:14:55 +00:00
p - > vel . X =
MulScale ( p - > vel . X , gs . playerfriction - ( gs . playerfriction > > 1 ) + ( gs . playerfriction > > 2 ) , 16 ) ;
2021-12-30 11:18:56 +00:00
p - > vel . Y =
MulScale ( p - > vel . Y , gs . playerfriction - ( gs . playerfriction > > 1 ) + ( gs . playerfriction > > 2 ) , 16 ) ;
2020-05-18 22:26:07 +00:00
}
}
HORIZONLY :
2020-11-02 23:20:51 +00:00
if ( psectlotag = = 1 | | p - > spritebridge = = 1 ) ii = ( 4L < < 8 ) ;
else ii = ( 20L < < 8 ) ;
2020-05-18 22:26:07 +00:00
2021-11-21 07:56:39 +00:00
if ( p - > insector ( ) & & p - > cursector - > lotag = = 2 ) k = 0 ;
2020-05-18 22:26:07 +00:00
else k = 1 ;
2020-10-25 07:50:03 +00:00
Collision clip { } ;
2020-05-18 22:26:07 +00:00
if ( ud . clipping )
{
2022-02-05 12:12:19 +00:00
p - > player_add_int_xy ( { p - > vel . X > > 14 , p - > vel . Y > > 14 } ) ;
2022-02-04 17:11:44 +00:00
updatesector ( p - > player_int_pos ( ) . X , p - > player_int_pos ( ) . Y , & p - > cursector ) ;
2021-11-26 20:52:01 +00:00
ChangeActorSect ( pact , p - > cursector ) ;
2020-05-18 22:26:07 +00:00
}
else
2022-02-05 12:29:21 +00:00
clipmove ( p - > pos , & p - > cursector , p - > vel . X , p - > vel . Y , 164 , ( 4 < < 8 ) , ii , CLIPMASK0 , clip ) ;
2020-05-18 22:26:07 +00:00
if ( p - > jetpack_on = = 0 & & psectlotag ! = 2 & & psectlotag ! = 1 & & shrunk )
2022-02-05 12:40:30 +00:00
p - > pos . Z + = 32 ;
2020-05-18 22:26:07 +00:00
2020-10-25 07:50:03 +00:00
if ( clip . type ! = kHitNone )
checkplayerhurt_d ( p , clip ) ;
2020-05-18 22:26:07 +00:00
if ( p - > jetpack_on = = 0 )
{
2021-12-21 19:33:39 +00:00
if ( pact - > spr . xvel > 16 )
2020-05-18 22:26:07 +00:00
{
if ( psectlotag ! = 1 & & psectlotag ! = 2 & & p - > on_ground )
{
p - > pycount + = 52 ;
p - > pycount & = 2047 ;
2022-08-30 20:25:07 +00:00
p - > pyoff = DAngle : : fromBuild ( p - > pycount ) . Sin ( ) * pact - > spr . xvel ;
const double factor = 64. / 1596 ; // What is 1596?
p - > pyoff = abs ( pact - > spr . xvel * DAngle : : fromBuild ( p - > pycount ) . Sin ( ) ) * factor ;
2020-05-18 22:26:07 +00:00
}
}
else if ( psectlotag ! = 2 & & psectlotag ! = 1 )
p - > pyoff = 0 ;
}
// RBG***
2022-08-22 16:34:01 +00:00
SetActor ( pact , p - > pos . plusZ ( gs . playerheight ) ) ;
2020-05-18 22:26:07 +00:00
if ( psectlotag < 3 )
{
2021-12-30 15:51:56 +00:00
psectp = pact - > sector ( ) ;
2021-11-18 16:34:31 +00:00
if ( ud . clipping = = 0 & & psectp - > lotag = = 31 )
2020-05-18 22:26:07 +00:00
{
2021-12-05 23:50:33 +00:00
auto secact = barrier_cast < DDukeActor * > ( psectp - > hitagactor ) ;
2021-12-21 17:19:45 +00:00
if ( secact & & secact - > spr . xvel & & secact - > temp_data [ 0 ] = = 0 )
2020-05-18 22:26:07 +00:00
{
quickkill ( p ) ;
return ;
}
}
}
2022-02-04 17:06:08 +00:00
if ( truefdist < gs . int_playerheight & & p - > on_ground & & psectlotag ! = 1 & & shrunk = = 0 & & p - > insector ( ) & & p - > cursector - > lotag = = 1 )
2020-10-25 07:50:03 +00:00
if ( ! S_CheckActorSoundPlaying ( pact , DUKE_ONWATER ) )
S_PlayActorSound ( DUKE_ONWATER , pact ) ;
2020-05-18 22:26:07 +00:00
2021-12-30 15:51:56 +00:00
if ( p - > cursector ! = pact - > sector ( ) )
2021-11-26 20:52:01 +00:00
ChangeActorSect ( pact , p - > cursector ) ;
2020-05-18 22:26:07 +00:00
2022-01-04 23:39:09 +00:00
int retry = 0 ;
while ( ud . clipping = = 0 )
2020-05-18 22:26:07 +00:00
{
2022-01-04 23:39:09 +00:00
int blocked ;
2022-02-05 12:29:21 +00:00
blocked = ( pushmove ( p - > pos , & p - > cursector , 164 , ( 4 < < 8 ) , ( 4 < < 8 ) , CLIPMASK0 ) < 0 & & furthestangle ( p - > GetActor ( ) , 8 ) < 512 ) ;
2022-01-04 23:39:09 +00:00
2022-02-03 23:55:12 +00:00
if ( fabs ( pact - > floorz - pact - > ceilingz ) < 48 | | blocked )
2020-05-18 22:26:07 +00:00
{
2021-12-30 15:51:56 +00:00
if ( ! ( pact - > sector ( ) - > lotag & 0x8000 ) & & ( isanunderoperator ( pact - > sector ( ) - > lotag ) | |
isanearoperator ( pact - > sector ( ) - > lotag ) ) )
fi . activatebysector ( pact - > sector ( ) , pact ) ;
2022-01-04 23:39:09 +00:00
if ( blocked )
2020-05-18 22:26:07 +00:00
{
2022-01-04 23:39:09 +00:00
if ( ! retry + + )
{
2022-02-05 12:29:21 +00:00
p - > pos = p - > opos = oldpos ;
2022-01-04 23:39:09 +00:00
continue ;
}
2020-05-18 22:26:07 +00:00
quickkill ( p ) ;
return ;
}
}
2021-11-18 16:34:31 +00:00
else if ( abs ( fz - cz ) < ( 32 < < 8 ) & & isanunderoperator ( psectp - > lotag ) )
2021-11-18 17:51:19 +00:00
fi . activatebysector ( psectp , pact ) ;
2022-01-04 23:39:09 +00:00
break ;
2020-05-18 22:26:07 +00:00
}
// center_view
2020-08-27 22:03:35 +00:00
if ( actions & SB_CENTERVIEW | | p - > hard_landing )
2020-05-18 22:26:07 +00:00
{
playerCenterView ( snum ) ;
}
2020-08-29 11:32:14 +00:00
else if ( actions & SB_LOOK_UP )
2020-05-18 22:26:07 +00:00
{
2020-08-28 22:57:07 +00:00
playerLookUp ( snum , actions ) ;
2020-05-18 22:26:07 +00:00
}
2020-08-29 11:32:14 +00:00
else if ( actions & SB_LOOK_DOWN )
2020-05-18 22:26:07 +00:00
{
2020-08-28 22:57:07 +00:00
playerLookDown ( snum , actions ) ;
2020-05-18 22:26:07 +00:00
}
2020-08-29 11:32:14 +00:00
else if ( actions & SB_AIM_UP )
2020-05-18 22:26:07 +00:00
{
2020-08-28 22:57:07 +00:00
playerAimUp ( snum , actions ) ;
2020-05-18 22:26:07 +00:00
}
2020-08-29 11:32:14 +00:00
else if ( actions & SB_AIM_DOWN )
2020-05-18 22:26:07 +00:00
{ // aim_down
2020-08-28 22:57:07 +00:00
playerAimDown ( snum , actions ) ;
2020-05-18 22:26:07 +00:00
}
2020-07-17 01:00:43 +00:00
2020-11-30 22:40:16 +00:00
if ( SyncInput ( ) )
2020-08-05 07:53:22 +00:00
{
2021-05-02 20:37:46 +00:00
p - > horizon . applyinput ( GetPlayerHorizon ( snum ) , & actions ) ;
2020-08-05 07:53:22 +00:00
}
2020-11-29 08:00:00 +00:00
p - > checkhardlanding ( ) ;
2020-05-18 22:26:07 +00:00
//Shooting code/changes
if ( p - > show_empty_weapon > 0 )
{
p - > show_empty_weapon - - ;
if ( p - > show_empty_weapon = = 0 )
{
if ( p - > last_full_weapon = = GROW_WEAPON )
p - > subweapon | = ( 1 < < GROW_WEAPON ) ;
else if ( p - > last_full_weapon = = SHRINKER_WEAPON )
p - > subweapon & = ~ ( 1 < < GROW_WEAPON ) ;
fi . addweapon ( p , p - > last_full_weapon ) ;
return ;
}
}
2020-10-23 17:50:18 +00:00
dokneeattack ( snum , { FEM1 , FEM2 , FEM3 , FEM4 , FEM5 , FEM6 , FEM7 , FEM8 , FEM9 , FEM10 , PODFEM1 , NAKED1 , STATUE } ) ;
2020-05-18 22:26:07 +00:00
if ( fi . doincrements ( p ) ) return ;
if ( p - > weapon_pos ! = 0 )
{
if ( p - > weapon_pos = = - 9 )
{
if ( p - > last_weapon > = 0 )
{
2020-09-16 11:01:09 +00:00
p - > oweapon_pos = p - > weapon_pos = 10 ;
2021-11-09 23:05:42 +00:00
// if(p->curr_weapon == KNEE_WEAPON) p->kickback_pic = 1;
2020-05-18 22:26:07 +00:00
p - > last_weapon = - 1 ;
}
else if ( p - > holster_weapon = = 0 )
2020-09-16 11:01:09 +00:00
p - > oweapon_pos = p - > weapon_pos = 10 ;
2020-05-18 22:26:07 +00:00
}
else p - > weapon_pos - - ;
}
// HACKS
2021-11-21 07:48:36 +00:00
processweapon ( snum , actions ) ;
2020-05-19 07:54:52 +00:00
}
2020-05-18 22:26:07 +00:00
2020-05-14 10:14:03 +00:00
END_DUKE_NS