2019-11-20 16:21:32 +00:00
//-------------------------------------------------------------------------
/*
Copyright ( C ) 2010 - 2019 EDuke32 developers and contributors
Copyright ( C ) 2019 sirlemonhead , Nuke . YKT
This file is part of PCExhumed .
PCExhumed is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
See the GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*/
//-------------------------------------------------------------------------
2019-11-22 23:11:37 +00:00
# include "ns.h"
2019-08-31 07:47:15 +00:00
# include "compat.h"
2019-08-26 03:59:14 +00:00
# include "player.h"
2020-08-18 07:52:08 +00:00
# include "aistuff.h"
2019-08-26 03:59:14 +00:00
# include "exhumed.h"
# include "names.h"
# include "engine.h"
# include "sequence.h"
# include "view.h"
2021-01-01 22:38:15 +00:00
# include "input.h"
2019-08-26 03:59:14 +00:00
# include "status.h"
# include "sound.h"
# include "sound.h"
2020-05-24 05:58:56 +00:00
# include "buildtiles.h"
2020-08-22 18:14:00 +00:00
# include "gstrings.h"
2020-08-23 10:26:52 +00:00
# include "gamestate.h"
2020-08-23 14:24:54 +00:00
# include "mapinfo.h"
2020-09-06 18:49:43 +00:00
# include "automap.h"
2021-01-04 19:44:46 +00:00
# include "interpolate.h"
2020-09-06 18:49:43 +00:00
2019-08-26 03:59:14 +00:00
# include <assert.h>
# include <stdio.h>
# include <string.h>
2019-11-22 23:11:37 +00:00
BEGIN_PS_NS
2021-05-13 10:58:30 +00:00
extern short nStatusSeqOffset ;
2019-08-26 03:59:14 +00:00
struct PlayerSave
{
2019-08-31 07:47:15 +00:00
int x ;
int y ;
int z ;
short nSector ;
short nAngle ;
2019-08-26 03:59:14 +00:00
} ;
2020-08-26 07:19:50 +00:00
int lPlayerXVel = 0 ;
int lPlayerYVel = 0 ;
2019-11-08 16:55:26 +00:00
short obobangle = 0 , bobangle = 0 ;
2019-08-26 03:59:14 +00:00
2020-10-11 09:33:28 +00:00
static actionSeq PlayerSeq [ ] = {
2019-08-31 07:47:15 +00:00
{ 18 , 0 } , { 0 , 0 } , { 9 , 0 } , { 27 , 0 } , { 63 , 0 } ,
2019-11-20 16:21:32 +00:00
{ 72 , 0 } , { 54 , 0 } , { 45 , 0 } , { 54 , 0 } , { 81 , 0 } ,
{ 90 , 0 } , { 99 , 0 } , { 108 , 0 } , { 8 , 0 } , { 0 , 0 } ,
{ 139 , 0 } , { 117 , 1 } , { 119 , 1 } , { 120 , 1 } , { 121 , 1 } ,
2019-08-31 07:47:15 +00:00
{ 122 , 1 }
2019-08-26 03:59:14 +00:00
} ;
static short nHeightTemplate [ ] = { 0 , 0 , 0 , 0 , 0 , 0 , 7 , 7 , 7 , 9 , 9 , 9 , 9 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ;
2019-11-20 16:21:32 +00:00
short nActionEyeLevel [ ] = {
2019-08-31 07:47:15 +00:00
- 14080 , - 14080 , - 14080 , - 14080 , - 14080 , - 14080 , - 8320 ,
- 8320 , - 8320 , - 8320 , - 8320 , - 8320 , - 8320 , - 14080 ,
- 14080 , - 14080 , - 14080 , - 14080 , - 14080 , - 14080 , - 14080
2019-08-26 03:59:14 +00:00
} ;
2019-08-31 09:08:38 +00:00
uint16_t nGunLotag [ ] = { 52 , 53 , 54 , 55 , 56 , 57 } ;
uint16_t nGunPicnum [ ] = { 57 , 488 , 490 , 491 , 878 , 899 , 3455 } ;
2019-08-26 03:59:14 +00:00
2019-08-31 09:08:38 +00:00
int16_t nItemText [ ] = {
2019-08-31 07:47:15 +00:00
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 18 , 20 , 19 , 13 , - 1 , 10 , 1 , 0 , 2 , - 1 , 3 ,
- 1 , 4 , 5 , 9 , 6 , 7 , 8 , - 1 , 11 , - 1 , 13 , 12 , 14 , 15 , - 1 , 16 , 17 ,
- 1 , - 1 , - 1 , 21 , 22 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 23 , 24 , 25 , 26 , 27 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1
2019-08-26 03:59:14 +00:00
} ;
int nLocalPlayer = 0 ;
short nBreathTimer [ kMaxPlayers ] ;
short nPlayerSwear [ kMaxPlayers ] ;
short nPlayerPushSect [ kMaxPlayers ] ;
short nDeathType [ kMaxPlayers ] ;
short nPlayerScore [ kMaxPlayers ] ;
short nPlayerColor [ kMaxPlayers ] ;
int nPlayerDY [ kMaxPlayers ] ;
int nPlayerDX [ kMaxPlayers ] ;
short nPistolClip [ kMaxPlayers ] ;
int nXDamage [ kMaxPlayers ] ;
int nYDamage [ kMaxPlayers ] ;
short nDoppleSprite [ kMaxPlayers ] ;
short nPlayerOldWeapon [ kMaxPlayers ] ;
short nPlayerClip [ kMaxPlayers ] ;
short nPlayerPushSound [ kMaxPlayers ] ;
short nTauntTimer [ kMaxPlayers ] ;
2019-08-31 09:08:38 +00:00
uint16_t nPlayerWeapons [ kMaxPlayers ] ; // each set bit represents a weapon the player has
2019-08-26 03:59:14 +00:00
Player PlayerList [ kMaxPlayers ] ;
short nPlayerViewSect [ kMaxPlayers ] ;
short nPlayerFloorSprite [ kMaxPlayers ] ;
PlayerSave sPlayerSave [ kMaxPlayers ] ;
2020-08-24 03:22:52 +00:00
int ototalvel [ kMaxPlayers ] = { 0 } ;
2019-08-26 03:59:14 +00:00
int totalvel [ kMaxPlayers ] = { 0 } ;
2019-11-08 16:45:10 +00:00
int16_t eyelevel [ kMaxPlayers ] , oeyelevel [ kMaxPlayers ] ;
2019-08-26 03:59:14 +00:00
short nNetStartSprite [ kMaxPlayers ] = { 0 } ;
short nStandHeight ;
short nPlayerGrenade [ kMaxPlayers ] ;
short nGrenadePlayer [ 50 ] ;
short word_D282A [ 32 ] ;
short PlayerCount ;
short nNetStartSprites ;
short nCurStartSprite ;
void RestoreSavePoint ( int nPlayer , int * x , int * y , int * z , short * nSector , short * nAngle )
{
2019-08-31 07:47:15 +00:00
* x = sPlayerSave [ nPlayer ] . x ;
* y = sPlayerSave [ nPlayer ] . y ;
* z = sPlayerSave [ nPlayer ] . z ;
* nSector = sPlayerSave [ nPlayer ] . nSector ;
* nAngle = sPlayerSave [ nPlayer ] . nAngle ;
2019-08-26 03:59:14 +00:00
}
void SetSavePoint ( int nPlayer , int x , int y , int z , short nSector , short nAngle )
{
2019-08-31 07:47:15 +00:00
sPlayerSave [ nPlayer ] . x = x ;
sPlayerSave [ nPlayer ] . y = y ;
sPlayerSave [ nPlayer ] . z = z ;
sPlayerSave [ nPlayer ] . nSector = nSector ;
sPlayerSave [ nPlayer ] . nAngle = nAngle ;
2019-08-26 03:59:14 +00:00
}
void feebtag ( int x , int y , int z , int nSector , short * nSprite , int nVal2 , int nVal3 )
{
2019-08-31 07:47:15 +00:00
* nSprite = - 1 ;
int startwall = sector [ nSector ] . wallptr ;
int nWalls = sector [ nSector ] . wallnum ;
int var_20 = nVal2 & 2 ;
int var_14 = nVal2 & 1 ;
while ( 1 )
{
if ( nSector ! = - 1 )
{
2020-10-15 17:10:51 +00:00
int i ;
SectIterator it ( nSector ) ;
while ( ( i = it . NextIndex ( ) ) > = 0 )
2019-08-31 07:47:15 +00:00
{
short nStat = sprite [ i ] . statnum ;
if ( nStat > = 900 & & ! ( sprite [ i ] . cstat & 0x8000 ) )
{
2021-01-04 12:02:00 +00:00
uint32_t xDiff = abs ( sprite [ i ] . x - x ) ;
uint32_t yDiff = abs ( sprite [ i ] . y - y ) ;
2019-08-31 07:47:15 +00:00
int zDiff = sprite [ i ] . z - z ;
if ( zDiff < 5120 & & zDiff > - 25600 )
{
2020-06-12 23:34:29 +00:00
uint32_t diff = xDiff * xDiff + yDiff * yDiff ;
if ( diff > INT_MAX )
{
2020-12-28 18:43:14 +00:00
DPrintf ( DMSG_WARNING , " %s %d: overflow \n " , __func__ , __LINE__ ) ;
diff = INT_MAX ;
2020-06-12 23:34:29 +00:00
}
int theSqrt = ksqrt ( diff ) ;
2019-08-31 07:47:15 +00:00
2020-01-07 00:11:19 +00:00
if ( theSqrt < nVal3 & & ( ( nStat ! = 950 & & nStat ! = 949 ) | | ! ( var_14 & 1 ) ) & & ( ( nStat ! = 912 & & nStat ! = 913 ) | | ! ( var_20 & 2 ) ) )
2019-08-31 07:47:15 +00:00
{
nVal3 = theSqrt ;
* nSprite = i ;
}
}
}
}
}
nWalls - - ;
if ( nWalls < - 1 )
return ;
nSector = wall [ startwall ] . nextsector ;
startwall + + ;
}
2019-08-26 03:59:14 +00:00
}
void InitPlayer ( )
{
2019-08-31 07:47:15 +00:00
for ( int i = 0 ; i < kMaxPlayers ; i + + ) {
PlayerList [ i ] . nSprite = - 1 ;
}
2019-08-26 03:59:14 +00:00
}
void InitPlayerKeys ( short nPlayer )
{
2019-08-31 07:47:15 +00:00
PlayerList [ nPlayer ] . keys = 0 ;
2019-08-26 03:59:14 +00:00
}
void InitPlayerInventory ( short nPlayer )
{
2019-08-31 07:47:15 +00:00
memset ( & PlayerList [ nPlayer ] , 0 , sizeof ( Player ) ) ;
2019-08-26 03:59:14 +00:00
2021-05-13 11:44:58 +00:00
PlayerList [ nPlayer ] . nItem = - 1 ;
2019-08-31 07:47:15 +00:00
nPlayerSwear [ nPlayer ] = 4 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
ResetPlayerWeapons ( nPlayer ) ;
2019-08-26 03:59:14 +00:00
2021-05-13 17:06:38 +00:00
PlayerList [ nPlayer ] . nLives = kDefaultLives ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
PlayerList [ nPlayer ] . nSprite = - 1 ;
PlayerList [ nPlayer ] . nRun = - 1 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
nPistolClip [ nPlayer ] = 6 ;
2021-01-19 08:44:16 +00:00
nPlayerClip [ nPlayer ] = 0 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
PlayerList [ nPlayer ] . nCurrentWeapon = 0 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( nPlayer = = nLocalPlayer ) {
2020-08-24 17:54:26 +00:00
automapMode = am_off ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
nPlayerScore [ nPlayer ] = 0 ;
2019-08-26 03:59:14 +00:00
2019-11-24 12:59:36 +00:00
auto pixels = tilePtr ( kTile3571 + nPlayer ) ;
2019-08-26 03:59:14 +00:00
2020-11-23 07:55:02 +00:00
nPlayerColor [ nPlayer ] = pixels [ tileWidth ( nPlayer + kTile3571 ) * tileHeight ( nPlayer + kTile3571 ) / 2 ] ;
2019-08-26 03:59:14 +00:00
}
short GetPlayerFromSprite ( short nSprite )
{
2019-08-31 07:47:15 +00:00
return RunData [ sprite [ nSprite ] . owner ] . nVal ;
2019-08-26 03:59:14 +00:00
}
void RestartPlayer ( short nPlayer )
{
2020-10-13 22:19:39 +00:00
auto plr = & PlayerList [ nPlayer ] ;
int nSprite = plr - > nSprite ;
auto nSpr = & sprite [ nSprite ] ;
int nDopSprite = nDoppleSprite [ nPlayer ] ;
int floorspr ;
if ( nSprite > - 1 )
{
runlist_DoSubRunRec ( nSpr - > owner ) ;
runlist_FreeRun ( nSpr - > lotag - 1 ) ;
changespritestat ( nSprite , 0 ) ;
plr - > nSprite = - 1 ;
int nFloorSprite = nPlayerFloorSprite [ nPlayer ] ;
if ( nFloorSprite > - 1 ) {
mydeletesprite ( nFloorSprite ) ;
}
if ( nDopSprite > - 1 )
{
runlist_DoSubRunRec ( sprite [ nDopSprite ] . owner ) ;
runlist_FreeRun ( sprite [ nDopSprite ] . lotag - 1 ) ;
mydeletesprite ( nDopSprite ) ;
}
}
nSprite = GrabBody ( ) ;
nSpr = & sprite [ nSprite ] ;
mychangespritesect ( nSprite , sPlayerSave [ nPlayer ] . nSector ) ;
changespritestat ( nSprite , 100 ) ;
assert ( nSprite > = 0 & & nSprite < kMaxSprites ) ;
int nDSprite = insertsprite ( nSpr - > sectnum , 100 ) ;
nDoppleSprite [ nPlayer ] = nDSprite ;
assert ( nDSprite > = 0 & & nDSprite < kMaxSprites ) ;
if ( nTotalPlayers > 1 )
{
int nNStartSprite = nNetStartSprite [ nCurStartSprite ] ;
auto nstspr = & sprite [ nNStartSprite ] ;
nCurStartSprite + + ;
if ( nCurStartSprite > = nNetStartSprites ) {
nCurStartSprite = 0 ;
}
nSpr - > x = nstspr - > x ;
nSpr - > y = nstspr - > y ;
nSpr - > z = nstspr - > z ;
mychangespritesect ( nSprite , nstspr - > sectnum ) ;
plr - > angle . ang = buildang ( nstspr - > ang & kAngleMask ) ;
nSpr - > ang = plr - > angle . ang . asbuild ( ) ;
floorspr = insertsprite ( nSpr - > sectnum , 0 ) ;
assert ( floorspr > = 0 & & floorspr < kMaxSprites ) ;
auto fspr = & sprite [ floorspr ] ;
fspr - > x = nSpr - > x ;
fspr - > y = nSpr - > y ;
fspr - > z = nSpr - > z ;
fspr - > yrepeat = 64 ;
fspr - > xrepeat = 64 ;
fspr - > cstat = 32 ;
fspr - > picnum = nPlayer + kTile3571 ;
}
else
{
nSpr - > x = sPlayerSave [ nPlayer ] . x ;
nSpr - > y = sPlayerSave [ nPlayer ] . y ;
nSpr - > z = sector [ sPlayerSave [ nPlayer ] . nSector ] . floorz ;
plr - > angle . ang = buildang ( sPlayerSave [ nPlayer ] . nAngle & kAngleMask ) ;
nSpr - > ang = plr - > angle . ang . asbuild ( ) ;
floorspr = - 1 ;
}
plr - > angle . backup ( ) ;
plr - > horizon . backup ( ) ;
nPlayerFloorSprite [ nPlayer ] = floorspr ;
nSpr - > cstat = 0x101 ;
nSpr - > shade = - 12 ;
nSpr - > clipdist = 58 ;
nSpr - > pal = 0 ;
nSpr - > xrepeat = 40 ;
nSpr - > yrepeat = 40 ;
nSpr - > xoffset = 0 ;
nSpr - > yoffset = 0 ;
nSpr - > picnum = seq_GetSeqPicnum ( kSeqJoe , 18 , 0 ) ;
int nHeight = GetSpriteHeight ( nSprite ) ;
nSpr - > xvel = 0 ;
nSpr - > yvel = 0 ;
nSpr - > zvel = 0 ;
2019-08-31 07:47:15 +00:00
2020-10-13 22:19:39 +00:00
nStandHeight = nHeight ;
2019-08-31 07:47:15 +00:00
2020-10-13 22:19:39 +00:00
nSpr - > hitag = 0 ;
nSpr - > extra = - 1 ;
nSpr - > lotag = runlist_HeadRun ( ) + 1 ;
auto nDSpr = & sprite [ nDSprite ] ;
nDSpr - > x = nSpr - > x ;
nDSpr - > y = nSpr - > y ;
nDSpr - > z = nSpr - > z ;
nDSpr - > xrepeat = nSpr - > xrepeat ;
nDSpr - > yrepeat = nSpr - > yrepeat ;
nDSpr - > xoffset = 0 ;
nDSpr - > yoffset = 0 ;
nDSpr - > shade = nSpr - > shade ;
nDSpr - > ang = nSpr - > ang ;
nDSpr - > cstat = nSpr - > cstat ;
2019-08-26 03:59:14 +00:00
2020-10-13 22:19:39 +00:00
nDSpr - > lotag = runlist_HeadRun ( ) + 1 ;
2019-08-26 03:59:14 +00:00
2020-10-13 22:19:39 +00:00
plr - > nAction = 0 ;
plr - > nHealth = 800 ; // TODO - define
2019-08-26 03:59:14 +00:00
2020-10-13 22:19:39 +00:00
if ( nNetPlayerCount ) {
plr - > nHealth = 1600 ; // TODO - define
}
2019-08-26 03:59:14 +00:00
2020-10-13 22:19:39 +00:00
plr - > field_2 = 0 ;
plr - > nSprite = nSprite ;
plr - > bIsMummified = false ;
2019-08-31 07:47:15 +00:00
2020-10-13 22:19:39 +00:00
if ( plr - > invincibility > = 0 ) {
plr - > invincibility = 0 ;
}
2021-05-13 17:15:53 +00:00
PlayerList [ nPlayer ] . nTorch = 0 ;
2020-10-13 22:19:39 +00:00
plr - > nMaskAmount = 0 ;
SetTorch ( nPlayer , 0 ) ;
2021-05-13 17:15:53 +00:00
PlayerList [ nPlayer ] . nInvisible = 0 ;
2020-10-13 22:19:39 +00:00
plr - > bIsFiring = 0 ;
plr - > field_3FOUR = 0 ;
nPlayerViewSect [ nPlayer ] = sPlayerSave [ nPlayer ] . nSector ;
plr - > field_3A = 0 ;
2021-05-13 17:15:53 +00:00
PlayerList [ nPlayer ] . nDouble = 0 ;
2019-08-31 07:47:15 +00:00
2020-10-13 22:19:39 +00:00
plr - > nSeq = kSeqJoe ;
nPlayerPushSound [ nPlayer ] = - 1 ;
2019-08-31 07:47:15 +00:00
2020-10-13 22:19:39 +00:00
plr - > field_38 = - 1 ;
2019-08-26 03:59:14 +00:00
2020-10-13 22:19:39 +00:00
if ( plr - > nCurrentWeapon = = 7 ) {
plr - > nCurrentWeapon = plr - > field_3C ;
}
2019-08-31 07:47:15 +00:00
2020-10-13 22:19:39 +00:00
plr - > field_3C = 0 ;
plr - > nAir = 100 ;
2019-08-26 03:59:14 +00:00
2021-05-02 13:54:19 +00:00
if ( ! ( currentLevel - > gameflags & LEVEL_EX_MULTI ) )
2020-10-13 22:19:39 +00:00
{
RestoreMinAmmo ( nPlayer ) ;
}
else
{
ResetPlayerWeapons ( nPlayer ) ;
plr - > nMagic = 0 ;
}
2019-08-26 03:59:14 +00:00
2020-10-13 22:19:39 +00:00
nPlayerGrenade [ nPlayer ] = - 1 ;
oeyelevel [ nPlayer ] = eyelevel [ nPlayer ] = - 14080 ;
dVertPan [ nPlayer ] = 0 ;
2019-08-26 03:59:14 +00:00
2020-10-13 22:19:39 +00:00
nTemperature [ nPlayer ] = 0 ;
2019-08-26 03:59:14 +00:00
2020-10-13 22:19:39 +00:00
nYDamage [ nPlayer ] = 0 ;
nXDamage [ nPlayer ] = 0 ;
2019-08-26 03:59:14 +00:00
2021-04-13 11:56:01 +00:00
plr - > nDestVertPan = plr - > horizon . ohoriz = plr - > horizon . horiz = q16horiz ( 0 ) ;
2020-10-13 22:19:39 +00:00
nBreathTimer [ nPlayer ] = 90 ;
2019-08-26 03:59:14 +00:00
2020-10-13 22:19:39 +00:00
nTauntTimer [ nPlayer ] = RandomSize ( 3 ) + 3 ;
2019-08-26 03:59:14 +00:00
2020-10-13 22:19:39 +00:00
nDSpr - > owner = runlist_AddRunRec ( nDSpr - > lotag - 1 , nPlayer | 0xA0000 ) ;
nSpr - > owner = runlist_AddRunRec ( nSpr - > lotag - 1 , nPlayer | 0xA0000 ) ;
2019-08-26 03:59:14 +00:00
2020-10-13 22:19:39 +00:00
if ( plr - > nRun < 0 ) {
plr - > nRun = runlist_AddRunRec ( NewRun , nPlayer | 0xA0000 ) ;
}
2019-08-26 03:59:14 +00:00
2020-10-13 22:19:39 +00:00
BuildRa ( nPlayer ) ;
2019-08-26 03:59:14 +00:00
2020-10-13 22:19:39 +00:00
if ( nPlayer = = nLocalPlayer )
{
nLocalSpr = nSprite ;
2019-08-26 03:59:14 +00:00
2020-10-13 22:19:39 +00:00
RestoreGreenPal ( ) ;
2021-04-13 11:56:01 +00:00
plr - > bPlayerPan = plr - > bLockPan = false ;
2020-10-13 22:19:39 +00:00
}
2019-08-26 03:59:14 +00:00
2020-10-13 22:19:39 +00:00
ototalvel [ nPlayer ] = totalvel [ nPlayer ] = 0 ;
2019-08-26 03:59:14 +00:00
2020-10-13 22:19:39 +00:00
memset ( & sPlayerInput [ nPlayer ] , 0 , sizeof ( PlayerInput ) ) ;
sPlayerInput [ nPlayer ] . nItem = - 1 ;
2019-08-26 03:59:14 +00:00
2020-10-13 22:19:39 +00:00
nDeathType [ nPlayer ] = 0 ;
nQuake [ nPlayer ] = 0 ;
2019-08-26 03:59:14 +00:00
}
2021-01-19 08:44:16 +00:00
2019-08-26 03:59:14 +00:00
int GrabPlayer ( )
{
2019-08-31 07:47:15 +00:00
if ( PlayerCount > = kMaxPlayers ) {
return - 1 ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
return PlayerCount + + ;
2019-08-26 03:59:14 +00:00
}
void StartDeathSeq ( int nPlayer , int nVal )
{
2019-08-31 07:47:15 +00:00
FreeRa ( nPlayer ) ;
short nSprite = PlayerList [ nPlayer ] . nSprite ;
PlayerList [ nPlayer ] . nHealth = 0 ;
short nLotag = sector [ sprite [ nSprite ] . sectnum ] . lotag ;
if ( nLotag > 0 ) {
runlist_SignalRun ( nLotag - 1 , nPlayer | 0x70000 ) ;
}
if ( nPlayerGrenade [ nPlayer ] > = 0 )
{
ThrowGrenade ( nPlayer , 0 , 0 , 0 , - 10000 ) ;
}
else
{
if ( nNetPlayerCount )
{
int nWeapon = PlayerList [ nPlayer ] . nCurrentWeapon ;
if ( nWeapon > kWeaponSword & & nWeapon < = kWeaponRing )
{
short nSector = sprite [ nSprite ] . sectnum ;
if ( SectBelow [ nSector ] > - 1 ) {
nSector = SectBelow [ nSector ] ;
}
int nGunSprite = GrabBodyGunSprite ( ) ;
changespritesect ( nGunSprite , nSector ) ;
sprite [ nGunSprite ] . x = sprite [ nSprite ] . x ;
sprite [ nGunSprite ] . y = sprite [ nSprite ] . y ;
sprite [ nGunSprite ] . z = sector [ nSector ] . floorz - 512 ;
changespritestat ( nGunSprite , nGunLotag [ nWeapon ] + 900 ) ;
sprite [ nGunSprite ] . picnum = nGunPicnum [ nWeapon ] ;
BuildItemAnim ( nGunSprite ) ;
}
}
}
StopFiringWeapon ( nPlayer ) ;
2020-10-07 06:40:59 +00:00
PlayerList [ nPlayer ] . horizon . ohoriz = PlayerList [ nPlayer ] . horizon . horiz = q16horiz ( 0 ) ;
2019-11-08 16:45:10 +00:00
oeyelevel [ nPlayer ] = eyelevel [ nPlayer ] = - 14080 ;
2021-05-13 17:15:53 +00:00
PlayerList [ nPlayer ] . nInvisible = 0 ;
2019-08-31 07:47:15 +00:00
dVertPan [ nPlayer ] = 15 ;
sprite [ nSprite ] . cstat & = 0x7FFF ;
SetNewWeaponImmediate ( nPlayer , - 2 ) ;
if ( SectDamage [ sprite [ nSprite ] . sectnum ] < = 0 )
{
nDeathType [ nPlayer ] = nVal ;
}
else
{
nDeathType [ nPlayer ] = 2 ;
}
nVal * = 2 ;
if ( nVal | | ! ( SectFlag [ sprite [ nSprite ] . sectnum ] & kSectUnderwater ) )
{
PlayerList [ nPlayer ] . nAction = nVal + 17 ;
}
else {
PlayerList [ nPlayer ] . nAction = 16 ;
}
PlayerList [ nPlayer ] . field_2 = 0 ;
sprite [ nSprite ] . cstat & = 0xFEFE ;
2019-11-20 16:21:32 +00:00
2019-08-31 07:47:15 +00:00
if ( nTotalPlayers = = 1 )
{
2021-05-02 13:54:19 +00:00
if ( ! ( currentLevel - > gameflags & LEVEL_EX_TRAINING ) ) { // if not on the training level
2021-05-13 17:06:38 +00:00
PlayerList [ nPlayer ] . nLives - - ;
2019-08-31 07:47:15 +00:00
}
2021-05-13 17:06:38 +00:00
if ( PlayerList [ nPlayer ] . nLives < 0 ) {
PlayerList [ nPlayer ] . nLives = 0 ;
2019-08-31 07:47:15 +00:00
}
}
2020-08-24 03:22:52 +00:00
ototalvel [ nPlayer ] = totalvel [ nPlayer ] = 0 ;
2019-08-26 03:59:14 +00:00
}
int AddAmmo ( int nPlayer , int nWeapon , int nAmmoAmount )
{
2019-08-31 07:47:15 +00:00
if ( ! nAmmoAmount ) {
nAmmoAmount = 1 ;
}
short nCurAmmo = PlayerList [ nPlayer ] . nAmmo [ nWeapon ] ;
if ( nCurAmmo > = 300 & & nAmmoAmount > 0 ) {
return 0 ;
}
nAmmoAmount = nCurAmmo + nAmmoAmount ;
if ( nAmmoAmount > 300 ) {
nAmmoAmount = 300 ;
}
PlayerList [ nPlayer ] . nAmmo [ nWeapon ] = nAmmoAmount ;
if ( nWeapon = = 1 )
{
if ( ! nPistolClip [ nPlayer ] ) {
nPistolClip [ nPlayer ] = 6 ;
}
}
return 1 ;
2019-08-26 03:59:14 +00:00
}
void SetPlayerMummified ( int nPlayer , int bIsMummified )
{
2019-08-31 07:47:15 +00:00
int nSprite = PlayerList [ nPlayer ] . nSprite ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sprite [ nSprite ] . yvel = 0 ;
sprite [ nSprite ] . xvel = 0 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
PlayerList [ nPlayer ] . bIsMummified = bIsMummified ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( bIsMummified )
{
PlayerList [ nPlayer ] . nAction = 13 ;
PlayerList [ nPlayer ] . nSeq = kSeqMummy ;
}
else
{
PlayerList [ nPlayer ] . nAction = 0 ;
PlayerList [ nPlayer ] . nSeq = kSeqJoe ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
PlayerList [ nPlayer ] . field_2 = 0 ;
2019-08-26 03:59:14 +00:00
}
void ShootStaff ( int nPlayer )
{
2019-08-31 07:47:15 +00:00
PlayerList [ nPlayer ] . nAction = 15 ;
PlayerList [ nPlayer ] . field_2 = 0 ;
PlayerList [ nPlayer ] . nSeq = kSeqJoe ;
2019-08-26 03:59:14 +00:00
}
2019-08-31 07:47:15 +00:00
void PlayAlert ( const char * str )
2019-08-26 03:59:14 +00:00
{
2019-08-31 07:47:15 +00:00
StatusMessage ( 300 , str ) ;
PlayLocalSound ( StaticSound [ kSound63 ] , 0 ) ;
2019-08-26 03:59:14 +00:00
}
2020-08-22 18:14:00 +00:00
static void pickupMessage ( int no )
{
no = nItemText [ no ] ;
if ( no ! = - 1 )
{
FStringf label ( " TXT_EX_PICKUP%d " , no + 1 ) ;
auto str = GStrings [ label ] ;
if ( str ) Printf ( PRINT_NOTIFY , " %s \n " , str ) ;
}
}
2020-09-21 10:37:09 +00:00
void UpdatePlayerSpriteAngle ( Player * pPlayer )
{
2021-01-05 00:01:47 +00:00
inita = sprite [ pPlayer - > nSprite ] . ang = pPlayer - > angle . ang . asbuild ( ) ;
2020-09-21 10:37:09 +00:00
}
2020-03-02 21:08:31 +00:00
void FuncPlayer ( int a , int nDamage , int nRun )
2019-08-26 03:59:14 +00:00
{
2019-08-31 07:47:15 +00:00
int var_48 = 0 ;
int var_40 ;
2021-05-02 13:54:19 +00:00
bool mplevel = ( currentLevel - > gameflags & LEVEL_EX_MULTI ) ;
2019-08-31 07:47:15 +00:00
short nPlayer = RunData [ nRun ] . nVal ;
assert ( nPlayer > = 0 & & nPlayer < kMaxPlayers ) ;
short nPlayerSprite = PlayerList [ nPlayer ] . nSprite ;
short nDopple = nDoppleSprite [ nPlayer ] ;
short nAction = PlayerList [ nPlayer ] . nAction ;
short nActionB = PlayerList [ nPlayer ] . nAction ;
2020-03-02 21:08:31 +00:00
int nMessage = a & kMessageMask ;
2019-08-31 07:47:15 +00:00
short nSprite2 ;
2020-10-07 21:08:40 +00:00
PlayerList [ nPlayer ] . angle . backup ( ) ;
2020-10-07 06:40:59 +00:00
PlayerList [ nPlayer ] . horizon . backup ( ) ;
2020-10-07 21:08:40 +00:00
PlayerList [ nPlayer ] . angle . resetadjustment ( ) ;
2020-10-07 06:40:59 +00:00
PlayerList [ nPlayer ] . horizon . resetadjustment ( ) ;
2019-11-08 16:45:10 +00:00
oeyelevel [ nPlayer ] = eyelevel [ nPlayer ] ;
2019-11-03 17:20:05 +00:00
2019-08-31 07:47:15 +00:00
switch ( nMessage )
{
case 0x90000 :
{
2020-10-11 09:33:28 +00:00
seq_PlotSequence ( a & 0xFFFF , SeqOffsets [ PlayerList [ nPlayer ] . nSeq ] + PlayerSeq [ nAction ] . a , PlayerList [ nPlayer ] . field_2 , PlayerSeq [ nAction ] . b ) ;
2019-08-31 07:47:15 +00:00
return ;
}
2019-11-20 16:21:32 +00:00
2019-08-31 07:47:15 +00:00
case 0xA0000 :
{
if ( PlayerList [ nPlayer ] . nHealth < = 0 ) {
return ;
}
nDamage = runlist_CheckRadialDamage ( nPlayerSprite ) ;
if ( ! nDamage ) {
return ;
}
nSprite2 = nRadialOwner ;
// fall through to case 0x80000
2019-12-02 14:56:24 +00:00
fallthrough__ ;
2019-08-31 07:47:15 +00:00
}
case 0x80000 :
{
// Dunno how to do this otherwise... we fall through from above but don't want to do this check..
if ( nMessage ! = 0xA0000 )
{
if ( ! nDamage ) {
return ;
}
2020-03-02 21:08:31 +00:00
nSprite2 = a & 0xFFFF ;
2019-08-31 07:47:15 +00:00
}
// ok continue case 0x80000 as normal, loc_1C57C
if ( ! PlayerList [ nPlayer ] . nHealth ) {
return ;
}
if ( ! PlayerList [ nPlayer ] . invincibility )
{
PlayerList [ nPlayer ] . nHealth - = nDamage ;
if ( nPlayer = = nLocalPlayer )
{
2019-10-12 21:09:55 +00:00
TintPalette ( nDamage , 0 , 0 ) ;
2019-08-31 07:47:15 +00:00
}
}
if ( PlayerList [ nPlayer ] . nHealth > 0 )
{
if ( nDamage > 40 | | ( totalmoves & 0xF ) < 2 )
{
if ( PlayerList [ nPlayer ] . invincibility ) {
return ;
}
if ( SectFlag [ sprite [ nPlayerSprite ] . sectnum ] & kSectUnderwater )
{
if ( nAction ! = 12 )
{
PlayerList [ nPlayer ] . field_2 = 0 ;
PlayerList [ nPlayer ] . nAction = 12 ;
return ;
2019-11-20 16:21:32 +00:00
}
2019-08-31 07:47:15 +00:00
}
else
{
if ( nAction ! = 4 )
{
PlayerList [ nPlayer ] . field_2 = 0 ;
PlayerList [ nPlayer ] . nAction = 4 ;
if ( nSprite2 > - 1 )
{
nPlayerSwear [ nPlayer ] - - ;
if ( nPlayerSwear [ nPlayer ] < = 0 )
{
D3PlayFX ( StaticSound [ kSound52 ] , nDopple ) ;
nPlayerSwear [ nPlayer ] = RandomSize ( 3 ) + 4 ;
}
}
}
}
}
return ;
}
else
{
2019-11-30 15:14:24 +00:00
// player has died
if ( nSprite2 > - 1 & & sprite [ nSprite2 ] . statnum = = 100 )
2019-08-31 07:47:15 +00:00
{
short nPlayer2 = GetPlayerFromSprite ( nSprite2 ) ;
if ( nPlayer2 = = nPlayer ) // player caused their own death
{
nPlayerScore [ nPlayer ] - - ;
}
else
{
nPlayerScore [ nPlayer ] + + ;
}
}
else if ( nSprite2 < 0 )
{
nPlayerScore [ nPlayer ] - - ;
}
if ( nMessage = = 0xA0000 )
{
for ( int i = 122 ; i < = 131 ; i + + )
{
BuildCreatureChunk ( nPlayerSprite , seq_GetSeqPicnum ( kSeqJoe , i , 0 ) ) ;
}
StartDeathSeq ( nPlayer , 1 ) ;
}
else
{
StartDeathSeq ( nPlayer , 0 ) ;
}
}
return ;
}
case 0x20000 :
{
sprite [ nPlayerSprite ] . xvel = sPlayerInput [ nPlayer ] . xVel > > 14 ;
sprite [ nPlayerSprite ] . yvel = sPlayerInput [ nPlayer ] . yVel > > 14 ;
if ( sPlayerInput [ nPlayer ] . nItem > - 1 )
{
UseItem ( nPlayer , sPlayerInput [ nPlayer ] . nItem ) ;
sPlayerInput [ nPlayer ] . nItem = - 1 ;
}
int var_EC = PlayerList [ nPlayer ] . field_2 ;
2020-10-11 09:33:28 +00:00
sprite [ nPlayerSprite ] . picnum = seq_GetSeqPicnum ( PlayerList [ nPlayer ] . nSeq , PlayerSeq [ nHeightTemplate [ nAction ] ] . a , var_EC ) ;
2019-08-31 07:47:15 +00:00
sprite [ nDopple ] . picnum = sprite [ nPlayerSprite ] . picnum ;
2021-05-13 17:15:53 +00:00
if ( PlayerList [ nPlayer ] . nTorch > 0 )
2019-08-31 07:47:15 +00:00
{
2021-05-13 17:15:53 +00:00
PlayerList [ nPlayer ] . nTorch - - ;
if ( PlayerList [ nPlayer ] . nTorch = = 0 )
2019-08-31 07:47:15 +00:00
{
SetTorch ( nPlayer , 0 ) ;
}
else
{
if ( nPlayer ! = nLocalPlayer )
{
nFlashDepth = 5 ;
AddFlash ( sprite [ nPlayerSprite ] . sectnum ,
sprite [ nPlayerSprite ] . x ,
sprite [ nPlayerSprite ] . y ,
sprite [ nPlayerSprite ] . z , 0 ) ;
}
}
}
2021-05-13 17:15:53 +00:00
if ( PlayerList [ nPlayer ] . nDouble > 0 )
2019-08-31 07:47:15 +00:00
{
2021-05-13 17:15:53 +00:00
PlayerList [ nPlayer ] . nDouble - - ;
if ( PlayerList [ nPlayer ] . nDouble = = 150 & & nPlayer = = nLocalPlayer ) {
2019-08-31 07:47:15 +00:00
PlayAlert ( " WEAPON POWER IS ABOUT TO EXPIRE " ) ;
}
}
2021-05-13 17:15:53 +00:00
if ( PlayerList [ nPlayer ] . nInvisible > 0 )
2019-08-31 07:47:15 +00:00
{
2021-05-13 17:15:53 +00:00
PlayerList [ nPlayer ] . nInvisible - - ;
if ( PlayerList [ nPlayer ] . nInvisible = = 0 )
2019-08-31 07:47:15 +00:00
{
sprite [ nPlayerSprite ] . cstat & = 0x7FFF ; // set visible
short nFloorSprite = nPlayerFloorSprite [ nPlayerSprite ] ;
if ( nFloorSprite > - 1 ) {
sprite [ nFloorSprite ] . cstat & = 0x7FFF ; // set visible
}
}
2021-05-13 17:15:53 +00:00
else if ( PlayerList [ nPlayer ] . nInvisible = = 150 & & nPlayer = = nLocalPlayer )
2019-08-31 07:47:15 +00:00
{
PlayAlert ( " INVISIBILITY IS ABOUT TO EXPIRE " ) ;
}
}
if ( PlayerList [ nPlayer ] . invincibility > 0 )
{
PlayerList [ nPlayer ] . invincibility - - ;
if ( PlayerList [ nPlayer ] . invincibility = = 150 & & nPlayer = = nLocalPlayer ) {
PlayAlert ( " INVINCIBILITY IS ABOUT TO EXPIRE " ) ;
}
}
if ( nQuake [ nPlayer ] ! = 0 )
{
nQuake [ nPlayer ] = - nQuake [ nPlayer ] ;
if ( nQuake [ nPlayer ] > 0 )
{
nQuake [ nPlayer ] - = 512 ;
if ( nQuake [ nPlayer ] < 0 )
nQuake [ nPlayer ] = 0 ;
}
}
// loc_1A494:
2020-11-30 22:40:16 +00:00
if ( SyncInput ( ) )
2020-09-21 10:37:09 +00:00
{
Player * pPlayer = & PlayerList [ nPlayer ] ;
2021-04-21 10:41:04 +00:00
pPlayer - > angle . applyinput ( sPlayerInput [ nPlayer ] . nAngle , & sPlayerInput [ nLocalPlayer ] . actions ) ;
2020-09-21 10:37:09 +00:00
UpdatePlayerSpriteAngle ( pPlayer ) ;
}
2019-08-31 07:47:15 +00:00
// sprite[nPlayerSprite].zvel is modified within Gravity()
short zVel = sprite [ nPlayerSprite ] . zvel ;
Gravity ( nPlayerSprite ) ;
if ( sprite [ nPlayerSprite ] . zvel > = 6500 & & zVel < 6500 )
{
2020-11-23 17:38:58 +00:00
D3PlayFX ( StaticSound [ kSound17 ] , nPlayerSprite ) ;
2019-08-31 07:47:15 +00:00
}
// loc_1A4E6
short nSector = sprite [ nPlayerSprite ] . sectnum ;
short nSectFlag = SectFlag [ nPlayerViewSect [ nPlayer ] ] ;
int playerX = sprite [ nPlayerSprite ] . x ;
int playerY = sprite [ nPlayerSprite ] . y ;
int x = ( sPlayerInput [ nPlayer ] . xVel * 4 ) > > 2 ;
int y = ( sPlayerInput [ nPlayer ] . yVel * 4 ) > > 2 ;
int z = ( sprite [ nPlayerSprite ] . zvel * 4 ) > > 2 ;
if ( sprite [ nPlayerSprite ] . zvel > 8192 )
sprite [ nPlayerSprite ] . zvel = 8192 ;
if ( PlayerList [ nPlayer ] . bIsMummified )
{
x / = 2 ;
y / = 2 ;
}
int spr_x = sprite [ nPlayerSprite ] . x ;
int spr_y = sprite [ nPlayerSprite ] . y ;
int spr_z = sprite [ nPlayerSprite ] . z ;
int spr_sectnum = sprite [ nPlayerSprite ] . sectnum ;
// TODO
// nSectFlag & kSectUnderwater;
zVel = sprite [ nPlayerSprite ] . zvel ;
int nMove = 0 ; // TEMP
if ( bSlipMode )
{
nMove = 0 ;
sprite [ nPlayerSprite ] . x + = ( x > > 14 ) ;
sprite [ nPlayerSprite ] . y + = ( y > > 14 ) ;
vec3_t pos = { sprite [ nPlayerSprite ] . x , sprite [ nPlayerSprite ] . y , sprite [ nPlayerSprite ] . z } ;
setsprite ( nPlayerSprite , & pos ) ;
sprite [ nPlayerSprite ] . z = sector [ sprite [ nPlayerSprite ] . sectnum ] . floorz ;
}
else
{
nMove = movesprite ( nPlayerSprite , x , y , z , 5120 , - 5120 , CLIPMASK0 ) ;
short var_54 = sprite [ nPlayerSprite ] . sectnum ;
pushmove_old ( & sprite [ nPlayerSprite ] . x , & sprite [ nPlayerSprite ] . y , & sprite [ nPlayerSprite ] . z , & var_54 , sprite [ nPlayerSprite ] . clipdist < < 2 , 5120 , - 5120 , CLIPMASK0 ) ;
if ( var_54 ! = sprite [ nPlayerSprite ] . sectnum ) {
mychangespritesect ( nPlayerSprite , var_54 ) ;
}
}
// loc_1A6E4
2019-09-22 19:09:50 +00:00
if ( inside ( sprite [ nPlayerSprite ] . x , sprite [ nPlayerSprite ] . y , sprite [ nPlayerSprite ] . sectnum ) ! = 1 )
2019-08-31 07:47:15 +00:00
{
mychangespritesect ( nPlayerSprite , spr_sectnum ) ;
sprite [ nPlayerSprite ] . x = spr_x ;
sprite [ nPlayerSprite ] . y = spr_y ;
if ( zVel < sprite [ nPlayerSprite ] . zvel ) {
sprite [ nPlayerSprite ] . zvel = zVel ;
}
}
2019-08-26 03:59:14 +00:00
// int _bTouchFloor = bTouchFloor;
2019-08-31 07:47:15 +00:00
short bUnderwater = SectFlag [ sprite [ nPlayerSprite ] . sectnum ] & kSectUnderwater ;
if ( bUnderwater )
{
nXDamage [ nPlayer ] / = 2 ;
nYDamage [ nPlayer ] / = 2 ;
}
// Trigger Ramses?
if ( ( SectFlag [ sprite [ nPlayerSprite ] . sectnum ] & 0x8000 ) & & bTouchFloor )
{
if ( nTotalPlayers < = 1 )
{
2020-09-21 09:28:39 +00:00
auto ang = GetAngleToSprite ( nPlayerSprite , nSpiritSprite ) & kAngleMask ;
2020-10-07 21:08:40 +00:00
PlayerList [ nPlayer ] . angle . settarget ( ang , true ) ;
2020-09-21 09:28:39 +00:00
sprite [ nPlayerSprite ] . ang = ang ;
2019-08-31 07:47:15 +00:00
2020-10-07 06:40:59 +00:00
PlayerList [ nPlayer ] . horizon . settarget ( 0 , true ) ;
2020-01-23 21:58:49 +00:00
2019-08-31 07:47:15 +00:00
lPlayerXVel = 0 ;
lPlayerYVel = 0 ;
2019-11-20 16:21:32 +00:00
2019-08-31 07:47:15 +00:00
sprite [ nPlayerSprite ] . xvel = 0 ;
sprite [ nPlayerSprite ] . yvel = 0 ;
sprite [ nPlayerSprite ] . zvel = 0 ;
2019-11-20 16:21:32 +00:00
2019-08-31 07:47:15 +00:00
if ( nFreeze < 1 )
{
nFreeze = 1 ;
StopAllSounds ( ) ;
StopLocalSound ( ) ;
InitSpiritHead ( ) ;
2021-04-18 00:04:17 +00:00
PlayerList [ nPlayer ] . nDestVertPan = q16horiz ( 0 ) ;
2021-05-02 13:54:19 +00:00
PlayerList [ nPlayer ] . horizon . settarget ( currentLevel - > ex_ramses_horiz ) ;
2019-08-31 07:47:15 +00:00
}
}
else
{
2020-09-11 18:56:46 +00:00
LevelFinished ( ) ;
2019-08-31 07:47:15 +00:00
}
return ;
}
if ( nMove & 0x3C000 )
{
if ( bTouchFloor )
{
// Damage stuff..
nXDamage [ nPlayer ] / = 2 ;
nYDamage [ nPlayer ] / = 2 ;
if ( nPlayer = = nLocalPlayer )
{
short zVelB = zVel ;
if ( zVelB < 0 ) {
zVelB = - zVelB ;
}
2021-04-16 13:37:05 +00:00
if ( zVelB > 512 & & ! PlayerList [ nPlayer ] . horizon . horiz . asq16 ( ) & & cl_slopetilting ) {
2021-04-18 00:04:17 +00:00
PlayerList [ nPlayer ] . nDestVertPan = q16horiz ( 0 ) ;
2019-08-31 07:47:15 +00:00
}
}
if ( zVel > = 6500 )
{
sprite [ nPlayerSprite ] . xvel > > = 2 ;
sprite [ nPlayerSprite ] . yvel > > = 2 ;
runlist_DamageEnemy ( nPlayerSprite , - 1 , ( ( zVel - 6500 ) > > 7 ) + 10 ) ;
if ( PlayerList [ nPlayer ] . nHealth < = 0 )
{
sprite [ nPlayerSprite ] . xvel = 0 ;
sprite [ nPlayerSprite ] . yvel = 0 ;
StopSpriteSound ( nPlayerSprite ) ;
2019-09-21 15:47:55 +00:00
PlayFXAtXYZ ( StaticSound [ kSoundJonFDie ] , sprite [ nPlayerSprite ] . x , sprite [ nPlayerSprite ] . y , sprite [ nPlayerSprite ] . z , sprite [ nPlayerSprite ] . sectnum | = 0x4000 ) ; // CHECKME
2019-08-31 07:47:15 +00:00
}
else
{
D3PlayFX ( StaticSound [ kSound27 ] | 0x2000 , nPlayerSprite ) ;
}
}
}
if ( ( ( nMove & 0xC000 ) = = 0x4000 ) | | ( ( nMove & 0xC000 ) = = 0x8000 ) )
{
2021-01-04 19:44:46 +00:00
int sectnum = 0 ;
2019-08-31 07:47:15 +00:00
if ( ( nMove & 0xC000 ) = = 0x4000 )
{
2021-01-04 19:44:46 +00:00
sectnum = nMove & 0x3FFF ;
2019-08-31 07:47:15 +00:00
}
else if ( ( nMove & 0xC000 ) = = 0x8000 )
{
2021-01-04 19:44:46 +00:00
sectnum = wall [ nMove & 0x3FFF ] . nextsector ;
2019-08-31 07:47:15 +00:00
}
2021-01-04 19:44:46 +00:00
if ( sectnum > = 0 )
2019-08-31 07:47:15 +00:00
{
2021-01-04 19:44:46 +00:00
if ( ( sector [ sectnum ] . hitag = = 45 ) & & bTouchFloor )
2019-08-31 07:47:15 +00:00
{
int nNormal = GetWallNormal ( nMove & 0x3FFF ) ;
int nDiff = AngleDiff ( nNormal , ( sprite [ nPlayerSprite ] . ang + 1024 ) & kAngleMask ) ;
if ( nDiff < 0 ) {
nDiff = - nDiff ;
}
if ( nDiff < = 256 )
{
2021-01-04 19:44:46 +00:00
nPlayerPushSect [ nPlayer ] = sectnum ;
2019-08-31 07:47:15 +00:00
2021-01-04 19:44:46 +00:00
int xvel = sPlayerInput [ nPlayer ] . xVel ;
int yvel = sPlayerInput [ nPlayer ] . yVel ;
int nMyAngle = GetMyAngle ( xvel , yvel ) ;
2019-11-20 16:21:32 +00:00
2021-01-04 19:44:46 +00:00
setsectinterpolate ( sectnum ) ;
MoveSector ( sectnum , nMyAngle , & xvel , & yvel ) ;
2019-08-31 07:47:15 +00:00
if ( nPlayerPushSound [ nPlayer ] < = - 1 )
{
nPlayerPushSound [ nPlayer ] = 1 ;
short nBlock = sector [ nPlayerPushSect [ nPlayer ] ] . extra ;
int nBlockSprite = sBlockInfo [ nBlock ] . nSprite ;
2019-11-13 22:49:02 +00:00
D3PlayFX ( StaticSound [ kSound23 ] , nBlockSprite | 0x4000 ) ;
2019-08-31 07:47:15 +00:00
}
else
{
sprite [ nPlayerSprite ] . x = spr_x ;
sprite [ nPlayerSprite ] . y = spr_y ;
sprite [ nPlayerSprite ] . z = spr_z ;
mychangespritesect ( nPlayerSprite , spr_sectnum ) ;
}
2021-01-04 19:44:46 +00:00
movesprite ( nPlayerSprite , xvel , yvel , z , 5120 , - 5120 , CLIPMASK0 ) ;
goto sectdone ;
2019-08-31 07:47:15 +00:00
}
}
}
}
}
// loc_1AB46:
if ( nPlayerPushSound [ nPlayer ] > - 1 )
{
if ( nPlayerPushSect [ nPlayer ] > - 1 )
{
2019-09-21 15:47:55 +00:00
StopSpriteSound ( sBlockInfo [ sector [ nPlayerPushSect [ nPlayer ] ] . extra ] . nSprite ) ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
nPlayerPushSound [ nPlayer ] = - 1 ;
}
2019-08-26 03:59:14 +00:00
2021-01-04 19:44:46 +00:00
sectdone :
2021-04-13 11:56:01 +00:00
if ( ! PlayerList [ nPlayer ] . bPlayerPan & & ! PlayerList [ nPlayer ] . bLockPan )
2021-01-05 00:01:31 +00:00
{
2021-04-13 11:56:01 +00:00
PlayerList [ nPlayer ] . nDestVertPan = q16horiz ( clamp ( ( spr_z - sprite [ nPlayerSprite ] . z ) < < 9 , gi - > playerHorizMin ( ) , gi - > playerHorizMax ( ) ) ) ;
2021-01-05 00:01:31 +00:00
}
2019-08-31 07:47:15 +00:00
playerX - = sprite [ nPlayerSprite ] . x ;
playerY - = sprite [ nPlayerSprite ] . y ;
2020-06-22 10:24:21 +00:00
uint32_t sqrtNum = playerX * playerX + playerY * playerY ;
if ( sqrtNum > INT_MAX )
{
2020-09-08 16:48:18 +00:00
DPrintf ( DMSG_WARNING , " %s %d: overflow \n " , __func__ , __LINE__ ) ;
2020-06-22 10:24:21 +00:00
sqrtNum = INT_MAX ;
}
2020-08-24 03:22:52 +00:00
ototalvel [ nPlayer ] = totalvel [ nPlayer ] ;
2020-06-22 10:24:21 +00:00
totalvel [ nPlayer ] = ksqrt ( sqrtNum ) ;
2019-08-31 07:47:15 +00:00
int nViewSect = sprite [ nPlayerSprite ] . sectnum ;
int EyeZ = eyelevel [ nPlayer ] + sprite [ nPlayerSprite ] . z + nQuake [ nPlayer ] ;
while ( 1 )
{
int nCeilZ = sector [ nViewSect ] . ceilingz ;
if ( EyeZ > = nCeilZ )
break ;
if ( SectAbove [ nViewSect ] < = - 1 )
break ;
nViewSect = SectAbove [ nViewSect ] ;
}
// Do underwater sector check
if ( bUnderwater )
{
if ( nViewSect ! = sprite [ nPlayerSprite ] . sectnum )
{
if ( ( nMove & 0xC000 ) = = 0x8000 )
{
int var_C4 = sprite [ nPlayerSprite ] . x ;
int var_D4 = sprite [ nPlayerSprite ] . y ;
int var_C8 = sprite [ nPlayerSprite ] . z ;
mychangespritesect ( nPlayerSprite , nViewSect ) ;
sprite [ nPlayerSprite ] . x = spr_x ;
sprite [ nPlayerSprite ] . y = spr_y ;
int var_FC = sector [ nViewSect ] . floorz + ( - 5120 ) ;
sprite [ nPlayerSprite ] . z = var_FC ;
if ( ( movesprite ( nPlayerSprite , x , y , 0 , 5120 , 0 , CLIPMASK0 ) & 0xC000 ) = = 0x8000 )
{
mychangespritesect ( nPlayerSprite , sprite [ nPlayerSprite ] . sectnum ) ;
sprite [ nPlayerSprite ] . x = var_C4 ;
sprite [ nPlayerSprite ] . y = var_D4 ;
sprite [ nPlayerSprite ] . z = var_C8 ;
}
else
{
sprite [ nPlayerSprite ] . z = var_FC - 256 ;
D3PlayFX ( StaticSound [ kSound42 ] , nPlayerSprite ) ;
}
}
}
}
// loc_1ADAF
nPlayerViewSect [ nPlayer ] = nViewSect ;
nPlayerDX [ nPlayer ] = sprite [ nPlayerSprite ] . x - spr_x ;
nPlayerDY [ nPlayer ] = sprite [ nPlayerSprite ] . y - spr_y ;
int var_5C = SectFlag [ nViewSect ] & kSectUnderwater ;
2019-08-31 09:08:38 +00:00
uint16_t buttons = sPlayerInput [ nPlayer ] . buttons ;
2020-08-28 20:51:05 +00:00
auto actions = sPlayerInput [ nPlayer ] . actions ;
2019-08-31 07:47:15 +00:00
// loc_1AEF5:
if ( PlayerList [ nPlayer ] . nHealth > 0 )
{
if ( PlayerList [ nPlayer ] . nMaskAmount > 0 )
{
PlayerList [ nPlayer ] . nMaskAmount - - ;
if ( PlayerList [ nPlayer ] . nMaskAmount = = 150 & & nPlayer = = nLocalPlayer ) {
PlayAlert ( " MASK IS ABOUT TO EXPIRE " ) ;
}
}
if ( ! PlayerList [ nPlayer ] . invincibility )
{
// Handle air
nBreathTimer [ nPlayer ] - - ;
if ( nBreathTimer [ nPlayer ] < = 0 )
{
nBreathTimer [ nPlayer ] = 90 ;
// if underwater
if ( var_5C )
{
if ( PlayerList [ nPlayer ] . nMaskAmount > 0 )
{
D3PlayFX ( StaticSound [ kSound30 ] , nPlayerSprite ) ;
PlayerList [ nPlayer ] . nAir = 100 ;
}
else
{
PlayerList [ nPlayer ] . nAir - = 25 ;
if ( PlayerList [ nPlayer ] . nAir > 0 )
{
D3PlayFX ( StaticSound [ kSound25 ] , nPlayerSprite ) ;
}
else
{
PlayerList [ nPlayer ] . nHealth + = ( PlayerList [ nPlayer ] . nAir < < 2 ) ;
if ( PlayerList [ nPlayer ] . nHealth < = 0 )
{
PlayerList [ nPlayer ] . nHealth = 0 ;
StartDeathSeq ( nPlayer , 0 ) ;
}
PlayerList [ nPlayer ] . nAir = 0 ;
if ( PlayerList [ nPlayer ] . nHealth < 300 )
{
D3PlayFX ( StaticSound [ kSound79 ] , nPlayerSprite ) ;
}
else
{
D3PlayFX ( StaticSound [ kSound19 ] , nPlayerSprite ) ;
}
}
}
2019-10-29 15:17:43 +00:00
DoBubbles ( nPlayer ) ;
2019-08-31 07:47:15 +00:00
}
}
}
// loc_1B0B9
if ( var_5C ) // if underwater
{
2021-05-13 17:15:53 +00:00
if ( PlayerList [ nPlayer ] . nTorch > 0 )
2019-08-31 07:47:15 +00:00
{
2021-05-13 17:15:53 +00:00
PlayerList [ nPlayer ] . nTorch = 0 ;
2019-08-31 07:47:15 +00:00
SetTorch ( nPlayer , 0 ) ;
}
}
else
{
int nTmpSectNum = sprite [ nPlayerSprite ] . sectnum ;
if ( totalvel [ nPlayer ] > 25 & & sprite [ nPlayerSprite ] . z > sector [ nTmpSectNum ] . floorz )
{
if ( SectDepth [ nTmpSectNum ] & & ! SectSpeed [ nTmpSectNum ] & & ! SectDamage [ nTmpSectNum ] )
{
D3PlayFX ( StaticSound [ kSound42 ] , nPlayerSprite ) ;
}
}
// CHECKME - wrong place?
if ( nSectFlag & kSectUnderwater )
{
if ( PlayerList [ nPlayer ] . nAir < 50 )
{
D3PlayFX ( StaticSound [ kSound14 ] , nPlayerSprite ) ;
}
nBreathTimer [ nPlayer ] = 1 ;
}
nBreathTimer [ nPlayer ] - - ;
if ( nBreathTimer [ nPlayer ] < = 0 )
{
nBreathTimer [ nPlayer ] = 90 ;
}
if ( PlayerList [ nPlayer ] . nAir < 100 )
{
PlayerList [ nPlayer ] . nAir = 100 ;
}
}
// loc_1B1EB
if ( nTotalPlayers > 1 )
{
int nFloorSprite = nPlayerFloorSprite [ nPlayer ] ;
sprite [ nFloorSprite ] . x = sprite [ nPlayerSprite ] . x ;
sprite [ nFloorSprite ] . y = sprite [ nPlayerSprite ] . y ;
if ( sprite [ nFloorSprite ] . sectnum ! = sprite [ nPlayerSprite ] . sectnum )
{
mychangespritesect ( nFloorSprite , sprite [ nPlayerSprite ] . sectnum ) ;
}
sprite [ nFloorSprite ] . z = sector [ sprite [ nPlayerSprite ] . sectnum ] . floorz ;
}
int var_30 = 0 ;
if ( PlayerList [ nPlayer ] . nHealth > = 800 )
{
var_30 = 2 ;
}
if ( PlayerList [ nPlayer ] . nMagic > = 1000 )
{
var_30 | = 1 ;
}
// code to handle item pickup?
short nearTagSector , nearTagWall , nearTagSprite ;
int nearHitDist ;
short nValB ;
// neartag finds the nearest sector, wall, and sprite which has its hitag and/or lotag set to a value.
2019-11-20 16:21:32 +00:00
neartag ( sprite [ nPlayerSprite ] . x , sprite [ nPlayerSprite ] . y , sprite [ nPlayerSprite ] . z , sprite [ nPlayerSprite ] . sectnum , sprite [ nPlayerSprite ] . ang ,
2019-08-31 07:47:15 +00:00
& nearTagSector , & nearTagWall , & nearTagSprite , ( int32_t * ) & nearHitDist , 1024 , 2 , NULL ) ;
feebtag ( sprite [ nPlayerSprite ] . x , sprite [ nPlayerSprite ] . y , sprite [ nPlayerSprite ] . z , sprite [ nPlayerSprite ] . sectnum ,
& nValB , var_30 , 768 ) ;
// Item pickup code
if ( nValB > = 0 & & sprite [ nValB ] . statnum > = 900 )
{
int var_8C = 16 ;
int var_88 = 9 ;
int var_70 = sprite [ nValB ] . statnum - 900 ;
int var_44 = 0 ;
// item lotags start at 6 (1-5 reserved?) so 0-offset them
2021-05-13 10:58:30 +00:00
int itemtype = var_70 - 6 ;
2019-08-31 07:47:15 +00:00
2021-05-13 10:58:30 +00:00
if ( itemtype < = 54 )
2019-08-31 07:47:15 +00:00
{
2021-05-13 10:58:30 +00:00
switch ( itemtype )
2019-08-31 07:47:15 +00:00
{
2019-08-26 03:59:14 +00:00
do_default :
2019-08-31 07:47:15 +00:00
default :
{
// loc_1B3C7
2019-10-29 22:31:40 +00:00
// CHECKME - is order of evaluation correct?
2020-09-08 16:07:52 +00:00
if ( ! mplevel | | ( var_70 > = 25 & & ( var_70 < = 25 | | var_70 = = 50 ) ) )
2019-08-31 07:47:15 +00:00
{
DestroyItemAnim ( nValB ) ;
mydeletesprite ( nValB ) ;
}
else
{
StartRegenerate ( nValB ) ;
}
2019-08-26 03:59:14 +00:00
do_default_b :
2019-08-31 07:47:15 +00:00
// loc_1BA74
if ( nPlayer = = nLocalPlayer )
{
if ( nItemText [ var_70 ] > - 1 & & nTotalPlayers = = 1 )
{
2020-08-22 18:14:00 +00:00
pickupMessage ( var_70 ) ;
2019-08-31 07:47:15 +00:00
}
2019-10-12 21:09:55 +00:00
TintPalette ( var_44 * 4 , var_8C * 4 , 0 ) ;
2019-08-31 07:47:15 +00:00
if ( var_88 > - 1 )
{
PlayLocalSound ( var_88 , 0 ) ;
}
}
break ;
}
case 0 : // Speed Loader
{
if ( AddAmmo ( nPlayer , 1 , sprite [ nValB ] . hitag ) )
{
2020-02-04 21:45:10 +00:00
var_88 = StaticSound [ kSoundAmmoPickup ] ;
2019-08-31 07:47:15 +00:00
goto do_default ;
}
break ;
}
case 1 : // Fuel Canister
{
2019-11-20 16:21:32 +00:00
if ( AddAmmo ( nPlayer , 3 , sprite [ nValB ] . hitag ) )
2019-08-31 07:47:15 +00:00
{
2020-02-04 21:45:10 +00:00
var_88 = StaticSound [ kSoundAmmoPickup ] ;
2019-08-31 07:47:15 +00:00
goto do_default ;
}
break ;
}
case 2 : // M - 60 Ammo Belt
{
if ( AddAmmo ( nPlayer , 2 , sprite [ nValB ] . hitag ) )
{
2020-02-04 21:45:10 +00:00
var_88 = StaticSound [ kSoundAmmoPickup ] ;
2019-08-31 07:47:15 +00:00
CheckClip ( nPlayer ) ;
goto do_default ;
}
break ;
}
case 3 : // Grenade
case 21 :
case 49 :
{
if ( AddAmmo ( nPlayer , 4 , 1 ) )
{
2020-02-04 21:45:10 +00:00
var_88 = StaticSound [ kSoundAmmoPickup ] ;
2019-08-31 07:47:15 +00:00
if ( ! ( nPlayerWeapons [ nPlayer ] & 0x10 ) )
{
nPlayerWeapons [ nPlayer ] | = 0x10 ;
SetNewWeaponIfBetter ( nPlayer , 4 ) ;
}
if ( var_70 = = 55 )
{
sprite [ nValB ] . cstat = 0x8000 ;
DestroyItemAnim ( nValB ) ;
// loc_1BA74: - repeated block, see in default case
if ( nPlayer = = nLocalPlayer )
{
if ( nItemText [ var_70 ] > - 1 & & nTotalPlayers = = 1 )
{
2020-08-22 18:14:00 +00:00
pickupMessage ( var_70 ) ;
2019-08-31 07:47:15 +00:00
}
2019-10-12 21:09:55 +00:00
TintPalette ( var_44 * 4 , var_8C * 4 , 0 ) ;
2019-08-31 07:47:15 +00:00
if ( var_88 > - 1 )
{
PlayLocalSound ( var_88 , 0 ) ;
}
}
break ;
}
else
{
goto do_default ;
}
}
break ;
}
case 4 : // Pickable item
case 9 : // Pickable item
case 10 : // Reserved
2019-11-20 16:21:32 +00:00
case 18 :
2019-08-31 07:47:15 +00:00
case 25 :
case 28 :
case 29 :
case 30 :
case 33 :
case 34 :
case 35 :
case 36 :
case 37 :
case 38 :
case 45 :
case 52 :
{
goto do_default ;
}
case 5 : // Map
{
GrabMap ( ) ;
goto do_default ;
}
case 6 : // Berry Twig
{
if ( sprite [ nValB ] . hitag = = 0 ) {
break ;
}
var_88 = 20 ;
int edx = 40 ;
if ( edx < = 0 | | ( ! ( var_30 & 2 ) ) )
{
if ( ! PlayerList [ nPlayer ] . invincibility | | edx > 0 )
{
PlayerList [ nPlayer ] . nHealth + = edx ;
if ( PlayerList [ nPlayer ] . nHealth > 800 )
{
PlayerList [ nPlayer ] . nHealth = 800 ;
}
else
{
if ( PlayerList [ nPlayer ] . nHealth < 0 )
{
var_88 = - 1 ;
StartDeathSeq ( nPlayer , 0 ) ;
}
}
}
if ( var_70 = = 12 )
{
sprite [ nValB ] . hitag = 0 ;
sprite [ nValB ] . picnum + + ;
changespritestat ( nValB , 0 ) ;
// loc_1BA74: - repeated block, see in default case
if ( nPlayer = = nLocalPlayer )
{
if ( nItemText [ var_70 ] > - 1 & & nTotalPlayers = = 1 )
{
2020-08-22 18:14:00 +00:00
pickupMessage ( var_70 ) ;
2019-08-31 07:47:15 +00:00
}
2019-10-12 21:09:55 +00:00
TintPalette ( var_44 * 4 , var_8C * 4 , 0 ) ;
2019-08-31 07:47:15 +00:00
if ( var_88 > - 1 )
{
PlayLocalSound ( var_88 , 0 ) ;
}
}
break ;
}
else
{
if ( var_70 ! = 14 )
{
var_88 = 21 ;
}
else
{
var_44 = var_8C ;
var_88 = 22 ;
var_8C = 0 ;
}
goto do_default ;
}
}
break ;
}
case 7 : // Blood Bowl
{
int edx = 160 ;
// Same code as case 6 now till break
if ( edx < = 0 | | ( ! ( var_30 & 2 ) ) )
{
if ( ! PlayerList [ nPlayer ] . invincibility | | edx > 0 )
{
PlayerList [ nPlayer ] . nHealth + = edx ;
if ( PlayerList [ nPlayer ] . nHealth > 800 )
{
PlayerList [ nPlayer ] . nHealth = 800 ;
}
else
{
if ( PlayerList [ nPlayer ] . nHealth < 0 )
{
var_88 = - 1 ;
StartDeathSeq ( nPlayer , 0 ) ;
}
}
}
if ( var_70 = = 12 )
{
sprite [ nValB ] . hitag = 0 ;
sprite [ nValB ] . picnum + + ;
changespritestat ( nValB , 0 ) ;
// loc_1BA74: - repeated block, see in default case
if ( nPlayer = = nLocalPlayer )
{
if ( nItemText [ var_70 ] > - 1 & & nTotalPlayers = = 1 )
{
2020-08-22 18:14:00 +00:00
pickupMessage ( var_70 ) ;
2019-08-31 07:47:15 +00:00
}
2019-10-12 21:09:55 +00:00
TintPalette ( var_44 * 4 , var_8C * 4 , 0 ) ;
2019-08-31 07:47:15 +00:00
if ( var_88 > - 1 )
{
PlayLocalSound ( var_88 , 0 ) ;
}
}
break ;
}
else
{
if ( var_70 ! = 14 )
{
var_88 = 21 ;
}
else
{
var_44 = var_8C ;
var_88 = 22 ;
var_8C = 0 ;
}
goto do_default ;
}
}
break ;
}
case 8 : // Cobra Venom Bowl
{
2019-11-16 12:37:21 +00:00
int edx = - 200 ;
2019-08-31 07:47:15 +00:00
// Same code as case 6 and 7 from now till break
if ( edx < = 0 | | ( ! ( var_30 & 2 ) ) )
{
if ( ! PlayerList [ nPlayer ] . invincibility | | edx > 0 )
{
PlayerList [ nPlayer ] . nHealth + = edx ;
if ( PlayerList [ nPlayer ] . nHealth > 800 )
{
PlayerList [ nPlayer ] . nHealth = 800 ;
}
else
{
if ( PlayerList [ nPlayer ] . nHealth < 0 )
{
var_88 = - 1 ;
StartDeathSeq ( nPlayer , 0 ) ;
}
}
}
if ( var_70 = = 12 )
{
sprite [ nValB ] . hitag = 0 ;
sprite [ nValB ] . picnum + + ;
changespritestat ( nValB , 0 ) ;
// loc_1BA74: - repeated block, see in default case
if ( nPlayer = = nLocalPlayer )
{
if ( nItemText [ var_70 ] > - 1 & & nTotalPlayers = = 1 )
{
2020-08-22 18:14:00 +00:00
pickupMessage ( var_70 ) ;
2019-08-31 07:47:15 +00:00
}
2019-10-12 21:09:55 +00:00
TintPalette ( var_44 * 4 , var_8C * 4 , 0 ) ;
2019-08-31 07:47:15 +00:00
if ( var_88 > - 1 )
{
PlayLocalSound ( var_88 , 0 ) ;
}
}
break ;
}
else
{
if ( var_70 ! = 14 )
{
var_88 = 21 ;
}
else
{
var_44 = var_8C ;
var_88 = 22 ;
var_8C = 0 ;
}
goto do_default ;
}
}
break ;
}
case 11 : // Bubble Nest
{
PlayerList [ nPlayer ] . nAir + = 10 ;
if ( PlayerList [ nPlayer ] . nAir > 100 ) {
PlayerList [ nPlayer ] . nAir = 100 ; // TODO - constant
}
if ( nBreathTimer [ nPlayer ] < 89 )
{
D3PlayFX ( StaticSound [ kSound13 ] , nPlayerSprite ) ;
}
nBreathTimer [ nPlayer ] = 90 ;
break ;
}
case 12 : // Still Beating Heart
{
if ( GrabItem ( nPlayer , kItemHeart ) ) {
goto do_default ;
}
break ;
}
case 13 : // Scarab amulet(Invicibility)
{
if ( GrabItem ( nPlayer , kItemInvincibility ) ) {
goto do_default ;
}
break ;
}
case 14 : // Severed Slave Hand(double damage)
{
if ( GrabItem ( nPlayer , kItemDoubleDamage ) ) {
goto do_default ;
}
break ;
}
case 15 : // Unseen eye(Invisibility)
{
if ( GrabItem ( nPlayer , kItemInvisibility ) ) {
goto do_default ;
}
break ;
}
case 16 : // Torch
{
if ( GrabItem ( nPlayer , kItemTorch ) ) {
goto do_default ;
}
break ;
}
case 17 : // Sobek Mask
{
if ( GrabItem ( nPlayer , kItemMask ) ) {
goto do_default ;
}
break ;
}
case 19 : // Extra Life
{
var_88 = - 1 ;
2019-11-20 16:21:32 +00:00
2021-05-13 17:06:38 +00:00
if ( PlayerList [ nPlayer ] . nLives > = kMaxPlayerLives ) {
2019-08-31 07:47:15 +00:00
break ;
}
2021-05-13 17:06:38 +00:00
PlayerList [ nPlayer ] . nLives + + ;
2019-08-31 07:47:15 +00:00
var_8C = 32 ;
var_44 = 32 ;
goto do_default ;
}
// FIXME - lots of repeated code from here down!!
case 20 : // sword pickup??
{
var_40 = 0 ;
int ebx = 0 ;
// loc_1B75D
int var_18 = 1 < < var_40 ;
short weapons = nPlayerWeapons [ nPlayer ] ;
if ( weapons & var_18 )
{
2020-09-08 16:07:52 +00:00
if ( mplevel )
2019-08-31 07:47:15 +00:00
{
AddAmmo ( nPlayer , WeaponInfo [ var_40 ] . nAmmoType , ebx ) ;
}
}
else
{
weapons = var_40 ;
SetNewWeaponIfBetter ( nPlayer , weapons ) ;
nPlayerWeapons [ nPlayer ] | = var_18 ;
AddAmmo ( nPlayer , WeaponInfo [ weapons ] . nAmmoType , ebx ) ;
2019-11-13 22:57:21 +00:00
var_88 = StaticSound [ kSound72 ] ;
2019-08-31 07:47:15 +00:00
}
if ( var_40 = = 2 ) {
CheckClip ( nPlayer ) ;
}
if ( var_70 < = 50 ) {
goto do_default ;
}
sprite [ nValB ] . cstat = 0x8000 ;
DestroyItemAnim ( nValB ) ;
2019-08-26 03:59:14 +00:00
////
2019-08-31 07:47:15 +00:00
// loc_1BA74: - repeated block, see in default case
if ( nPlayer = = nLocalPlayer )
{
if ( nItemText [ var_70 ] > - 1 & & nTotalPlayers = = 1 )
{
2020-08-22 18:14:00 +00:00
pickupMessage ( var_70 ) ;
2019-08-31 07:47:15 +00:00
}
2019-10-12 21:09:55 +00:00
TintPalette ( var_44 * 4 , var_8C * 4 , 0 ) ;
2019-08-31 07:47:15 +00:00
if ( var_88 > - 1 )
{
PlayLocalSound ( var_88 , 0 ) ;
}
}
break ;
2019-08-26 03:59:14 +00:00
/////
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
case 22 : // .357 Magnum Revolver
case 46 :
{
var_40 = 1 ;
int ebx = 6 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
// loc_1B75D
int var_18 = 1 < < var_40 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
short weapons = nPlayerWeapons [ nPlayer ] ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( weapons & var_18 )
{
2020-09-08 16:07:52 +00:00
if ( mplevel )
2019-08-31 07:47:15 +00:00
{
AddAmmo ( nPlayer , WeaponInfo [ var_40 ] . nAmmoType , ebx ) ;
}
}
else
{
weapons = var_40 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
SetNewWeaponIfBetter ( nPlayer , weapons ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
nPlayerWeapons [ nPlayer ] | = var_18 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
AddAmmo ( nPlayer , WeaponInfo [ weapons ] . nAmmoType , ebx ) ;
2019-11-13 22:57:21 +00:00
var_88 = StaticSound [ kSound72 ] ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( var_40 = = 2 ) {
CheckClip ( nPlayer ) ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( var_70 < = 50 ) {
goto do_default ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sprite [ nValB ] . cstat = 0x8000 ;
DestroyItemAnim ( nValB ) ;
2019-08-26 03:59:14 +00:00
////
2019-08-31 07:47:15 +00:00
// loc_1BA74: - repeated block, see in default case
if ( nPlayer = = nLocalPlayer )
{
if ( nItemText [ var_70 ] > - 1 & & nTotalPlayers = = 1 )
{
2020-08-22 18:14:00 +00:00
pickupMessage ( var_70 ) ;
2019-08-31 07:47:15 +00:00
}
2019-10-12 21:09:55 +00:00
TintPalette ( var_44 * 4 , var_8C * 4 , 0 ) ;
2019-08-31 07:47:15 +00:00
if ( var_88 > - 1 )
{
PlayLocalSound ( var_88 , 0 ) ;
}
}
break ;
2019-08-26 03:59:14 +00:00
/////
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
case 23 : // M - 60 Machine Gun
case 47 :
{
var_40 = 2 ;
int ebx = 24 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
// loc_1B75D
int var_18 = 1 < < var_40 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
short weapons = nPlayerWeapons [ nPlayer ] ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( weapons & var_18 )
{
2020-09-08 16:07:52 +00:00
if ( mplevel )
2019-08-31 07:47:15 +00:00
{
AddAmmo ( nPlayer , WeaponInfo [ var_40 ] . nAmmoType , ebx ) ;
}
}
else
{
weapons = var_40 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
SetNewWeaponIfBetter ( nPlayer , weapons ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
nPlayerWeapons [ nPlayer ] | = var_18 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
AddAmmo ( nPlayer , WeaponInfo [ weapons ] . nAmmoType , ebx ) ;
2019-11-13 22:57:21 +00:00
var_88 = StaticSound [ kSound72 ] ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( var_40 = = 2 ) {
CheckClip ( nPlayer ) ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( var_70 < = 50 ) {
goto do_default ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sprite [ nValB ] . cstat = 0x8000 ;
DestroyItemAnim ( nValB ) ;
2019-08-26 03:59:14 +00:00
////
2019-08-31 07:47:15 +00:00
// loc_1BA74: - repeated block, see in default case
if ( nPlayer = = nLocalPlayer )
{
if ( nItemText [ var_70 ] > - 1 & & nTotalPlayers = = 1 )
{
2020-08-22 18:14:00 +00:00
pickupMessage ( var_70 ) ;
2019-08-31 07:47:15 +00:00
}
2019-10-12 21:09:55 +00:00
TintPalette ( var_44 * 4 , var_8C * 4 , 0 ) ;
2019-08-31 07:47:15 +00:00
if ( var_88 > - 1 )
{
PlayLocalSound ( var_88 , 0 ) ;
}
}
break ;
2019-08-26 03:59:14 +00:00
/////
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
case 24 : // Flame Thrower
case 48 :
{
var_40 = 3 ;
int ebx = 100 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
// loc_1B75D
int var_18 = 1 < < var_40 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
short weapons = nPlayerWeapons [ nPlayer ] ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( weapons & var_18 )
{
2020-09-08 16:07:52 +00:00
if ( mplevel )
2019-08-31 07:47:15 +00:00
{
AddAmmo ( nPlayer , WeaponInfo [ var_40 ] . nAmmoType , ebx ) ;
}
}
else
{
weapons = var_40 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
SetNewWeaponIfBetter ( nPlayer , weapons ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
nPlayerWeapons [ nPlayer ] | = var_18 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
AddAmmo ( nPlayer , WeaponInfo [ weapons ] . nAmmoType , ebx ) ;
2019-11-13 22:57:21 +00:00
var_88 = StaticSound [ kSound72 ] ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( var_40 = = 2 ) {
CheckClip ( nPlayer ) ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( var_70 < = 50 ) {
goto do_default ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sprite [ nValB ] . cstat = 0x8000 ;
DestroyItemAnim ( nValB ) ;
2019-08-26 03:59:14 +00:00
////
2019-08-31 07:47:15 +00:00
// loc_1BA74: - repeated block, see in default case
if ( nPlayer = = nLocalPlayer )
{
if ( nItemText [ var_70 ] > - 1 & & nTotalPlayers = = 1 )
{
2020-08-22 18:14:00 +00:00
pickupMessage ( var_70 ) ;
2019-08-31 07:47:15 +00:00
}
2019-10-12 21:09:55 +00:00
TintPalette ( var_44 * 4 , var_8C * 4 , 0 ) ;
2019-08-31 07:47:15 +00:00
if ( var_88 > - 1 )
{
PlayLocalSound ( var_88 , 0 ) ;
}
}
break ;
2019-08-26 03:59:14 +00:00
/////
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
case 26 : // Cobra Staff
case 50 :
{
var_40 = 5 ;
int ebx = 20 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
// loc_1B75D
int var_18 = 1 < < var_40 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
short weapons = nPlayerWeapons [ nPlayer ] ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( weapons & var_18 )
{
2020-09-08 16:07:52 +00:00
if ( mplevel )
2019-08-31 07:47:15 +00:00
{
AddAmmo ( nPlayer , WeaponInfo [ var_40 ] . nAmmoType , ebx ) ;
}
}
else
{
weapons = var_40 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
SetNewWeaponIfBetter ( nPlayer , weapons ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
nPlayerWeapons [ nPlayer ] | = var_18 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
AddAmmo ( nPlayer , WeaponInfo [ weapons ] . nAmmoType , ebx ) ;
2019-11-13 22:57:21 +00:00
var_88 = StaticSound [ kSound72 ] ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( var_40 = = 2 ) {
CheckClip ( nPlayer ) ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( var_70 < = 50 ) {
goto do_default ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sprite [ nValB ] . cstat = 0x8000 ;
DestroyItemAnim ( nValB ) ;
2019-08-26 03:59:14 +00:00
////
2019-08-31 07:47:15 +00:00
// loc_1BA74: - repeated block, see in default case
if ( nPlayer = = nLocalPlayer )
{
if ( nItemText [ var_70 ] > - 1 & & nTotalPlayers = = 1 )
{
2020-08-22 18:14:00 +00:00
pickupMessage ( var_70 ) ;
2019-08-31 07:47:15 +00:00
}
2019-10-12 21:09:55 +00:00
TintPalette ( var_44 * 4 , var_8C * 4 , 0 ) ;
2019-08-31 07:47:15 +00:00
if ( var_88 > - 1 )
{
PlayLocalSound ( var_88 , 0 ) ;
}
}
break ;
2019-08-26 03:59:14 +00:00
/////
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
case 27 : // Eye of Ra Gauntlet
case 51 :
{
var_40 = 6 ;
int ebx = 2 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
// loc_1B75D
int var_18 = 1 < < var_40 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
short weapons = nPlayerWeapons [ nPlayer ] ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( weapons & var_18 )
{
2020-09-08 16:07:52 +00:00
if ( mplevel )
2019-08-31 07:47:15 +00:00
{
AddAmmo ( nPlayer , WeaponInfo [ var_40 ] . nAmmoType , ebx ) ;
}
}
else
{
weapons = var_40 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
SetNewWeaponIfBetter ( nPlayer , weapons ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
nPlayerWeapons [ nPlayer ] | = var_18 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
AddAmmo ( nPlayer , WeaponInfo [ weapons ] . nAmmoType , ebx ) ;
2019-11-13 22:57:21 +00:00
var_88 = StaticSound [ kSound72 ] ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( var_40 = = 2 ) {
CheckClip ( nPlayer ) ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( var_70 < = 50 ) {
goto do_default ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sprite [ nValB ] . cstat = 0x8000 ;
DestroyItemAnim ( nValB ) ;
2019-08-26 03:59:14 +00:00
////
2019-08-31 07:47:15 +00:00
// loc_1BA74: - repeated block, see in default case
if ( nPlayer = = nLocalPlayer )
{
if ( nItemText [ var_70 ] > - 1 & & nTotalPlayers = = 1 )
{
2020-08-22 18:14:00 +00:00
pickupMessage ( var_70 ) ;
2019-08-31 07:47:15 +00:00
}
2019-10-12 21:09:55 +00:00
TintPalette ( var_44 * 4 , var_8C * 4 , 0 ) ;
2019-08-31 07:47:15 +00:00
if ( var_88 > - 1 )
{
PlayLocalSound ( var_88 , 0 ) ;
}
}
break ;
2019-08-26 03:59:14 +00:00
/////
2019-08-31 07:47:15 +00:00
}
case 31 : // Cobra staff ammo
{
if ( AddAmmo ( nPlayer , 5 , 1 ) ) {
2020-02-04 21:45:10 +00:00
var_88 = StaticSound [ kSoundAmmoPickup ] ;
2019-08-31 07:47:15 +00:00
goto do_default ;
}
2019-11-20 16:21:32 +00:00
2019-08-31 07:47:15 +00:00
break ;
}
case 32 : // Raw Energy
{
if ( AddAmmo ( nPlayer , 6 , sprite [ nValB ] . hitag ) ) {
2020-02-04 21:45:10 +00:00
var_88 = StaticSound [ kSoundAmmoPickup ] ;
2019-08-31 07:47:15 +00:00
goto do_default ;
}
break ;
}
case 39 : // Power key
case 40 : // Time key
case 41 : // War key
case 42 : // Earth key
{
2021-05-13 10:58:30 +00:00
int keybit = 4096 < < ( itemtype - 39 ) ;
2019-08-31 07:47:15 +00:00
var_88 = - 1 ;
2021-05-13 10:58:30 +00:00
if ( ! ( PlayerList [ nPlayer ] . keys & keybit ) )
2019-08-31 07:47:15 +00:00
{
2021-05-13 10:58:30 +00:00
PlayerList [ nPlayer ] . keys | = keybit ;
2019-08-31 07:47:15 +00:00
if ( nTotalPlayers > 1 )
{
goto do_default_b ;
}
else
{
goto do_default ;
}
}
break ;
}
case 43 : // Magical Essence
case 44 : // ?
{
if ( PlayerList [ nPlayer ] . nMagic > = 1000 ) {
break ;
}
2019-11-20 16:21:32 +00:00
2020-02-04 21:45:10 +00:00
var_88 = StaticSound [ kSoundMana1 ] ;
2019-08-31 07:47:15 +00:00
PlayerList [ nPlayer ] . nMagic + = 100 ;
if ( PlayerList [ nPlayer ] . nMagic > = 1000 ) {
PlayerList [ nPlayer ] . nMagic = 1000 ;
}
goto do_default ;
}
case 53 : // Scarab (Checkpoint)
{
if ( nLocalPlayer = = nPlayer )
{
short nAnim = sprite [ nValB ] . owner ;
AnimList [ nAnim ] . nSeq + + ;
2020-11-29 23:47:53 +00:00
AnimList [ nAnim ] . AnimFlags & = 0xEF ;
2019-08-31 07:47:15 +00:00
AnimList [ nAnim ] . field_2 = 0 ;
changespritestat ( nValB , 899 ) ;
}
SetSavePoint ( nPlayer , sprite [ nPlayerSprite ] . x , sprite [ nPlayerSprite ] . y , sprite [ nPlayerSprite ] . z , sprite [ nPlayerSprite ] . sectnum , sprite [ nPlayerSprite ] . ang ) ;
break ;
}
case 54 : // Golden Sarcophagus (End Level)
{
2020-08-22 07:31:17 +00:00
if ( ! bInDemo )
{
2020-09-11 18:56:46 +00:00
LevelFinished ( ) ;
2019-08-31 07:47:15 +00:00
}
DestroyItemAnim ( nValB ) ;
mydeletesprite ( nValB ) ;
break ;
}
}
}
}
// CORRECT ? // loc_1BAF9:
if ( bTouchFloor )
{
if ( sector [ sprite [ nPlayerSprite ] . sectnum ] . lotag > 0 )
{
runlist_SignalRun ( sector [ sprite [ nPlayerSprite ] . sectnum ] . lotag - 1 , nPlayer | 0x50000 ) ;
}
}
if ( nSector ! = sprite [ nPlayerSprite ] . sectnum )
{
if ( sector [ nSector ] . lotag > 0 )
{
runlist_SignalRun ( sector [ nSector ] . lotag - 1 , nPlayer | 0x70000 ) ;
}
if ( sector [ sprite [ nPlayerSprite ] . sectnum ] . lotag > 0 )
{
runlist_SignalRun ( sector [ sprite [ nPlayerSprite ] . sectnum ] . lotag - 1 , nPlayer | 0x60000 ) ;
}
}
if ( ! PlayerList [ nPlayer ] . bIsMummified )
{
2020-08-28 20:51:05 +00:00
if ( actions & SB_OPEN )
2019-08-31 07:47:15 +00:00
{
ClearSpaceBar ( nPlayer ) ;
if ( nearTagWall > = 0 & & wall [ nearTagWall ] . lotag > 0 )
{
runlist_SignalRun ( wall [ nearTagWall ] . lotag - 1 , nPlayer | 0x40000 ) ;
}
if ( nearTagSector > = 0 & & sector [ nearTagSector ] . lotag > 0 )
{
runlist_SignalRun ( sector [ nearTagSector ] . lotag - 1 , nPlayer | 0x40000 ) ;
}
}
// was int var_38 = buttons & 0x8
2020-08-28 20:51:05 +00:00
if ( actions & SB_FIRE )
2019-08-31 07:47:15 +00:00
{
FireWeapon ( nPlayer ) ;
}
else
{
StopFiringWeapon ( nPlayer ) ;
}
// loc_1BC57:
// CHECKME - are we finished with 'nSector' variable at this point? if so, maybe set it to sprite[nPlayerSprite].sectnum so we can make this code a bit neater. Don't assume sprite[nPlayerSprite].sectnum == nSector here!!
if ( nStandHeight > ( sector [ sprite [ nPlayerSprite ] . sectnum ] . floorz - sector [ sprite [ nPlayerSprite ] . sectnum ] . ceilingz ) ) {
var_48 = 1 ;
}
// Jumping
2020-08-28 20:51:05 +00:00
if ( actions & SB_JUMP )
2019-08-31 07:47:15 +00:00
{
if ( bUnderwater )
{
sprite [ nPlayerSprite ] . zvel = - 2048 ;
nActionB = 10 ;
}
else if ( bTouchFloor )
{
if ( nAction < 6 | | nAction > 8 )
{
sprite [ nPlayerSprite ] . zvel = - 3584 ;
nActionB = 3 ;
}
}
// goto loc_1BE70:
}
2020-08-28 20:51:05 +00:00
else if ( actions & SB_CROUCH )
2019-08-31 07:47:15 +00:00
{
if ( bUnderwater )
{
sprite [ nPlayerSprite ] . zvel = 2048 ;
nActionB = 10 ;
}
else
{
2019-12-03 00:23:09 +00:00
if ( eyelevel [ nPlayer ] < - 8320 ) {
eyelevel [ nPlayer ] + = ( ( - 8320 - eyelevel [ nPlayer ] ) > > 1 ) ;
2019-08-31 07:47:15 +00:00
}
2019-12-03 00:23:09 +00:00
loc_1BD2E :
2019-08-31 07:47:15 +00:00
if ( totalvel [ nPlayer ] < 1 ) {
nActionB = 6 ;
}
else {
nActionB = 7 ;
}
}
// goto loc_1BE70:
}
else
{
if ( PlayerList [ nPlayer ] . nHealth > 0 )
{
int var_EC = nActionEyeLevel [ nAction ] ;
eyelevel [ nPlayer ] + = ( var_EC - eyelevel [ nPlayer ] ) > > 1 ;
if ( bUnderwater )
{
if ( totalvel [ nPlayer ] < = 1 )
nActionB = 9 ;
else
nActionB = 10 ;
}
else
{
// CHECKME - confirm branching in this area is OK
if ( var_48 )
{
2019-12-03 00:23:09 +00:00
goto loc_1BD2E ;
2019-08-31 07:47:15 +00:00
}
else
{
if ( totalvel [ nPlayer ] < = 1 ) {
nActionB = 0 ; //bUnderwater; // this is just setting to 0
}
else if ( totalvel [ nPlayer ] < = 30 ) {
nActionB = 2 ;
}
else
{
nActionB = 1 ;
}
}
}
}
2019-12-03 00:23:09 +00:00
// loc_1BE30
2020-08-28 20:51:05 +00:00
if ( actions & SB_FIRE ) // was var_38
2019-08-31 07:47:15 +00:00
{
2019-12-03 00:23:09 +00:00
if ( bUnderwater )
2019-08-31 07:47:15 +00:00
{
2019-12-03 00:23:09 +00:00
nActionB = 11 ;
}
else
{
if ( nActionB ! = 2 & & nActionB ! = 1 )
2019-08-31 07:47:15 +00:00
{
2019-12-03 00:23:09 +00:00
nActionB = 5 ;
2019-08-31 07:47:15 +00:00
}
}
}
}
// loc_1BE70:
// Handle player pressing number keys to change weapon
2020-08-26 22:58:21 +00:00
uint8_t var_90 = sPlayerInput [ nPlayer ] . getNewWeapon ( ) ;
2019-08-31 07:47:15 +00:00
if ( var_90 )
{
var_90 - - ;
if ( nPlayerWeapons [ nPlayer ] & ( 1 < < var_90 ) )
{
SetNewWeapon ( nPlayer , var_90 ) ;
}
}
}
else // player is mummified
{
2020-08-28 20:51:05 +00:00
if ( actions & SB_FIRE )
2019-08-31 07:47:15 +00:00
{
FireWeapon ( nPlayer ) ;
}
if ( nAction ! = 15 )
{
if ( totalvel [ nPlayer ] < = 1 )
{
nActionB = 13 ;
}
else
{
nActionB = 14 ;
}
}
}
// loc_1BF09
if ( nActionB ! = nAction & & nAction ! = 4 )
{
nAction = nActionB ;
PlayerList [ nPlayer ] . nAction = nActionB ;
PlayerList [ nPlayer ] . field_2 = 0 ;
}
2020-09-21 10:37:09 +00:00
2021-04-13 11:56:01 +00:00
Player * pPlayer = & PlayerList [ nPlayer ] ;
2020-11-30 22:40:16 +00:00
if ( SyncInput ( ) )
2020-09-21 10:37:09 +00:00
{
2021-04-21 10:41:04 +00:00
pPlayer - > horizon . applyinput ( sPlayerInput [ nPlayer ] . pan , & sPlayerInput [ nLocalPlayer ] . actions ) ;
2020-09-21 10:37:09 +00:00
}
2021-04-13 11:56:01 +00:00
2021-04-19 10:23:22 +00:00
if ( actions & ( SB_LOOK_UP | SB_LOOK_DOWN ) | | sPlayerInput [ nPlayer ] . pan )
2021-04-13 11:56:01 +00:00
{
pPlayer - > nDestVertPan = pPlayer - > horizon . horiz ;
pPlayer - > bPlayerPan = pPlayer - > bLockPan = true ;
}
2021-04-19 10:23:22 +00:00
else if ( actions & ( SB_AIM_UP | SB_AIM_DOWN | SB_CENTERVIEW ) )
{
pPlayer - > nDestVertPan = pPlayer - > horizon . horiz ;
pPlayer - > bPlayerPan = pPlayer - > bLockPan = false ;
}
2021-04-13 11:56:01 +00:00
if ( totalvel [ nPlayer ] > 20 )
{
pPlayer - > bPlayerPan = false ;
}
2021-04-16 13:37:05 +00:00
if ( cl_slopetilting )
2021-04-13 11:56:01 +00:00
{
2021-04-18 00:04:17 +00:00
double nVertPan = ( pPlayer - > nDestVertPan - pPlayer - > horizon . horiz ) . asbuildf ( ) * 0.25 ;
2021-04-16 13:37:05 +00:00
if ( nVertPan ! = 0 )
{
pPlayer - > horizon . addadjustment ( abs ( nVertPan ) > = 4 ? clamp ( nVertPan , - 4 , 4 ) : nVertPan * 2. ) ;
}
2021-04-13 11:56:01 +00:00
}
2019-08-31 07:47:15 +00:00
}
else // else, player's health is less than 0
{
// loc_1C0E9
2020-08-28 20:51:05 +00:00
if ( actions & SB_OPEN )
2019-08-31 07:47:15 +00:00
{
ClearSpaceBar ( nPlayer ) ;
if ( nAction > = 16 )
{
if ( nPlayer = = nLocalPlayer )
{
StopAllSounds ( ) ;
StopLocalSound ( ) ;
GrabPalette ( ) ;
}
PlayerList [ nPlayer ] . nCurrentWeapon = nPlayerOldWeapon [ nPlayer ] ;
2021-05-13 17:06:38 +00:00
if ( PlayerList [ nPlayer ] . nLives & & nNetTime )
2019-08-31 07:47:15 +00:00
{
if ( nAction ! = 20 )
{
sprite [ nPlayerSprite ] . picnum = seq_GetSeqPicnum ( kSeqJoe , 120 , 0 ) ;
sprite [ nPlayerSprite ] . cstat = 0 ;
sprite [ nPlayerSprite ] . z = sector [ sprite [ nPlayerSprite ] . sectnum ] . floorz ;
}
// will invalidate nPlayerSprite
RestartPlayer ( nPlayer ) ;
nPlayerSprite = PlayerList [ nPlayer ] . nSprite ;
nDopple = nDoppleSprite [ nPlayer ] ;
}
else
{
2020-09-08 16:07:52 +00:00
DoGameOverScene ( mplevel ) ;
2020-08-23 10:26:52 +00:00
return ;
2019-08-31 07:47:15 +00:00
}
}
}
}
// loc_1C201:
if ( nLocalPlayer = = nPlayer )
{
nLocalEyeSect = nPlayerViewSect [ nLocalPlayer ] ;
CheckAmbience ( nLocalEyeSect ) ;
}
2020-10-11 09:33:28 +00:00
int var_AC = SeqOffsets [ PlayerList [ nPlayer ] . nSeq ] + PlayerSeq [ nAction ] . a ;
2019-08-31 07:47:15 +00:00
seq_MoveSequence ( nPlayerSprite , var_AC , PlayerList [ nPlayer ] . field_2 ) ;
PlayerList [ nPlayer ] . field_2 + + ;
if ( PlayerList [ nPlayer ] . field_2 > = SeqSize [ var_AC ] )
{
PlayerList [ nPlayer ] . field_2 = 0 ;
switch ( PlayerList [ nPlayer ] . nAction )
{
default :
break ;
case 3 :
PlayerList [ nPlayer ] . field_2 = SeqSize [ var_AC ] - 1 ;
break ;
case 4 :
PlayerList [ nPlayer ] . nAction = 0 ;
break ;
case 16 :
PlayerList [ nPlayer ] . field_2 = SeqSize [ var_AC ] - 1 ;
if ( sprite [ nPlayerSprite ] . z < sector [ sprite [ nPlayerSprite ] . sectnum ] . floorz ) {
sprite [ nPlayerSprite ] . z + = 256 ;
}
if ( ! RandomSize ( 5 ) )
{
int mouthX , mouthY , mouthZ ;
short mouthSect ;
WheresMyMouth ( nPlayer , & mouthX , & mouthY , & mouthZ , & mouthSect ) ;
BuildAnim ( - 1 , 71 , 0 , mouthX , mouthY , sprite [ nPlayerSprite ] . z + 3840 , mouthSect , 75 , 128 ) ;
}
break ;
case 17 :
PlayerList [ nPlayer ] . nAction = 18 ;
break ;
case 19 :
sprite [ nPlayerSprite ] . cstat | = 0x8000 ;
PlayerList [ nPlayer ] . nAction = 20 ;
break ;
}
}
// loc_1C3B4:
if ( nPlayer = = nLocalPlayer )
{
initx = sprite [ nPlayerSprite ] . x ;
inity = sprite [ nPlayerSprite ] . y ;
initz = sprite [ nPlayerSprite ] . z ;
initsect = sprite [ nPlayerSprite ] . sectnum ;
inita = sprite [ nPlayerSprite ] . ang ;
}
if ( ! PlayerList [ nPlayer ] . nHealth )
{
nYDamage [ nPlayer ] = 0 ;
nXDamage [ nPlayer ] = 0 ;
if ( eyelevel [ nPlayer ] > = - 2816 )
{
eyelevel [ nPlayer ] = - 2816 ;
dVertPan [ nPlayer ] = 0 ;
}
else
{
2020-10-07 06:40:59 +00:00
if ( PlayerList [ nPlayer ] . horizon . horiz . asq16 ( ) < 0 )
2019-08-31 07:47:15 +00:00
{
2020-10-07 06:40:59 +00:00
PlayerList [ nPlayer ] . horizon . settarget ( 0 ) ;
2019-08-31 07:47:15 +00:00
eyelevel [ nPlayer ] - = ( dVertPan [ nPlayer ] < < 8 ) ;
}
else
{
2020-10-07 06:40:59 +00:00
PlayerList [ nPlayer ] . horizon . addadjustment ( dVertPan [ nPlayer ] ) ;
2020-09-21 09:28:39 +00:00
2020-10-07 06:40:59 +00:00
if ( PlayerList [ nPlayer ] . horizon . horiz . asq16 ( ) > gi - > playerHorizMax ( ) )
2019-08-31 07:47:15 +00:00
{
2020-10-07 06:40:59 +00:00
PlayerList [ nPlayer ] . horizon . settarget ( gi - > playerHorizMax ( ) ) ;
2019-08-31 07:47:15 +00:00
}
2020-10-07 06:40:59 +00:00
else if ( PlayerList [ nPlayer ] . horizon . horiz . asq16 ( ) < = 0 )
2019-08-31 07:47:15 +00:00
{
if ( ! ( SectFlag [ sprite [ nPlayerSprite ] . sectnum ] & kSectUnderwater ) )
{
SetNewWeapon ( nPlayer , nDeathType [ nPlayer ] + 8 ) ;
}
}
dVertPan [ nPlayer ] - - ;
}
}
}
// loc_1C4E1
sprite [ nDopple ] . x = sprite [ nPlayerSprite ] . x ;
sprite [ nDopple ] . y = sprite [ nPlayerSprite ] . y ;
sprite [ nDopple ] . z = sprite [ nPlayerSprite ] . z ;
if ( SectAbove [ sprite [ nPlayerSprite ] . sectnum ] > - 1 )
{
sprite [ nDopple ] . ang = sprite [ nPlayerSprite ] . ang ;
mychangespritesect ( nDopple , SectAbove [ sprite [ nPlayerSprite ] . sectnum ] ) ;
sprite [ nDopple ] . cstat = 0x101 ;
}
else
{
sprite [ nDopple ] . cstat = 0x8000 ;
}
MoveWeapons ( nPlayer ) ;
return ;
}
}
2019-08-26 03:59:14 +00:00
}
2019-12-26 21:00:04 +00:00
2020-11-29 23:47:53 +00:00
FSerializer & Serialize ( FSerializer & arc , const char * keyname , Player & w , Player * def )
{
if ( arc . BeginObject ( keyname ) )
{
arc ( " health " , w . nHealth )
( " at2 " , w . field_2 )
( " action " , w . nAction )
( " sprite " , w . nSprite )
( " mummy " , w . bIsMummified )
( " invincible " , w . invincibility )
( " air " , w . nAir )
( " seq " , w . nSeq )
2021-05-13 11:44:58 +00:00
( " item " , w . nItem )
2020-11-29 23:47:53 +00:00
( " maskamount " , w . nMaskAmount )
( " keys " , w . keys )
( " magic " , w . nMagic )
. Array ( " items " , w . items , countof ( w . items ) )
. Array ( " ammo " , w . nAmmo , countof ( w . nAmmo ) )
( " weapon " , w . nCurrentWeapon )
( " isfiring " , w . bIsFiring )
( " field3f " , w . field_3FOUR )
( " field38 " , w . field_38 )
( " field3a " , w . field_3A )
( " field3c " , w . field_3C )
( " seq " , w . nSeq )
( " horizon " , w . horizon )
( " angle " , w . angle )
2021-05-13 17:06:38 +00:00
( " lives " , w . nLives )
2021-05-13 17:15:53 +00:00
( " double " , w . nDouble )
( " invisible " , w . nInvisible )
( " torch " , w . nTorch )
2020-11-29 23:47:53 +00:00
. EndObject ( ) ;
}
return arc ;
}
FSerializer & Serialize ( FSerializer & arc , const char * keyname , PlayerSave & w , PlayerSave * def )
{
if ( arc . BeginObject ( keyname ) )
{
arc ( " x " , w . x )
( " y " , w . y )
( " z " , w . z )
( " sector " , w . nSector )
( " angle " , w . nAngle )
. EndObject ( ) ;
}
return arc ;
}
void SerializePlayer ( FSerializer & arc )
{
if ( arc . BeginObject ( " player " ) )
{
arc ( " lxvel " , lPlayerXVel )
( " lyvel " , lPlayerYVel )
( " bobangle " , bobangle )
( " standheight " , nStandHeight )
( " playercount " , PlayerCount )
( " netstartsprites " , nNetStartSprites )
( " localplayer " , nLocalPlayer )
. Array ( " grenadeplayer " , nGrenadePlayer , countof ( nGrenadePlayer ) )
. Array ( " curstartsprite " , nNetStartSprite , PlayerCount )
. Array ( " breathtimer " , nBreathTimer , PlayerCount )
. Array ( " playerswear " , nPlayerSwear , PlayerCount )
. Array ( " pushsect " , nPlayerPushSect , PlayerCount )
. Array ( " deathtype " , nDeathType , PlayerCount )
. Array ( " score " , nPlayerScore , PlayerCount )
. Array ( " color " , nPlayerColor , PlayerCount )
. Array ( " dx " , nPlayerDX , PlayerCount )
. Array ( " dy " , nPlayerDY , PlayerCount )
. Array ( " pistolclip " , nPistolClip , PlayerCount )
. Array ( " xdamage " , nXDamage , PlayerCount )
. Array ( " ydamage " , nYDamage , PlayerCount )
. Array ( " dopplesprite " , nDoppleSprite , PlayerCount )
. Array ( " oldweapon " , nPlayerOldWeapon , PlayerCount )
. Array ( " clip " , nPlayerClip , PlayerCount )
. Array ( " pushsound " , nPlayerPushSound , PlayerCount )
. Array ( " taunttimer " , nTauntTimer , PlayerCount )
. Array ( " weapons " , nPlayerWeapons , PlayerCount )
. Array ( " list " , PlayerList , PlayerCount )
. Array ( " viewsect " , nPlayerViewSect , PlayerCount )
. Array ( " floorspr " , nPlayerFloorSprite , PlayerCount )
. Array ( " save " , sPlayerSave , PlayerCount )
. Array ( " totalvel " , totalvel , PlayerCount )
. Array ( " eyelevel " , eyelevel , PlayerCount )
. Array ( " netstartsprite " , nNetStartSprite , PlayerCount )
. Array ( " grenade " , nPlayerGrenade , PlayerCount )
2021-05-13 11:44:58 +00:00
. Array ( " d282a " , word_D282A , PlayerCount ) ;
arc . EndObject ( ) ;
2020-11-29 23:47:53 +00:00
}
}
2019-12-26 21:00:04 +00:00
2021-05-13 20:28:02 +00:00
DEFINE_FIELD_X ( ExhumedPlayer , Player , nHealth ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , nLives ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , nDouble ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , nInvisible ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , nTorch ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , field_2 ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , nAction ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , nSprite ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , bIsMummified ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , invincibility ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , nAir ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , nSeq ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , nMaskAmount ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , keys ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , nMagic ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , nItem ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , items ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , nAmmo ) ; // TODO - kMaxWeapons?
DEFINE_FIELD_X ( ExhumedPlayer , Player , pad ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , nCurrentWeapon ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , field_3FOUR ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , bIsFiring ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , field_38 ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , field_3A ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , field_3C ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , nRun ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , bPlayerPan ) ;
DEFINE_FIELD_X ( ExhumedPlayer , Player , bLockPan ) ;
DEFINE_ACTION_FUNCTION ( _Exhumed , GetViewPlayer )
{
ACTION_RETURN_POINTER ( & PlayerList [ nLocalPlayer ] ) ;
}
2021-07-16 13:52:56 +00:00
DEFINE_ACTION_FUNCTION ( _Exhumed , GetPistolClip )
{
ACTION_RETURN_POINTER ( & nPistolClip [ nLocalPlayer ] ) ;
}
2021-07-17 04:57:43 +00:00
DEFINE_ACTION_FUNCTION ( _Exhumed , GetPlayerClip )
{
ACTION_RETURN_POINTER ( & nPlayerClip [ nLocalPlayer ] ) ;
}
2021-05-13 20:28:02 +00:00
DEFINE_ACTION_FUNCTION ( _ExhumedPlayer , IsUnderwater )
{
PARAM_SELF_STRUCT_PROLOGUE ( Player ) ;
auto nLocalPlayer = self - PlayerList ;
ACTION_RETURN_BOOL ( SectFlag [ nPlayerViewSect [ nLocalPlayer ] ] & kSectUnderwater ) ;
}
DEFINE_ACTION_FUNCTION ( _ExhumedPlayer , GetAngle )
{
PARAM_SELF_STRUCT_PROLOGUE ( Player ) ;
ACTION_RETURN_INT ( sprite [ self - > nSprite ] . ang ) ;
}
2019-11-22 23:11:37 +00:00
END_PS_NS