2020-05-17 06:51:49 +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-17 06:51:49 +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
2020-05-17 11:51:18 +00:00
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
2020-05-17 06:51:49 +00:00
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-08-24 18:34:18 +00:00
# include "gamecontrol.h"
2020-05-17 06:51:49 +00:00
2020-07-17 18:56:10 +00:00
BEGIN_DUKE_NS
2020-05-17 06:51:49 +00:00
2020-07-17 20:19:22 +00:00
static int WeaponToSend ;
static ESyncBits BitsToSend ;
2020-07-17 18:56:10 +00:00
2020-07-18 11:27:24 +00:00
// State timer counters.
static int nonsharedtimer ;
static int turnheldtime ;
static int lastcontroltime ;
static double lastCheck ;
2020-08-24 18:20:15 +00:00
void GameInterface : : ResetFollowPos ( bool message )
{
if ( automapFollow )
{
ud . folx = ps [ screenpeek ] . oposx ;
ud . foly = ps [ screenpeek ] . oposy ;
ud . fola = ps [ screenpeek ] . getoang ( ) ;
}
if ( message ) FTA ( automapFollow ? QUOTE_MAP_FOLLOW_ON : QUOTE_MAP_FOLLOW_OFF , & ps [ myconnectindex ] ) ;
}
2020-07-15 17:48:04 +00:00
//---------------------------------------------------------------------------
//
// handles UI side input not handled via CCMDs or CVARs.
// Most of what's in here needs to be offloaded to CCMDs
//
//---------------------------------------------------------------------------
void nonsharedkeys ( void )
{
if ( ud . recstat = = 2 )
{
ControlInfo noshareinfo ;
CONTROL_GetInput ( & noshareinfo ) ;
}
if ( System_WantGuiCapture ( ) )
return ;
if ( buttonMap . ButtonDown ( gamefunc_See_Coop_View ) & & ( ud . coop | | ud . recstat = = 2 ) )
{
buttonMap . ClearButton ( gamefunc_See_Coop_View ) ;
screenpeek = connectpoint2 [ screenpeek ] ;
if ( screenpeek = = - 1 ) screenpeek = 0 ;
}
if ( ( ud . multimode > 1 ) & & buttonMap . ButtonDown ( gamefunc_Show_Opponents_Weapon ) )
{
buttonMap . ClearButton ( gamefunc_Show_Opponents_Weapon ) ;
ud . showweapons = 1 - ud . showweapons ;
cl_showweapon = ud . showweapons ;
FTA ( QUOTE_WEAPON_MODE_OFF - ud . showweapons , & ps [ screenpeek ] ) ;
}
2020-08-24 18:34:18 +00:00
if ( buttonMap . ButtonDown ( gamefunc_Third_Person_View ) )
2020-07-15 17:48:04 +00:00
{
2020-08-24 18:34:18 +00:00
buttonMap . ClearButton ( gamefunc_Third_Person_View ) ;
if ( ! isRRRA ( ) | | ( ! ps [ myconnectindex ] . OnMotorcycle & & ! ps [ myconnectindex ] . OnBoat ) )
2020-07-15 17:48:04 +00:00
{
2020-08-24 18:34:18 +00:00
if ( ps [ myconnectindex ] . over_shoulder_on )
ps [ myconnectindex ] . over_shoulder_on = 0 ;
else
2020-07-15 17:48:04 +00:00
{
2020-08-24 18:34:18 +00:00
ps [ myconnectindex ] . over_shoulder_on = 1 ;
cameradist = 0 ;
2020-08-25 06:47:50 +00:00
cameraclock = gameclock ;
2020-07-15 17:48:04 +00:00
}
2020-08-24 18:34:18 +00:00
FTA ( QUOTE_VIEW_MODE_OFF + ps [ myconnectindex ] . over_shoulder_on , & ps [ myconnectindex ] ) ;
2020-07-15 17:48:04 +00:00
}
}
2020-08-24 18:34:18 +00:00
if ( automapMode ! = am_off )
2020-07-15 17:48:04 +00:00
{
2020-08-24 18:34:18 +00:00
int j ;
2020-08-25 06:47:50 +00:00
if ( nonsharedtimer > 0 | | gameclock < nonsharedtimer )
2020-07-15 17:48:04 +00:00
{
2020-08-25 06:47:50 +00:00
j = gameclock - nonsharedtimer ;
2020-08-24 18:34:18 +00:00
nonsharedtimer + = j ;
2020-07-15 17:48:04 +00:00
}
2020-08-24 18:34:18 +00:00
else
2020-07-15 17:48:04 +00:00
{
2020-08-24 18:34:18 +00:00
j = 0 ;
2020-08-25 06:47:50 +00:00
nonsharedtimer = gameclock ;
2020-07-15 17:48:04 +00:00
}
2020-08-24 18:34:18 +00:00
if ( buttonMap . ButtonDown ( gamefunc_Enlarge_Screen ) )
ps [ myconnectindex ] . zoom + = mulscale6 ( j , max ( ps [ myconnectindex ] . zoom , 256 ) ) ;
if ( buttonMap . ButtonDown ( gamefunc_Shrink_Screen ) )
ps [ myconnectindex ] . zoom - = mulscale6 ( j , max ( ps [ myconnectindex ] . zoom , 256 ) ) ;
ps [ myconnectindex ] . zoom = clamp ( ps [ myconnectindex ] . zoom , 48 , 2048 ) ;
2020-07-15 17:48:04 +00:00
}
}
2020-05-17 06:51:49 +00:00
//---------------------------------------------------------------------------
//
2020-05-17 11:25:39 +00:00
// handles all HUD related input, i.e. inventory item selection and activation plus weapon selection.
//
// Note: This doesn't restrict the events to WW2GI - since the other games do
// not define any by default there is no harm done keeping the code clean.
2020-05-17 06:51:49 +00:00
//
//---------------------------------------------------------------------------
2020-05-17 11:25:39 +00:00
void hud_input ( int snum )
{
int i , k ;
uint8_t dainv ;
unsigned int j ;
struct player_struct * p ;
short unk ;
unk = 0 ;
p = & ps [ snum ] ;
i = p - > aim_mode ;
2020-07-06 11:26:26 +00:00
p - > aim_mode = PlayerInput ( snum , SKB_AIMMODE ) ;
2020-05-17 11:25:39 +00:00
if ( p - > aim_mode < i )
p - > return_to_center = 9 ;
2020-08-03 03:28:16 +00:00
// Backup weapon here as hud_input() is the first function where any one of the weapon variables can change.
backupweapon ( p ) ;
2020-08-02 13:00:53 +00:00
2020-05-17 11:25:39 +00:00
if ( isRR ( ) )
{
2020-07-06 11:26:26 +00:00
if ( PlayerInput ( snum , SKB_QUICK_KICK ) & & p - > last_pissed_time = = 0 )
2020-05-17 11:25:39 +00:00
{
if ( ! isRRRA ( ) | | sprite [ p - > i ] . extra > 0 )
{
p - > last_pissed_time = 4000 ;
2020-07-29 20:43:06 +00:00
S_PlayActorSound ( 437 , p - > i ) ;
2020-05-17 11:25:39 +00:00
if ( sprite [ p - > i ] . extra < = max_player_health - max_player_health / 10 )
{
sprite [ p - > i ] . extra + = 2 ;
p - > last_extra = sprite [ p - > i ] . extra ;
}
else if ( sprite [ p - > i ] . extra < max_player_health )
sprite [ p - > i ] . extra = max_player_health ;
}
}
}
else
{
2020-07-06 11:26:26 +00:00
if ( PlayerInput ( snum , SKB_QUICK_KICK ) & & p - > quick_kick = = 0 & & ( p - > curr_weapon ! = KNEE_WEAPON | | p - > kickback_pic = = 0 ) )
2020-05-17 11:25:39 +00:00
{
SetGameVarID ( g_iReturnVarID , 0 , - 1 , snum ) ;
OnEvent ( EVENT_QUICKKICK , - 1 , snum , - 1 ) ;
if ( GetGameVarID ( g_iReturnVarID , - 1 , snum ) = = 0 )
{
p - > quick_kick = 14 ;
2020-07-28 18:43:33 +00:00
if ( ! p - > quick_kick_msg & & snum = = screenpeek ) FTA ( QUOTE_MIGHTY_FOOT , p ) ;
p - > quick_kick_msg = true ;
2020-05-17 11:25:39 +00:00
}
}
}
2020-07-28 18:43:33 +00:00
if ( ! PlayerInput ( snum , SKB_QUICK_KICK ) ) p - > quick_kick_msg = false ;
2020-05-17 11:25:39 +00:00
2020-07-06 11:26:26 +00:00
if ( ! PlayerInputBits ( snum , SKB_INTERFACE_BITS ) )
2020-05-17 11:25:39 +00:00
p - > interface_toggle_flag = 0 ;
else if ( p - > interface_toggle_flag = = 0 )
{
p - > interface_toggle_flag = 1 ;
2020-05-17 11:51:18 +00:00
// Don't go on if paused or dead.
2020-07-15 16:10:31 +00:00
if ( paused ) return ;
2020-05-17 11:51:18 +00:00
if ( sprite [ p - > i ] . extra < = 0 ) return ;
// Activate an inventory item. This just forwards to the other inventory bits. If the inventory selector was taken out of the playsim this could be removed.
2020-07-06 11:26:26 +00:00
if ( PlayerInput ( snum , SKB_INVENTORY ) & & p - > newowner = = - 1 )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
SetGameVarID ( g_iReturnVarID , 0 , - 1 , snum ) ;
OnEvent ( EVENT_INVENTORY , - 1 , snum , - 1 ) ;
if ( GetGameVarID ( g_iReturnVarID , - 1 , snum ) = = 0 )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
switch ( p - > inven_icon )
{
// Yet another place where no symbolic constants were used. :(
2020-07-06 11:26:26 +00:00
case ICON_JETPACK : PlayerSetInput ( snum , SKB_JETPACK ) ; break ;
case ICON_HOLODUKE : PlayerSetInput ( snum , SKB_HOLODUKE ) ; break ;
case ICON_HEATS : PlayerSetInput ( snum , SKB_NIGHTVISION ) ; break ;
case ICON_FIRSTAID : PlayerSetInput ( snum , SKB_MEDKIT ) ; break ;
case ICON_STEROIDS : PlayerSetInput ( snum , SKB_STEROIDS ) ; break ;
2020-05-17 11:51:18 +00:00
}
2020-05-17 11:25:39 +00:00
}
}
2020-07-06 11:26:26 +00:00
if ( ! isRR ( ) & & PlayerInput ( snum , SKB_NIGHTVISION ) )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
SetGameVarID ( g_iReturnVarID , 0 , - 1 , snum ) ;
OnEvent ( EVENT_USENIGHTVISION , - 1 , snum , - 1 ) ;
if ( GetGameVarID ( g_iReturnVarID , - 1 , snum ) = = 0 & & p - > heat_amount > 0 )
{
p - > heat_on = ! p - > heat_on ;
setpal ( p ) ;
p - > inven_icon = 5 ;
2020-07-25 07:32:54 +00:00
S_PlayActorSound ( NITEVISION_ONOFF , p - > i ) ;
2020-05-17 11:51:18 +00:00
FTA ( 106 + ( ! p - > heat_on ) , p ) ;
}
2020-05-17 11:25:39 +00:00
}
2020-07-06 11:26:26 +00:00
if ( PlayerInput ( snum , SKB_STEROIDS ) )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
SetGameVarID ( g_iReturnVarID , 0 , - 1 , snum ) ;
OnEvent ( EVENT_USESTEROIDS , - 1 , snum , - 1 ) ;
if ( GetGameVarID ( g_iReturnVarID , - 1 , snum ) = = 0 )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
if ( p - > steroids_amount = = 400 )
{
p - > steroids_amount - - ;
2020-07-25 07:32:54 +00:00
S_PlayActorSound ( DUKE_TAKEPILLS , p - > i ) ;
2020-05-17 11:51:18 +00:00
p - > inven_icon = ICON_STEROIDS ;
FTA ( 12 , p ) ;
}
2020-05-17 11:25:39 +00:00
}
2020-05-17 11:51:18 +00:00
return ;
2020-05-17 11:25:39 +00:00
}
2020-07-06 11:26:26 +00:00
if ( PlayerInput ( snum , SKB_INV_LEFT ) | | PlayerInput ( snum , SKB_INV_RIGHT ) )
2020-05-17 11:51:18 +00:00
{
p - > invdisptime = 26 * 2 ;
2020-05-17 11:25:39 +00:00
2020-07-06 11:26:26 +00:00
if ( PlayerInput ( snum , SKB_INV_RIGHT ) ) k = 1 ;
2020-05-17 11:51:18 +00:00
else k = 0 ;
2020-05-17 11:25:39 +00:00
2020-05-17 11:51:18 +00:00
dainv = p - > inven_icon ;
2020-05-17 11:25:39 +00:00
2020-05-17 11:51:18 +00:00
i = 0 ;
CHECKINV1 :
2020-05-17 11:25:39 +00:00
2020-05-17 11:51:18 +00:00
if ( i < 9 )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
i + + ;
switch ( dainv )
{
case 4 :
if ( p - > jetpack_amount > 0 & & i > 1 )
break ;
if ( k ) dainv = 5 ;
else dainv = 3 ;
goto CHECKINV1 ;
case 6 :
if ( p - > scuba_amount > 0 & & i > 1 )
break ;
if ( k ) dainv = 7 ;
else dainv = 5 ;
goto CHECKINV1 ;
case 2 :
if ( p - > steroids_amount > 0 & & i > 1 )
break ;
if ( k ) dainv = 3 ;
else dainv = 1 ;
goto CHECKINV1 ;
case 3 :
if ( p - > holoduke_amount > 0 & & i > 1 )
break ;
if ( k ) dainv = 4 ;
else dainv = 2 ;
goto CHECKINV1 ;
case 0 :
case 1 :
if ( p - > firstaid_amount > 0 & & i > 1 )
break ;
if ( k ) dainv = 2 ;
else dainv = 7 ;
goto CHECKINV1 ;
case 5 :
if ( p - > heat_amount > 0 & & i > 1 )
break ;
if ( k ) dainv = 6 ;
else dainv = 4 ;
goto CHECKINV1 ;
case 7 :
if ( p - > boot_amount > 0 & & i > 1 )
break ;
if ( k ) dainv = 1 ;
else dainv = 6 ;
goto CHECKINV1 ;
}
2020-05-17 11:25:39 +00:00
}
2020-05-17 11:51:18 +00:00
else dainv = 0 ;
2020-05-17 11:25:39 +00:00
2020-05-17 11:51:18 +00:00
// These events force us to keep the inventory selector in the playsim as opposed to the UI where it really belongs.
2020-07-06 11:26:26 +00:00
if ( PlayerInput ( snum , SKB_INV_LEFT ) )
2020-05-17 11:51:18 +00:00
{
SetGameVarID ( g_iReturnVarID , dainv , - 1 , snum ) ;
OnEvent ( EVENT_INVENTORYLEFT , - 1 , snum , - 1 ) ;
dainv = GetGameVarID ( g_iReturnVarID , - 1 , snum ) ;
}
2020-07-06 11:26:26 +00:00
if ( PlayerInput ( snum , SKB_INV_RIGHT ) )
2020-05-17 11:51:18 +00:00
{
SetGameVarID ( g_iReturnVarID , dainv , - 1 , snum ) ;
OnEvent ( EVENT_INVENTORYRIGHT , - 1 , snum , - 1 ) ;
dainv = GetGameVarID ( g_iReturnVarID , - 1 , snum ) ;
}
p - > inven_icon = dainv ;
// Someone must have really hated constant data, doing this with a switch/case (and of course also with literal numbers...)
static const uint8_t invquotes [ ] = { QUOTE_MEDKIT , QUOTE_STEROIDS , QUOTE_HOLODUKE , QUOTE_JETPACK , QUOTE_NVG , QUOTE_SCUBA , QUOTE_BOOTS } ;
if ( dainv > = 1 & & dainv < 8 ) FTA ( invquotes [ dainv - 1 ] , p ) ;
2020-05-17 11:25:39 +00:00
}
2020-07-16 21:32:00 +00:00
j = ( PlayerInputBits ( snum , SKB_WEAPONMASK_BITS ) / SKB_FIRST_WEAPON_BIT ) - 1 ;
2020-07-17 18:56:10 +00:00
if ( j > = 0 )
{
int a = 0 ;
}
2020-05-17 11:25:39 +00:00
if ( j > 0 & & p - > kickback_pic > 0 )
p - > wantweaponfire = j ;
// Here we have to be extra careful that the weapons do not get mixed up, so let's keep the code for Duke and RR completely separate.
fi . selectweapon ( snum , j ) ;
2020-07-06 11:26:26 +00:00
if ( PlayerInput ( snum , SKB_HOLSTER ) )
2020-05-17 11:25:39 +00:00
{
if ( p - > curr_weapon > KNEE_WEAPON )
{
if ( p - > holster_weapon = = 0 & & p - > weapon_pos = = 0 )
{
p - > holster_weapon = 1 ;
p - > weapon_pos = - 1 ;
FTA ( QUOTE_WEAPON_LOWERED , p ) ;
}
else if ( p - > holster_weapon = = 1 & & p - > weapon_pos = = - 9 )
{
p - > holster_weapon = 0 ;
p - > weapon_pos = 10 ;
FTA ( QUOTE_WEAPON_RAISED , p ) ;
}
}
}
2020-07-06 11:26:26 +00:00
if ( PlayerInput ( snum , SKB_HOLODUKE ) & & ( isRR ( ) | | p - > newowner = = - 1 ) )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
SetGameVarID ( g_iReturnVarID , 0 , - 1 , snum ) ;
OnEvent ( EVENT_HOLODUKEON , - 1 , snum , - 1 ) ;
if ( GetGameVarID ( g_iReturnVarID , - 1 , snum ) = = 0 )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
if ( ! isRR ( ) )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
if ( p - > holoduke_on = = - 1 )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
if ( p - > holoduke_amount > 0 )
{
p - > inven_icon = 3 ;
p - > holoduke_on = i =
EGS ( p - > cursectnum ,
p - > posx ,
p - > posy ,
p - > posz + ( 30 < < 8 ) , TILE_APLAYER , - 64 , 0 , 0 , p - > getang ( ) , 0 , 0 , - 1 , 10 ) ;
hittype [ i ] . temp_data [ 3 ] = hittype [ i ] . temp_data [ 4 ] = 0 ;
sprite [ i ] . yvel = snum ;
sprite [ i ] . extra = 0 ;
FTA ( 47 , p ) ;
}
else FTA ( QUOTE_HOLODUKE_ON , p ) ;
2020-07-25 07:32:54 +00:00
S_PlayActorSound ( TELEPORTER , p - > holoduke_on ) ;
2020-05-17 11:25:39 +00:00
}
2020-05-17 11:51:18 +00:00
else
{
2020-07-25 07:32:54 +00:00
S_PlayActorSound ( TELEPORTER , p - > holoduke_on ) ;
2020-05-17 11:51:18 +00:00
p - > holoduke_on = - 1 ;
FTA ( QUOTE_HOLODUKE_NOT_FOUND , p ) ;
}
2020-05-17 11:25:39 +00:00
}
2020-05-17 11:51:18 +00:00
else // In RR this means drinking whiskey.
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
if ( p - > holoduke_amount > 0 & & sprite [ p - > i ] . extra < max_player_health )
{
p - > holoduke_amount - = 400 ;
sprite [ p - > i ] . extra + = 5 ;
if ( sprite [ p - > i ] . extra > max_player_health )
sprite [ p - > i ] . extra = max_player_health ;
p - > drink_amt + = 5 ;
p - > inven_icon = 3 ;
if ( p - > holoduke_amount = = 0 )
checkavailinven ( p ) ;
2020-07-25 07:32:54 +00:00
if ( p - > drink_amt < 99 & & ! S_CheckActorSoundPlaying ( p - > i , 425 ) )
S_PlayActorSound ( 425 , p - > i ) ;
2020-05-17 11:51:18 +00:00
}
2020-05-17 11:25:39 +00:00
}
}
}
2020-07-06 11:26:26 +00:00
if ( isRR ( ) & & PlayerInput ( snum , SKB_NIGHTVISION ) & & p - > newowner = = - 1 )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
SetGameVarID ( g_iReturnVarID , 0 , - 1 , snum ) ;
OnEvent ( EVENT_USENIGHTVISION , - 1 , snum , - 1 ) ;
if ( GetGameVarID ( g_iReturnVarID , - 1 , snum ) = = 0 )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
if ( p - > yehaa_timer = = 0 )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
p - > yehaa_timer = 126 ;
2020-07-25 07:32:54 +00:00
S_PlayActorSound ( 390 , p - > i ) ;
2020-05-17 11:51:18 +00:00
p - > noise_radius = 16384 ;
madenoise ( snum ) ;
if ( sector [ p - > cursectnum ] . lotag = = 857 )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
if ( sprite [ p - > i ] . extra < = max_player_health )
{
sprite [ p - > i ] . extra + = 10 ;
if ( sprite [ p - > i ] . extra > = max_player_health )
sprite [ p - > i ] . extra = max_player_health ;
}
2020-05-17 11:25:39 +00:00
}
2020-05-17 11:51:18 +00:00
else
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
if ( sprite [ p - > i ] . extra + 1 < = max_player_health )
{
sprite [ p - > i ] . extra + + ;
}
2020-05-17 11:25:39 +00:00
}
}
}
}
2020-07-06 11:26:26 +00:00
if ( PlayerInput ( snum , SKB_MEDKIT ) )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
SetGameVarID ( g_iReturnVarID , 0 , - 1 , snum ) ;
OnEvent ( EVENT_USEMEDKIT , - 1 , snum , - 1 ) ;
if ( GetGameVarID ( g_iReturnVarID , - 1 , snum ) = = 0 )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
if ( p - > firstaid_amount > 0 & & sprite [ p - > i ] . extra < max_player_health )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
if ( ! isRR ( ) )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
j = max_player_health - sprite [ p - > i ] . extra ;
if ( ( unsigned int ) p - > firstaid_amount > j )
{
p - > firstaid_amount - = j ;
sprite [ p - > i ] . extra = max_player_health ;
p - > inven_icon = 1 ;
}
else
{
sprite [ p - > i ] . extra + = p - > firstaid_amount ;
p - > firstaid_amount = 0 ;
checkavailinven ( p ) ;
}
2020-07-25 07:32:54 +00:00
S_PlayActorSound ( DUKE_USEMEDKIT , p - > i ) ;
2020-05-17 11:25:39 +00:00
}
else
{
2020-05-17 11:51:18 +00:00
j = 10 ;
if ( p - > firstaid_amount > j )
{
p - > firstaid_amount - = j ;
sprite [ p - > i ] . extra + = j ;
if ( sprite [ p - > i ] . extra > max_player_health )
sprite [ p - > i ] . extra = max_player_health ;
p - > inven_icon = 1 ;
}
else
{
sprite [ p - > i ] . extra + = p - > firstaid_amount ;
p - > firstaid_amount = 0 ;
checkavailinven ( p ) ;
}
2020-05-17 11:25:39 +00:00
if ( sprite [ p - > i ] . extra > max_player_health )
sprite [ p - > i ] . extra = max_player_health ;
2020-05-17 11:51:18 +00:00
p - > drink_amt + = 10 ;
2020-07-25 07:32:54 +00:00
if ( p - > drink_amt < = 100 & & ! S_CheckActorSoundPlaying ( p - > i , DUKE_USEMEDKIT ) )
S_PlayActorSound ( DUKE_USEMEDKIT , p - > i ) ;
2020-05-17 11:25:39 +00:00
}
}
}
}
2020-07-06 11:26:26 +00:00
if ( PlayerInput ( snum , SKB_JETPACK ) & & ( isRR ( ) | | p - > newowner = = - 1 ) )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
SetGameVarID ( g_iReturnVarID , 0 , - 1 , snum ) ;
OnEvent ( EVENT_USEJETPACK , - 1 , snum , - 1 ) ;
if ( GetGameVarID ( g_iReturnVarID , - 1 , snum ) = = 0 )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
if ( ! isRR ( ) )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
if ( p - > jetpack_amount > 0 )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
p - > jetpack_on = ! p - > jetpack_on ;
if ( p - > jetpack_on )
{
p - > inven_icon = 4 ;
2020-07-25 07:32:54 +00:00
S_StopSound ( - 1 , p - > i , CHAN_VOICE ) ; // this will stop the falling scream
S_PlayActorSound ( DUKE_JETPACK_ON , p - > i ) ;
2020-05-17 11:51:18 +00:00
FTA ( QUOTE_JETPACK_ON , p ) ;
}
else
{
p - > hard_landing = 0 ;
p - > poszv = 0 ;
2020-07-25 07:32:54 +00:00
S_PlayActorSound ( DUKE_JETPACK_OFF , p - > i ) ;
S_StopSound ( DUKE_JETPACK_IDLE , p - > i ) ;
S_StopSound ( DUKE_JETPACK_ON , p - > i ) ;
2020-05-17 11:51:18 +00:00
FTA ( QUOTE_JETPACK_OFF , p ) ;
}
2020-05-17 11:25:39 +00:00
}
2020-05-17 11:51:18 +00:00
else FTA ( QUOTE_JETPACK_NOT_FOUND , p ) ;
2020-05-17 11:25:39 +00:00
}
2020-05-17 11:51:18 +00:00
else
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
// eat cow pie
if ( p - > jetpack_amount > 0 & & sprite [ p - > i ] . extra < max_player_health )
2020-05-17 11:25:39 +00:00
{
2020-07-25 07:32:54 +00:00
if ( ! S_CheckActorSoundPlaying ( p - > i , 429 ) )
S_PlayActorSound ( 429 , p - > i ) ;
2020-05-17 11:51:18 +00:00
p - > jetpack_amount - = 100 ;
if ( p - > drink_amt > 0 )
{
p - > drink_amt - = 5 ;
if ( p - > drink_amt < 0 )
p - > drink_amt = 0 ;
}
if ( p - > eat < 100 )
{
p - > eat + = 5 ;
if ( p - > eat > 100 )
p - > eat = 100 ;
}
sprite [ p - > i ] . extra + = 5 ;
2020-05-17 11:25:39 +00:00
2020-05-17 11:51:18 +00:00
p - > inven_icon = 4 ;
2020-05-17 11:25:39 +00:00
2020-05-17 11:51:18 +00:00
if ( sprite [ p - > i ] . extra > max_player_health )
sprite [ p - > i ] . extra = max_player_health ;
2020-05-17 11:25:39 +00:00
2020-05-17 11:51:18 +00:00
if ( p - > jetpack_amount < = 0 )
checkavailinven ( p ) ;
}
2020-05-17 11:25:39 +00:00
}
}
}
2020-07-06 11:26:26 +00:00
if ( PlayerInput ( snum , SKB_TURNAROUND ) & & p - > one_eighty_count = = 0 )
2020-05-17 11:25:39 +00:00
{
2020-05-17 11:51:18 +00:00
SetGameVarID ( g_iReturnVarID , 0 , - 1 , snum ) ;
OnEvent ( EVENT_TURNAROUND , - 1 , snum , - 1 ) ;
if ( GetGameVarID ( g_iReturnVarID , - 1 , snum ) = = 0 )
{
2020-07-17 01:00:43 +00:00
p - > one_eighty_count = - F16 ( 1024 ) ;
2020-05-17 11:51:18 +00:00
}
2020-05-17 11:25:39 +00:00
}
}
}
2020-07-16 16:58:31 +00:00
2020-07-17 22:34:20 +00:00
//---------------------------------------------------------------------------
//
2020-07-18 07:59:16 +00:00
// Main input routine.
// This includes several input improvements from EDuke32, but this code
// has been mostly rewritten completely to make it clearer and reduce redundancy.
2020-07-17 22:34:20 +00:00
//
//---------------------------------------------------------------------------
2020-07-16 16:58:31 +00:00
enum
{
2020-07-17 22:34:20 +00:00
TURBOTURNTIME = ( TICRATE / 8 ) , // 7
NORMALTURN = 15 ,
PREAMBLETURN = 5 ,
NORMALKEYMOVE = 40 ,
MAXVEL = ( ( NORMALKEYMOVE * 2 ) + 10 ) ,
MAXSVEL = ( ( NORMALKEYMOVE * 2 ) + 10 ) ,
MAXANGVEL = 1024 ,
MAXHORIZVEL = 256 ,
ONEEIGHTYSCALE = 4 ,
MOTOTURN = 20 ,
MAXVELMOTO = 120 ,
2020-07-16 16:58:31 +00:00
} ;
2020-07-16 20:49:26 +00:00
//---------------------------------------------------------------------------
//
2020-07-17 22:34:20 +00:00
// handles the input bits
2020-07-16 20:49:26 +00:00
//
//---------------------------------------------------------------------------
2020-07-17 22:59:10 +00:00
static void processInputBits ( player_struct * p , ControlInfo & info )
2020-07-16 20:49:26 +00:00
{
2020-07-17 22:34:20 +00:00
bool onVehicle = p - > OnMotorcycle | | p - > OnBoat ;
2020-07-17 18:56:10 +00:00
if ( buttonMap . ButtonDown ( gamefunc_Fire ) ) loc . bits | = SKB_FIRE ;
if ( buttonMap . ButtonDown ( gamefunc_Open ) ) loc . bits | = SKB_OPEN ;
2020-07-16 20:49:26 +00:00
2020-07-17 20:09:01 +00:00
// These 3 bits are only available when not riding a bike or boat.
2020-07-17 18:56:10 +00:00
if ( onVehicle ) BitsToSend & = ~ ( SKB_HOLSTER | SKB_TURNAROUND | SKB_CENTER_VIEW ) ;
2020-07-17 20:19:22 +00:00
loc . bits | = BitsToSend ;
BitsToSend = 0 ;
2020-07-17 18:56:10 +00:00
if ( buttonMap . ButtonDown ( gamefunc_Dpad_Select ) )
2020-07-16 20:49:26 +00:00
{
2020-07-17 18:56:10 +00:00
if ( info . dx < 0 | | info . dyaw < 0 ) loc . bits | = SKB_INV_LEFT ;
if ( info . dx > 0 | | info . dyaw < 0 ) loc . bits | = SKB_INV_RIGHT ;
2020-07-17 22:34:20 +00:00
}
2020-07-19 20:34:59 +00:00
if ( gamequit ) loc . bits | = SKB_GAMEQUIT ;
2020-07-17 22:34:20 +00:00
if ( ! onVehicle )
{
if ( buttonMap . ButtonDown ( gamefunc_Jump ) ) loc . bits | = SKB_JUMP ;
if ( buttonMap . ButtonDown ( gamefunc_Crouch ) | | buttonMap . ButtonDown ( gamefunc_Toggle_Crouch ) | | p - > crouch_toggle )
{
loc . bits | = SKB_CROUCH ;
if ( isRR ( ) ) loc . bits & = ~ SKB_JUMP ;
}
if ( buttonMap . ButtonDown ( gamefunc_Aim_Up ) | | ( buttonMap . ButtonDown ( gamefunc_Dpad_Aiming ) & & info . dz > 0 ) ) loc . bits | = SKB_AIM_UP ;
if ( ( buttonMap . ButtonDown ( gamefunc_Aim_Down ) | | ( buttonMap . ButtonDown ( gamefunc_Dpad_Aiming ) & & info . dz < 0 ) ) ) loc . bits | = SKB_AIM_DOWN ;
if ( G_CheckAutorun ( buttonMap . ButtonDown ( gamefunc_Run ) ) ) loc . bits | = SKB_RUN ;
if ( buttonMap . ButtonDown ( gamefunc_Look_Left ) | | ( isRR ( ) & & p - > drink_amt > 88 ) ) loc . bits | = SKB_LOOK_LEFT ;
if ( buttonMap . ButtonDown ( gamefunc_Look_Right ) ) loc . bits | = SKB_LOOK_RIGHT ;
if ( buttonMap . ButtonDown ( gamefunc_Look_Up ) ) loc . bits | = SKB_LOOK_UP ;
if ( buttonMap . ButtonDown ( gamefunc_Look_Down ) | | ( isRR ( ) & & p - > drink_amt > 99 ) ) loc . bits | = SKB_LOOK_DOWN ;
if ( buttonMap . ButtonDown ( gamefunc_Quick_Kick ) ) loc . bits | = SKB_QUICK_KICK ;
if ( in_mousemode | | buttonMap . ButtonDown ( gamefunc_Mouse_Aiming ) ) loc . bits | = SKB_AIMMODE ;
int j = WeaponToSend ;
WeaponToSend = 0 ;
if ( VOLUMEONE & & ( j > = 7 & & j < = 10 ) ) j = 0 ;
if ( buttonMap . ButtonDown ( gamefunc_Dpad_Select ) & & info . dz > 0 ) j = 11 ;
if ( buttonMap . ButtonDown ( gamefunc_Dpad_Select ) & & info . dz < 0 ) j = 12 ;
if ( j & & ( loc . bits & SKB_WEAPONMASK_BITS ) = = 0 )
loc . bits | = ESyncBits : : FromInt ( j * SKB_FIRST_WEAPON_BIT ) ;
}
if ( buttonMap . ButtonDown ( gamefunc_Dpad_Select ) )
{
2020-07-17 18:56:10 +00:00
// This eats the controller input for regular use
info . dx = 0 ;
info . dz = 0 ;
info . dyaw = 0 ;
2020-07-16 20:49:26 +00:00
}
2020-07-17 18:56:10 +00:00
if ( buttonMap . ButtonDown ( gamefunc_Dpad_Aiming ) )
info . dz = 0 ;
2020-07-16 21:32:00 +00:00
}
2020-07-18 07:59:16 +00:00
//---------------------------------------------------------------------------
//
// split off so that it can later be integrated into the other games more easily.
//
//---------------------------------------------------------------------------
static void checkCrouchToggle ( player_struct * p )
{
int const sectorLotag = p - > cursectnum ! = - 1 ? sector [ p - > cursectnum ] . lotag : 0 ;
int const crouchable = sectorLotag ! = ST_2_UNDERWATER & & ( sectorLotag ! = ST_1_ABOVE_WATER | | p - > spritebridge ) ;
if ( buttonMap . ButtonDown ( gamefunc_Toggle_Crouch ) )
{
p - > crouch_toggle = ! p - > crouch_toggle & & crouchable ;
if ( crouchable )
buttonMap . ClearButton ( gamefunc_Toggle_Crouch ) ;
}
if ( buttonMap . ButtonDown ( gamefunc_Crouch ) | | buttonMap . ButtonDown ( gamefunc_Jump ) | | p - > jetpack_on | | ( ! crouchable & & p - > on_ground ) )
p - > crouch_toggle = 0 ;
}
2020-07-18 11:27:24 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
int getticssincelastupdate ( )
{
2020-08-25 06:47:50 +00:00
int tics = lastcontroltime = = 0 | | gameclock < lastcontroltime ? 0 : gameclock - lastcontroltime ;
lastcontroltime = gameclock ;
2020-07-18 11:27:24 +00:00
return tics ;
}
2020-07-16 21:32:00 +00:00
//---------------------------------------------------------------------------
//
2020-07-17 22:34:20 +00:00
// handles movement
2020-07-16 21:32:00 +00:00
//
//---------------------------------------------------------------------------
2020-07-17 22:59:10 +00:00
static void processMovement ( player_struct * p , input_t & input , ControlInfo & info , double scaleFactor )
2020-07-16 21:32:00 +00:00
{
2020-07-17 22:34:20 +00:00
bool mouseaim = in_mousemode | | buttonMap . ButtonDown ( gamefunc_Mouse_Aiming ) ;
// JBF: Run key behaviour is selectable
int running = G_CheckAutorun ( buttonMap . ButtonDown ( gamefunc_Run ) ) ;
int turnamount = NORMALTURN < < running ;
int keymove = NORMALKEYMOVE < < running ;
if ( buttonMap . ButtonDown ( gamefunc_Strafe ) )
input . svel - = info . mousex * 4.f + scaleFactor * info . dyaw * keymove ;
else
input . q16avel + = fix16_from_float ( info . mousex + scaleFactor * info . dyaw ) ;
if ( mouseaim )
input . q16horz + = fix16_from_float ( info . mousey ) ;
else
input . fvel - = info . mousey * 8.f ;
if ( ! in_mouseflip ) input . q16horz = - input . q16horz ;
input . q16horz - = fix16_from_dbl ( scaleFactor * ( info . dpitch ) ) ;
input . svel - = scaleFactor * ( info . dx * keymove ) ;
input . fvel - = scaleFactor * ( info . dz * keymove ) ;
if ( buttonMap . ButtonDown ( gamefunc_Strafe ) )
{
if ( ! loc . svel )
{
if ( buttonMap . ButtonDown ( gamefunc_Turn_Left ) )
input . svel = keymove ;
2020-07-17 18:56:10 +00:00
2020-07-17 22:34:20 +00:00
if ( buttonMap . ButtonDown ( gamefunc_Turn_Right ) )
input . svel = - keymove ;
}
}
else
{
2020-07-18 11:27:24 +00:00
int tics = getticssincelastupdate ( ) ;
2020-07-17 22:34:20 +00:00
if ( buttonMap . ButtonDown ( gamefunc_Turn_Left ) )
{
turnheldtime + = tics ;
2020-07-18 19:28:57 +00:00
input . q16avel - = fix16_from_dbl ( 2 * scaleFactor * ( turnheldtime > = TURBOTURNTIME ? turnamount : PREAMBLETURN ) ) ;
2020-07-17 22:34:20 +00:00
}
else if ( buttonMap . ButtonDown ( gamefunc_Turn_Right ) )
{
turnheldtime + = tics ;
2020-07-18 19:28:57 +00:00
input . q16avel + = fix16_from_dbl ( 2 * scaleFactor * ( turnheldtime > = TURBOTURNTIME ? turnamount : PREAMBLETURN ) ) ;
2020-07-17 22:34:20 +00:00
}
else
2020-07-18 11:27:24 +00:00
{
2020-07-17 22:34:20 +00:00
turnheldtime = 0 ;
2020-07-18 11:27:24 +00:00
lastcontroltime = 0 ;
}
2020-07-17 22:34:20 +00:00
}
2020-07-24 08:32:01 +00:00
if ( abs ( loc . svel ) < keymove )
2020-07-17 22:34:20 +00:00
{
if ( buttonMap . ButtonDown ( gamefunc_Strafe_Left ) )
input . svel + = keymove ;
2020-07-16 21:32:00 +00:00
2020-07-17 22:34:20 +00:00
if ( buttonMap . ButtonDown ( gamefunc_Strafe_Right ) )
input . svel + = - keymove ;
}
2020-07-24 08:32:01 +00:00
if ( abs ( loc . fvel ) < keymove )
2020-07-17 22:34:20 +00:00
{
if ( isRR ( ) & & p - > drink_amt > = 66 & & p - > drink_amt < = 87 )
{
if ( buttonMap . ButtonDown ( gamefunc_Move_Forward ) )
{
input . fvel + = keymove ;
if ( p - > drink_amt & 1 )
input . svel + = keymove ;
else
input . svel - = keymove ;
}
if ( buttonMap . ButtonDown ( gamefunc_Move_Backward ) )
{
input . fvel + = - keymove ;
if ( p - > drink_amt & 1 )
input . svel - = keymove ;
else
input . svel + = keymove ;
}
}
else
{
if ( buttonMap . ButtonDown ( gamefunc_Move_Forward ) )
input . fvel + = keymove ;
2020-07-16 20:49:26 +00:00
2020-07-17 22:34:20 +00:00
if ( buttonMap . ButtonDown ( gamefunc_Move_Backward ) )
input . fvel + = - keymove ;
}
}
2020-07-16 20:49:26 +00:00
}
2020-07-16 17:16:56 +00:00
//---------------------------------------------------------------------------
//
2020-07-17 22:34:20 +00:00
// split out for readability
2020-07-16 17:16:56 +00:00
//
//---------------------------------------------------------------------------
2020-07-24 10:46:20 +00:00
static double motoApplyTurn ( player_struct * p , int turnl , int turnr , int bike_turn , bool goback , double factor )
2020-07-16 17:16:56 +00:00
{
2020-07-24 10:46:20 +00:00
int turnvel = 0 ;
2020-08-04 07:10:44 +00:00
p - > oTiltStatus = p - > TiltStatus ;
2020-07-24 10:46:20 +00:00
2020-07-16 17:16:56 +00:00
if ( p - > MotoSpeed = = 0 | | ! p - > on_ground )
{
2020-07-18 11:27:24 +00:00
turnheldtime = 0 ;
lastcontroltime = 0 ;
2020-07-16 17:16:56 +00:00
if ( turnl )
{
p - > TiltStatus - = ( float ) factor ;
if ( p - > TiltStatus < - 10 )
p - > TiltStatus = - 10 ;
}
else if ( turnr )
{
p - > TiltStatus + = ( float ) factor ;
if ( p - > TiltStatus > 10 )
p - > TiltStatus = 10 ;
}
}
else
{
2020-07-18 11:27:24 +00:00
int tics = getticssincelastupdate ( ) ;
2020-07-24 10:46:20 +00:00
if ( turnl | | turnr | | p - > moto_drink ! = 0 )
2020-07-16 17:16:56 +00:00
{
2020-07-24 10:46:20 +00:00
if ( turnl | | p - > moto_drink < 0 )
2020-07-16 17:16:56 +00:00
{
2020-07-24 10:46:20 +00:00
turnheldtime + = tics ;
p - > TiltStatus - = ( float ) factor ;
if ( p - > TiltStatus < - 10 )
p - > TiltStatus = - 10 ;
if ( turnheldtime > = TURBOTURNTIME & & p - > MotoSpeed > 0 )
{
if ( goback ) turnvel + = bike_turn ? 40 : 20 ;
else turnvel + = bike_turn ? - 40 : - 20 ;
}
else
{
if ( goback ) turnvel + = bike_turn ? 20 : 6 ;
else turnvel + = bike_turn ? - 20 : - 6 ;
}
2020-07-16 17:16:56 +00:00
}
2020-07-24 10:46:20 +00:00
if ( turnr | | p - > moto_drink > 0 )
2020-07-16 17:16:56 +00:00
{
2020-07-24 10:46:20 +00:00
turnheldtime + = tics ;
p - > TiltStatus + = ( float ) factor ;
if ( p - > TiltStatus > 10 )
p - > TiltStatus = 10 ;
if ( turnheldtime > = TURBOTURNTIME & & p - > MotoSpeed > 0 )
{
if ( goback ) turnvel + = bike_turn ? - 40 : - 20 ;
else turnvel + = bike_turn ? 40 : 20 ;
}
else
{
if ( goback ) turnvel + = bike_turn ? - 20 : - 6 ;
else turnvel + = bike_turn ? 20 : 6 ;
}
2020-07-16 17:16:56 +00:00
}
}
else
{
turnheldtime = 0 ;
2020-07-18 11:27:24 +00:00
lastcontroltime = 0 ;
2020-07-16 17:16:56 +00:00
if ( p - > TiltStatus > 0 )
p - > TiltStatus - = ( float ) factor ;
else if ( p - > TiltStatus < 0 )
p - > TiltStatus + = ( float ) factor ;
}
}
2020-07-24 23:51:52 +00:00
if ( fabs ( p - > TiltStatus ) < factor )
p - > TiltStatus = 0 ;
2020-07-24 10:46:20 +00:00
return turnvel * factor ;
2020-07-16 17:16:56 +00:00
}
2020-07-16 16:58:31 +00:00
//---------------------------------------------------------------------------
//
2020-07-16 17:16:56 +00:00
// same for the boat
2020-07-16 16:58:31 +00:00
//
//---------------------------------------------------------------------------
2020-07-24 11:27:47 +00:00
static double boatApplyTurn ( player_struct * p , int turnl , int turnr , int boat_turn , double factor )
2020-07-16 16:58:31 +00:00
{
2020-07-24 11:27:47 +00:00
int turnvel = 0 ;
2020-07-18 11:27:24 +00:00
int tics = getticssincelastupdate ( ) ;
2020-07-16 16:58:31 +00:00
if ( p - > MotoSpeed )
{
2020-07-24 11:27:47 +00:00
if ( turnl | | turnr | | p - > moto_drink ! = 0 )
2020-07-16 16:58:31 +00:00
{
2020-07-24 11:27:47 +00:00
if ( turnl | | p - > moto_drink < 0 )
2020-07-16 16:58:31 +00:00
{
2020-07-24 11:27:47 +00:00
turnheldtime + = tics ;
if ( ! p - > NotOnWater )
{
p - > TiltStatus - = ( float ) factor ;
if ( p - > TiltStatus < - 10 )
p - > TiltStatus = - 10 ;
}
if ( turnheldtime > = TURBOTURNTIME )
{
if ( p - > NotOnWater ) turnvel + = boat_turn ? - 12 : - 6 ;
else turnvel + = boat_turn ? - 40 : - 20 ;
}
else
{
if ( p - > NotOnWater ) turnvel + = boat_turn ? - 4 : - 2 ;
else turnvel + = boat_turn ? - 12 : - 6 ;
}
2020-07-16 16:58:31 +00:00
}
2020-07-24 11:27:47 +00:00
if ( turnr | | p - > moto_drink > 0 )
2020-07-16 16:58:31 +00:00
{
2020-07-24 11:27:47 +00:00
turnheldtime + = tics ;
if ( ! p - > NotOnWater )
{
p - > TiltStatus + = ( float ) factor ;
if ( p - > TiltStatus > 10 )
p - > TiltStatus = 10 ;
}
if ( turnheldtime > = TURBOTURNTIME )
{
if ( p - > NotOnWater ) turnvel + = boat_turn ? 12 : 6 ;
else turnvel + = boat_turn ? 40 : 20 ;
}
else
{
if ( p - > NotOnWater ) turnvel + = boat_turn ? 4 : 2 ;
else turnvel + = boat_turn ? 12 : 6 ;
}
2020-07-16 16:58:31 +00:00
}
}
else if ( ! p - > NotOnWater )
{
turnheldtime = 0 ;
2020-07-18 11:27:24 +00:00
lastcontroltime = 0 ;
2020-07-16 16:58:31 +00:00
if ( p - > TiltStatus > 0 )
p - > TiltStatus - = ( float ) factor ;
else if ( p - > TiltStatus < 0 )
p - > TiltStatus + = ( float ) factor ;
}
}
2020-07-24 11:27:47 +00:00
else if ( ! p - > NotOnWater )
2020-07-18 11:27:24 +00:00
{
turnheldtime = 0 ;
lastcontroltime = 0 ;
2020-07-24 11:27:47 +00:00
if ( p - > TiltStatus > 0 )
p - > TiltStatus - = ( float ) factor ;
else if ( p - > TiltStatus < 0 )
p - > TiltStatus + = ( float ) factor ;
2020-07-18 11:27:24 +00:00
}
2020-07-24 11:27:47 +00:00
2020-07-24 11:38:11 +00:00
if ( fabs ( p - > TiltStatus ) < factor )
2020-07-24 11:27:47 +00:00
p - > TiltStatus = 0 ;
return turnvel * factor ;
2020-07-16 16:58:31 +00:00
}
2020-07-17 18:56:10 +00:00
//---------------------------------------------------------------------------
//
// much of this was rewritten from scratch to make the logic easier to follow.
//
//---------------------------------------------------------------------------
2020-07-17 22:59:10 +00:00
static void processVehicleInput ( player_struct * p , ControlInfo & info , input_t & input , double scaleAdjust )
2020-07-17 18:56:10 +00:00
{
2020-07-17 20:09:01 +00:00
auto turnspeed = info . mousex + scaleAdjust * info . dyaw * ( 1. / 32 ) ; // originally this was 64, not 32. Why the change?
2020-07-17 18:56:10 +00:00
int turnl = buttonMap . ButtonDown ( gamefunc_Turn_Left ) | | buttonMap . ButtonDown ( gamefunc_Strafe_Left ) ;
int turnr = buttonMap . ButtonDown ( gamefunc_Turn_Right ) | | buttonMap . ButtonDown ( gamefunc_Strafe_Right ) ;
// Cancel out micro-movement
const double turn_threshold = 1 / 65536. ;
2020-07-17 20:09:01 +00:00
if ( turnspeed < - turn_threshold )
2020-07-17 18:56:10 +00:00
turnl = 1 ;
2020-07-17 20:09:01 +00:00
else if ( turnspeed > turn_threshold )
2020-07-17 18:56:10 +00:00
turnr = 1 ;
else
2020-07-17 20:09:01 +00:00
turnspeed = 0 ;
2020-07-17 18:56:10 +00:00
2020-07-17 20:09:01 +00:00
if ( p - > OnBoat | | ! p - > moto_underwater )
{
if ( buttonMap . ButtonDown ( gamefunc_Move_Forward ) | | buttonMap . ButtonDown ( gamefunc_Strafe ) )
loc . bits | = SKB_JUMP ;
if ( buttonMap . ButtonDown ( gamefunc_Move_Backward ) )
loc . bits | = SKB_AIM_UP ;
if ( buttonMap . ButtonDown ( gamefunc_Run ) )
loc . bits | = SKB_CROUCH ;
}
2020-07-17 18:56:10 +00:00
if ( turnl )
loc . bits | = SKB_AIM_DOWN ;
if ( turnr )
loc . bits | = SKB_LOOK_LEFT ;
2020-07-17 20:09:01 +00:00
double turnvel ;
if ( p - > OnMotorcycle )
{
2020-07-17 22:34:20 +00:00
bool backward = buttonMap . ButtonDown ( gamefunc_Move_Backward ) & & p - > MotoSpeed < = 0 ;
2020-07-17 20:09:01 +00:00
2020-07-24 10:46:20 +00:00
turnvel = motoApplyTurn ( p , turnl , turnr , turnspeed , backward , scaleAdjust ) ;
2020-07-17 20:09:01 +00:00
if ( p - > moto_underwater ) p - > MotoSpeed = 0 ;
}
else
{
2020-07-24 11:27:47 +00:00
turnvel = boatApplyTurn ( p , turnl , turnr , turnspeed ! = 0 , scaleAdjust ) ;
2020-07-17 20:09:01 +00:00
}
2020-07-17 18:56:10 +00:00
// What is this? Optimization for playing with a mouse which the original did not have?
2020-07-17 20:09:01 +00:00
if ( turnspeed )
turnvel * = clamp ( turnspeed * turnspeed , 0. , 1. ) ;
2020-07-17 18:56:10 +00:00
input . fvel = p - > MotoSpeed ;
input . q16avel = fix16_from_dbl ( turnvel ) ;
}
2020-07-18 07:59:16 +00:00
//---------------------------------------------------------------------------
//
// finalizes the input and passes it to the global input buffer
//
//---------------------------------------------------------------------------
static void FinalizeInput ( int playerNum , input_t & input , bool vehicle )
{
auto p = & ps [ playerNum ] ;
bool blocked = movementBlocked ( playerNum ) | | sprite [ p - > i ] . extra < = 0 | | ( p - > dead_flag & & ! ud . god ) ;
2020-08-24 17:31:43 +00:00
if ( ( automapFollow & & automapMode ! = am_off ) | | blocked )
2020-07-18 07:59:16 +00:00
{
2020-08-24 17:31:43 +00:00
if ( automapFollow & & automapMode ! = am_off )
2020-07-18 07:59:16 +00:00
{
ud . folfvel = input . fvel ;
ud . folavel = fix16_to_int ( input . q16avel ) ;
}
loc . fvel = loc . svel = 0 ;
loc . q16avel = loc . q16horz = 0 ;
2020-08-04 03:02:19 +00:00
input . q16avel = input . q16horz = 0 ;
2020-07-18 07:59:16 +00:00
}
else
{
if ( p - > on_crane < 0 )
{
if ( ! vehicle )
{
loc . fvel = clamp ( loc . fvel + input . fvel , - MAXVEL , MAXVEL ) ;
loc . svel = clamp ( loc . svel + input . svel , - MAXSVEL , MAXSVEL ) ;
}
else
loc . fvel = clamp ( input . fvel , - ( MAXVELMOTO / 8 ) , MAXVELMOTO ) ;
}
2020-08-05 21:25:04 +00:00
else
{
loc . fvel = input . fvel = 0 ;
loc . svel = input . svel = 0 ;
}
2020-07-18 07:59:16 +00:00
if ( p - > on_crane < 0 & & p - > newowner = = - 1 )
{
2020-08-05 07:59:46 +00:00
loc . q16avel = fix16_clamp ( loc . q16avel + input . q16avel , F16 ( - MAXANGVEL ) , F16 ( MAXANGVEL ) ) ;
2020-08-03 11:19:45 +00:00
if ( ! cl_syncinput & & input . q16avel )
2020-07-18 07:59:16 +00:00
{
2020-08-03 11:19:45 +00:00
p - > one_eighty_count = 0 ;
2020-07-18 07:59:16 +00:00
}
}
2020-08-05 21:25:04 +00:00
else
{
loc . q16avel = input . q16avel = 0 ;
}
2020-07-18 07:59:16 +00:00
if ( p - > newowner = = - 1 & & p - > return_to_center < = 0 )
{
loc . q16horz = fix16_clamp ( loc . q16horz + input . q16horz , F16 ( - MAXHORIZVEL ) , F16 ( MAXHORIZVEL ) ) ;
}
2020-08-05 21:25:04 +00:00
else
{
loc . q16horz = input . q16horz = 0 ;
}
2020-07-18 07:59:16 +00:00
}
}
2020-07-17 22:59:10 +00:00
//---------------------------------------------------------------------------
//
// main input handler routine
//
//---------------------------------------------------------------------------
void GetInput ( )
{
double elapsedInputTicks ;
auto const p = & ps [ myconnectindex ] ;
auto now = I_msTimeF ( ) ;
// do not let this become too large - it would create overflows resulting in undefined behavior. The very first tic must not use the timer difference at all because the timer has not been set yet.
// This really needs to have the timer fixed to be robust, doing it ad-hoc here is not really safe.
2020-07-24 09:38:09 +00:00
if ( lastCheck > 0 ) elapsedInputTicks = min ( now - lastCheck , 1000.0 / REALGAMETICSPERSEC ) ;
2020-07-17 22:59:10 +00:00
else elapsedInputTicks = 1 ;
lastCheck = now ;
if ( paused )
{
loc = { } ;
2020-07-19 20:34:59 +00:00
if ( gamequit ) loc . bits | = SKB_GAMEQUIT ;
2020-07-17 22:59:10 +00:00
return ;
}
if ( numplayers = = 1 )
{
setlocalplayerinput ( p ) ;
}
2020-08-04 07:11:32 +00:00
double scaleAdjust = ! cl_syncinput ? elapsedInputTicks * REALGAMETICSPERSEC / 1000.0 : 1 ;
2020-07-17 22:59:10 +00:00
ControlInfo info ;
CONTROL_GetInput ( & info ) ;
input_t input { } ;
if ( isRRRA ( ) & & ( p - > OnMotorcycle | | p - > OnBoat ) )
{
p - > crouch_toggle = 0 ;
processInputBits ( p , info ) ;
processVehicleInput ( p , info , input , scaleAdjust ) ;
FinalizeInput ( myconnectindex , input , true ) ;
2020-08-05 07:53:22 +00:00
if ( ! cl_syncinput & & sprite [ p - > i ] . extra > 0 )
2020-07-17 22:59:10 +00:00
{
2020-08-05 07:53:22 +00:00
apply_seasick ( p , scaleAdjust ) ;
2020-07-17 22:59:10 +00:00
}
}
else
{
processMovement ( p , input , info , scaleAdjust ) ;
checkCrouchToggle ( p ) ;
processInputBits ( p , info ) ;
FinalizeInput ( myconnectindex , input , false ) ;
2020-08-05 07:53:22 +00:00
}
2020-07-17 22:59:10 +00:00
2020-08-05 07:53:22 +00:00
if ( ! cl_syncinput )
{
// Do these in the same order as the old code.
calcviewpitch ( p , scaleAdjust ) ;
applylook ( myconnectindex , scaleAdjust , input . q16avel ) ;
2020-08-05 07:59:01 +00:00
sethorizon ( myconnectindex , loc . bits , scaleAdjust , input . q16horz ) ;
2020-07-17 22:59:10 +00:00
}
}
2020-07-17 20:09:01 +00:00
2020-07-17 18:56:10 +00:00
//---------------------------------------------------------------------------
//
// CCMD based input. The basics are from Randi's ZDuke but this uses dynamic
// registration to only have the commands active when this game module runs.
//
//---------------------------------------------------------------------------
static int ccmd_slot ( CCmdFuncPtr parm )
{
if ( parm - > numparms ! = 1 ) return CCMD_SHOWHELP ;
auto slot = atoi ( parm - > parms [ 0 ] ) ;
if ( slot > = 1 & & slot < = 10 )
{
WeaponToSend = slot ;
return CCMD_OK ;
}
return CCMD_SHOWHELP ;
}
void registerinputcommands ( )
{
C_RegisterFunction ( " slot " , " slot <weaponslot>: select a weapon from the given slot (1-10) " , ccmd_slot ) ;
C_RegisterFunction ( " weapprev " , nullptr , [ ] ( CCmdFuncPtr ) - > int { WeaponToSend = 11 ; return CCMD_OK ; } ) ;
C_RegisterFunction ( " weapnext " , nullptr , [ ] ( CCmdFuncPtr ) - > int { WeaponToSend = 12 ; return CCMD_OK ; } ) ;
2020-08-24 18:34:18 +00:00
C_RegisterFunction ( " pause " , nullptr , [ ] ( CCmdFuncPtr ) - > int { BitsToSend | = SKB_PAUSE ; sendPause = true ; return CCMD_OK ; } ) ;
2020-07-25 13:41:11 +00:00
C_RegisterFunction ( " steroids " , nullptr , [ ] ( CCmdFuncPtr ) - > int { BitsToSend | = SKB_STEROIDS ; return CCMD_OK ; } ) ;
C_RegisterFunction ( " nightvision " , nullptr , [ ] ( CCmdFuncPtr ) - > int { BitsToSend | = SKB_NIGHTVISION ; return CCMD_OK ; } ) ;
C_RegisterFunction ( " medkit " , nullptr , [ ] ( CCmdFuncPtr ) - > int { BitsToSend | = SKB_MEDKIT ; return CCMD_OK ; } ) ;
C_RegisterFunction ( " centerview " , nullptr , [ ] ( CCmdFuncPtr ) - > int { BitsToSend | = SKB_CENTER_VIEW ; return CCMD_OK ; } ) ;
C_RegisterFunction ( " holsterweapon " , nullptr , [ ] ( CCmdFuncPtr ) - > int { BitsToSend | = SKB_HOLSTER ; return CCMD_OK ; } ) ;
C_RegisterFunction ( " invprev " , nullptr , [ ] ( CCmdFuncPtr ) - > int { BitsToSend | = SKB_INV_LEFT ; return CCMD_OK ; } ) ;
C_RegisterFunction ( " invnext " , nullptr , [ ] ( CCmdFuncPtr ) - > int { BitsToSend | = SKB_INV_RIGHT ; return CCMD_OK ; } ) ;
C_RegisterFunction ( " holoduke " , nullptr , [ ] ( CCmdFuncPtr ) - > int { BitsToSend | = SKB_HOLODUKE ; return CCMD_OK ; } ) ;
C_RegisterFunction ( " jetpack " , nullptr , [ ] ( CCmdFuncPtr ) - > int { BitsToSend | = SKB_JETPACK ; return CCMD_OK ; } ) ;
C_RegisterFunction ( " turnaround " , nullptr , [ ] ( CCmdFuncPtr ) - > int { BitsToSend | = SKB_TURNAROUND ; return CCMD_OK ; } ) ;
C_RegisterFunction ( " invuse " , nullptr , [ ] ( CCmdFuncPtr ) - > int { BitsToSend | = SKB_INVENTORY ; return CCMD_OK ; } ) ;
C_RegisterFunction ( " backoff " , nullptr , [ ] ( CCmdFuncPtr ) - > int { BitsToSend | = SKB_ESCAPE ; return CCMD_OK ; } ) ;
2020-07-17 18:56:10 +00:00
}
2020-07-18 11:27:24 +00:00
// This is called from ImputState::ClearAllInput and resets all static state being used here.
2020-07-17 18:56:10 +00:00
void GameInterface : : clearlocalinputstate ( )
{
WeaponToSend = 0 ;
BitsToSend = 0 ;
2020-07-18 11:27:24 +00:00
nonsharedtimer = 0 ;
turnheldtime = 0 ;
lastcontroltime = 0 ;
lastCheck = 0 ;
2020-07-17 18:56:10 +00:00
}
2020-05-17 11:25:39 +00:00
END_DUKE_NS